Skip to content

Commit

Permalink
fix(deploy): ensure werf commands run consistently with service values
Browse files Browse the repository at this point in the history
Signed-off-by: Aleksei Igrychev <aleksei.igrychev@palark.com>
  • Loading branch information
alexey-igrychev committed Oct 29, 2024
1 parent 7a4a74b commit f2ba5fa
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 43 deletions.
130 changes: 93 additions & 37 deletions cmd/werf/helm/get_autogenerated_values.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package helm
import (
"context"
"fmt"
"path/filepath"

"github.com/spf13/cobra"

Expand All @@ -13,6 +14,7 @@ import (
"github.com/werf/werf/v2/pkg/config"
"github.com/werf/werf/v2/pkg/config/deploy_params"
"github.com/werf/werf/v2/pkg/deploy/helm/chart_extender/helpers"
"github.com/werf/werf/v2/pkg/docker"
"github.com/werf/werf/v2/pkg/git_repo"
"github.com/werf/werf/v2/pkg/git_repo/gitdata"
"github.com/werf/werf/v2/pkg/image"
Expand Down Expand Up @@ -44,12 +46,18 @@ func NewGetAutogeneratedValuesCmd(ctx context.Context) *cobra.Command {
ctx := cmd.Context()

global_warnings.SuppressGlobalWarnings = true
if *commonCmdData.LogDebug {
global_warnings.SuppressGlobalWarnings = false
}
defer global_warnings.PrintGlobalWarnings(ctx)

if err := common.ProcessLogOptions(&commonCmdData); err != nil {
common.PrintHelp(cmd)
return err
}

common.LogVersion()

return runGetServiceValues(ctx, args)
},
})
Expand All @@ -69,38 +77,48 @@ func NewGetAutogeneratedValuesCmd(ctx context.Context) *cobra.Command {
common.SetupHomeDir(&commonCmdData, cmd, common.SetupHomeDirOptions{})
common.SetupSSHKey(&commonCmdData, cmd)

common.SetupIntrospectAfterError(&commonCmdData, cmd)
common.SetupIntrospectBeforeError(&commonCmdData, cmd)
common.SetupIntrospectStage(&commonCmdData, cmd)

common.SetupSecondaryStagesStorageOptions(&commonCmdData, cmd)
common.SetupCacheStagesStorageOptions(&commonCmdData, cmd)
common.SetupRepoOptions(&commonCmdData, cmd, common.RepoDataOptions{})
common.SetupRepoOptions(&commonCmdData, cmd, common.RepoDataOptions{OptionalRepo: true})
common.SetupFinalRepo(&commonCmdData, cmd)
common.SetupStubTags(&commonCmdData, cmd)

common.SetupSynchronization(&commonCmdData, cmd)
common.SetupKubeConfig(&commonCmdData, cmd)
common.SetupKubeConfigBase64(&commonCmdData, cmd)
common.SetupKubeContext(&commonCmdData, cmd)

common.SetupUseCustomTag(&commonCmdData, cmd)
common.SetupVirtualMerge(&commonCmdData, cmd)

common.SetupNamespace(&commonCmdData, cmd, true)

common.SetupDockerConfig(&commonCmdData, cmd, "Command needs granted permissions to read and pull images from the specified repo")
common.SetupDockerConfig(&commonCmdData, cmd, "Command needs granted permissions to read, pull and push images into the specified repo and to pull base images")
common.SetupInsecureRegistry(&commonCmdData, cmd)
common.SetupSkipTlsVerifyRegistry(&commonCmdData, cmd)
common.SetupContainerRegistryMirror(&commonCmdData, cmd)

common.SetupStubTags(&commonCmdData, cmd)
common.SetupLogOptionsDefaultQuiet(&commonCmdData, cmd)
common.SetupLogProjectDir(&commonCmdData, cmd)

common.SetupLogOptions(&commonCmdData, cmd)
common.SetupNamespace(&commonCmdData, cmd, true)

common.SetupSetDockerConfigJsonValue(&commonCmdData, cmd)

common.SetupSaveBuildReport(&commonCmdData, cmd)
common.SetupBuildReportPath(&commonCmdData, cmd)

common.SetupUseCustomTag(&commonCmdData, cmd)
common.SetupVirtualMerge(&commonCmdData, cmd)

common.SetupParallelOptions(&commonCmdData, cmd, common.DefaultBuildParallelTasksLimit)

common.SetupRequireBuiltImages(&commonCmdData, cmd)
commonCmdData.SetupPlatform(cmd)

return cmd
}

func runGetServiceValues(ctx context.Context, imageNameListFromArgs []string) error {
logboek.SetAcceptedLevel(level.Error)

if err := werf.Init(*commonCmdData.TmpDir, *commonCmdData.HomeDir); err != nil {
return fmt.Errorf("initialization error: %w", err)
}
Expand Down Expand Up @@ -133,7 +151,7 @@ func runGetServiceValues(ctx context.Context, imageNameListFromArgs []string) er
return err
}

if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogVerbose || *commonCmdData.LogDebug}); err != nil {
if err := true_git.Init(ctx, true_git.Options{LiveGitOutput: *commonCmdData.LogDebug}); err != nil {
return err
}

Expand All @@ -147,7 +165,7 @@ func runGetServiceValues(ctx context.Context, imageNameListFromArgs []string) er
defer func() {
err := ssh_agent.Terminate()
if err != nil {
logboek.Error().LogF("WARNING: ssh agent termination failed: %s\n", err)
logboek.Warn().LogF("WARNING: ssh agent termination failed: %s\n", err)
}
}()

Expand All @@ -156,7 +174,9 @@ func runGetServiceValues(ctx context.Context, imageNameListFromArgs []string) er
return err
}

_, werfConfig, err := common.GetRequiredWerfConfig(ctx, &commonCmdData, giterminismManager, common.GetWerfConfigOptions(&commonCmdData, false))
common.ProcessLogProjectDir(&commonCmdData, giterminismManager.ProjectDir())

_, werfConfig, err := common.GetRequiredWerfConfig(ctx, &commonCmdData, giterminismManager, common.GetWerfConfigOptions(&commonCmdData, true))
if err != nil {
return fmt.Errorf("unable to load werf config: %w", err)
}
Expand All @@ -167,13 +187,20 @@ func runGetServiceValues(ctx context.Context, imageNameListFromArgs []string) er
}

projectName := werfConfig.Meta.Project
environment := *commonCmdData.Environment

namespace, err := deploy_params.GetKubernetesNamespace(*commonCmdData.Namespace, environment, werfConfig)
projectTmpDir, err := tmp_manager.CreateProjectDir(ctx)
if err != nil {
return fmt.Errorf("getting project tmp dir failed: %w", err)
}
defer tmp_manager.ReleaseProjectDir(projectTmpDir)

buildOptions, err := common.GetBuildOptions(ctx, &commonCmdData, werfConfig, imagesToProcess)
if err != nil {
return err
}

logboek.LogOptionalLn()

var imagesInfoGetters []*image.InfoGetter
var imagesRepository string
var isStub bool
Expand All @@ -191,11 +218,9 @@ func runGetServiceValues(ctx context.Context, imageNameListFromArgs []string) er
isStub = true
stubImageNameList = append(stubImageNameList, imagesToProcess.FinalImageNameList...)
default:
projectTmpDir, err := tmp_manager.CreateProjectDir(ctx)
if err != nil {
return fmt.Errorf("getting project tmp dir failed: %w", err)
if err := common.DockerRegistryInit(ctx, &commonCmdData, registryMirrors); err != nil {
return err
}
defer tmp_manager.ReleaseProjectDir(projectTmpDir)

stagesStorage, err := common.GetStagesStorage(ctx, containerBackend, &commonCmdData)
if err != nil {
Expand All @@ -205,6 +230,10 @@ func runGetServiceValues(ctx context.Context, imageNameListFromArgs []string) er
if err != nil {
return err
}
common.SetupOndemandKubeInitializer(*commonCmdData.KubeContext, *commonCmdData.KubeConfig, *commonCmdData.KubeConfigBase64, *commonCmdData.KubeConfigPathMergeList)
if err := common.GetOndemandKubeInitializer().Init(ctx); err != nil {
return err
}
synchronization, err := common.GetSynchronization(ctx, &commonCmdData, projectName, stagesStorage)
if err != nil {
return err
Expand All @@ -228,25 +257,38 @@ func runGetServiceValues(ctx context.Context, imageNameListFromArgs []string) er

storageManager := manager.NewStorageManager(projectName, stagesStorage, finalStagesStorage, secondaryStagesStorageList, cacheStagesStorageList, storageLockManager)

conveyorOptions, err := common.GetConveyorOptions(ctx, &commonCmdData, imagesToProcess)
imagesRepository = storageManager.GetServiceValuesRepo()

conveyorOptions, err := common.GetConveyorOptionsWithParallel(ctx, &commonCmdData, imagesToProcess, buildOptions)
if err != nil {
return err
}

// Override default behaviour:
// Print build logs on error by default.
// Always print logs if --log-verbose is specified (level.Info).
isVerbose := logboek.Context(ctx).IsAcceptedLevel(level.Default)
conveyorOptions.DeferBuildLog = !isVerbose

conveyorWithRetry := build.NewConveyorWithRetryWrapper(werfConfig, giterminismManager, giterminismManager.ProjectDir(), projectTmpDir, ssh_agent.SSHAuthSock, containerBackend, storageManager, storageLockManager, conveyorOptions)
defer conveyorWithRetry.Terminate()

if err := conveyorWithRetry.WithRetryBlock(ctx, func(c *build.Conveyor) error {
shouldBeBuiltOptions, err := common.GetShouldBeBuiltOptions(&commonCmdData, imagesToProcess)
if err != nil {
return err
if common.GetRequireBuiltImages(ctx, &commonCmdData) {
shouldBeBuiltOptions, err := common.GetShouldBeBuiltOptions(&commonCmdData, imagesToProcess)
if err != nil {
return err
}

if err := c.ShouldBeBuilt(ctx, shouldBeBuiltOptions); err != nil {
return err
}
} else {
if err := c.Build(ctx, buildOptions); err != nil {
return err
}
}

if err := c.ShouldBeBuilt(ctx, shouldBeBuiltOptions); err != nil {
return err
}

imagesRepository = storageManager.StagesStorage.String()
imagesInfoGetters, err = c.GetImageInfoGetters(image.InfoGetterOptions{CustomTagFunc: useCustomTagFunc})
if err != nil {
return err
Expand All @@ -256,8 +298,21 @@ func runGetServiceValues(ctx context.Context, imageNameListFromArgs []string) er
}); err != nil {
return err
}

logboek.LogOptionalLn()
}

releaseNamespace, err := deploy_params.GetKubernetesNamespace(
*commonCmdData.Namespace,
*commonCmdData.Environment,
werfConfig,
)
if err != nil {
return fmt.Errorf("get kubernetes namespace: %w", err)
}

registryCredentialsPath := docker.GetDockerConfigCredentialsFile(*commonCmdData.DockerConfig)

headHash, err := giterminismManager.LocalGitRepo().HeadCommitHash(ctx)
if err != nil {
return fmt.Errorf("getting HEAD commit hash failed: %w", err)
Expand All @@ -268,20 +323,21 @@ func runGetServiceValues(ctx context.Context, imageNameListFromArgs []string) er
return fmt.Errorf("getting HEAD commit time failed: %w", err)
}

serviceValues, err := helpers.GetServiceValues(ctx, projectName, imagesRepository, imagesInfoGetters, helpers.ServiceValuesOptions{
Namespace: namespace,
Env: environment,
vals, err := helpers.GetServiceValues(ctx, werfConfig.Meta.Project, imagesRepository, imagesInfoGetters, helpers.ServiceValuesOptions{
Namespace: releaseNamespace,
Env: *commonCmdData.Environment,
IsStub: isStub,
DisableEnvStub: true,
StubImageNameList: stubImageNameList,
CommitHash: headHash,
CommitDate: headTime,
StubImageNameList: stubImageNameList, SetDockerConfigJsonValue: *commonCmdData.SetDockerConfigJsonValue,
DockerConfigPath: filepath.Dir(registryCredentialsPath),
CommitHash: headHash,
CommitDate: headTime,
})
if err != nil {
return fmt.Errorf("error creating service values: %w", err)
return fmt.Errorf("get service values: %w", err)
}

fmt.Printf("%s", util.DumpYaml(serviceValues))
fmt.Printf("%s", util.DumpYaml(vals))

return nil
}
7 changes: 3 additions & 4 deletions cmd/werf/render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ func NewCmd(ctx context.Context) *cobra.Command {
common.SetupFinalRepo(&commonCmdData, cmd)
common.SetupStubTags(&commonCmdData, cmd)

common.SetupSynchronization(&commonCmdData, cmd)
common.SetupKubeConfig(&commonCmdData, cmd)
common.SetupKubeConfigBase64(&commonCmdData, cmd)
common.SetupKubeContext(&commonCmdData, cmd)
Expand All @@ -121,8 +122,6 @@ func NewCmd(ctx context.Context) *cobra.Command {
common.SetupLogOptionsDefaultQuiet(&commonCmdData, cmd)
common.SetupLogProjectDir(&commonCmdData, cmd)

common.SetupSynchronization(&commonCmdData, cmd)

common.SetupRelease(&commonCmdData, cmd, true)
common.SetupNamespace(&commonCmdData, cmd, true)
common.SetupAddAnnotations(&commonCmdData, cmd)
Expand Down Expand Up @@ -477,12 +476,12 @@ func runRender(ctx context.Context, imageNameListFromArgs []string) error {

headHash, err := giterminismManager.LocalGitRepo().HeadCommitHash(ctx)
if err != nil {
return fmt.Errorf("get HEAD commit hash: %w", err)
return fmt.Errorf("getting HEAD commit hash failed: %w", err)
}

headTime, err := giterminismManager.LocalGitRepo().HeadCommitTime(ctx)
if err != nil {
return fmt.Errorf("get HEAD commit time: %w", err)
return fmt.Errorf("getting HEAD commit time failed: %w", err)
}

if vals, err := helpers.GetServiceValues(ctx, werfConfig.Meta.Project, imagesRepository, imagesInfoGetters, helpers.ServiceValuesOptions{
Expand Down
46 changes: 44 additions & 2 deletions docs/_includes/reference/cli/werf_helm_get_autogenerated_values.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ werf helm get-autogenerated-values [IMAGE_NAME...] [options]
{{ header }} Options

```shell
--build-report-path=''
Change build report path and format (by default $WERF_BUILD_REPORT_PATH or
".werf-build-report.json" if not set). Extension must be either .json for JSON format
or .env for env-file format. If extension not specified, then .json is used
--cache-repo=[]
Specify one or multiple cache repos with images that will be used as a cache. Cache
will be populated when pushing newly built images into the primary repo and when
Expand Down Expand Up @@ -59,7 +63,8 @@ werf helm get-autogenerated-values [IMAGE_NAME...] [options]
--docker-config=''
Specify docker config directory path. Default $WERF_DOCKER_CONFIG or $DOCKER_CONFIG or
~/.docker (in the order of priority)
Command needs granted permissions to read and pull images from the specified repo
Command needs granted permissions to read, pull and push images into the specified repo
and to pull base images
--env=''
Use specified environment (default $WERF_ENV)
--final-repo=''
Expand Down Expand Up @@ -94,6 +99,27 @@ werf helm get-autogenerated-values [IMAGE_NAME...] [options]
Use specified dir to store werf cache files and dirs (default $WERF_HOME or ~/.werf)
--insecure-registry=false
Use plain HTTP requests when accessing a registry (default $WERF_INSECURE_REGISTRY)
--introspect-before-error=false
Introspect failed stage in the clean state, before running all assembly instructions of
the stage
--introspect-error=false
Introspect failed stage in the state, right after running failed assembly instruction
--introspect-stage=[]
Introspect a specific stage. The option can be used multiple times to introspect
several stages.

There are the following formats to use:
* specify IMAGE_NAME/STAGE_NAME to introspect stage STAGE_NAME of either image or
artifact IMAGE_NAME
* specify STAGE_NAME or */STAGE_NAME for the introspection of all existing stages with
name STAGE_NAME

IMAGE_NAME is the name of an image or artifact described in werf.yaml, the nameless
image specified with ~.
STAGE_NAME should be one of the following: from, beforeInstall,
dependenciesBeforeInstall, gitArchive, install, dependenciesAfterInstall, beforeSetup,
dependenciesBeforeSetup, setup, dependenciesAfterSetup, gitCache, gitLatestPatch,
dockerInstructions, dockerfile
--kube-config=''
Kubernetes config file path (default $WERF_KUBE_CONFIG, or $WERF_KUBECONFIG, or
$KUBECONFIG)
Expand All @@ -112,7 +138,9 @@ werf helm get-autogenerated-values [IMAGE_NAME...] [options]
--log-pretty=true
Enable emojis, auto line wrapping and log process border (default $WERF_LOG_PRETTY or
true).
--log-quiet=false
--log-project-dir=false
Print current project directory path (default $WERF_LOG_PROJECT_DIR)
--log-quiet=true
Disable explanatory output (default $WERF_LOG_QUIET).
--log-terminal-width=-1
Set log terminal width.
Expand All @@ -131,6 +159,11 @@ werf helm get-autogenerated-values [IMAGE_NAME...] [options]
--namespace=''
Use specified Kubernetes namespace (default [[ project ]]-[[ env ]] template or
deploy.namespace custom template from werf.yaml or $WERF_NAMESPACE)
-p, --parallel=true
Run in parallel (default $WERF_PARALLEL or true)
--parallel-tasks-limit=5
Parallel tasks limit, set -1 to remove the limitation (default
$WERF_PARALLEL_TASKS_LIMIT or 5)
--platform=[]
Enable platform emulation when building images with werf, format: OS/ARCH[/VARIANT]
($WERF_PLATFORM or $DOCKER_DEFAULT_PLATFORM by default)
Expand All @@ -156,11 +189,20 @@ werf helm get-autogenerated-values [IMAGE_NAME...] [options]
repo Harbor username (default $WERF_REPO_HARBOR_USERNAME)
--repo-quay-token=''
repo quay.io token (default $WERF_REPO_QUAY_TOKEN)
-Z, --require-built-images=false
Requires all used images to be previously built and exist in repo. Exits with error if
needed images are not cached and so require to run build instructions (default
$WERF_REQUIRE_BUILT_IMAGES)
--save-build-report=false
Save build report (by default $WERF_SAVE_BUILD_REPORT or false). Its path and format
configured with --build-report-path
--secondary-repo=[]
Specify one or multiple secondary read-only repos with images that will be used as a
cache.
Also, can be specified with $WERF_SECONDARY_REPO_* (e.g. $WERF_SECONDARY_REPO_1=...,
$WERF_SECONDARY_REPO_2=...)
--set-docker-config-json-value=false
Shortcut to set current docker config into the .Values.dockerconfigjson
--skip-tls-verify-registry=false
Skip TLS certificate validation when accessing a registry (default
$WERF_SKIP_TLS_VERIFY_REGISTRY)
Expand Down

0 comments on commit f2ba5fa

Please sign in to comment.