Skip to content

Commit 71c0a0b

Browse files
authored
Merge pull request #36 from securebuildhq/divolgin/sc-130119/image-package-build-s-get-stuck-in-queued
Process APKOs on package updates asynchronously
2 parents d7ad961 + c97238a commit 71c0a0b

File tree

1 file changed

+14
-91
lines changed

1 file changed

+14
-91
lines changed

pkg/listener/update-build-package-status.go

Lines changed: 14 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ func updateBuildPackageStatus(ctx context.Context, executionID string) error {
349349

350350
// Queue build_image_with_vm_assigned events for images that depend on this package
351351
if err := queueBuildApkoEventsForPackage(ctx, pkgVersion.PackageID, pkgVersion.Version); err != nil {
352-
logger.Warn("failed to queue build_image_with_vm_assigned events for dependent images",
352+
logger.Error(fmt.Errorf("failed to queue build_image_with_vm_assigned events for dependent images: %w", err),
353353
zap.String("packageID", pkgVersion.PackageID),
354354
zap.Error(err))
355355
}
@@ -619,7 +619,8 @@ func readRemoteFileContent(client *ssh.Client, filePath string) (string, error)
619619
return string(output), nil
620620
}
621621

622-
// queueBuildApkoEventsForPackage creates build_image_with_vm_assigned events for APKOs that depend on the given package
622+
// queueBuildApkoEventsForPackage enqueues build_apko events for APKOs that depend on the given package.
623+
// VM assignment and image build creation happen asynchronously in the build_apko handler, so the status checker is not blocked.
623624
func queueBuildApkoEventsForPackage(ctx context.Context, packageID string, version string) error {
624625
// Get the package info for logging
625626
pkg, err := sbpackage.GetPackage(ctx, packageID)
@@ -644,115 +645,37 @@ func queueBuildApkoEventsForPackage(ctx context.Context, packageID string, versi
644645
zap.Int("apkoCount", len(apkoIDs)),
645646
zap.Strings("apkoIDs", apkoIDs))
646647

647-
// Queue a build_image_with_vm_assigned event for each dependent APKO
648648
for _, apkoID := range apkoIDs {
649-
// Get the latest APKO version directly
650-
latestApkoVersion, err := image.GetLatestImageAPKOVersion(ctx, apkoID)
649+
// Get image ID for this APKO (build_apko handler expects imageId + apkoId)
650+
_, imageID, err := image.GetAPKO(ctx, apkoID)
651651
if err != nil {
652-
logger.Warn("failed to get latest APKO version",
652+
logger.Warn("failed to get APKO for dependent image build",
653653
zap.String("apkoID", apkoID),
654654
zap.Error(err))
655655
continue
656656
}
657657

658-
imageBuild, err := image.CreateImageBuild(ctx, latestApkoVersion.ID)
659-
if err != nil {
660-
logger.Warn("failed to create image build",
661-
zap.String("apkoID", apkoID),
662-
zap.Error(err))
663-
continue
664-
}
665-
666-
// Update build status to queued
667-
if err := image.UpdateImageBuildStatus(ctx, imageBuild.ID, imagetypes.ImageBuildStatusQueued); err != nil {
668-
logger.Warn("failed to update image build status to queued", zap.Error(err))
669-
}
670-
671-
// Assign VM for image building (selects best available architecture)
672-
logger.Debug("assigning VM for image build",
673-
zap.String("buildID", imageBuild.ID),
674-
zap.Duration("timeout", time.Minute*10),
675-
)
676-
677-
// Create a context with timeout
678-
timeoutCtx, cancel := context.WithTimeout(ctx, time.Minute*10)
679-
defer cancel()
680-
681-
// Select the best architecture based on available VM counts
682-
selectedArch, err := builder.SelectBestArchitectureForImageBuild(ctx)
683-
if err != nil {
684-
logger.Warn("IMAGE BUILD FAILED: architecture selection failure",
685-
zap.String("buildID", imageBuild.ID),
686-
zap.String("apkoID", apkoID),
687-
zap.Error(fmt.Errorf("failed to select architecture for image build: %w", err)))
688-
689-
// Mark build as failed
690-
if statusErr := image.UpdateImageBuildStatus(ctx, imageBuild.ID, imagetypes.ImageBuildStatusFailed, fmt.Errorf("architecture selection failure: %w", err)); statusErr != nil {
691-
logger.Warn("failed to update image build status to failed", zap.Error(statusErr))
692-
}
693-
continue
658+
payload := BuildAPKOPayload{
659+
ImageID: imageID,
660+
APKOID: apkoID,
694661
}
695-
696-
logger.Debug("selected architecture for image build",
697-
zap.String("buildID", imageBuild.ID),
698-
zap.String("apkoID", apkoID),
699-
zap.String("architecture", selectedArch))
700-
701-
// Take VM with selected architecture for image building (can build both architectures)
702-
vm, err := builder.TakeVMWithAssignment(timeoutCtx, selectedArch, "build_image", imageBuild.ID)
703-
if err != nil {
704-
logger.Warn("IMAGE BUILD FAILED: VM assignment failure - could not assign VM for image build",
705-
zap.String("buildID", imageBuild.ID),
706-
zap.String("apkoID", apkoID),
707-
zap.String("architecture", selectedArch),
708-
zap.Error(fmt.Errorf("failed to take %s VM for image build: %w", selectedArch, err)))
709-
710-
// Mark build as failed
711-
if statusErr := image.UpdateImageBuildStatus(ctx, imageBuild.ID, imagetypes.ImageBuildStatusFailed, fmt.Errorf("VM assignment failure: %w", err)); statusErr != nil {
712-
logger.Warn("failed to update image build status to failed", zap.Error(statusErr))
713-
}
714-
continue
715-
}
716-
717-
vmID := vm.ID
718-
719-
// Update build record with VM ID
720-
if err := image.SetImageBuildBuilderID(ctx, imageBuild.ID, vmID); err != nil {
721-
logger.Warn("failed to set image build builder ID", zap.Error(err))
722-
}
723-
724-
// Create payload for build_image_with_vm_assigned event
725-
payload := BuildImageWithVMAssignedPayload{
726-
VMID: vmID,
727-
BuildID: imageBuild.ID,
728-
}
729-
730662
payloadJSON, err := json.Marshal(payload)
731663
if err != nil {
732-
logger.Warn("failed to marshal build_image_with_vm_assigned payload",
664+
logger.Warn("failed to marshal build_apko payload",
733665
zap.String("apkoID", apkoID),
734666
zap.Error(err))
735-
736-
// Mark build as failed
737-
if statusErr := image.UpdateImageBuildStatus(ctx, imageBuild.ID, imagetypes.ImageBuildStatusFailed, fmt.Errorf("JSON marshalling failure: %w", err)); statusErr != nil {
738-
logger.Warn("failed to update image build status to failed", zap.Error(statusErr))
739-
}
740667
continue
741668
}
742669

743-
if err := persistence.EnqueueWork(ctx, "build_image_with_vm_assigned", string(payloadJSON)); err != nil {
744-
logger.Warn("failed to enqueue build_image_with_vm_assigned event",
670+
if err := persistence.EnqueueWork(ctx, "build_apko", string(payloadJSON)); err != nil {
671+
logger.Warn("failed to enqueue build_apko event",
672+
zap.String("packageID", packageID),
745673
zap.String("apkoID", apkoID),
746674
zap.Error(err))
747-
748-
// Mark build as failed
749-
if statusErr := image.UpdateImageBuildStatus(ctx, imageBuild.ID, imagetypes.ImageBuildStatusFailed, fmt.Errorf("work queue enqueue failure: %w", err)); statusErr != nil {
750-
logger.Warn("failed to update image build status to failed", zap.Error(statusErr))
751-
}
752675
continue
753676
}
754677

755-
logger.Info("queued build_image_with_vm_assigned event for dependent APKO",
678+
logger.Info("queued build_apko event for dependent APKO",
756679
zap.String("packageID", packageID),
757680
zap.String("apkoID", apkoID))
758681
}

0 commit comments

Comments
 (0)