Skip to content

Commit

Permalink
Merge pull request #313 from Tinyblargon/snapshot-addon
Browse files Browse the repository at this point in the history
Snapshot addons
  • Loading branch information
Tinyblargon authored Mar 9, 2024
2 parents b043e37 + c3aa491 commit 4ced342
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 39 deletions.
2 changes: 1 addition & 1 deletion cli/command/create/create-snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ var (
if err != nil {
return
}
err = config.CreateSnapshot(client, vmr)
err = config.Create(client, vmr)
if err != nil {
return
}
Expand Down
2 changes: 1 addition & 1 deletion cli/command/delete/delete-snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var (
RunE: func(cmd *cobra.Command, args []string) (err error) {
id := cli.ValidateIntIDset(args, "GuestID")
snapName := cli.RequiredIDset(args, 1, "SnapshotName")
_, err = proxmox.DeleteSnapshot(cli.NewClient(), proxmox.NewVmRef(id), proxmox.SnapshotName(snapName))
_, err = proxmox.SnapshotName(snapName).Delete(cli.NewClient(), proxmox.NewVmRef(id))
if err != nil {
return
}
Expand Down
2 changes: 1 addition & 1 deletion cli/command/guest/guest-rollback.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var guest_rollbackCmd = &cobra.Command{
RunE: func(cmd *cobra.Command, args []string) (err error) {
vmr := proxmox.NewVmRef(cli.ValidateIntIDset(args, "GuestID"))
snapName := cli.RequiredIDset(args, 1, "SnapshotName")
_, err = proxmox.RollbackSnapshot(cli.NewClient(), vmr, snapName)
_, err = proxmox.SnapshotName(snapName).Rollback(cli.NewClient(), vmr)
if err == nil {
fmt.Fprintf(GuestCmd.OutOrStdout(), "Guest with id (%d) has been rolled back to snapshot (%s)\n", vmr.VmId(), snapName)
}
Expand Down
2 changes: 1 addition & 1 deletion cli/command/update/update-snapshotdescription.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var update_snapshotCmd = &cobra.Command{
id := cli.ValidateIntIDset(args, "GuestID")
snapName := cli.RequiredIDset(args, 1, "SnapshotName")
des := cli.OptionalIDset(args, 2)
err = proxmox.UpdateSnapshotDescription(cli.NewClient(), proxmox.NewVmRef(id), proxmox.SnapshotName(snapName), des)
err = proxmox.SnapshotName(snapName).UpdateDescription(cli.NewClient(), proxmox.NewVmRef(id), des)
if err != nil {
return
}
Expand Down
2 changes: 1 addition & 1 deletion proxmox/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ func (c *Client) ListQemuSnapshot(vmr *VmRef) (taskResponse map[string]interface

// DEPRECATED superseded by RollbackSnapshot()
func (c *Client) RollbackQemuVm(vmr *VmRef, snapshot string) (exitStatus string, err error) {
return RollbackSnapshot(c, vmr, snapshot)
return RollbackSnapshot(c, vmr, SnapshotName(snapshot))
}

// DEPRECATED SetVmConfig - send config options
Expand Down
109 changes: 75 additions & 34 deletions proxmox/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,31 @@ func (config ConfigSnapshot) mapToApiValues() map[string]interface{} {
}
}

func (config ConfigSnapshot) CreateSnapshot(c *Client, vmr *VmRef) (err error) {
err = c.CheckVmRef(vmr)
if err != nil {
// Creates a snapshot and validates the input
func (config ConfigSnapshot) Create(c *Client, vmr *VmRef) (err error) {
if err = c.CheckVmRef(vmr); err != nil {
return
}
err = config.Validate()
if err != nil {
if err = config.Validate(); err != nil {
return
}
return config.Create_Unsafe(c, vmr)
}

// Create a snapshot without validating the input, use ConfigSnapshot.Create() to validate the input.
func (config ConfigSnapshot) Create_Unsafe(c *Client, vmr *VmRef) error {
params := config.mapToApiValues()
_, err = c.PostWithTask(params, "/nodes/"+vmr.node+"/"+vmr.vmType+"/"+strconv.Itoa(vmr.vmId)+"/snapshot/")
_, err := c.PostWithTask(params, "/nodes/"+vmr.node+"/"+vmr.vmType+"/"+strconv.Itoa(vmr.vmId)+"/snapshot/")
if err != nil {
params, _ := json.Marshal(&params)
return fmt.Errorf("error creating Snapshot: %v, (params: %v)", err, string(params))
}
return
return nil
}

// deprecated use ConfigSnapshot.Create() instead
func (config ConfigSnapshot) CreateSnapshot(c *Client, vmr *VmRef) error {
return config.Create(c, vmr)
}

func (config ConfigSnapshot) Validate() error {
Expand All @@ -48,44 +57,25 @@ func (config ConfigSnapshot) Validate() error {
type rawSnapshots []interface{}

func ListSnapshots(c *Client, vmr *VmRef) (rawSnapshots, error) {
err := c.CheckVmRef(vmr)
if err != nil {
if err := c.CheckVmRef(vmr); err != nil {
return nil, err
}
return c.GetItemConfigInterfaceArray("/nodes/"+vmr.node+"/"+vmr.vmType+"/"+strconv.Itoa(vmr.vmId)+"/snapshot/", "Guest", "SNAPSHOTS")
}

// Can only be used to update the description of an already existing snapshot
// Updates the description of the specified snapshot, same as SnapshotName.UpdateDescription()
func UpdateSnapshotDescription(c *Client, vmr *VmRef, snapshot SnapshotName, description string) (err error) {
err = c.CheckVmRef(vmr)
if err != nil {
return
}
err = snapshot.Validate()
if err != nil {
return
}
return c.Put(map[string]interface{}{"description": description}, "/nodes/"+vmr.node+"/"+vmr.vmType+"/"+strconv.Itoa(vmr.vmId)+"/snapshot/"+string(snapshot)+"/config")
return snapshot.UpdateDescription(c, vmr, description)
}

// Deletes a snapshot, same as SnapshotName.Delete()
func DeleteSnapshot(c *Client, vmr *VmRef, snapshot SnapshotName) (exitStatus string, err error) {
err = c.CheckVmRef(vmr)
if err != nil {
return
}
err = snapshot.Validate()
if err != nil {
return
}
return c.DeleteWithTask("/nodes/" + vmr.node + "/" + vmr.vmType + "/" + strconv.Itoa(vmr.vmId) + "/snapshot/" + string(snapshot))
return snapshot.Delete(c, vmr)
}

func RollbackSnapshot(c *Client, vmr *VmRef, snapshot string) (exitStatus string, err error) {
err = c.CheckVmRef(vmr)
if err != nil {
return
}
return c.PostWithTask(nil, "/nodes/"+vmr.node+"/"+vmr.vmType+"/"+strconv.Itoa(vmr.vmId)+"/snapshot/"+snapshot+"/rollback")
// Rollback to a snapshot, same as SnapshotName.Rollback()
func RollbackSnapshot(c *Client, vmr *VmRef, snapshot SnapshotName) (exitStatus string, err error) {
return snapshot.Rollback(c, vmr)
}

// Used for formatting the output when retrieving snapshots
Expand Down Expand Up @@ -155,6 +145,57 @@ const (
SnapshotName_Error_StartNoLetter string = "SnapshotName must start with a letter"
)

// Deletes the specified snapshot, validates the input
func (snap SnapshotName) Delete(c *Client, vmr *VmRef) (exitStatus string, err error) {
if err = c.CheckVmRef(vmr); err != nil {
return
}
if err = snap.Validate(); err != nil {
return
}
// TODO check if snapshot exists
return snap.Delete_Unsafe(c, vmr)
}

// Deletes the specified snapshot without validating the input, use SnapshotName.Delete() to validate the input.
func (snap SnapshotName) Delete_Unsafe(c *Client, vmr *VmRef) (exitStatus string, err error) {
return c.DeleteWithTask("/nodes/" + vmr.node + "/" + vmr.vmType + "/" + strconv.Itoa(vmr.vmId) + "/snapshot/" + string(snap))
}

// Rollback to the specified snapshot, validates the input
func (snap SnapshotName) Rollback(c *Client, vmr *VmRef) (exitStatus string, err error) {
if err = c.CheckVmRef(vmr); err != nil {
return
}
if err = snap.Validate(); err != nil {
return
}
// TODO check if snapshot exists
return snap.Rollback_Unsafe(c, vmr)
}

// Rollback to the specified snapshot without validating the input, use SnapshotName.Rollback() to validate the input.
func (snap SnapshotName) Rollback_Unsafe(c *Client, vmr *VmRef) (exitStatus string, err error) {
return c.PostWithTask(nil, "/nodes/"+vmr.node+"/"+vmr.vmType+"/"+strconv.FormatInt(int64(vmr.vmId), 10)+"/snapshot/"+string(snap)+"/rollback")
}

// Updates the description of the specified snapshot, validates the input
func (snap SnapshotName) UpdateDescription(c *Client, vmr *VmRef, description string) (err error) {
if err = c.CheckVmRef(vmr); err != nil {
return
}
if err = snap.Validate(); err != nil {
return
}
// TODO check if snapshot exists
return snap.UpdateDescription_Unsafe(c, vmr, description)
}

// Updates the description of the specified snapshot without validating the input, use SnapshotName.UpdateDescription() to validate the input.
func (snap SnapshotName) UpdateDescription_Unsafe(c *Client, vmr *VmRef, description string) error {
return c.Put(map[string]interface{}{"description": description}, "/nodes/"+vmr.node+"/"+vmr.vmType+"/"+strconv.Itoa(vmr.vmId)+"/snapshot/"+string(snap)+"/config")
}

func (name SnapshotName) Validate() error {
regex, _ := regexp.Compile(`^([a-zA-Z])([a-z]|[A-Z]|[0-9]|_|-){2,39}$`)
if !regex.Match([]byte(name)) {
Expand Down

0 comments on commit 4ced342

Please sign in to comment.