lxd icon indicating copy to clipboard operation
lxd copied to clipboard

Local image import does not acquire image lock

Open dmitry-lyfar opened this issue 1 year ago • 0 comments

Required information

  • Distribution: ubuntu
  • Distribution version: 24.04
  • The output of "snap list --all lxd core20 core22 core24 snapd":
Name    Version         Rev    Tracking       Publisher   Notes
core20  20240227        2264   latest/stable  canonical✓  base,disabled
core20  20240416        2318   latest/stable  canonical✓  base
core22  20240111        1122   latest/stable  canonical✓  base,disabled
core22  20240408        1380   latest/stable  canonical✓  base
core24  20240426        405    latest/stable  canonical✓  base,disabled
core24  20240528        423    latest/stable  canonical✓  base
lxd     5.21.1-d46c406  28460  5.21/stable    canonical✓  disabled
lxd     5.21.2-34459c8  29568  5.21/stable    canonical✓  -
snapd   2.62            21465  latest/stable  canonical✓  snapd,disabled
snapd   2.63            21759  latest/stable  canonical✓  snapd
  • The output of "lxc info" or if that fails: info.txt

Issue description

If one downloads the image using CopyImage AND uses lxc import with the same image fingerprint concurrently, LXD returns an error due to the latter not locking for the image access, apparently.

Steps to reproduce

  1. lxc export <image> .
  2. Build and run the following API request:
const LxdSock = "/var/snap/lxd/common/lxd/unix.socket"

func main() {
	if srv, err := lxd.ConnectLXDUnix(LxdSock, nil); err == nil {
		defer srv.Disconnect()
		srv := srv.UseProject("default")

		imageServer, err := lxd.ConnectSimpleStreams("https://cloud-images.ubuntu.com/releases", nil)
		if err != nil {
			panic(err)
		}
		defer imageServer.Disconnect()

		var imageInfo *api.Image
		alias, _, err := imageServer.GetImageAlias("22.04/amd64")
		if err != nil {
			panic(err)
		}

		imageInfo, _, err = imageServer.GetImage(alias.Target)
		if err != nil {
			panic(err)
		}

		copyArgs := lxd.ImageCopyArgs{
			AutoUpdate: true,
			Public:     false,
			Type:       "container",
		}

		copyop, err := srv.CopyImage(imageServer, *imageInfo, &copyArgs)
		if err != nil {
			panic(err)
		}

		err = copyop.Wait()
		if err != nil {
			panic(err)
		}
	}
}
  1. While the image is being downloaded, in the second terminal, run lxc image import <local-file-meta> <local-file-squashfs> (you get both files in step 1).

Problem

Step 2 will fail with the following:

Failed remote image download: Failed creating image record: Failed saving main image record: UNIQUE constraint failed: images.project_id, images.fingerprint

Expected

It should not be possible to import an image if it is locked by another operation.

dmitry-lyfar avatar Aug 02 '24 00:08 dmitry-lyfar