Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions internal/buildapi/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,9 @@ func listBuilds(c *gin.Context) {
return
}

// Resolve external route once for translating internal registry URLs
externalRoute, _ := getExternalRegistryRoute(ctx, k8sClient, namespace)

resp := make([]BuildListItem, 0, len(list.Items))
for _, b := range list.Items {
var startStr, compStr string
Expand All @@ -1471,6 +1474,18 @@ func listBuilds(c *gin.Context) {
if b.Status.CompletionTime != nil {
compStr = b.Status.CompletionTime.Format(time.RFC3339)
}

containerImage := b.Spec.GetContainerPush()
diskImage := b.Spec.GetExportOCI()
if b.Spec.GetUseServiceAccountAuth() && externalRoute != "" {
if containerImage != "" {
containerImage = translateToExternalURL(containerImage, externalRoute)
}
if diskImage != "" {
diskImage = translateToExternalURL(diskImage, externalRoute)
}
}

resp = append(resp, BuildListItem{
Name: b.Name,
Phase: b.Status.Phase,
Expand All @@ -1479,8 +1494,8 @@ func listBuilds(c *gin.Context) {
CreatedAt: b.CreationTimestamp.Format(time.RFC3339),
StartTime: startStr,
CompletionTime: compStr,
ContainerImage: b.Spec.GetContainerPush(),
DiskImage: b.Spec.GetExportOCI(),
ContainerImage: containerImage,
DiskImage: diskImage,
})
}
writeJSON(c, http.StatusOK, resp)
Expand Down
26 changes: 10 additions & 16 deletions internal/common/tasks/scripts/push_artifact.sh
Original file line number Diff line number Diff line change
Expand Up @@ -175,22 +175,26 @@ target="$(params.target)"
arch="$(params.arch)"

config_file="/etc/partition-config/partition-rules.yaml"
default_partitions=""
if [ -f "$config_file" ]; then
# Use yq to extract included partitions for target (using bracket notation for safety)
default_partitions=$(yq eval ".targets[\"${target}\"].include[]" "$config_file" 2>/dev/null | tr '\n' ',' | sed 's/,$//')

if [ -n "$default_partitions" ]; then
echo "Default partitions for target '$target': $default_partitions"
else
default_partitions="boot_a,system_a,system_b"
echo "No default partitions configured for target '$target', using fallback: $default_partitions"
echo "No default partitions configured for target '$target', skipping default-partitions annotation"
fi
else
default_partitions="boot_a,system_a,system_b"
echo "No partition configuration found, using fallback: $default_partitions"
echo "No partition configuration found, skipping default-partitions annotation"
fi

default_partitions_escaped=$(json_escape "$default_partitions")
default_partitions_annotation=""
if [ -n "$default_partitions" ]; then
default_partitions_escaped=$(json_escape "$default_partitions")
default_partitions_annotation=",
\"automotive.sdv.cloud.redhat.com/default-partitions\": \"${default_partitions_escaped}\""
fi

cd /workspace/shared

Expand Down Expand Up @@ -279,8 +283,7 @@ if [ -d "${parts_dir}" ] && [ -n "$(ls -A "${parts_dir}" 2>/dev/null)" ]; then
"automotive.sdv.cloud.redhat.com/parts": "${file_list}",
"automotive.sdv.cloud.redhat.com/distro": "${distro}",
"automotive.sdv.cloud.redhat.com/target": "${target}",
"automotive.sdv.cloud.redhat.com/arch": "${arch}",
"automotive.sdv.cloud.redhat.com/default-partitions": "${default_partitions_escaped}"
"automotive.sdv.cloud.redhat.com/arch": "${arch}"${default_partitions_annotation}
},
${layer_annotations_json}
}
Expand Down Expand Up @@ -308,14 +311,6 @@ EOF

echo ""
echo "=== Multi-layer artifact pushed successfully ==="
echo ""
echo "After pull, you get:"
echo "$file_list" | sed 's/,/\n/g' | while read -r f; do echo " ./$f"; done
echo ""
echo "Pull commands:"
echo " All files: oras pull ${repo_url}"
echo " Single file: oras pull ${repo_url} --include \"boot_a.simg.gz\""
echo " Inspect: oras manifest fetch ${repo_url} | jq ."

else
# Fallback to single-file push (original behavior)
Expand Down Expand Up @@ -355,5 +350,4 @@ else

echo ""
echo "=== Artifact pushed successfully ==="
echo "Pull: oras pull ${repo_url}"
fi
51 changes: 50 additions & 1 deletion internal/controller/imagebuild/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -532,9 +532,58 @@ func (r *ImageBuildReconciler) createBuildTaskRun(
"password": []byte(tokenResp.Status.Token),
},
}
if _, err := clientset.CoreV1().Secrets(imageBuild.Namespace).Create(ctx, ociSecret, metav1.CreateOptions{}); err != nil {
if _, err := clientset.CoreV1().Secrets(imageBuild.Namespace).Create(ctx, ociSecret, metav1.CreateOptions{}); err != nil && !errors.IsAlreadyExists(err) {
return fmt.Errorf("failed to create flash OCI auth secret: %w", err)
}
} else if imageBuild.Spec.SecretRef != "" && flashImageRef != "" {
// External registry: read credentials from the registry-auth secret and
// create a flash-oci-auth secret with username/password keys that the
// flash script expects.
registrySecret := &corev1.Secret{}
if err := r.Get(ctx, client.ObjectKey{
Namespace: imageBuild.Namespace,
Name: imageBuild.Spec.SecretRef,
}, registrySecret); err != nil {
return fmt.Errorf("failed to read registry secret %q for flash OCI credentials: %w", imageBuild.Spec.SecretRef, err)
}
regUser := registrySecret.Data["REGISTRY_USERNAME"]
regPass := registrySecret.Data["REGISTRY_PASSWORD"]
hasUser := len(regUser) > 0
hasPass := len(regPass) > 0
if hasUser && hasPass {
flashOCIAuthSecretName = imageBuild.Name + "-flash-oci-auth"
ociSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: flashOCIAuthSecretName,
Namespace: imageBuild.Namespace,
Labels: map[string]string{
"app.kubernetes.io/managed-by": "automotive-dev-operator",
"app.kubernetes.io/part-of": "automotive-dev",
"automotive.sdv.cloud.redhat.com/build-name": imageBuild.Name,
"automotive.sdv.cloud.redhat.com/transient": "true",
"automotive.sdv.cloud.redhat.com/resource-type": "flash-oci-auth",
},
OwnerReferences: []metav1.OwnerReference{
*metav1.NewControllerRef(imageBuild, automotivev1alpha1.GroupVersion.WithKind("ImageBuild")),
},
},
Type: corev1.SecretTypeOpaque,
Data: map[string][]byte{
"username": regUser,
"password": regPass,
},
}
if err := r.Create(ctx, ociSecret); err != nil && !errors.IsAlreadyExists(err) {
return fmt.Errorf("failed to create flash OCI auth secret from registry credentials: %w", err)
}
} else if hasUser || hasPass {
missing := "REGISTRY_PASSWORD"
if !hasUser {
missing = "REGISTRY_USERNAME"
}
log.Info("Partial registry credentials in secret, skipping flash OCI auth",
"secret", imageBuild.Spec.SecretRef, "missing", missing)
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

params = append(params,
Expand Down