Skip to content

Commit

Permalink
lxc: Check the dereferencedAlias really exists on the remote before e…
Browse files Browse the repository at this point in the history
…xporting it

When doing a `lxc image export ..`, dereferencing the provided image name either returns
a fingerprint or a human readable alias. Both forms can be fine. However, since this `dereferenceAlias`
operation is not really checking if the image associated with this alias exists on the remote,
we were creating a local target based on the same string that a user entered. Most of the time, this
`targetMeta` string was resolved to a fingerprint (e.g, `/var/lib/snapd/hostfs/home/gab/d2a43fade9d0055e454a091b2e9bd819f7eb715a3d4d46667644a5784d40172`)
and this was fine because there is only the fingerprint file created and no intermediate directories.

Anyway, I think it is safer to systematically check for the image existence prior to creating
any file resources. This way we avoid changing the filesystem write logic that could annoy exsting users and break their
export image pipeline:

```
target := "."
targetMeta := fingerprint
if len(args) > 1 {
	target = args[1]
	if shared.IsDir(shared.HostPathFollow(args[1])) {
		targetMeta = filepath.Join(args[1], targetMeta)
	} else {
		targetMeta = args[1]
	}
}
targetMeta = shared.HostPathFollow(targetMeta)
```

Signed-off-by: Gabriel Mougard <gabriel.mougard@canonical.com>
  • Loading branch information
gabrielmougard committed Mar 15, 2024
1 parent 4f3af9a commit df91a4e
Showing 1 changed file with 8 additions and 1 deletion.
9 changes: 8 additions & 1 deletion lxc/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"

"github.com/canonical/lxd/client"
lxd "github.com/canonical/lxd/client"
"github.com/canonical/lxd/shared"
"github.com/canonical/lxd/shared/api"
cli "github.com/canonical/lxd/shared/cmd"
Expand Down Expand Up @@ -524,6 +524,13 @@ func (c *cmdImageExport) Run(cmd *cobra.Command, args []string) error {

fingerprint := c.image.dereferenceAlias(remoteServer, imageType, name)

// Check if the returned fingerprint (that could also be an alias)
// exists on the remote before creating any files on the host system
_, _, err = remoteServer.GetImage(fingerprint)
if err != nil {
return err
}

// Default target is current directory
target := "."
targetMeta := fingerprint
Expand Down

0 comments on commit df91a4e

Please sign in to comment.