From 24062e9961510d1638a846945387aebacf9428d9 Mon Sep 17 00:00:00 2001 From: Srikumar Venugopal Date: Mon, 22 Jan 2024 11:37:17 +0000 Subject: [PATCH] Support for sub-folders when mounting S3 buckets (#263) * initial support for s3 folders Signed-off-by: SRIKUMAR VENUGOPAL * adding support for building local component containers with podman Signed-off-by: SRIKUMAR VENUGOPAL * bug fixes in build bash scripts Signed-off-by: SRIKUMAR VENUGOPAL * bug fixes in build bash scripts Signed-off-by: SRIKUMAR VENUGOPAL * bug fixes in build bash scripts Signed-off-by: SRIKUMAR VENUGOPAL * bug fixes in build bash scripts Signed-off-by: SRIKUMAR VENUGOPAL * bug fixes in build bash scripts Signed-off-by: SRIKUMAR VENUGOPAL * bug fixes in build bash scripts Signed-off-by: SRIKUMAR VENUGOPAL * docker buildx load after build Signed-off-by: SRIKUMAR VENUGOPAL * docker buildx load after build Signed-off-by: SRIKUMAR VENUGOPAL --------- Signed-off-by: SRIKUMAR VENUGOPAL --- build-tools/build_components.sh | 45 ++++++++-- src/csi-s3/pkg/s3/config.go | 1 + src/csi-s3/pkg/s3/mounter_goofys.go | 49 ++++++----- src/csi-s3/pkg/s3/nodeserver.go | 10 +++ src/csi-s3/pkg/s3/s3-client.go | 4 +- ...ild_and_push_multiarch_dataset_operator.sh | 5 -- .../build_dataset_operator.sh | 5 -- .../build_multiarch_dataset_operator.sh | 86 +++++++++++++++++++ .../controllers/datasetinternal_controller.go | 66 ++++++++++---- src/dataset-operator/go.mod | 1 + src/dataset-operator/go.sum | 1 + .../build_and_push_multiarch_generate_keys.sh | 5 -- src/generate-keys/build_generate_keys.sh | 4 - .../build_multiarch_generate_keys.sh | 86 +++++++++++++++++++ 14 files changed, 301 insertions(+), 67 deletions(-) delete mode 100755 src/dataset-operator/build_and_push_multiarch_dataset_operator.sh delete mode 100755 src/dataset-operator/build_dataset_operator.sh create mode 100755 src/dataset-operator/build_multiarch_dataset_operator.sh delete mode 100755 src/generate-keys/build_and_push_multiarch_generate_keys.sh delete mode 100755 src/generate-keys/build_generate_keys.sh create mode 100755 src/generate-keys/build_multiarch_generate_keys.sh diff --git a/build-tools/build_components.sh b/build-tools/build_components.sh index 62ad9821..8751cdc3 100755 --- a/build-tools/build_components.sh +++ b/build-tools/build_components.sh @@ -30,16 +30,47 @@ do esac done +shift $((OPTIND-1)) + +REGISTRY_URL="${1:-quay.io/datashim-io}" +VERSION="${2:-latest}" + +DOCKERCMD="docker" +ALTDOCKERCMD="podman" +if !(command -v ${DOCKERCMD} &> /dev/null) +then + echo "Docker command not found" + if !(command -v ${ALTDOCKERCMD} &> /dev/null) + then + echo "Neither ${DOCKERCMD} nor ${ALTDOCKERCMD} commands found.. cannot build " + exit 1 + else + DOCKERCMD=${ALTDOCKERCMD} + fi +else + echo "Docker command found" + cmd_type=$(type -t ${DOCKERCMD}) + if [ $cmd_type == "alias" ] + then + echo "${DOCKERCMD} is an alias, switching to ${ALTDOCKERCMD}" + DOCKERCMD=${ALTDOCKERCMD} + fi +fi + +if [ ${DOCKERCMD} == "docker" ] +then + if [ $CREATE_NEW_BUILDX_CONTEXT = "yes" ]; then + docker buildx create --use + fi +fi + if [ $BUILD_AND_PUSH = "yes" ]; then if [ $SKIP_LOGIN = "no" ]; then echo $REGISTRY_PASSWORD | docker login -u $REGISTRY_USERNAME --password-stdin $REGISTRY_URL fi - if [ $CREATE_NEW_BUILDX_CONTEXT = "yes" ]; then - docker buildx create --use - fi - (cd ../src/dataset-operator && ./build_and_push_multiarch_dataset_operator.sh $REGISTRY_URL) - (cd ../src/generate-keys && ./build_and_push_multiarch_generate_keys.sh $REGISTRY_URL) + (cd ../src/dataset-operator && ./build_multiarch_dataset_operator.sh -p $REGISTRY_URL $VERSION) + (cd ../src/generate-keys && ./build_multiarch_generate_keys.sh -p $REGISTRY_URL $VERSION) else - (cd ../src/dataset-operator && ./build_dataset_operator.sh $REGISTRY_URL) - (cd ../src/generate-keys && ./build_generate_keys.sh $REGISTRY_URL) + (cd ../src/dataset-operator && ./build_multiarch_dataset_operator.sh $REGISTRY_URL $VERSION) + (cd ../src/generate-keys && ./build_multiarch_generate_keys.sh $REGISTRY_URL $VERSION) fi diff --git a/src/csi-s3/pkg/s3/config.go b/src/csi-s3/pkg/s3/config.go index 22443c4c..cb36c48a 100644 --- a/src/csi-s3/pkg/s3/config.go +++ b/src/csi-s3/pkg/s3/config.go @@ -8,6 +8,7 @@ type Config struct { Endpoint string Mounter string Bucket string + Folder string RemoveOnDelete bool Readonly bool Provision bool diff --git a/src/csi-s3/pkg/s3/mounter_goofys.go b/src/csi-s3/pkg/s3/mounter_goofys.go index e9b8a09d..c65294d4 100644 --- a/src/csi-s3/pkg/s3/mounter_goofys.go +++ b/src/csi-s3/pkg/s3/mounter_goofys.go @@ -2,13 +2,14 @@ package s3 import ( "fmt" - "github.com/golang/glog" "log" "os" + + "github.com/golang/glog" ) const ( - goofysCmd = "goofys" + goofysCmd = "goofys" ) // Implements Mounter @@ -18,12 +19,12 @@ type goofysMounter struct { region string accessKeyID string secretAccessKey string - volumeID string - readonly bool + volumeID string + readonly bool } func newGoofysMounter(b *bucket, cfg *Config, volume string) (Mounter, error) { - glog.V(3).Infof("Mounting using goofys volume %s",volume) + glog.V(3).Infof("Mounting using goofys volume %s", volume) //TODO we need to handle regions as well //region := cfg.Region //// if endpoint is set we need a default region @@ -36,8 +37,8 @@ func newGoofysMounter(b *bucket, cfg *Config, volume string) (Mounter, error) { region: cfg.Region, accessKeyID: cfg.AccessKeyID, secretAccessKey: cfg.SecretAccessKey, - readonly: cfg.Readonly, - volumeID: volume, + readonly: cfg.Readonly, + volumeID: volume, }, nil } @@ -57,11 +58,11 @@ func (goofys *goofysMounter) Mount(source string, target string) error { } args := []string{ fmt.Sprintf("--endpoint=%s", goofys.endpoint), - "--type-cache-ttl","1s", - "--stat-cache-ttl","1s", - "--dir-mode","0777", - "--file-mode","0777", - "--http-timeout","5m", + "--type-cache-ttl", "1s", + "--stat-cache-ttl", "1s", + "--dir-mode", "0777", + "--file-mode", "0777", + "--http-timeout", "5m", //fmt.Sprintf("--cheap=%s", os.Getenv("cheap")), "-o", "allow_other", } @@ -71,21 +72,28 @@ func (goofys *goofysMounter) Mount(source string, target string) error { if goofys.region != "" { args = append(args, "--region", goofys.region) } - if(goofys.readonly) { - args = append(args, "-o","ro") + if goofys.readonly { + args = append(args, "-o", "ro") + } + if goofys.bucket.Folder == "" { + glog.V(4).Infof("This bucket %s contains no folder prefixes", goofys.bucket.Name) + args = append(args, + fmt.Sprintf("%s", goofys.bucket.Name), + fmt.Sprintf("%s", target)) + } else { + glog.V(4).Infof("This bucket %s contains folder prefix %s", goofys.bucket.Name, goofys.bucket.Folder) + args = append(args, + fmt.Sprintf("%s:%s", goofys.bucket.Name, goofys.bucket.Folder), + fmt.Sprintf("%s", target)) } - args = append(args, - fmt.Sprintf("%s", goofys.bucket.Name), - fmt.Sprintf("%s", target)) return fuseMount(target, goofysCmd, args) } - func writes3fsPassGoofy(goofys *goofysMounter) error { awsPath := fmt.Sprintf("%s/.aws", os.Getenv("HOME")) if _, err := os.Stat(awsPath); os.IsNotExist(err) { - mkdir_err := os.Mkdir(awsPath,0700) + mkdir_err := os.Mkdir(awsPath, 0700) if mkdir_err != nil { return mkdir_err } @@ -98,10 +106,9 @@ func writes3fsPassGoofy(goofys *goofysMounter) error { log.Println(err) } defer f.Close() - textToAdd := "["+goofys.volumeID+"]\naws_access_key_id = "+goofys.accessKeyID+"\naws_secret_access_key ="+goofys.secretAccessKey+"\n" + textToAdd := "[" + goofys.volumeID + "]\naws_access_key_id = " + goofys.accessKeyID + "\naws_secret_access_key =" + goofys.secretAccessKey + "\n" if _, err := f.WriteString(textToAdd); err != nil { log.Println(err) } return nil } - diff --git a/src/csi-s3/pkg/s3/nodeserver.go b/src/csi-s3/pkg/s3/nodeserver.go index b3fa1f43..aaccd5dd 100644 --- a/src/csi-s3/pkg/s3/nodeserver.go +++ b/src/csi-s3/pkg/s3/nodeserver.go @@ -122,6 +122,15 @@ func (ns *nodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis return nil, status.Error(codes.InvalidArgument, "Bucket name not provided for mounting") } + // srikumarv - this is a hack to support folders for the current csi-s3 implementation used in + // Datashim + folder := "" + if len(s3.cfg.Folder) != 0 { + folder = s3.cfg.Folder + } else { + glog.V(2).Infof("s3: no fspath found for bucket %s", bucketName) + } + //b, err := s3.getBucket(bucketName) //if err != nil { // return nil, err @@ -130,6 +139,7 @@ func (ns *nodeServer) NodePublishVolume(ctx context.Context, req *csi.NodePublis b := &bucket{ Name: bucketName, + Folder: folder, Mounter: volContext[mounterTypeKey], } diff --git a/src/csi-s3/pkg/s3/s3-client.go b/src/csi-s3/pkg/s3/s3-client.go index 36881eaa..57fdae3c 100644 --- a/src/csi-s3/pkg/s3/s3-client.go +++ b/src/csi-s3/pkg/s3/s3-client.go @@ -20,6 +20,7 @@ type s3Client struct { type bucket struct { Name string + Folder string Mounter string } @@ -54,6 +55,7 @@ func newS3ClientFromSecrets(secrets map[string]string) (*s3Client, error) { Region: secrets["region"], Endpoint: secrets["endpoint"], Bucket: secrets["bucket"], + Folder: secrets["folder"], Readonly: readonly, Provision: provision, RemoveOnDelete: removeOnDelete, @@ -127,7 +129,7 @@ func (client *s3Client) emptyBucket(bucketName string) error { // return err //} -//TODO is it not used at all? +// TODO is it not used at all? func (client *s3Client) metadataExist(bucketName string) bool { opts := minio.GetObjectOptions{} _, err := client.minio.GetObject(bucketName, metadataName, opts) diff --git a/src/dataset-operator/build_and_push_multiarch_dataset_operator.sh b/src/dataset-operator/build_and_push_multiarch_dataset_operator.sh deleted file mode 100755 index 2421357a..00000000 --- a/src/dataset-operator/build_and_push_multiarch_dataset_operator.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -REGISTRY_URL="${1:-quay.io/datashim-io}" -VERSION="${2:-latest}" -docker buildx build --platform linux/amd64,linux/arm64,linux/ppc64le --push -t ${REGISTRY_URL}/dataset-operator:${VERSION} . diff --git a/src/dataset-operator/build_dataset_operator.sh b/src/dataset-operator/build_dataset_operator.sh deleted file mode 100755 index a938599e..00000000 --- a/src/dataset-operator/build_dataset_operator.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -REGISTRY_URL="${1:-quay.io/datashim-io}" -VERSION="${2:-latest}" -docker build -t ${REGISTRY_URL}/dataset-operator:${VERSION} . \ No newline at end of file diff --git a/src/dataset-operator/build_multiarch_dataset_operator.sh b/src/dataset-operator/build_multiarch_dataset_operator.sh new file mode 100755 index 00000000..354b4b6f --- /dev/null +++ b/src/dataset-operator/build_multiarch_dataset_operator.sh @@ -0,0 +1,86 @@ +#!/bin/bash +set -e + +print_usage() { + echo "usage: $0 [-p] " + echo "Use -p to build and push multiarch images" +} + +PUSH="false" +while getopts 'p' flag; do +case "$flag" in + p) + PUSH="true" + ;; + ?) + print_usage >&2 + exit 1 + ;; +esac +done + +shift $((OPTIND-1)) + +REGISTRY_URL="${1:-quay.io/datashim-io}" +VERSION="${2:-latest}" + +docker_build () { + docker buildx build --platform linux/amd64 -t ${REGISTRY_URL}/dataset-operator:${VERSION} . + docker buildx build --load -t ${REGISTRY_URL}/dataset-operator:${VERSION} . +} + +docker_build_and_push () { + docker buildx build --platform linux/amd64,linux/arm64,linux/ppc64le --push -t ${REGISTRY_URL}/dataset-operator:${VERSION} . +} + +podman_build () { + podman manifest create ${REGISTRY_URL}/dataset-operator:${VERSION} + podman buildx build --platform linux/amd64,linux/arm64 --manifest ${REGISTRY_URL}/dataset-operator:${VERSION} . +} + +podman_push () { + podman manifest push ${REGISTRY_URL}/dataset-operator:${VERSION} + +} + +DOCKERCMD="docker" +ALTDOCKERCMD="podman" +if !(command -v ${DOCKERCMD} &> /dev/null) +then + echo "Docker command not found" + if !(command -v ${ALTDOCKERCMD} &> /dev/null) + then + echo "Neither ${DOCKERCMD} nor ${ALTDOCKERCMD} commands found.. cannot build " + exit 1 + else + DOCKERCMD=${ALTDOCKERCMD} + fi +else + echo "Docker command found" + cmd_type=$(type -t ${DOCKERCMD}) + if [ $cmd_type == "alias" ] + then + echo "${DOCKERCMD} is an alias, switching to ${ALTDOCKERCMD}" + DOCKERCMD=${ALTDOCKERCMD} + fi +fi + +if [ $PUSH == "true" ] +then + echo "pushing images to the registry" + if [ ${DOCKERCMD} == "docker" ] + then + docker_build_and_push + else + podman_build + podman_push + fi +else + echo "building image locally" + if [ ${DOCKERCMD} == "docker" ] + then + docker_build + else + podman_build + fi +fi diff --git a/src/dataset-operator/controllers/datasetinternal_controller.go b/src/dataset-operator/controllers/datasetinternal_controller.go index 837875d0..03d26e0c 100644 --- a/src/dataset-operator/controllers/datasetinternal_controller.go +++ b/src/dataset-operator/controllers/datasetinternal_controller.go @@ -20,6 +20,7 @@ import ( "context" b64 "encoding/base64" "strconv" + "strings" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" @@ -338,16 +339,14 @@ func processLocalDatasetH3(cr *datasets.DatasetInternal, rc *DatasetInternalReco } } return reconcile.Result{}, nil - } -func processLocalDatasetCOS(cr *datasets.DatasetInternal, rc *DatasetInternalReconciler) (reconcile.Result, error) { - processLocalDatasetLogger := logi.WithValues("Dataset.Namespace", cr.Namespace, "Dataset.Name", cr.Name, "Method", "processLocalDataset") - +func checkAndExtractObjectStorageAccess(cr *datasets.DatasetInternal, rc *DatasetInternalReconciler) (accessKeyID, secretAccessKey string, authError error) { + checkObjectStorageLogger := logi.WithValues("Dataset.Namespace", cr.Namespace, "Dataset.Name", cr.Name, "Method", "checkAndExtractObjectStorageAccess") authProvided := false secretOK := false - var secretName, secretNamespace, accessKeyID, secretAccessKey string + var secretName, secretNamespace string var ok = false if secretName, ok = cr.Spec.Local["secret-name"]; ok { @@ -355,13 +354,13 @@ func processLocalDatasetCOS(cr *datasets.DatasetInternal, rc *DatasetInternalRec //16/12 - We will limit secrets to the same namespace as the dataset to fix #146 if secretNamespace, ok = cr.Spec.Local["secret-namespace"]; ok { if secretNamespace == cr.ObjectMeta.Namespace { - processLocalDatasetLogger.Info("Error: secret namespace is same as dataset namespace, allowed", "Dataset.Name", cr.ObjectMeta.Name) + checkObjectStorageLogger.Info("Secret namespace is same as dataset namespace, allowed", "Dataset.Name", cr.ObjectMeta.Name) secretOK = true } else { - processLocalDatasetLogger.Info("Error: secret namespace is different from dataset namespace, not allowed", "Dataset.Name", cr.ObjectMeta.Name) + checkObjectStorageLogger.Info("Error: secret namespace is different from dataset namespace, not allowed", "Dataset.Name", cr.ObjectMeta.Name) } } else { - processLocalDatasetLogger.Info("No secret namespace provided - using dataset namespace for secret", "Dataset Name", cr.ObjectMeta.Name, "Namespace", cr.ObjectMeta.Namespace) + checkObjectStorageLogger.Info("No secret namespace provided - using dataset namespace for secret", "Dataset Name", cr.ObjectMeta.Name, "Namespace", cr.ObjectMeta.Namespace) secretNamespace = cr.ObjectMeta.Namespace secretOK = true } @@ -373,7 +372,7 @@ func processLocalDatasetCOS(cr *datasets.DatasetInternal, rc *DatasetInternalRec err := rc.Client.Get(context.TODO(), types.NamespacedName{Name: secretName, Namespace: secretNamespace}, cosSecret) if err != nil && errors.IsNotFound(err) { - processLocalDatasetLogger.Error(err, "Provided secret not found! ", "Dataset.Name", cr.Name) + checkObjectStorageLogger.Error(err, "Provided secret not found! ", "Dataset.Name", cr.Name) authProvided = false } else { _, accessIDPresent := cosSecret.Data["accessKeyID"] @@ -383,14 +382,14 @@ func processLocalDatasetCOS(cr *datasets.DatasetInternal, rc *DatasetInternalRec secretAccessKey = string(cosSecret.Data["secretAccessKey"]) authProvided = true } else { - processLocalDatasetLogger.Error(nil, "Secret does not have access Key or secret Access Key", "Dataset.Name", cr.Name) + checkObjectStorageLogger.Error(nil, "Secret does not have access Key or secret Access Key", "Dataset.Name", cr.Name) authProvided = false } } } else { if accessKeyID, ok = cr.Spec.Local["accessKeyID"]; ok { if secretAccessKey, ok = cr.Spec.Local["secretAccessKey"]; !ok { - processLocalDatasetLogger.Error(nil, "Secret Key not provided with the access key", "Dataset.Name", cr.Name) + checkObjectStorageLogger.Error(nil, "Secret Key not provided with the access key", "Dataset.Name", cr.Name) authProvided = false } else { authProvided = true @@ -399,16 +398,42 @@ func processLocalDatasetCOS(cr *datasets.DatasetInternal, rc *DatasetInternalRec } if !authProvided { - err := errors.NewBadRequest("No useable secret provided for authentication") - processLocalDatasetLogger.Error(err, "Failed to initialise", "Dataset.Name", cr.Name) - return reconcile.Result{}, err + authError := errors.NewBadRequest("No useable secret provided for authentication") + checkObjectStorageLogger.Error(authError, "Failed to initialise", "Dataset.Name", cr.Name) + return "", "", authError } - processLocalDatasetLogger.Info("Authentication info has been successfully retrieved", "Dataset.Name", cr.Name) + return accessKeyID, secretAccessKey, nil +} + +func processLocalDatasetCOS(cr *datasets.DatasetInternal, rc *DatasetInternalReconciler) (reconcile.Result, error) { + processLocalDatasetLogger := logi.WithValues("Dataset.Namespace", cr.Namespace, "Dataset.Name", cr.Name, "Method", "processLocalDataset") + + // Sri - 18/1 - the validation of the dataset fields should be done in a validating admission controller + + accessKeyID, secretAccessKey, err := checkAndExtractObjectStorageAccess(cr, rc) + if err != nil { + return reconcile.Result{}, err + } else { + processLocalDatasetLogger.Info("Authentication info has been successfully retrieved", "Dataset.Name", cr.Name) + } endpoint := cr.Spec.Local["endpoint"] - bucket := cr.Spec.Local["bucket"] - region := cr.Spec.Local["region"] + // Sri - we assume that the first substring is the bucket name and the rest is the prefix (or folder) + bucket, prefix, found := strings.Cut(cr.Spec.Local["bucket"], "/") + + if !found { + processLocalDatasetLogger.Info("There was no prefix associated with the bucket for Dataset", "Dataset.Name", cr.Name, "bucket", bucket) + } else { + processLocalDatasetLogger.Info("Found a prefix associated with the bucket for Dataset", "Dataset.Name", cr.Name, "bucket", bucket, "prefix", prefix) + } + + region, ok := cr.Spec.Local["region"] + if ok { + processLocalDatasetLogger.Info("Region extracted from Dataset", "Dataset.Name", cr.Name, "bucket", bucket, "region", region) + } else { + processLocalDatasetLogger.Info("No region information was provided for Dataset", "Dataset.Name", cr.Name, "bucket", bucket) + } readonly := getBooleanStringForKeyInMap(processLocalDatasetLogger, "false", "readonly", cr.Spec.Local) provision := getBooleanStringForKeyInMap(processLocalDatasetLogger, "false", "provision", cr.Spec.Local) @@ -431,6 +456,7 @@ func processLocalDatasetCOS(cr *datasets.DatasetInternal, rc *DatasetInternalRec "secretAccessKey": secretAccessKey, "endpoint": endpoint, "bucket": bucket, + "folder": prefix, "region": region, "readonly": readonly, "extract": extract, @@ -445,6 +471,7 @@ func processLocalDatasetCOS(cr *datasets.DatasetInternal, rc *DatasetInternalRec configData := map[string]string{ "endpoint": endpoint, "bucket": bucket, + "folder": prefix, "region": region, } @@ -489,7 +516,7 @@ func processLocalDatasetCOS(cr *datasets.DatasetInternal, rc *DatasetInternalRec } foundPVC := &corev1.PersistentVolumeClaim{} - err := rc.Client.Get(context.TODO(), types.NamespacedName{Name: newPVC.Name, Namespace: newPVC.Namespace}, foundPVC) + err = rc.Client.Get(context.TODO(), types.NamespacedName{Name: newPVC.Name, Namespace: newPVC.Namespace}, foundPVC) if err != nil && errors.IsNotFound(err) { processLocalDatasetLogger.Info("Creating new pvc", "PVC.Namespace", newPVC.Namespace, "PVC.Name", newPVC.Name) err = rc.Client.Create(context.TODO(), newPVC) @@ -582,6 +609,7 @@ func processLocalDatasetNFS(cr *datasets.DatasetInternal, rc *DatasetInternalRec "share": share, "createDirPVC": createDirPVC, } + pvSource := &corev1.CSIPersistentVolumeSource{ Driver: csiDriverName, VolumeHandle: csiVolumeHandle, @@ -1072,7 +1100,7 @@ func getBooleanStringForKeyInMap(reqLogger logr.Logger, defaultValue string, key if err == nil { toret = strconv.FormatBool(valueBool) } else { - reqLogger.Info("Value set to be " + valueString + " rejected since it has to be true/false, using default " + defaultValue) + reqLogger.Info("Value set to§ be " + valueString + " rejected since it has to be true/false, using default " + defaultValue) } } return toret diff --git a/src/dataset-operator/go.mod b/src/dataset-operator/go.mod index 1a0cfe5e..d635687a 100644 --- a/src/dataset-operator/go.mod +++ b/src/dataset-operator/go.mod @@ -5,6 +5,7 @@ go 1.19 require ( github.com/akolb1/gometastore v0.0.0-20221218020403-aaa7217ecd00 github.com/go-logr/logr v1.2.4 + github.com/golang/mock v1.6.0 github.com/google/uuid v1.3.0 github.com/kubernetes-csi/csi-test/v5 v5.0.0 github.com/onsi/ginkgo/v2 v2.11.0 diff --git a/src/dataset-operator/go.sum b/src/dataset-operator/go.sum index 8892b0f3..22f953b4 100644 --- a/src/dataset-operator/go.sum +++ b/src/dataset-operator/go.sum @@ -157,6 +157,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= diff --git a/src/generate-keys/build_and_push_multiarch_generate_keys.sh b/src/generate-keys/build_and_push_multiarch_generate_keys.sh deleted file mode 100755 index 9b0a76cb..00000000 --- a/src/generate-keys/build_and_push_multiarch_generate_keys.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -REGISTRY_URL="${1:-quay.io/datashim-io}" -VERSION="${2:-latest}" -docker buildx build --platform linux/amd64,linux/arm64,linux/ppc64le --push -t ${REGISTRY_URL}/generate-keys:${VERSION} . diff --git a/src/generate-keys/build_generate_keys.sh b/src/generate-keys/build_generate_keys.sh deleted file mode 100755 index d43a4958..00000000 --- a/src/generate-keys/build_generate_keys.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -REGISTRY_URL="${1:-quay.io/datashim-io}" -docker build -t ${REGISTRY_URL}/generate-keys . \ No newline at end of file diff --git a/src/generate-keys/build_multiarch_generate_keys.sh b/src/generate-keys/build_multiarch_generate_keys.sh new file mode 100755 index 00000000..f7bf2b52 --- /dev/null +++ b/src/generate-keys/build_multiarch_generate_keys.sh @@ -0,0 +1,86 @@ +#!/bin/bash +set -e + +print_usage() { + echo "usage: $0 [-p] " + echo "Use -p to build and push multiarch images" +} + +PUSH="false" +while getopts 'p' flag; do +case "$flag" in + p) + PUSH="true" + ;; + ?) + print_usage >&2 + exit 1 + ;; +esac +done + +shift $((OPTIND-1)) + +REGISTRY_URL="${1:-quay.io/datashim-io}" +VERSION="${2:-latest}" + +docker_build () { + docker buildx build --platform linux/amd64 -t ${REGISTRY_URL}/generate-keys:${VERSION} . + docker buildx build --load -t ${REGISTRY_URL}/generate-keys:${VERSION} . +} + +docker_build_and_push () { + docker buildx build --platform linux/amd64,linux/arm64 --push -t ${REGISTRY_URL}/generate-keys:${VERSION} . +} + +podman_build () { + podman manifest create ${REGISTRY_URL}/generate-keys:${VERSION} + podman buildx build --platform linux/amd64,linux/arm64 --manifest ${REGISTRY_URL}/generate-keys:${VERSION} . +} + +podman_push () { + podman manifest push ${REGISTRY_URL}/generate-keys:${VERSION} + +} + +DOCKERCMD="docker" +ALTDOCKERCMD="podman" +if !(command -v ${DOCKERCMD} &> /dev/null) +then + echo "Docker command not found" + if !(command -v ${ALTDOCKERCMD} &> /dev/null) + then + echo "Neither ${DOCKERCMD} nor ${ALTDOCKERCMD} commands found.. cannot build " + exit 1 + else + DOCKERCMD=${ALTDOCKERCMD} + fi +else + echo "Docker command found" + cmd_type=$(type -t ${DOCKERCMD}) + if [ $cmd_type == "alias" ] + then + echo "${DOCKERCMD} is an alias, switching to ${ALTDOCKERCMD}" + DOCKERCMD=${ALTDOCKERCMD} + fi +fi + +if [ $PUSH == "true" ] +then + echo "pushing images to the registry" + if [ ${DOCKERCMD} == "docker" ] + then + docker_build_and_push + else + podman_build + podman_push + fi +else + echo "building image locally" + if [ ${DOCKERCMD} == "docker" ] + then + docker_build + else + podman_build + fi +fi