Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨feat: Enhance support for containers #126

Merged
merged 2 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
187 changes: 182 additions & 5 deletions containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,24 +52,28 @@
return status, c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/status/start", c.Node, c.VMID), nil, &status)
}

func (c *Container) Stop(ctx context.Context) (status *ContainerStatus, err error) {
func (c *Container) Stop(ctx context.Context) (status string, err error) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh did we really add this before the the data field was being auto-parsed... goodness that was a long time ago. great fix and probably can remove the ContainerStatus type too right? it's at this point useless

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually when I checked the API doc realized it turns the UPID as a string so I don't think we need something like containerStatus. IMO returning the UPID as it is might not be the correct way to do it so we can convert them to tasks. Here is an example of start but any status command returns the same object:

root@lowtower:~# pvesh create /nodes/lowtower/lxc/150/status/start UPID:lowtower:0035154F:068C3DB0:65E99E9D:vzstart:150:root@pam:

So what I'm offering is converting that one to

func (c *Container) Stop(ctx context.Context) (task *Task, err error) { var upid UPID if err := c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/status/stop", c.Node, c.VMID), nil, &upid); err != nil { return nil, err } return NewTask(upid, c.client), nil }

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i agree to that change, let's do that. UPID and Tasks didnt exist when those funcs were initially wrote so let's go that route.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool! I've created #129 so if you agree we can continue from there.

return status, c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/status/stop", c.Node, c.VMID), nil, &status)
}

func (c *Container) Suspend(ctx context.Context) (status *ContainerStatus, err error) {
func (c *Container) Suspend(ctx context.Context) (status string, err error) {
return status, c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/status/suspend", c.Node, c.VMID), nil, &status)
}

func (c *Container) Reboot(ctx context.Context) (status *ContainerStatus, err error) {
func (c *Container) Reboot(ctx context.Context) (status string, err error) {
return status, c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/status/reboot", c.Node, c.VMID), nil, &status)
}

func (c *Container) Resume(ctx context.Context) (status *ContainerStatus, err error) {
func (c *Container) Resume(ctx context.Context) (status string, err error) {
return status, c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/status/resume", c.Node, c.VMID), nil, &status)
}

func (c *Container) Shutdown(ctx context.Context, force bool, timeout int) (status string, err error) {
return status, c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/status/shutdown", c.Node, c.VMID), map[string]interface{}{"force": force, "timeout": timeout}, &status)
}

func (c *Container) TermProxy(ctx context.Context) (vnc *VNC, err error) {
return vnc, c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxk/%d/termproxy", c.Node, c.VMID), nil, &vnc)
luthermonson marked this conversation as resolved.
Show resolved Hide resolved
return vnc, c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/termproxy", c.Node, c.VMID), nil, &vnc)

Check warning on line 76 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L76

Added line #L76 was not covered by tests
}

func (c *Container) VNCWebSocket(vnc *VNC) (chan string, chan string, chan error, func() error, error) {
Expand All @@ -78,3 +82,176 @@

return c.client.VNCWebSocket(p, vnc)
}

func (c *Container) Feature(ctx context.Context) (hasFeature bool, err error) {
var feature struct {
HasFeature bool `json:"hasFeature"`
}
err = c.client.Get(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/feature", c.Node, c.VMID), &feature)
return feature.HasFeature, err

Check warning on line 91 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L86-L91

Added lines #L86 - L91 were not covered by tests
}

// This seems broken on the proxmox side: https://pve.proxmox.com/pve-docs/api-viewer/index.html#/nodes/{node}/lxc/{vmid}/interfaces
// I wasn't able to make it work with the API. Tested on {"release":"7.3","repoid":"c3928077","version":"7.3-3"}
// func (c *Container) Interfaces(ctx context.Context) (interfaces []string, err error) {
// err = c.client.Get(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/interfaces", c.Node, c.VMID), &interfaces)
// return interfaces, err
// }

func (c *Container) Migrate(ctx context.Context, params *ContainerMigrateOptions) (task *Task, err error) {
var upid UPID
if err := c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/migrate", c.Node, c.VMID), params, &upid); err != nil {
return nil, err
}
return NewTask(upid, c.client), nil

Check warning on line 106 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L101-L106

Added lines #L101 - L106 were not covered by tests
}

func (c *Container) Resize(ctx context.Context, disk, size string) (task *Task, err error) {
var upid UPID
if err := c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/resize", c.Node, c.VMID), map[string]interface{}{"disk": disk, "size": size}, &upid); err != nil {
return nil, err
}
return NewTask(upid, c.client), nil

Check warning on line 114 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L109-L114

Added lines #L109 - L114 were not covered by tests
}

func (c *Container) MoveVolume(ctx context.Context, params *VirtualMachineMoveDiskOptions) (task *Task, err error) {
var upid UPID
if err := c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/move_volume", c.Node, c.VMID), params, &upid); err != nil {
return nil, err
}
return NewTask(upid, c.client), nil

Check warning on line 122 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L117-L122

Added lines #L117 - L122 were not covered by tests
}

func (c *Container) RRDData(ctx context.Context, timeframe Timeframe, consolidationFunction ConsolidationFunction) (rrddata []*RRDData, err error) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any chance you learned anything writing the container RRDData func to help fix the virtualmachine func for this guy #112 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I didn't realize the issue before so I just followed the same method for Containers as we do on VirtualMachines. If you think that can cause issues we can remove or I can try to follow up on the issue and if I find anything I can come back to this one.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have no context, i thought it worked tbh and havent looked into it

u := url.URL{Path: fmt.Sprintf("/lxc/%s/qemu/%d/rrddata", c.Node, c.VMID)}

// consolidation functions are variadic because they're optional, putting everything into one string and sending that
params := url.Values{}
if len(consolidationFunction) > 0 {

f := ""
for _, cf := range consolidationFunction {
f = f + string(cf)
}
params.Add("cf", f)

Check warning on line 136 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L125-L136

Added lines #L125 - L136 were not covered by tests
}

params.Add("timeframe", string(timeframe))
u.RawQuery = params.Encode()

err = c.client.Get(ctx, u.String(), &rrddata)
return

Check warning on line 143 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L139-L143

Added lines #L139 - L143 were not covered by tests
}

func (c *Container) Template(ctx context.Context) error {
return c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/template", c.Node, c.VMID), nil, nil)
}

func (c *Container) VNCProxy(ctx context.Context, vncOptions VNCProxyOptions) (vnc *VNC, err error) {
return vnc, c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/vncproxy", c.Node, c.VMID), vncOptions, &vnc)

Check warning on line 151 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L150-L151

Added lines #L150 - L151 were not covered by tests
}

func (c *Container) Snapshots(ctx context.Context) (snapshots []*ContainerSnapshot, err error) {
err = c.client.Get(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/snapshot", c.Node, c.VMID), &snapshots)
return
}

func (c *Container) NewSnapshot(ctx context.Context, snapName string) (task *Task, err error) {
var upid UPID
if err := c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/snapshot", c.Node, c.VMID), map[string]interface{}{"snapname": snapName}, &upid); err != nil {
return nil, err
}

Check warning on line 163 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L162-L163

Added lines #L162 - L163 were not covered by tests
return NewTask(upid, c.client), nil
}

func (c *Container) GetSnapshot(ctx context.Context, snapshot string) (snap []*ContainerSnapshot, err error) {
return snap, c.client.Get(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/snapshot/%s", c.Node, c.VMID, snapshot), &snap)
}

func (c *Container) DeleteSnapshot(ctx context.Context, snapshot string) (task *Task, err error) {
var upid UPID
if err := c.client.Delete(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/snapshot/%s", c.Node, c.VMID, snapshot), &upid); err != nil {
return nil, err
}

Check warning on line 175 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L174-L175

Added lines #L174 - L175 were not covered by tests
return NewTask(upid, c.client), nil
}

func (c *Container) RollbackSnapshot(ctx context.Context, snapshot string, start bool) (task *Task, err error) {
var upid UPID
if err := c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/snapshot/%s/rollback", c.Node, c.VMID, snapshot), map[string]interface{}{"start": start}, &upid); err != nil {
return nil, err
}

Check warning on line 183 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L182-L183

Added lines #L182 - L183 were not covered by tests
return NewTask(upid, c.client), nil
}

func (c *Container) GetSnapshotConfig(ctx context.Context, snapshot string) (config map[string]interface{}, err error) {
return config, c.client.Get(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/snapshot/%s/config", c.Node, c.VMID, snapshot), &config)

Check warning on line 188 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L187-L188

Added lines #L187 - L188 were not covered by tests
}

func (c *Container) UpdateSnapshot(ctx context.Context, snapshot string) error {
return c.client.Put(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/snapshot/%s/config", c.Node, c.VMID, snapshot), nil, nil)

Check warning on line 192 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L191-L192

Added lines #L191 - L192 were not covered by tests
}

func (c *Container) Firewall(ctx context.Context) (firewall *Firewall, err error) {
return firewall, c.client.Get(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/firewall", c.Node, c.VMID), &firewall)

Check warning on line 196 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L195-L196

Added lines #L195 - L196 were not covered by tests
}

func (c *Container) GetFirewallAliases(ctx context.Context) (aliases []*FirewallAlias, err error) {
return aliases, c.client.Get(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/firewall/aliases", c.Node, c.VMID), &aliases)

Check warning on line 200 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L199-L200

Added lines #L199 - L200 were not covered by tests
}

func (c *Container) NewFirewallAlias(ctx context.Context, alias *FirewallAlias) error {
return c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/firewall/aliases", c.Node, c.VMID), alias, nil)

Check warning on line 204 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L203-L204

Added lines #L203 - L204 were not covered by tests
}

func (c *Container) GetFirewallAlias(ctx context.Context, name string) (alias *FirewallAlias, err error) {
return alias, c.client.Get(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/firewall/aliases/%s", c.Node, c.VMID, name), &alias)

Check warning on line 208 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L207-L208

Added lines #L207 - L208 were not covered by tests
}

func (c *Container) UpdateFirewallAlias(ctx context.Context, name string, alias *FirewallAlias) error {
return c.client.Put(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/firewall/aliases/%s", c.Node, c.VMID, name), alias, nil)

Check warning on line 212 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L211-L212

Added lines #L211 - L212 were not covered by tests
}

func (c *Container) DeleteFirewallAlias(ctx context.Context, name string) error {
return c.client.Delete(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/firewall/aliases/%s", c.Node, c.VMID, name), nil)

Check warning on line 216 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L215-L216

Added lines #L215 - L216 were not covered by tests
}

func (c *Container) GetFirewallIPSet(ctx context.Context) (ipsets []*FirewallIPSet, err error) {
return ipsets, c.client.Get(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/firewall/ipset", c.Node, c.VMID), &ipsets)

Check warning on line 220 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L219-L220

Added lines #L219 - L220 were not covered by tests
}

func (c *Container) NewFirewallIPSet(ctx context.Context, ipset *FirewallIPSet) error {
return c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/firewall/ipset", c.Node, c.VMID), ipset, nil)

Check warning on line 224 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L223-L224

Added lines #L223 - L224 were not covered by tests
}

func (c *Container) DeleteFirewallIPSet(ctx context.Context, name string, force bool) error {
return c.client.Delete(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/firewall/ipset/%s", c.Node, c.VMID, name), map[string]interface{}{"force": force})

Check warning on line 228 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L227-L228

Added lines #L227 - L228 were not covered by tests
}

func (c *Container) FirewallRules(ctx context.Context) (rules []*FirewallRule, err error) {
return rules, c.client.Get(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/firewall/rules", c.Node, c.VMID), &rules)

Check warning on line 232 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L231-L232

Added lines #L231 - L232 were not covered by tests
}

func (c *Container) NewFirewallRule(ctx context.Context, rule *FirewallRule) error {
return c.client.Post(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/firewall/rules", c.Node, c.VMID), rule, nil)

Check warning on line 236 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L235-L236

Added lines #L235 - L236 were not covered by tests
}

func (c *Container) GetFirewallRule(ctx context.Context, rulePos int) (rule *FirewallRule, err error) {
return rule, c.client.Get(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/firewall/rules/%d", c.Node, c.VMID, rulePos), &rule)

Check warning on line 240 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L239-L240

Added lines #L239 - L240 were not covered by tests
}

func (c *Container) UpdateFirewallRule(ctx context.Context, rulePos int, rule *FirewallRule) error {
return c.client.Put(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/firewall/rules/%d", c.Node, c.VMID, rulePos), rule, nil)

Check warning on line 244 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L243-L244

Added lines #L243 - L244 were not covered by tests
}

func (c *Container) DeleteFirewallRule(ctx context.Context, rulePos int) error {
return c.client.Delete(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/firewall/rules/%d", c.Node, c.VMID, rulePos), nil)

Check warning on line 248 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L247-L248

Added lines #L247 - L248 were not covered by tests
}

func (c *Container) GetFirewallOptions(ctx context.Context) (options *FirewallVirtualMachineOption, err error) {
return options, c.client.Get(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/firewall/options", c.Node, c.VMID), &options)

Check warning on line 252 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L251-L252

Added lines #L251 - L252 were not covered by tests
}

func (c *Container) UpdateFirewallOptions(ctx context.Context, options *FirewallVirtualMachineOption) error {
return c.client.Put(ctx, fmt.Sprintf("/nodes/%s/lxc/%d/firewall/options", c.Node, c.VMID), options, nil)

Check warning on line 256 in containers.go

View check run for this annotation

Codecov / codecov/patch

containers.go#L255-L256

Added lines #L255 - L256 were not covered by tests
}
Loading
Loading