Skip to content

Commit

Permalink
Merge pull request #1254 from stgraber/main
Browse files Browse the repository at this point in the history
Add missing placement scriptlet calls
  • Loading branch information
hallyn authored Sep 25, 2024
2 parents c6f6b22 + c0643ad commit ee8803d
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 62 deletions.
90 changes: 45 additions & 45 deletions cmd/incusd/daemon_images.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func imageOperationLock(ctx context.Context, fingerprint string) (locking.Unlock
}

// ImageDownload resolves the image fingerprint and if not in the database, downloads it.
func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *operations.Operation, args *ImageDownloadArgs) (*api.Image, error) {
func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *operations.Operation, args *ImageDownloadArgs) (*api.Image, bool, error) {
var err error
var ctxMap logger.Ctx

Expand Down Expand Up @@ -91,7 +91,7 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
// Setup client
remote, err = incus.ConnectPublicIncus(args.Server, clientArgs)
if err != nil {
return nil, fmt.Errorf("Failed to connect to the server %q: %w", args.Server, err)
return nil, false, fmt.Errorf("Failed to connect to the server %q: %w", args.Server, err)
}

server, ok := remote.(incus.InstanceServer)
Expand All @@ -102,13 +102,13 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
// Setup OCI client
remote, err = incus.ConnectOCI(args.Server, clientArgs)
if err != nil {
return nil, fmt.Errorf("Failed to connect to simple streams server %q: %w", args.Server, err)
return nil, false, fmt.Errorf("Failed to connect to simple streams server %q: %w", args.Server, err)
}
} else if protocol == "simplestreams" {
// Setup simplestreams client
remote, err = incus.ConnectSimpleStreams(args.Server, clientArgs)
if err != nil {
return nil, fmt.Errorf("Failed to connect to simple streams server %q: %w", args.Server, err)
return nil, false, fmt.Errorf("Failed to connect to simple streams server %q: %w", args.Server, err)
}
}

Expand All @@ -123,7 +123,7 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
// Expand partial fingerprints
info, _, err = remote.GetImage(fp)
if err != nil {
return nil, fmt.Errorf("Failed getting remote image info: %w", err)
return nil, false, fmt.Errorf("Failed getting remote image info: %w", err)
}

fp = info.Fingerprint
Expand All @@ -133,7 +133,7 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
// Ensure we are the only ones operating on this image.
unlock, err := imageOperationLock(ctx, fp)
if err != nil {
return nil, err
return nil, false, err
}

defer unlock()
Expand All @@ -158,7 +158,7 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
return nil
})
if err != nil {
return nil, err
return nil, false, err
}
}

Expand All @@ -180,22 +180,22 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
return err
})
if err != nil {
return nil, fmt.Errorf("Failed locating image %q in the cluster: %w", imgInfo.Fingerprint, err)
return nil, false, fmt.Errorf("Failed locating image %q in the cluster: %w", imgInfo.Fingerprint, err)
}

if nodeAddress != "" {
// The image is available from another node, let's try to import it.
err = instanceImageTransfer(s, r, args.ProjectName, imgInfo.Fingerprint, nodeAddress)
if err != nil {
return nil, fmt.Errorf("Failed transferring image %q from %q: %w", imgInfo.Fingerprint, nodeAddress, err)
return nil, false, fmt.Errorf("Failed transferring image %q from %q: %w", imgInfo.Fingerprint, nodeAddress, err)
}

err = s.DB.Cluster.Transaction(ctx, func(ctx context.Context, tx *db.ClusterTx) error {
// As the image record already exists in the project, just add the node ID to the image.
return tx.AddImageToLocalNode(ctx, args.ProjectName, imgInfo.Fingerprint)
})
if err != nil {
return nil, fmt.Errorf("Failed adding transferred image %q to local cluster member: %w", imgInfo.Fingerprint, err)
return nil, false, fmt.Errorf("Failed adding transferred image %q to local cluster member: %w", imgInfo.Fingerprint, err)
}
}
} else if response.IsNotFoundError(err) {
Expand Down Expand Up @@ -240,15 +240,15 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
return tx.CreateImageSource(ctx, id, args.Server, args.Protocol, args.Certificate, alias)
})
if err != nil {
return nil, err
return nil, false, err
}

// Transfer image if needed (after database record has been created above).
if nodeAddress != "" {
// The image is available from another node, let's try to import it.
err = instanceImageTransfer(s, r, args.ProjectName, info.Fingerprint, nodeAddress)
if err != nil {
return nil, fmt.Errorf("Failed transferring image: %w", err)
return nil, false, fmt.Errorf("Failed transferring image: %w", err)
}
}
}
Expand All @@ -261,7 +261,7 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope

// If not requested in a particular pool, we're done.
if args.StoragePool == "" {
return info, nil
return info, false, nil
}

ctxMap["pool"] = args.StoragePool
Expand All @@ -282,12 +282,12 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
return err
})
if err != nil {
return nil, err
return nil, false, err
}

if slices.Contains(poolIDs, poolID) {
logger.Debug("Image already exists on storage pool", ctxMap)
return info, nil
return info, false, nil
}

// Import the image in the pool.
Expand All @@ -297,11 +297,11 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
if err != nil {
ctxMap["err"] = err
logger.Debug("Failed to create image on storage pool", ctxMap)
return nil, fmt.Errorf("Failed to create image %q on storage pool %q: %w", info.Fingerprint, args.StoragePool, err)
return nil, false, fmt.Errorf("Failed to create image %q on storage pool %q: %w", info.Fingerprint, args.StoragePool, err)
}

logger.Debug("Created image on storage pool", ctxMap)
return info, nil
return info, false, nil
}

// Begin downloading
Expand Down Expand Up @@ -353,14 +353,14 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
// Create the target files
dest, err := os.Create(destName)
if err != nil {
return nil, err
return nil, false, err
}

defer func() { _ = dest.Close() }()

destRootfs, err := os.Create(destName + ".rootfs")
if err != nil {
return nil, err
return nil, false, err
}

defer func() { _ = destRootfs.Close() }()
Expand All @@ -370,7 +370,7 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
if args.Secret != "" {
info, _, err = remote.GetPrivateImage(fp, args.Secret)
if err != nil {
return nil, err
return nil, false, err
}

// Expand the fingerprint now and mark alias string to match
Expand All @@ -379,7 +379,7 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
} else {
info, _, err = remote.GetImage(fp)
if err != nil {
return nil, err
return nil, false, err
}
}
}
Expand All @@ -390,7 +390,7 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
}

if args.Budget > 0 && info.Size > args.Budget {
return nil, fmt.Errorf("Remote image with size %d exceeds allowed bugdget of %d", info.Size, args.Budget)
return nil, false, fmt.Errorf("Remote image with size %d exceeds allowed bugdget of %d", info.Size, args.Budget)
}

// Download the image
Expand All @@ -417,44 +417,44 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
}

if err != nil {
return nil, err
return nil, false, err
}

// Truncate down to size
if resp.RootfsSize > 0 {
err = destRootfs.Truncate(resp.RootfsSize)
if err != nil {
return nil, err
return nil, false, err
}
}

err = dest.Truncate(resp.MetaSize)
if err != nil {
return nil, err
return nil, false, err
}

// Deal with unified images
if resp.RootfsSize == 0 {
err := os.Remove(destName + ".rootfs")
if err != nil {
return nil, err
return nil, false, err
}
}

err = dest.Close()
if err != nil {
return nil, err
return nil, false, err
}

err = destRootfs.Close()
if err != nil {
return nil, err
return nil, false, err
}
} else if protocol == "direct" {
// Setup HTTP client
httpClient, err := localUtil.HTTPClient(args.Certificate, s.Proxy)
if err != nil {
return nil, err
return nil, false, err
}

// Use relatively short response header timeout so as not to hold the image lock open too long.
Expand All @@ -463,21 +463,21 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope

req, err := http.NewRequest("GET", args.Server, nil)
if err != nil {
return nil, err
return nil, false, err
}

req.Header.Set("User-Agent", version.UserAgent)

// Make the request
raw, doneCh, err := cancel.CancelableDownload(canceler, httpClient.Do, req)
if err != nil {
return nil, err
return nil, false, err
}

defer close(doneCh)

if raw.StatusCode != http.StatusOK {
return nil, fmt.Errorf("Unable to fetch %q: %s", args.Server, raw.Status)
return nil, false, fmt.Errorf("Unable to fetch %q: %s", args.Server, raw.Status)
}

// Progress handler
Expand All @@ -494,7 +494,7 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
// Create the target files
f, err := os.Create(destName)
if err != nil {
return nil, err
return nil, false, err
}

defer func() { _ = f.Close() }()
Expand All @@ -506,19 +506,19 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
writer := internalIO.NewQuotaWriter(io.MultiWriter(f, sha256), args.Budget)
size, err := io.Copy(writer, body)
if err != nil {
return nil, err
return nil, false, err
}

// Validate hash
result := fmt.Sprintf("%x", sha256.Sum(nil))
if result != fp {
return nil, fmt.Errorf("Hash mismatch for %q: %s != %s", args.Server, result, fp)
return nil, false, fmt.Errorf("Hash mismatch for %q: %s != %s", args.Server, result, fp)
}

// Parse the image
imageMeta, imageType, err := getImageMetadata(destName)
if err != nil {
return nil, err
return nil, false, err
}

info = &api.Image{}
Expand All @@ -538,10 +538,10 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope

err = f.Close()
if err != nil {
return nil, err
return nil, false, err
}
} else {
return nil, fmt.Errorf("Unsupported protocol: %v", protocol)
return nil, false, fmt.Errorf("Unsupported protocol: %v", protocol)
}

// Override visiblity
Expand All @@ -559,7 +559,7 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
return tx.CreateImage(ctx, args.ProjectName, info.Fingerprint, info.Filename, info.Size, info.Public, info.AutoUpdate, info.Architecture, info.CreatedAt, info.ExpiresAt, info.Properties, info.Type, nil)
})
if err != nil {
return nil, fmt.Errorf("Failed creating image record: %w", err)
return nil, false, fmt.Errorf("Failed creating image record: %w", err)
}

// Image is in the DB now, don't wipe on-disk files on failure
Expand All @@ -570,13 +570,13 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
if newDestName != destName {
err = internalUtil.FileMove(destName, newDestName)
if err != nil {
return nil, err
return nil, false, err
}

if util.PathExists(destName + ".rootfs") {
err = internalUtil.FileMove(destName+".rootfs", newDestName+".rootfs")
if err != nil {
return nil, err
return nil, false, err
}
}
}
Expand All @@ -592,15 +592,15 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
return tx.CreateImageSource(ctx, id, args.Server, protocol, args.Certificate, alias)
})
if err != nil {
return nil, err
return nil, false, err
}
}

// Import into the requested storage pool
if args.StoragePool != "" {
err = imageCreateInPool(s, info, args.StoragePool)
if err != nil {
return nil, err
return nil, false, err
}
}

Expand All @@ -610,11 +610,11 @@ func ImageDownload(ctx context.Context, r *http.Request, s *state.State, op *ope
return tx.SetImageCachedAndLastUseDate(ctx, args.ProjectName, fp, time.Now().UTC())
})
if err != nil {
return nil, fmt.Errorf("Failed setting cached flag and last use date: %w", err)
return nil, false, fmt.Errorf("Failed setting cached flag and last use date: %w", err)
}
}

logger.Info("Image downloaded", ctxMap)

return info, nil
return info, true, nil
}
6 changes: 3 additions & 3 deletions cmd/incusd/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ func imgPostRemoteInfo(ctx context.Context, s *state.State, r *http.Request, req
return nil, fmt.Errorf("must specify one of alias or fingerprint for init from image")
}

info, err := ImageDownload(ctx, r, s, op, &ImageDownloadArgs{
info, _, err := ImageDownload(ctx, r, s, op, &ImageDownloadArgs{
Server: req.Source.Server,
Protocol: req.Source.Protocol,
Certificate: req.Source.Certificate,
Expand Down Expand Up @@ -546,7 +546,7 @@ func imgPostURLInfo(ctx context.Context, s *state.State, r *http.Request, req ap
}

// Import the image
info, err := ImageDownload(ctx, r, s, op, &ImageDownloadArgs{
info, _, err := ImageDownload(ctx, r, s, op, &ImageDownloadArgs{
Server: url,
Protocol: "direct",
Alias: hash,
Expand Down Expand Up @@ -2198,7 +2198,7 @@ func autoUpdateImage(ctx context.Context, s *state.State, op *operations.Operati
default:
}

newInfo, err = ImageDownload(ctx, nil, s, op, &ImageDownloadArgs{
newInfo, _, err = ImageDownload(ctx, nil, s, op, &ImageDownloadArgs{
Server: source.Server,
Protocol: source.Protocol,
Certificate: source.Certificate,
Expand Down
Loading

0 comments on commit ee8803d

Please sign in to comment.