diff --git a/pkg/cache/memory/draft.go b/pkg/cache/memory/draft.go index 0e21b833..ba60354a 100644 --- a/pkg/cache/memory/draft.go +++ b/pkg/cache/memory/draft.go @@ -23,11 +23,11 @@ import ( ) type cachedDraft struct { - repository.PackageDraft + repository.PackageRevisionDraft cache *cachedRepository } -var _ repository.PackageDraft = &cachedDraft{} +var _ repository.PackageRevisionDraft = &cachedDraft{} func (cd *cachedDraft) Close(ctx context.Context, version string) (repository.PackageRevision, error) { ctx, span := tracer.Start(ctx, "cachedDraft::Close", trace.WithAttributes()) @@ -36,6 +36,7 @@ func (cd *cachedDraft) Close(ctx context.Context, version string) (repository.Pa if err != nil { return nil, err } + if v != cd.cache.lastVersion { _, _, err = cd.cache.refreshAllCachedPackages(ctx) if err != nil { @@ -62,7 +63,7 @@ func (cd *cachedDraft) Close(ctx context.Context, version string) (repository.Pa return nil, err } - if closed, err := cd.PackageDraft.Close(ctx, nextVersion); err != nil { + if closed, err := cd.PackageRevisionDraft.Close(ctx, nextVersion); err != nil { return nil, err } else { return cd.cache.update(ctx, closed) diff --git a/pkg/cache/memory/repository.go b/pkg/cache/memory/repository.go index a7584a7c..d584a2d0 100644 --- a/pkg/cache/memory/repository.go +++ b/pkg/cache/memory/repository.go @@ -114,26 +114,24 @@ func (r *cachedRepository) getRefreshError() error { } func (r *cachedRepository) getPackageRevisions(ctx context.Context, filter repository.ListPackageRevisionFilter, forceRefresh bool) ([]repository.PackageRevision, error) { - r.mutex.Lock() - defer r.mutex.Unlock() _, packageRevisions, err := r.getCachedPackages(ctx, forceRefresh) if err != nil { return nil, err } - + r.mutex.Lock() + defer r.mutex.Unlock() return toPackageRevisionSlice(packageRevisions, filter), nil } func (r *cachedRepository) getPackages(ctx context.Context, filter repository.ListPackageFilter, forceRefresh bool) ([]repository.Package, error) { - r.mutex.Lock() - defer r.mutex.Unlock() packages, _, err := r.getCachedPackages(ctx, forceRefresh) if err != nil { return nil, err } - + r.mutex.Lock() + defer r.mutex.Unlock() return toPackageSlice(packages, filter), nil } @@ -141,6 +139,8 @@ func (r *cachedRepository) getPackages(ctx context.Context, filter repository.Li // mutex must be held. func (r *cachedRepository) getCachedPackages(ctx context.Context, forceRefresh bool) (map[repository.PackageKey]*cachedPackage, map[repository.PackageRevisionKey]*cachedPackageRevision, error) { // must hold mutex + + r.mutex.Lock() packages := r.cachedPackages packageRevisions := r.cachedPackageRevisions err := r.refreshRevisionsError @@ -157,6 +157,7 @@ func (r *cachedRepository) getCachedPackages(ctx context.Context, forceRefresh b } } } + r.mutex.Unlock() if packages == nil { packages, packageRevisions, err = r.refreshAllCachedPackages(ctx) @@ -165,19 +166,19 @@ func (r *cachedRepository) getCachedPackages(ctx context.Context, forceRefresh b return packages, packageRevisions, err } -func (r *cachedRepository) CreatePackageRevision(ctx context.Context, obj *v1alpha1.PackageRevision) (repository.PackageDraft, error) { +func (r *cachedRepository) CreatePackageRevision(ctx context.Context, obj *v1alpha1.PackageRevision) (repository.PackageRevisionDraft, error) { created, err := r.repo.CreatePackageRevision(ctx, obj) if err != nil { return nil, err } return &cachedDraft{ - PackageDraft: created, - cache: r, + PackageRevisionDraft: created, + cache: r, }, nil } -func (r *cachedRepository) UpdatePackageRevision(ctx context.Context, old repository.PackageRevision) (repository.PackageDraft, error) { +func (r *cachedRepository) UpdatePackageRevision(ctx context.Context, old repository.PackageRevision) (repository.PackageRevisionDraft, error) { // Unwrap unwrapped := old.(*cachedPackageRevision).PackageRevision created, err := r.repo.UpdatePackageRevision(ctx, unwrapped) @@ -186,14 +187,12 @@ func (r *cachedRepository) UpdatePackageRevision(ctx context.Context, old reposi } return &cachedDraft{ - PackageDraft: created, - cache: r, + PackageRevisionDraft: created, + cache: r, }, nil } func (r *cachedRepository) update(ctx context.Context, updated repository.PackageRevision) (*cachedPackageRevision, error) { - r.mutex.Lock() - defer r.mutex.Unlock() // TODO: Technically we only need this package, not all packages if _, _, err := r.getCachedPackages(ctx, false); err != nil { @@ -201,6 +200,8 @@ func (r *cachedRepository) update(ctx context.Context, updated repository.Packag // TODO: Invalidate all watches? We're dropping an add/update event return nil, err } + r.mutex.Lock() + defer r.mutex.Unlock() k := updated.Key() // previous := r.cachedPackageRevisions[k] @@ -236,7 +237,6 @@ func (r *cachedRepository) update(ctx context.Context, updated repository.Packag } func (r *cachedRepository) createMainPackageRevision(ctx context.Context, updatedMain repository.PackageRevision) error { - //Search and delete any old main pkgRev of an older workspace in the cache for pkgRevKey := range r.cachedPackageRevisions { if (pkgRevKey.Repository == updatedMain.Key().Repository) && (pkgRevKey.Package == updatedMain.Key().Package) && (pkgRevKey.Revision == updatedMain.Key().Revision) { @@ -403,6 +403,8 @@ func (r *cachedRepository) flush() { func (r *cachedRepository) refreshAllCachedPackages(ctx context.Context) (map[repository.PackageKey]*cachedPackage, map[repository.PackageRevisionKey]*cachedPackageRevision, error) { // TODO: Avoid simultaneous fetches? // TODO: Push-down partial refresh? + r.mutex.Lock() + defer r.mutex.Unlock() start := time.Now() defer func() { klog.Infof("repo %s: refresh finished in %f secs", r.id, time.Since(start).Seconds()) }() diff --git a/pkg/git/draft.go b/pkg/git/draft.go index 00ec1a8a..34048da0 100644 --- a/pkg/git/draft.go +++ b/pkg/git/draft.go @@ -25,7 +25,7 @@ import ( "go.opentelemetry.io/otel/trace" ) -type gitPackageDraft struct { +type gitPackageRevisionDraft struct { parent *gitRepository // repo is repo containing the package path string // the path to the package from the repo root revision string @@ -49,29 +49,29 @@ type gitPackageDraft struct { tree plumbing.Hash } -var _ repository.PackageDraft = &gitPackageDraft{} +var _ repository.PackageRevisionDraft = &gitPackageRevisionDraft{} -func (d *gitPackageDraft) UpdateResources(ctx context.Context, new *v1alpha1.PackageRevisionResources, change *v1alpha1.Task) error { +func (d *gitPackageRevisionDraft) UpdateResources(ctx context.Context, new *v1alpha1.PackageRevisionResources, change *v1alpha1.Task) error { ctx, span := tracer.Start(ctx, "gitPackageDraft::UpdateResources", trace.WithAttributes()) defer span.End() return d.parent.UpdateDraftResources(ctx, d, new, change) } -func (d *gitPackageDraft) UpdateLifecycle(ctx context.Context, new v1alpha1.PackageRevisionLifecycle) error { +func (d *gitPackageRevisionDraft) UpdateLifecycle(ctx context.Context, new v1alpha1.PackageRevisionLifecycle) error { d.lifecycle = new return nil } // Finish round of updates. -func (d *gitPackageDraft) Close(ctx context.Context, version string) (repository.PackageRevision, error) { +func (d *gitPackageRevisionDraft) Close(ctx context.Context, version string) (repository.PackageRevision, error) { ctx, span := tracer.Start(ctx, "gitPackageDraft::Close", trace.WithAttributes()) defer span.End() return d.parent.CloseDraft(ctx, version, d) } -func (d *gitPackageDraft) GetName() string { +func (d *gitPackageRevisionDraft) GetName() string { packageDirectory := d.parent.directory packageName := strings.TrimPrefix(d.path, packageDirectory+"/") return packageName diff --git a/pkg/git/git.go b/pkg/git/git.go index 33b6b6a6..7a6e84ab 100644 --- a/pkg/git/git.go +++ b/pkg/git/git.go @@ -350,7 +350,7 @@ func (r *gitRepository) listPackageRevisions(ctx context.Context, filter reposit return result, nil } -func (r *gitRepository) CreatePackageRevision(ctx context.Context, obj *v1alpha1.PackageRevision) (repository.PackageDraft, error) { +func (r *gitRepository) CreatePackageRevision(ctx context.Context, obj *v1alpha1.PackageRevision) (repository.PackageRevisionDraft, error) { ctx, span := tracer.Start(ctx, "gitRepository::CreatePackageRevision", trace.WithAttributes()) defer span.End() r.mutex.Lock() @@ -378,7 +378,7 @@ func (r *gitRepository) CreatePackageRevision(ctx context.Context, obj *v1alpha1 // TODO: This should also create a new 'Package' resource if one does not already exist - return &gitPackageDraft{ + return &gitPackageRevisionDraft{ parent: r, path: packagePath, workspaceName: obj.Spec.WorkspaceName, @@ -391,7 +391,7 @@ func (r *gitRepository) CreatePackageRevision(ctx context.Context, obj *v1alpha1 }, nil } -func (r *gitRepository) UpdatePackageRevision(ctx context.Context, old repository.PackageRevision) (repository.PackageDraft, error) { +func (r *gitRepository) UpdatePackageRevision(ctx context.Context, old repository.PackageRevision) (repository.PackageRevisionDraft, error) { ctx, span := tracer.Start(ctx, "gitRepository::UpdatePackageRevision", trace.WithAttributes()) defer span.End() r.mutex.Lock() @@ -424,7 +424,7 @@ func (r *gitRepository) UpdatePackageRevision(ctx context.Context, old repositor // sure we don't end up requesting the same lock twice. lifecycle := r.getLifecycle(ctx, oldGitPackage) - return &gitPackageDraft{ + return &gitPackageRevisionDraft{ parent: r, path: oldGitPackage.path, revision: oldGitPackage.revision, @@ -1427,7 +1427,7 @@ func (r *gitRepository) UpdateLifecycle(ctx context.Context, pkgRev *gitPackageR return nil } -func (r *gitRepository) UpdateDraftResources(ctx context.Context, draft *gitPackageDraft, new *v1alpha1.PackageRevisionResources, change *v1alpha1.Task) error { +func (r *gitRepository) UpdateDraftResources(ctx context.Context, draft *gitPackageRevisionDraft, new *v1alpha1.PackageRevisionResources, change *v1alpha1.Task) error { ctx, span := tracer.Start(ctx, "gitPackageDraft::UpdateResources", trace.WithAttributes()) defer span.End() r.mutex.Lock() @@ -1480,7 +1480,7 @@ func (r *gitRepository) UpdateDraftResources(ctx context.Context, draft *gitPack return nil } -func (r *gitRepository) CloseDraft(ctx context.Context, version string, d *gitPackageDraft) (*gitPackageRevision, error) { +func (r *gitRepository) CloseDraft(ctx context.Context, version string, d *gitPackageRevisionDraft) (*gitPackageRevision, error) { r.mutex.Lock() defer r.mutex.Unlock() @@ -1601,7 +1601,7 @@ func (r *gitRepository) doGitWithAuth(ctx context.Context, op func(transport.Aut return nil } -func (r *gitRepository) commitPackageToMain(ctx context.Context, d *gitPackageDraft) (commitHash, newPackageTreeHash plumbing.Hash, base *plumbing.Reference, err error) { +func (r *gitRepository) commitPackageToMain(ctx context.Context, d *gitPackageRevisionDraft) (commitHash, newPackageTreeHash plumbing.Hash, base *plumbing.Reference, err error) { branch := r.branch localRef := branch.RefInLocal() diff --git a/pkg/oci/mutate.go b/pkg/oci/mutate.go index adbf9719..54ab526d 100644 --- a/pkg/oci/mutate.go +++ b/pkg/oci/mutate.go @@ -41,7 +41,7 @@ import ( "k8s.io/klog/v2" ) -func (r *ociRepository) CreatePackageRevision(ctx context.Context, obj *v1alpha1.PackageRevision) (repository.PackageDraft, error) { +func (r *ociRepository) CreatePackageRevision(ctx context.Context, obj *v1alpha1.PackageRevision) (repository.PackageRevisionDraft, error) { base := empty.Image packageName := obj.Spec.PackageName @@ -65,7 +65,7 @@ func (r *ociRepository) CreatePackageRevision(ctx context.Context, obj *v1alpha1 }, nil } -func (r *ociRepository) UpdatePackageRevision(ctx context.Context, old repository.PackageRevision) (repository.PackageDraft, error) { +func (r *ociRepository) UpdatePackageRevision(ctx context.Context, old repository.PackageRevision) (repository.PackageRevisionDraft, error) { oldPackage := old.(*ociPackageRevision) packageName := oldPackage.packageName workspace := oldPackage.workspaceName @@ -118,7 +118,7 @@ type ociPackageDraft struct { lifecycle v1alpha1.PackageRevisionLifecycle // New value of the package revision lifecycle } -var _ repository.PackageDraft = (*ociPackageDraft)(nil) +var _ repository.PackageRevisionDraft = (*ociPackageDraft)(nil) func (p *ociPackageDraft) UpdateResources(ctx context.Context, new *v1alpha1.PackageRevisionResources, task *v1alpha1.Task) error { _, span := tracer.Start(ctx, "ociPackageDraft::UpdateResources", trace.WithAttributes()) diff --git a/pkg/repository/fake/repository.go b/pkg/repository/fake/repository.go index 9fd6c0c8..689bba28 100644 --- a/pkg/repository/fake/repository.go +++ b/pkg/repository/fake/repository.go @@ -57,7 +57,7 @@ func (r *Repository) ListPackageRevisions(_ context.Context, filter repository.L return revs, nil } -func (r *Repository) CreatePackageRevision(_ context.Context, pr *v1alpha1.PackageRevision) (repository.PackageDraft, error) { +func (r *Repository) CreatePackageRevision(_ context.Context, pr *v1alpha1.PackageRevision) (repository.PackageRevisionDraft, error) { return nil, nil } @@ -65,7 +65,7 @@ func (r *Repository) DeletePackageRevision(context.Context, repository.PackageRe return nil } -func (r *Repository) UpdatePackageRevision(context.Context, repository.PackageRevision) (repository.PackageDraft, error) { +func (r *Repository) UpdatePackageRevision(context.Context, repository.PackageRevision) (repository.PackageRevisionDraft, error) { return nil, nil } diff --git a/pkg/repository/repository.go b/pkg/repository/repository.go index 1aa2fa3f..d73e90d7 100644 --- a/pkg/repository/repository.go +++ b/pkg/repository/repository.go @@ -95,9 +95,14 @@ type PackageRevision interface { // ResourceVersion returns the Kube resource version of the package ResourceVersion() string + // Create the main package revision + // TODO: This is a git thing and probably shouldn't be on the generic PackageRevision interface ToMainPackageRevision() PackageRevision + // Get the Kubernetes metadata for the package revision GetMeta() meta.PackageRevisionMeta + + // Set the Kubernetes metadata for the package revision SetMeta(meta.PackageRevisionMeta) } @@ -118,7 +123,7 @@ type Package interface { GetLatestRevision() string } -type PackageDraft interface { +type PackageRevisionDraft interface { UpdateResources(ctx context.Context, new *v1alpha1.PackageRevisionResources, task *v1alpha1.Task) error // Updates desired lifecycle of the package. The lifecycle is applied on Close. UpdateLifecycle(ctx context.Context, new v1alpha1.PackageRevisionLifecycle) error @@ -196,13 +201,13 @@ type Repository interface { ListPackageRevisions(ctx context.Context, filter ListPackageRevisionFilter) ([]PackageRevision, error) // CreatePackageRevision creates a new package revision - CreatePackageRevision(ctx context.Context, obj *v1alpha1.PackageRevision) (PackageDraft, error) + CreatePackageRevision(ctx context.Context, obj *v1alpha1.PackageRevision) (PackageRevisionDraft, error) // DeletePackageRevision deletes a package revision DeletePackageRevision(ctx context.Context, old PackageRevision) error // UpdatePackageRevision updates a package - UpdatePackageRevision(ctx context.Context, old PackageRevision) (PackageDraft, error) + UpdatePackageRevision(ctx context.Context, old PackageRevision) (PackageRevisionDraft, error) // ListPackages lists all packages in the repository ListPackages(ctx context.Context, filter ListPackageFilter) ([]Package, error) diff --git a/pkg/task/generictaskhandler.go b/pkg/task/generictaskhandler.go index 1d863d5b..27b32b31 100644 --- a/pkg/task/generictaskhandler.go +++ b/pkg/task/generictaskhandler.go @@ -69,7 +69,7 @@ func (th *genericTaskHandler) SetReferenceResolver(referenceResolver repository. th.referenceResolver = referenceResolver } -func (th *genericTaskHandler) ApplyTasks(ctx context.Context, draft repository.PackageDraft, repositoryObj *configapi.Repository, obj *api.PackageRevision, packageConfig *builtins.PackageConfig) error { +func (th *genericTaskHandler) ApplyTasks(ctx context.Context, draft repository.PackageRevisionDraft, repositoryObj *configapi.Repository, obj *api.PackageRevision, packageConfig *builtins.PackageConfig) error { var mutations []mutation // Unless first task is Init or Clone, insert Init to create an empty package. @@ -106,7 +106,7 @@ func (th *genericTaskHandler) ApplyTasks(ctx context.Context, draft repository.P return nil } -func (th *genericTaskHandler) DoPRMutations(ctx context.Context, namespace string, repoPR repository.PackageRevision, oldObj *api.PackageRevision, newObj *api.PackageRevision, draft repository.PackageDraft) error { +func (th *genericTaskHandler) DoPRMutations(ctx context.Context, namespace string, repoPR repository.PackageRevision, oldObj *api.PackageRevision, newObj *api.PackageRevision, draft repository.PackageRevisionDraft) error { ctx, span := tracer.Start(ctx, "genericTaskHandler::DoPRMutations", trace.WithAttributes()) defer span.End() @@ -198,7 +198,7 @@ func taskTypeOneOf(taskType api.TaskType, oneOf ...api.TaskType) bool { return false } -func (th *genericTaskHandler) DoPRResourceMutations(ctx context.Context, pr2Update repository.PackageRevision, draft repository.PackageDraft, oldRes, newRes *api.PackageRevisionResources) (*api.RenderStatus, error) { +func (th *genericTaskHandler) DoPRResourceMutations(ctx context.Context, pr2Update repository.PackageRevision, draft repository.PackageRevisionDraft, oldRes, newRes *api.PackageRevisionResources) (*api.RenderStatus, error) { ctx, span := tracer.Start(ctx, "genericTaskHandler::DoPRResourceMutations", trace.WithAttributes()) defer span.End() @@ -443,7 +443,7 @@ func isRenderMutation(m mutation) bool { } // applyResourceMutations mutates the resources and returns the most recent renderResult. -func applyResourceMutations(ctx context.Context, draft repository.PackageDraft, baseResources repository.PackageResources, mutations []mutation) (applied repository.PackageResources, renderStatus *api.RenderStatus, err error) { +func applyResourceMutations(ctx context.Context, draft repository.PackageRevisionDraft, baseResources repository.PackageResources, mutations []mutation) (applied repository.PackageResources, renderStatus *api.RenderStatus, err error) { var lastApplied mutation for _, m := range mutations { updatedResources, taskResult, err := m.apply(ctx, baseResources) diff --git a/pkg/task/taskhandler.go b/pkg/task/taskhandler.go index e30f3336..7eda25f1 100644 --- a/pkg/task/taskhandler.go +++ b/pkg/task/taskhandler.go @@ -37,9 +37,9 @@ type TaskHandler interface { SetCredentialResolver(repository.CredentialResolver) SetReferenceResolver(repository.ReferenceResolver) - ApplyTasks(ctx context.Context, draft repository.PackageDraft, repositoryObj *configapi.Repository, obj *api.PackageRevision, packageConfig *builtins.PackageConfig) error - DoPRMutations(ctx context.Context, namespace string, repoPR repository.PackageRevision, oldObj *api.PackageRevision, newObj *api.PackageRevision, draft repository.PackageDraft) error - DoPRResourceMutations(ctx context.Context, pr2Update repository.PackageRevision, draft repository.PackageDraft, oldRes, newRes *api.PackageRevisionResources) (*api.RenderStatus, error) + ApplyTasks(ctx context.Context, draft repository.PackageRevisionDraft, repositoryObj *configapi.Repository, obj *api.PackageRevision, packageConfig *builtins.PackageConfig) error + DoPRMutations(ctx context.Context, namespace string, repoPR repository.PackageRevision, oldObj *api.PackageRevision, newObj *api.PackageRevision, draft repository.PackageRevisionDraft) error + DoPRResourceMutations(ctx context.Context, pr2Update repository.PackageRevision, draft repository.PackageRevisionDraft, oldRes, newRes *api.PackageRevisionResources) (*api.RenderStatus, error) } type mutation interface { diff --git a/scripts/run-load-test.sh b/scripts/run-load-test.sh new file mode 100755 index 00000000..2cd8758c --- /dev/null +++ b/scripts/run-load-test.sh @@ -0,0 +1,399 @@ +#! /usr/bin/env bash + +script_name=$(basename "$0") + +git_repo_server="" +git_repo_count=0 +package_count=0 +package_revision_count=0 +result_file=load_test_results.txt +repo_result_file=load_test_repo_results.csv +log_file=load_test.log +dirty_mode=false + +usage() +{ + echo "" + echo "$script_name - runs a load test on porch" + echo "" + echo " usage: $script_name [-options]" + echo "" + echo " options" + echo " -h - this help message" + echo " -s hostname - the host name of the git server for porch git repos" + echo " -r repo-count - the number of repos to create during the test, a positive integer" + echo " -p package-count - the number of packages to create in each repo during the test, a positive integer" + echo " -e package-revision-count - the number of packagerevisions to create on each package during the test, a positive integer" + echo " -f result-file - the file where the raw results will be stored, defaults to $result_file" + echo " -o repo-result-file - the file where the results by reop will be stored, defaults to $repo_result_file" + echo " -l log-file - the file where the test log will be stored, defaults to $log_file" + echo " -y - dirty mode, do not clean up after tests" + echo "" + exit 255; +} + +while getopts "hs:r:p:e:f:o:l:y" opt +do + case $opt in + h) + usage + ;; + s) + git_repo_server=$OPTARG + ;; + r) + git_repo_count=$OPTARG + ;; + p) + package_count=$OPTARG + ;; + e) + package_revision_count=$OPTARG + ;; + f) + result_file=$OPTARG + ;; + o) + repo_result_file=$OPTARG + ;; + l) + log_file=$OPTARG + ;; + y) + dirty_mode=true + ;; + \?) + usage + ;; + esac +done + +if [[ -z "$git_repo_server" ]] +then + echo "git server for porch git repos not specified with the -s flag" + exit 1 +fi + +if [[ "$git_repo_count" -lt 1 ]] +then + echo "git repo count must be specified as a positive integer on the -r flag" + exit 1 +fi + +if [[ "$package_count" -lt 1 ]] +then + echo "package count must be specified as a positive integer on the -p flag" + exit 1 +fi + +if [[ "$package_revision_count" -lt 1 ]] +then + echo "pacakge revision count must be specified as a positive integer on the -e flag" + exit 1 +fi + +if [ -z "$result_file" ] +then + echo "result file not specified on -f flag" + exit 1 +fi + +if [ -z "$repo_result_file" ] +then + echo "repo result file not specified on -o flag" + exit 1 +fi + +if [ -z "$log_file" ] +then + echo "log file not specified on -l flag" + exit 1 +fi + +echo "running load test towards git server http://nephio:secret@$git_repo_server:3000/nephio/" +echo " $git_repo_count repos will be created" +echo " $package_count packages in each repo" +echo " $package_revision_count pacakge revisions in each package" +echo " results will be stored in \"$result_file\"" +echo " repo results will be stored in \"$repo_result_file\"" +echo " the log will be stored in \"$log_file\"" + +update_package_resources() { + cat << EOF > "$1/Kptfile" +apiVersion: kpt.dev/v1 +kind: Kptfile + +metadata: + name: "$1" + annotations: + config.kubernetes.io/local-config: "true" + +info: + description: network function "$1" blueprint + +pipeline: + mutators: + - image: gcr.io/kpt-fn/apply-replacements:v0.1.1 + configPath: apply-replacements-annotation1.yaml + - image: gcr.io/kpt-fn/apply-replacements:v0.1.1 + configPath: apply-replacements-annotation2.yaml +EOF + + cat << EOF > "$1/deployment.yaml" +apiVersion: apps/v1 +kind: Deployment +metadata: + name: "$1" + annotations: + annotation1: no-value-1 + annotation2: no-value-2 +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: "$1" + template: + metadata: + labels: + app.kubernetes.io/name: "$1" + spec: + containers: + - name: nginx + image: nginx:latest +EOF + + cat << EOF > "$1/cm_deployment.yaml" +apiVersion: v1 +kind: ConfigMap +metadata: + name: cm-deployment + annotations: + config.kubernetes.io/local-config: "true" +data: + annotation1: local-annotation-1 + annotation2: local-annotation-2 +EOF + + cat << EOF > "$1/apply-replacements-annotation1.yaml" +apiVersion: fn.kpt.dev/v1alpha1 +kind: ApplyReplacements +metadata: + name: replace-annotation1 + annotations: + config.kubernetes.io/local-config: "true" +replacements: +- source: + kind: ConfigMap + name: cm-deployment + fieldPath: data.annotation1 + targets: + - select: + kind: Deployment + fieldPaths: + - metadata.annotations.annotation1 +EOF + + cat << EOF > "$1/apply-replacements-annotation2.yaml" +apiVersion: fn.kpt.dev/v1alpha1 +kind: ApplyReplacements +metadata: + name: replace-annotation1 + annotations: + config.kubernetes.io/local-config: "true" +replacements: +- source: + kind: ConfigMap + name: cm-deployment + fieldPath: data.annotation2 + targets: + - select: + kind: Deployment + fieldPaths: + - metadata.annotations.annotation2 +EOF +} + +create_package_revision() { + TMP_DIR=$(mktemp -d) + pushd "$TMP_DIR" || return + + porchctl -n porch-scale rpkg pull "$1" "$1" + update_package_resources "$1" + porchctl -n porch-scale rpkg push "$1" "$1" + porchctl -n porch-scale rpkg propose "$1" + porchctl -n porch-scale rpkg approve "$1" + + popd || return + + if ! $dirty_mode + then + rm -fr "$TMP_DIR" + fi +} + +create_package () { + start_prv1=$EPOCHREALTIME + pkg_v1=$(porchctl -n porch-scale rpkg init "network-function-$2" --repository="$1" --workspace=v1 | cut -f1 -d' ' ) + echo "$1:$2:1 $pkg_v1 initialized" >> "$result_file" + + create_package_revision "$pkg_v1" + echo "$1:$2:1 $pkg_v1 approved, took $(echo $EPOCHREALTIME-$start_prv1 | bc -l) seconds" >> "$result_file" + + for k in $(seq 2 "$package_revision_count") + do + start_prvx=$EPOCHREALTIME + + pkg_vx=$(porchctl rpkg copy -n porch-scale "$pkg_v1" "--workspace=v$k" | cut -f1 -d' ' ) + echo "$1:$2:$k $pkg_vx copied" >> "$result_file" + create_package_revision "$pkg_vx" + echo "$1:$2:$k $pkg_vx approved, took $(echo $EPOCHREALTIME-$start_prvx | bc -l) seconds" >> "$result_file" + done +} + +create_repo () { + git_repo_name="porch-scale-test-$1" + + echo "creating repo $git_repo_name . . ." + { + curl -k -H "content-type: application/json" "http://nephio:secret@$git_repo_server:3000/api/v1/user/repos" --data '{"name":"'"$git_repo_name"'"}' >> "$log_file" 2>&1 + + TMP_DIR=$(mktemp -d) + pushd "$TMP_DIR" || return + git clone "http://nephio:secret@$git_repo_server:3000/nephio/$git_repo_name.git" + + pushd "$git_repo_name" || return + git switch -c main + touch README.md + git add README.md + git config user.name nephio + git commit -m "first commit" + git push -u origin main + popd || return + + popd || return + + if ! $dirty_mode + then + rm -fr "$TMP_DIR" + fi + } >> "$log_file" 2>&1 + + kubectl apply -f - <> "$log_file" 2>&1 +apiVersion: config.porch.kpt.dev/v1alpha1 +kind: Repository + +metadata: + name: "$git_repo_name" + namespace: porch-scale + +spec: + description: "$git_repo_name" + content: Package + deployment: false + type: git + git: + repo: "http://$git_repo_server:3000/nephio/$git_repo_name.git" + directory: / + branch: main + createBranch: true + secretRef: + name: gitea +EOF + + echo "created repo $git_repo_name" + + for j in $(seq 1 "$package_count") + do + create_package "$git_repo_name" "$j" >> "$log_file" 2>&1 + done +} + +create_namespace_secret() { + kubectl apply -f - <> "$log_file" 2>&1 +apiVersion: v1 +kind: Namespace +metadata: + name: porch-scale + +--- +apiVersion: v1 +kind: Secret +metadata: + name: gitea + namespace: porch-scale +type: kubernetes.io/basic-auth +data: + username: bmVwaGlv + password: c2VjcmV0 +EOF +} + +delete_package_revisions () { + for pkg in $(porchctl rpkg get -n porch-scale | grep -v 'WORKSPACENAME' | cut -f1 -d' ') + do + start_prvd=$EPOCHREALTIME + porchctl -n porch-scale rpkg propose-delete "$pkg" >> "$log_file" 2>&1 + porchctl -n porch-scale rpkg delete "$pkg" >> "$log_file" 2>&1 + echo "$pkg deleted, took $(echo $EPOCHREALTIME-$start_prvd | bc -l) seconds" + done +} + +delete_repo () { + git_repo_name="porch-scale-test-$1" + + echo "deleting repo $git_repo_name . . ." + curl -k -H "content-type: application/json" --request DELETE "http://nephio:secret@$git_repo_server:3000/api/v1/repos/nephio/$git_repo_name" >> "$log_file" 2>&1 + kubectl delete -n porch-scale repositories.config.porch.kpt.dev "$git_repo_name" >> "$log_file" 2>&1 + echo "deleted repo $git_repo_name" +} + +split_repo_results() { + TMP_DIR=$(mktemp -d) + CURRENT_DIR=$(pwd) + + grep "approved, took" "$result_file" | sed -e 's/\(:[0-9]* \).*, took /\1/' -e 's/ seconds$//' -e 's/ /,/' > "$TMP_DIR/approved.csv" + grep "deleted, took" "$result_file" | sed -e 's/deleted, took //' -e 's/ seconds$//' -e 's/ /,/' > "$TMP_DIR/deleted.csv" + + cd "$TMP_DIR" || exit + + for i in $(seq 1 "$git_repo_count") + do + repo_suffix=$(printf "%0${#git_repo_count}d" "$i") + echo "REPO-$repo_suffix-TEST,REPO-$repo_suffix-TIME" > "repo_$repo_suffix.csv" + grep "^porch-scale-test-$i\:" approved.csv | sed "s/^porch-scale-test-$i://" >> "repo_$repo_suffix.csv" + grep "^porch-scale-test-$i-" deleted.csv | sed "s/^porch-scale-test-$i-/del-/" >> "repo_$repo_suffix.csv" + done + + paste -d',' ./repo_*.csv + + cd "$CURRENT_DIR" || exit + if ! $dirty_mode + then + rm -fr "$TMP_DIR" + fi +} + +rm -fr "$result_file" "$repo_result_file" "$log_file" + +create_namespace_secret + +for i in $(seq 1 "$git_repo_count") +do + create_repo "$i" >> "$result_file" +done + +if ! $dirty_mode +then + delete_package_revisions >> "$result_file" + + for i in $(seq 1 "$git_repo_count") + do + delete_repo "$i" >> "$result_file" + done + + kubectl delete ns porch-scale +fi + +split_repo_results > "$repo_result_file" + +echo "load test towards git server http://nephio:secret@$git_repo_server:3000/nephio/ completed"