-
Notifications
You must be signed in to change notification settings - Fork 50
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) { | ||
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) | ||
} | ||
|
||
func (c *Container) VNCWebSocket(vnc *VNC) (chan string, chan string, chan error, func() error, error) { | ||
|
@@ -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 | ||
} | ||
|
||
// 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 | ||
} | ||
|
||
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 | ||
} | ||
|
||
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 | ||
} | ||
|
||
func (c *Container) RRDData(ctx context.Context, timeframe Timeframe, consolidationFunction ConsolidationFunction) (rrddata []*RRDData, err error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 ? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) | ||
} | ||
|
||
params.Add("timeframe", string(timeframe)) | ||
u.RawQuery = params.Encode() | ||
|
||
err = c.client.Get(ctx, u.String(), &rrddata) | ||
return | ||
} | ||
|
||
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) | ||
} | ||
|
||
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 | ||
} | ||
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 | ||
} | ||
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 | ||
} | ||
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) | ||
} | ||
|
||
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) | ||
} | ||
|
||
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) | ||
} | ||
|
||
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) | ||
} | ||
|
||
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) | ||
} | ||
|
||
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) | ||
} | ||
|
||
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) | ||
} | ||
|
||
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) | ||
} | ||
|
||
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) | ||
} | ||
|
||
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) | ||
} | ||
|
||
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}) | ||
} | ||
|
||
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) | ||
} | ||
|
||
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) | ||
} | ||
|
||
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) | ||
} | ||
|
||
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) | ||
} | ||
|
||
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) | ||
} | ||
|
||
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) | ||
} | ||
|
||
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) | ||
} |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 }
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.