diff --git a/containers.go b/containers.go index 759920b..7ce36d6 100644 --- a/containers.go +++ b/containers.go @@ -40,6 +40,8 @@ func (c *Container) Delete(ctx context.Context) (task *Task, err error) { return NewTask(upid, c.client), nil } +// Config sets ContainerOptions for Container +// see https://pve.proxmox.com/pve-docs/api-viewer/index.html#/nodes/{node}/lxc/{vmid}/config for available attributes func (c *Container) Config(ctx context.Context, options ...ContainerOption) (*Task, error) { var upid UPID data := make(map[string]interface{}) diff --git a/containers_test.go b/containers_test.go index 8ce01e7..0262ce2 100644 --- a/containers_test.go +++ b/containers_test.go @@ -8,6 +8,20 @@ import ( "github.com/stretchr/testify/assert" ) +func TestContainer(t *testing.T) { + mocks.On(mockConfig) + defer mocks.Off() + client := mockClient() + ctx := context.Background() + node := Node{ + client: client, + Name: "node1", + } + container, err := node.Container(ctx, 101) + assert.Nil(t, err) + assert.NotEmpty(t, container, container.ContainerConfig) +} + func TestContainers(t *testing.T) { mocks.On(mockConfig) defer mocks.Off() @@ -81,8 +95,9 @@ func TestContainerConfig(t *testing.T) { Node: "node1", VMID: 101, } - _, err := container.Config(ctx) + task, err := container.Config(ctx) assert.Nil(t, err) + assert.NotEmpty(t, task) } func TestContainerStart(t *testing.T) { diff --git a/nodes.go b/nodes.go index 2a838bb..3b2e87a 100644 --- a/nodes.go +++ b/nodes.go @@ -102,14 +102,20 @@ func (n *Node) Containers(ctx context.Context) (c Containers, err error) { } func (n *Node) Container(ctx context.Context, vmid int) (*Container, error) { - var c Container + c := &Container{ + client: n.client, + Node: n.Name, + } + if err := n.client.Get(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/status/current", n.Name, vmid), &c); err != nil { return nil, err } - c.client = n.client - c.Node = n.Name - return &c, nil + if err := n.client.Get(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/config", n.Name, vmid), &c.ContainerConfig); err != nil { + return nil, err + } + + return c, nil } func (n *Node) NewContainer(ctx context.Context, vmid int, options ...ContainerOption) (*Task, error) { diff --git a/tests/mocks/pve7x/nodes.go b/tests/mocks/pve7x/nodes.go index 01335b9..51d70b1 100644 --- a/tests/mocks/pve7x/nodes.go +++ b/tests/mocks/pve7x/nodes.go @@ -910,7 +910,7 @@ func nodes() { }`) gock.New(config.C.URI). - Get("^/nodes/node1/lxc"). + Get("^/nodes/node1/lxc$"). Reply(200). JSON(`{ "data": [{"cpu":0,"cpus":1,"disk":640397312,"diskread":273694720,"diskwrite":200982528,"maxdisk":8350298112,"maxmem":536870912,"maxswap":536870912,"mem":34304000,"name":"test","netin":94558593,"netout":1618542,"pid":248173,"status":"running","swap":0,"type":"lxc","uptime":919760,"vmid":"106"},{"cpu":0,"cpus":1,"disk":639303680,"diskread":283123712,"diskwrite":201687040,"maxdisk":8350298112,"maxmem":536870912,"maxswap":536870912,"mem":34508800,"name":"zort","netin":94560801,"netout":1619838,"pid":248045,"status":"running","swap":0,"type":"lxc","uptime":919761,"vmid":"105"},{"cpu":0,"cpus":1,"disk":0,"diskread":0,"diskwrite":0,"maxdisk":8589934592,"maxmem":536870912,"maxswap":536870912,"mem":0,"name":"test-container","netin":0,"netout":0,"status":"stopped","swap":0,"template":1,"type":"lxc","uptime":0,"vmid":"101"}] @@ -960,6 +960,48 @@ func nodes() { Reply(200). JSON(`{"data": "null"}`) + gock.New(config.C.URI). + Get("^/nodes/node1/lxc/101/config"). + Reply(200). + JSON(`{"data": +{ + "arch" : "amd64", + "cores" : 2, + "digest" : "5911baea29f4c0073fb063fd9ab29e75892832bf", + "features" : "fuse=1,mknod=1,nesting=1", + "hostname" : "test-container", + "lxc" : [ + [ + "lxc.cgroup2.devices.allow", + "c 226:0 rwm" + ], + [ + "lxc.cgroup2.devices.allow", + "c 226:128 rwm" + ], + [ + "lxc.cgroup2.devices.allow", + "c 29:0 rwm" + ], + [ + "lxc.mount.entry", + "/dev/dri dev/dri none bind,optional,create=dir" + ], + [ + "lxc.mount.entry", + "/dev/fb0 dev/fb0 none bind,optional,create=file" + ] + ], + "memory" : 4096, + "mp0" : "/mnt/foo/bar,mp=/storage", + "net0" : "name=eth0,bridge=vmbr0,firewall=1,hwaddr=5D:CF:BD:B2:C5:39,ip=dhcp,type=veth", + "onboot" : 1, + "ostype" : "debian", + "rootfs" : "vmstore:subvol-101-disk-0,size=30G", + "swap" : 512, + "tags" : "tag1;tag2" +}}`) + gock.New(config.C.URI). Post("^/nodes/node1/lxc/101/status/start"). Reply(200). diff --git a/tests/mocks/pve8x/nodes.go b/tests/mocks/pve8x/nodes.go index 6596315..cbeae00 100644 --- a/tests/mocks/pve8x/nodes.go +++ b/tests/mocks/pve8x/nodes.go @@ -105,5 +105,4 @@ func nodes() { } ] }`) - } diff --git a/types.go b/types.go index 7bdbd59..0ca7265 100644 --- a/types.go +++ b/types.go @@ -667,17 +667,19 @@ func (l *Log) UnmarshalJSON(b []byte) error { type Containers []*Container type Container struct { - Name string - Node string - client *Client + client *Client + ContainerConfig *ContainerConfig + CPUs int - Status string - VMID StringOrUint64 - Uptime uint64 - MaxMem uint64 MaxDisk uint64 + MaxMem uint64 MaxSwap uint64 + Name string + Node string + Status string Tags string + Uptime uint64 + VMID StringOrUint64 } type ContainerInterfaces []*ContainerInterface @@ -701,6 +703,77 @@ type ContainerCloneOptions struct { Target string `json:"target,omitempty"` } +type ContainerConfig struct { + Arch string `json:"arch,omitempty"` + CMode string `json:"cmode,omitempty"` + Console IntOrBool `json:"console,omitempty"` + Cores int `json:"cores,omitempty"` + CPULimit int `json:"cpulimit,omitempty"` + CPUUnits int `json:"cpuunits,omitempty"` + Debug IntOrBool `json:"debug,omitempty"` + Description string `json:"description,omitempty"` + Dev0 string `json:"dev0,omitempty"` + Dev1 string `json:"dev1,omitempty"` + Dev2 string `json:"dev2,omitempty"` + Dev3 string `json:"dev3,omitempty"` + Dev4 string `json:"dev4,omitempty"` + Dev5 string `json:"dev5,omitempty"` + Dev6 string `json:"dev6,omitempty"` + Dev7 string `json:"dev7,omitempty"` + Dev8 string `json:"dev8,omitempty"` + Dev9 string `json:"dev9,omitempty"` + Digest string `json:"digest"` + Features string `json:"features,omitempty"` + HookScript string `json:"hookscript,omitempty"` + LXC [][]string `json:"lxc,omitempty"` + Hostname string `json:"hostname,omitempty"` + Lock string `json:"lock,omitempty"` + Memory int `json:"memory,omitempty"` + Mp0 string `json:"mp0,omitempty"` + Mp1 string `json:"mp1,omitempty"` + Mp2 string `json:"mp2,omitempty"` + Mp3 string `json:"mp3,omitempty"` + Mp4 string `json:"mp4,omitempty"` + Mp5 string `json:"mp5,omitempty"` + Mp6 string `json:"mp6,omitempty"` + Mp7 string `json:"mp7,omitempty"` + Mp8 string `json:"mp8,omitempty"` + Mp9 string `json:"mp9,omitempty"` + Nameserver string `json:"nameserver,omitempty"` + Net0 string `json:"net0,omitempty"` + Net1 string `json:"net1,omitempty"` + Net2 string `json:"net2,omitempty"` + Net3 string `json:"net3,omitempty"` + Net4 string `json:"net4,omitempty"` + Net5 string `json:"net5,omitempty"` + Net6 string `json:"net6,omitempty"` + Net7 string `json:"net7,omitempty"` + Net8 string `json:"net8,omitempty"` + Net9 string `json:"net9,omitempty"` + OnBoot IntOrBool `json:"onboot,omitempty"` + OSType string `json:"ostype,omitempty"` + Protection IntOrBool `json:"protection,omitempty"` + RootFS string `json:"rootfs,omitempty"` + SearchDomain string `json:"searchdomain:omitempty"` + Startup string `json:"startup:omitempty"` + Swap int `json:"swap,omitempty"` + Tags string `json:"tags,omitempty"` + Template IntOrBool `json:"template,omitempty"` + Timezone string `json:"timezone,omitempty"` + TTY int `json:"tty,omitempty"` + Unprivileged IntOrBool `json:"unpriviledged,omitempty"` + Unused0 string `json:"unused0,omitempty"` + Unused1 string `json:"unused1,omitempty"` + Unused2 string `json:"unused2,omitempty"` + Unused3 string `json:"unused3,omitempty"` + Unused4 string `json:"unused4,omitempty"` + Unused5 string `json:"unused5,omitempty"` + Unused6 string `json:"unused6,omitempty"` + Unused7 string `json:"unused7,omitempty"` + Unused8 string `json:"unused8,omitempty"` + Unused9 string `json:"unused9,omitempty"` +} + // ContainerOptions A key/value pair used to modify a container(LXC) config // Refer to https://pve.proxmox.com/pve-docs/api-viewer/#/nodes/{node}/lxc/{vmid}/config for a list of valid values type ContainerOptions []*ContainerOption