Skip to main content

clicd-virtualization-panel

Use CLICD to manage LXC/KVM virtualization with web console, NAT/IPv6 networking, WebSSH/VNC, resource controls, and security monitoring.

설치로 이동

소스 정보

저장소
reason-machines/devtools-skills
최근 소스 활동
2026년 6월 11일 00:02
감지된 SKILL.md 언어
영어
스타
4
포크
0

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
clicd-virtualization-panel
description
Use CLICD to manage LXC/KVM virtualization with web console, NAT/IPv6 networking, WebSSH/VNC, resource controls, and security monitoring.
triggers
["set up CLICD virtualization panel","manage LXC containers with CLICD","configure CLICD NAT networking","use CLICD REST API","create KVM virtual machines in CLICD","configure CLICD security alerts","manage CLICD user permissions","integrate CLICD with billing system"]
# CLICD Virtualization Panel Skill > Skill by [ara.so](https://ara.so) — Devtools Skills collection. CLICD is a lightweight virtualization management panel for LXC and KVM that provides a web console, CLI tools, REST API, NAT/IPv6 networking, WebSSH/WebVNC access, resource quotas, traffic limits, snapshots, delegated sub-user access, and security monitoring. Built with Go backend and React frontend. ## Installation ### One-Click Install ```bash # Install CLICD curl -fsSL https://raw.githubusercontent.com/MengMengCode/CLICD/main/install.sh | sudo sh # Uninstall CLICD curl -fsSL https://raw.githubusercontent.com/MengMengCode/CLICD/main/install.sh | sudo sh -s -- uninstall ``` ### Prerequisites - Linux system with systemd - LXC or KVM/QEMU installed - Root or sudo access - iptables and conntrack-tools ### Post-Installation After installation, CLICD runs as a systemd service: ```bash # Check service status sudo systemctl status clicd # View logs sudo journalctl -u clicd -f # Restart service sudo systemctl restart clicd ``` Access the web interface at `http://your-server-ip:8080` (default port). ## Configuration ### Main Configuration File Configuration is typically stored in `/etc/clicd/config.yaml` or similar location: ```yaml server: host: "0.0.0.0" port: 8080 tls: enabled: false cert_file: "" key_file: "" letsencrypt: false domain: "" database: type: "sqlite" path: "/var/lib/clicd/clicd.db" lxc: enabled: true default_storage_pool: "default" default_network: "lxcbr0" kvm: enabled: true default_storage_pool: "default" default_network: "virbr0" networking: nat4: enabled: true public_ip: "1.2.3.4" port_range_start: 10000 port_range_end: 60000 ipv6: enabled: true prefix: "2001:db8::/48" auto_detect: true security: alerts_enabled: true conntrack_monitoring: true admin: username: "admin" # Set password via CLI or web interface ``` ### Environment Variables ```bash # Override config file location export CLICD_CONFIG="/path/to/config.yaml" # Set admin password (first run) export CLICD_ADMIN_PASSWORD="your-secure-password" # Database path export CLICD_DB_PATH="/var/lib/clicd/clicd.db" # Log level export CLICD_LOG_LEVEL="info" ``` ## CLI Usage CLICD provides a CLI interface for common operations: ### Container Management ```bash # List all containers clicd container list # Create a new LXC container clicd container create \ --name web-server-01 \ --type lxc \ --template ubuntu-22.04 \ --cpu 2 \ --memory 2048 \ --disk 20 \ --ipv4 nat \ --ipv6 auto # Start a container clicd container start web-server-01 # Stop a container clicd container stop web-server-01 # Delete a container clicd container delete web-server-01 --force # Reset container password clicd container password web-server-01 --password "NewSecurePass123" # Batch operations clicd container batch-start --ids "1,2,3,4,5" clicd container batch-stop --pattern "test-*" ``` ### Image Management ```bash # List available images clicd image list # Download an image clicd image download ubuntu-22.04-lxc # Enable/disable images clicd image enable ubuntu-22.04-lxc clicd image disable centos-7-lxc # Clear image cache clicd image cache-clear ``` ### Networking ```bash # List NAT port mappings clicd nat list # Add port mapping clicd nat add \ --container web-server-01 \ --protocol tcp \ --public-port 8080 \ --private-port 80 # Remove port mapping clicd nat remove --id 123 # Check IPv6 status clicd ipv6 status # Assign IPv6 to container clicd ipv6 assign --container web-server-01 ``` ### User Management ```bash # Create sub-user clicd user create \ --username client01 \ --password "SecurePass123" \ --containers "web-server-01,db-server-01" # Generate delegation link clicd user link --username client01 # List users clicd user list # Update user permissions clicd user update --username client01 --add-container api-server-01 ``` ## REST API All API endpoints are versioned under `/api/v1`. Authentication uses API keys or session tokens. ### Authentication ```go package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" "os" ) type LoginRequest struct { Username string `json:"username"` Password string `json:"password"` } type LoginResponse struct { Token string `json:"token"` Message string `json:"message"` } func login() (string, error) { apiURL := os.Getenv("CLICD_API_URL") // e.g., http://localhost:8080 reqBody := LoginRequest{ Username: os.Getenv("CLICD_USERNAME"), Password: os.Getenv("CLICD_PASSWORD"), } jsonData, _ := json.Marshal(reqBody) resp, err := http.Post( apiURL+"/api/v1/auth/login", "application/json", bytes.NewBuffer(jsonData), ) if err != nil { return "", err } defer resp.Body.Close() var loginResp LoginResponse body, _ := io.ReadAll(resp.Body) json.Unmarshal(body, &loginResp) return loginResp.Token, nil } ``` ### Container Operations ```go type Container struct { ID int `json:"id"` Name string `json:"name"` Type string `json:"type"` // "lxc" or "kvm" Status string `json:"status"` CPU int `json:"cpu"` Memory int `json:"memory"` // MB Disk int `json:"disk"` // GB IPv4 string `json:"ipv4"` IPv6 string `json:"ipv6"` ExpiryDate string `json:"expiry_date"` } type CreateContainerRequest struct { Name string `json:"name"` Type string `json:"type"` Template string `json:"template"` CPU int `json:"cpu"` Memory int `json:"memory"` Disk int `json:"disk"` Password string `json:"password"` IPv4Type string `json:"ipv4_type"` // "nat" or "public" IPv6Enable bool `json:"ipv6_enable"` ExpiryDays int `json:"expiry_days"` } func createContainer(token string, req CreateContainerRequest) (*Container, error) { apiURL := os.Getenv("CLICD_API_URL") jsonData, _ := json.Marshal(req) httpReq, _ := http.NewRequest( "POST", apiURL+"/api/v1/containers", bytes.NewBuffer(jsonData), ) httpReq.Header.Set("Authorization", "Bearer "+token) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} resp, err := client.Do(httpReq) if err != nil { return nil, err } defer resp.Body.Close() var container Container body, _ := io.ReadAll(resp.Body) json.Unmarshal(body, &container) return &container, nil } func listContainers(token string) ([]Container, error) { apiURL := os.Getenv("CLICD_API_URL") httpReq, _ := http.NewRequest("GET", apiURL+"/api/v1/containers", nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(httpReq) if err != nil { return nil, err } defer resp.Body.Close() var containers []Container body, _ := io.ReadAll(resp.Body) json.Unmarshal(body, &containers) return containers, nil } func startContainer(token string, containerID int) error { apiURL := os.Getenv("CLICD_API_URL") httpReq, _ := http.NewRequest( "POST", fmt.Sprintf("%s/api/v1/containers/%d/start", apiURL, containerID), nil, ) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(httpReq) if err != nil { return err } defer resp.Body.Close() return nil } func deleteContainer(token string, containerID int, force bool) error { apiURL := os.Getenv("CLICD_API_URL") url := fmt.Sprintf("%s/api/v1/containers/%d", apiURL, containerID) if force { url += "?force=true" } httpReq, _ := http.NewRequest("DELETE", url, nil) httpReq.Header.Set("Authorization", "Bearer "+token) client := &http.Client{} resp, err := client.Do(httpReq) if err != nil { return err } defer resp.Body.Close() return nil } ``` ### Batch Operations ```go type BatchActionRequest struct { IDs []int `json:"ids"` Action string `json:"action"` // "start", "stop", "restart", "delete" } type BatchCreateRequest struct { Count int `json:"count"` NamePrefix string `json:"name_prefix"` Template string `json:"template"` CPU int `json:"cpu"` Memory int `json:"memory"` Disk int `json:"disk"` } func batchAction(token string, req BatchActionRequest) error { apiURL := os.Getenv("CLICD_API_URL") jsonData, _ := json.Marshal(req) httpReq, _ := http.NewRequest( "POST", apiURL+"/api/v1/containers/batch", bytes.NewBuffer(jsonData), ) httpReq.Header.Set("Authorization", "Bearer "+token) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} resp, err := client.Do(httpReq) if err != nil { return err } defer resp.Body.Close() return nil } func batchCreate(token string, req BatchCreateRequest) ([]Container, error) { apiURL := os.Getenv("CLICD_API_URL") jsonData, _ := json.Marshal(req) httpReq, _ := http.NewRequest( "POST", apiURL+"/api/v1/containers/batch-create", bytes.NewBuffer(jsonData), ) httpReq.Header.Set("Authorization", "Bearer "+token) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} resp, err := client.Do(httpReq) if err != nil { return nil, err } defer resp.Body.Close() var containers []Container body, _ := io.ReadAll(resp.Body) json.Unmarshal(body, &containers) return containers, nil } ``` ### Networking API ```go type NATMapping struct { ID int `json:"id"` ContainerID int `json:"container_id"` Protocol string `json:"protocol"` // "tcp" or "udp" PublicPort int `json:"public_port"` PrivatePort int `json:"private_port"` } type CreateNATRequest struct { ContainerID int `json:"container_id"` Protocol string `json:"protocol"` PrivatePort int `json:"private_port"` PublicPort int `json:"public_port,omitempty"` // Auto-assign if 0 } func createNATMapping(token string, req CreateNATRequest) (*NATMapping, error) { apiURL := os.Getenv("CLICD_API_URL") jsonData, _ := json.Marshal(req) httpReq, _ := http.NewRequest( "POST", apiURL+"/api/v1/nat", bytes.NewBuffer(jsonData), ) httpReq.Header.Set("Authorization", "Bearer "+token) httpReq.Header.Set("Content-Type", "application/json") client := &http.Client{} resp, err := client.Do(httpReq) if err != nil { return nil, err } defer resp.Body.Close() var mapping NATMapping body, _ := io.ReadAll(resp.Body) json.Unmarshal(body, &mapping) return &mapping, nil } func assignIPv6(token string, containerID int) (string, error) {
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기