mirror of
https://github.com/lukaszraczylo/kubernetes-images-sync-operator.git
synced 2026-07-01 02:55:03 +00:00
Mount imageSecrets in the worker pod
This commit is contained in:
@@ -21,6 +21,7 @@ limitations under the License.
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -142,6 +143,11 @@ func (in *ClusterImageExportSpec) DeepCopyInto(out *ClusterImageExportSpec) {
|
|||||||
(*out)[key] = val
|
(*out)[key] = val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if in.ImagePullSecrets != nil {
|
||||||
|
in, out := &in.ImagePullSecrets, &out.ImagePullSecrets
|
||||||
|
*out = make([]corev1.LocalObjectReference, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterImageExportSpec.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterImageExportSpec.
|
||||||
@@ -211,6 +217,11 @@ func (in *ClusterImageSpec) DeepCopyInto(out *ClusterImageSpec) {
|
|||||||
(*out)[key] = val
|
(*out)[key] = val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if in.ImagePullSecrets != nil {
|
||||||
|
in, out := &in.ImagePullSecrets, &out.ImagePullSecrets
|
||||||
|
*out = make([]corev1.LocalObjectReference, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterImageSpec.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterImageSpec.
|
||||||
|
|||||||
+2
-2
@@ -10,9 +10,9 @@ description: |
|
|||||||
|
|
||||||
type: application
|
type: application
|
||||||
|
|
||||||
version: 0.1.23
|
version: 0.1.27
|
||||||
|
|
||||||
appVersion: "0.1.23"
|
appVersion: "0.1.27"
|
||||||
|
|
||||||
home: https://github.com/lukaszraczylo/kubernetes-images-sync-operator
|
home: https://github.com/lukaszraczylo/kubernetes-images-sync-operator
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ sa:
|
|||||||
- ALL
|
- ALL
|
||||||
image:
|
image:
|
||||||
repository: ghcr.io/lukaszraczylo/kubernetes-images-sync-operator
|
repository: ghcr.io/lukaszraczylo/kubernetes-images-sync-operator
|
||||||
tag: 0.1.23
|
tag: 0.1.27
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
cpu: 500m
|
cpu: 500m
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
gnupg2 \
|
gnupg2 \
|
||||||
python3-pip \
|
python3-pip \
|
||||||
sudo \
|
sudo \
|
||||||
|
jq \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
RUN echo "deb [arch=${TARGETARCH}] https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/unstable/xUbuntu_22.04/ /" | tee /etc/apt/sources.list.d/devel:kubic:libcontainers:unstable.list \
|
RUN echo "deb [arch=${TARGETARCH}] https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/unstable/xUbuntu_22.04/ /" | tee /etc/apt/sources.list.d/devel:kubic:libcontainers:unstable.list \
|
||||||
@@ -30,7 +31,10 @@ RUN adduser --disabled-password --gecos "" --uid 1001 runner \
|
|||||||
WORKDIR /home/runner
|
WORKDIR /home/runner
|
||||||
|
|
||||||
COPY storage.conf containers.conf registries.conf /home/runner/.config/containers/
|
COPY storage.conf containers.conf registries.conf /home/runner/.config/containers/
|
||||||
COPY requirements.txt export.py cleanup.py s3_utils.py ./
|
COPY requirements.txt export.py cleanup.py s3_utils.py podman-preauth.sh ./
|
||||||
USER runner
|
USER runner
|
||||||
RUN sudo chown -R runner:runner /home/runner/.config \
|
RUN sudo chown -R runner:runner /home/runner/.config \
|
||||||
&& python3 -m pip install --no-cache-dir --only-binary=:all: -r requirements.txt
|
&& python3 -m pip install --no-cache-dir --only-binary=:all: -r requirements.txt \
|
||||||
|
&& sudo chmod +x podman-preauth.sh
|
||||||
|
ENTRYPOINT ["/home/runner/podman-preauth.sh"]
|
||||||
|
CMD ["bash", "-c"]
|
||||||
Executable
+33
@@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
PODMAN_AUTH_FILE="/home/runner/.config/containers/auth.json"
|
||||||
|
|
||||||
|
# Initialize the auth file if it doesn't exist or is empty
|
||||||
|
mkdir -p $(dirname $PODMAN_AUTH_FILE)
|
||||||
|
if [ ! -s "$PODMAN_AUTH_FILE" ]; then
|
||||||
|
echo '{"auths":{}}' > $PODMAN_AUTH_FILE
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Loop through all mounted secret directories
|
||||||
|
for secret_dir in /home/runner/.docker-secret-*; do
|
||||||
|
if [ -d "$secret_dir" ]; then
|
||||||
|
config_file="$secret_dir/.dockerconfigjson"
|
||||||
|
if [ -f "$config_file" ]; then
|
||||||
|
# Merge the auth data into the podman auth file
|
||||||
|
jq -s '.[0].auths * .[1].auths | {auths: .}' $PODMAN_AUTH_FILE $config_file > ${PODMAN_AUTH_FILE}.tmp
|
||||||
|
mv ${PODMAN_AUTH_FILE}.tmp $PODMAN_AUTH_FILE
|
||||||
|
# Extract registry, username, and password from the config file
|
||||||
|
jq -r '.auths | to_entries[] | "\(.key) \(.value.auth)"' $config_file | while read registry auth; do
|
||||||
|
username=$(echo $auth | base64 -d | cut -d: -f1)
|
||||||
|
password=$(echo $auth | base64 -d | cut -d: -f2-)
|
||||||
|
# Perform podman login
|
||||||
|
podman login --username "$username" --password "$password" "$registry"
|
||||||
|
echo "podman: Successfully logged into $registry"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Run the original command
|
||||||
|
exec "$@"
|
||||||
@@ -82,7 +82,7 @@ func (r *ClusterImageReconciler) Reconcile(ctx context.Context, req ctrl.Request
|
|||||||
case shared.STATUS_SUCCESS, shared.STATUS_FAILED, shared.STATUS_PRESENT:
|
case shared.STATUS_SUCCESS, shared.STATUS_FAILED, shared.STATUS_PRESENT:
|
||||||
return ctrl.Result{}, nil // No further action needed
|
return ctrl.Result{}, nil // No further action needed
|
||||||
default:
|
default:
|
||||||
l.Info("Unexpected ClusterImage status", "Status", clusterImage.Status.Progress)
|
// l.Info("Unexpected ClusterImage status", "Status", clusterImage.Status.Progress)
|
||||||
return ctrl.Result{}, nil
|
return ctrl.Result{}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -188,7 +188,7 @@ func (r *ClusterImageReconciler) handleRunningClusterImage(ctx context.Context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
l.Info("Reconciling ClusterImage completed", "Name", clusterImage.Name, "Status", clusterImage.Status.Progress)
|
// l.Info("Reconciling ClusterImage completed", "Name", clusterImage.Name, "Status", clusterImage.Status.Progress)
|
||||||
|
|
||||||
return r.updateClusterImageExportStatus(ctx, clusterImage)
|
return r.updateClusterImageExportStatus(ctx, clusterImage)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ const clusterImageExportFinalizer = "finalizer.clusterimageexport.raczylo.com"
|
|||||||
|
|
||||||
func (r *ClusterImageExportReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
func (r *ClusterImageExportReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||||
l := log.FromContext(ctx)
|
l := log.FromContext(ctx)
|
||||||
l.Info("Reconciling ClusterImageExport")
|
// l.Info("Reconciling ClusterImageExport")
|
||||||
|
|
||||||
// Fetch the ClusterImageExport instance
|
// Fetch the ClusterImageExport instance
|
||||||
clusterImageExport := &raczylocomv1.ClusterImageExport{}
|
clusterImageExport := &raczylocomv1.ClusterImageExport{}
|
||||||
@@ -224,7 +224,7 @@ func (r *ClusterImageExportReconciler) listImagesInCluster(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
containersList = shared.RemoveDuplicates(containersList)
|
containersList = shared.RemoveDuplicates(containersList)
|
||||||
l.Info("List of containers in the cluster", "containers", containersList)
|
// l.Info("List of containers in the cluster", "containers", containersList)
|
||||||
|
|
||||||
return containersList, nil
|
return containersList, nil
|
||||||
}
|
}
|
||||||
@@ -270,12 +270,13 @@ func (r *ClusterImageExportReconciler) runCleanupJob(ctx context.Context, cluste
|
|||||||
}
|
}
|
||||||
|
|
||||||
jobParams := shared.JobParams{
|
jobParams := shared.JobParams{
|
||||||
Name: normalisedImageName,
|
Name: normalisedImageName,
|
||||||
Namespace: clusterImageExport.Namespace,
|
Namespace: clusterImageExport.Namespace,
|
||||||
Image: shared.BACKUP_JOB_IMAGE,
|
Image: shared.BACKUP_JOB_IMAGE,
|
||||||
Commands: defaultCommands,
|
Commands: defaultCommands,
|
||||||
Annotations: clusterImageExport.Spec.JobAnnotations,
|
Annotations: clusterImageExport.Spec.JobAnnotations,
|
||||||
ServiceAccount: os.Getenv("POD_SERVICE_ACCOUNT"),
|
ServiceAccount: os.Getenv("POD_SERVICE_ACCOUNT"),
|
||||||
|
ImagePullSecrets: clusterImageExport.Spec.ImagePullSecrets,
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanupJob := shared.CreateJob(jobParams, func(raczylocomv1.ClusterImageExport) []string { return nil })
|
cleanupJob := shared.CreateJob(jobParams, func(raczylocomv1.ClusterImageExport) []string { return nil })
|
||||||
|
|||||||
+31
-10
@@ -24,7 +24,28 @@ type JobParams struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func CreateJob[T any](params JobParams, setupFunc func(T) []string) *batchv1.Job {
|
func CreateJob[T any](params JobParams, setupFunc func(T) []string) *batchv1.Job {
|
||||||
return &batchv1.Job{
|
volumes := []corev1.Volume{}
|
||||||
|
volumeMounts := []corev1.VolumeMount{}
|
||||||
|
|
||||||
|
if len(params.ImagePullSecrets) > 0 {
|
||||||
|
for i, secret := range params.ImagePullSecrets {
|
||||||
|
volumes = append(volumes, corev1.Volume{
|
||||||
|
Name: fmt.Sprintf("secret-%d", i),
|
||||||
|
VolumeSource: corev1.VolumeSource{
|
||||||
|
Secret: &corev1.SecretVolumeSource{
|
||||||
|
SecretName: secret.Name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
volumeMounts = append(volumeMounts, corev1.VolumeMount{
|
||||||
|
Name: fmt.Sprintf("secret-%d", i),
|
||||||
|
MountPath: fmt.Sprintf("/home/runner/.docker-secret-%d", i),
|
||||||
|
ReadOnly: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
j := &batchv1.Job{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: params.Name,
|
Name: params.Name,
|
||||||
Namespace: params.Namespace,
|
Namespace: params.Namespace,
|
||||||
@@ -46,17 +67,16 @@ func CreateJob[T any](params JobParams, setupFunc func(T) []string) *batchv1.Job
|
|||||||
RestartPolicy: corev1.RestartPolicyOnFailure,
|
RestartPolicy: corev1.RestartPolicyOnFailure,
|
||||||
ServiceAccountName: params.ServiceAccount,
|
ServiceAccountName: params.ServiceAccount,
|
||||||
ImagePullSecrets: params.ImagePullSecrets,
|
ImagePullSecrets: params.ImagePullSecrets,
|
||||||
|
Volumes: volumes,
|
||||||
Containers: []corev1.Container{
|
Containers: []corev1.Container{
|
||||||
{
|
{
|
||||||
Name: "export",
|
Name: "exporter",
|
||||||
Image: params.Image,
|
Image: params.Image,
|
||||||
TTY: true,
|
TTY: true,
|
||||||
Command: []string{
|
Command: []string{},
|
||||||
"bash",
|
Args: []string{"/bin/bash", "-c", strings.Join(params.Commands, " && ")},
|
||||||
"-c",
|
VolumeMounts: volumeMounts,
|
||||||
strings.Join(params.Commands, " && "),
|
Env: params.EnvVars,
|
||||||
},
|
|
||||||
Env: params.EnvVars,
|
|
||||||
SecurityContext: &corev1.SecurityContext{
|
SecurityContext: &corev1.SecurityContext{
|
||||||
Privileged: pointer.Bool(true),
|
Privileged: pointer.Bool(true),
|
||||||
},
|
},
|
||||||
@@ -66,6 +86,7 @@ func CreateJob[T any](params JobParams, setupFunc func(T) []string) *batchv1.Job
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
return j
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetupS3Params(s3Config raczylocomv1.ClusterImageStorageS3) []string {
|
func SetupS3Params(s3Config raczylocomv1.ClusterImageStorageS3) []string {
|
||||||
|
|||||||
Reference in New Issue
Block a user