Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat(custom-tags): add %image_content_based_tag% shortcut
Signed-off-by: Alexey Igrychev <alexey.igrychev@flant.com>
  • Loading branch information
alexey-igrychev committed Apr 13, 2022
1 parent 15cd90d commit efd1072
Show file tree
Hide file tree
Showing 11 changed files with 70 additions and 54 deletions.
18 changes: 11 additions & 7 deletions cmd/werf/common/common.go
Expand Up @@ -426,18 +426,22 @@ Also, can be specified with $WERF_SECONDARY_REPO_* (e.g. $WERF_SECONDARY_REPO_1=

func SetupAddCustomTag(cmdData *CmdData, cmd *cobra.Command) {
cmdData.AddCustomTag = new([]string)
cmd.Flags().StringArrayVarP(cmdData.AddCustomTag, "add-custom-tag", "", []string{}, `Set tag aliases for the content-based tag of each image.
It is necessary to use the image name shortcut %image% or %image_slug% in the tag format if there is more than one image in the werf config.
Also, can be defined with $WERF_ADD_CUSTOM_TAG_* (e.g. $WERF_ADD_CUSTOM_TAG_1="%image%-tag1", $WERF_ADD_CUSTOM_TAG_2="%image%-tag2").
For cleaning custom tags and associated content-based tag are treated as one`)
cmd.Flags().StringArrayVarP(cmdData.AddCustomTag, "add-custom-tag", "", []string{}, `Set tag alias for the content-based tag.
The alias may contain the following shortcuts:
- %image%, %image_slug% or %image_safe_slug% to use the image name (necessary if there is more than one image in the werf config);
- %image_content_based_tag% to use a content-based tag.
For cleaning custom tags and associated content-based tag are treated as one.
Also can be defined with $WERF_ADD_CUSTOM_TAG_* (e.g. $WERF_ADD_CUSTOM_TAG_1="%image%-tag1", $WERF_ADD_CUSTOM_TAG_2="%image%-tag2")`)
}

func SetupUseCustomTag(cmdData *CmdData, cmd *cobra.Command) {
cmdData.UseCustomTag = new(string)
cmd.Flags().StringVarP(cmdData.UseCustomTag, "use-custom-tag", "", os.Getenv("WERF_USE_CUSTOM_TAG"), `Use a tag alias in helm templates instead of an image content-based tag (NOT RECOMMENDED).
It is necessary to use the image name shortcut %image% or %image_slug% in the tag format if there is more than one image in the werf config.
Also, can be defined with $WERF_USE_CUSTOM_TAG (e.g. $WERF_USE_CUSTOM_TAG="%image%-tag").
For cleaning custom tags and associated content-based tag are treated as one`)
The alias may contain the following shortcuts:
- %image%, %image_slug% or %image_safe_slug% to use the image name (necessary if there is more than one image in the werf config);
- %image_content_based_tag% to use a content-based tag.
For cleaning custom tags and associated content-based tag are treated as one.
Also, can be defined with $WERF_USE_CUSTOM_TAG (e.g. $WERF_USE_CUSTOM_TAG="%image%-tag")`)
}

func SetupCacheStagesStorageOptions(cmdData *CmdData, cmd *cobra.Command) {
Expand Down
20 changes: 11 additions & 9 deletions cmd/werf/common/conveyor_options.go
Expand Up @@ -78,7 +78,7 @@ func GetBuildOptions(commonCmdData *CmdData, giterminismManager giterminism_mana
return buildOptions, nil
}

func getCustomTagFuncList(commonCmdData *CmdData, giterminismManager giterminism_manager.Interface, werfConfig *config.WerfConfig) ([]func(string) string, error) {
func getCustomTagFuncList(commonCmdData *CmdData, giterminismManager giterminism_manager.Interface, werfConfig *config.WerfConfig) ([]build.CustomTagFunc, error) {
tagOptionValues := getCustomTagOptionValues(commonCmdData)
if len(tagOptionValues) == 0 {
return nil, nil
Expand All @@ -95,12 +95,13 @@ func getCustomTagFuncList(commonCmdData *CmdData, giterminismManager giterminism
templateName := "--add/use-custom-tag"
tmpl := template.New(templateName).Delims("%", "%")
tmpl = tmpl.Funcs(map[string]interface{}{
"image": func() string { return "%[1]s" },
"image_slug": func() string { return "%[2]s" },
"image_safe_slug": func() string { return "%[3]s" },
"image": func() string { return "%[1]s" },
"image_slug": func() string { return "%[2]s" },
"image_safe_slug": func() string { return "%[3]s" },
"image_content_based_tag": func() string { return "%[4]s" },
})

var tagFuncList []func(string) string
var tagFuncList []build.CustomTagFunc
for _, optionValue := range tagOptionValues {
tmpl, err := tmpl.Parse(optionValue)
if err != nil {
Expand All @@ -113,17 +114,18 @@ func getCustomTagFuncList(commonCmdData *CmdData, giterminismManager giterminism
}

tagOrFormat := buf.String()
tagFunc := func(imageName string) string {
tagFunc := func(imageName, contentBasedTag string) string {
if strings.ContainsRune(tagOrFormat, '%') {
return fmt.Sprintf(tagOrFormat, imageName, slug.Slug(imageName), slug.DockerTag(imageName))
return fmt.Sprintf(tagOrFormat, imageName, slug.Slug(imageName), slug.DockerTag(imageName), contentBasedTag)
} else {
return tagOrFormat
}
}

contentBasedTagStub := strings.Repeat("x", 70) // 1b77754d35b0a3e603731828ee6f2400c4f937382874db2566c616bb-1624991915332
var prevImageTag string
for _, img := range werfConfig.GetAllImages() {
imageTag := tagFunc(img.GetName())
imageTag := tagFunc(img.GetName(), contentBasedTagStub)

if err := slug.ValidateDockerTag(imageTag); err != nil {
return nil, fmt.Errorf("invalid custom tag %q: %w", optionValue, err)
Expand All @@ -143,7 +145,7 @@ func getCustomTagFuncList(commonCmdData *CmdData, giterminismManager giterminism
return tagFuncList, nil
}

func GetUseCustomTagFunc(commonCmdData *CmdData, giterminismManager giterminism_manager.Interface, werfConfig *config.WerfConfig) (func(string) string, error) {
func GetUseCustomTagFunc(commonCmdData *CmdData, giterminismManager giterminism_manager.Interface, werfConfig *config.WerfConfig) (build.CustomTagFunc, error) {
customTagFuncList, err := getCustomTagFuncList(commonCmdData, giterminismManager, werfConfig)
if err != nil {
return nil, err
Expand Down
14 changes: 8 additions & 6 deletions docs/_includes/reference/cli/werf_build.md
Expand Up @@ -42,12 +42,14 @@ werf build [IMAGE_NAME...] [options]

```shell
--add-custom-tag=[]
Set tag aliases for the content-based tag of each image.
It is necessary to use the image name shortcut %image% or %image_slug% in the tag
format if there is more than one image in the werf config.
Also, can be defined with $WERF_ADD_CUSTOM_TAG_* (e.g.
$WERF_ADD_CUSTOM_TAG_1="%image%-tag1", $WERF_ADD_CUSTOM_TAG_2="%image%-tag2").
For cleaning custom tags and associated content-based tag are treated as one
Set tag alias for the content-based tag.
The alias may contain the following shortcuts:
- %image%, %image_slug% or %image_safe_slug% to use the image name (necessary if there
is more than one image in the werf config);
- %image_content_based_tag% to use a content-based tag.
For cleaning custom tags and associated content-based tag are treated as one.
Also can be defined with $WERF_ADD_CUSTOM_TAG_* (e.g.
$WERF_ADD_CUSTOM_TAG_1="%image%-tag1", $WERF_ADD_CUSTOM_TAG_2="%image%-tag2")
--allowed-docker-storage-volume-usage=70
Set allowed percentage of docker storage volume usage which will cause cleanup of least
recently used local docker images (default 70% or
Expand Down
11 changes: 6 additions & 5 deletions docs/_includes/reference/cli/werf_bundle_export.md
Expand Up @@ -269,11 +269,12 @@ werf bundle export [options]
--use-custom-tag=''
Use a tag alias in helm templates instead of an image content-based tag (NOT
RECOMMENDED).
It is necessary to use the image name shortcut %image% or %image_slug% in the tag
format if there is more than one image in the werf config.
Also, can be defined with $WERF_USE_CUSTOM_TAG (e.g.
$WERF_USE_CUSTOM_TAG="%image%-tag").
For cleaning custom tags and associated content-based tag are treated as one
The alias may contain the following shortcuts:
- %image%, %image_slug% or %image_safe_slug% to use the image name (necessary if there
is more than one image in the werf config);
- %image_content_based_tag% to use a content-based tag.
For cleaning custom tags and associated content-based tag are treated as one.
Also, can be defined with $WERF_USE_CUSTOM_TAG (e.g. $WERF_USE_CUSTOM_TAG="%image%-tag")
--values=[]
Specify helm values in a YAML file or a URL (can specify multiple).
Also, can be defined with $WERF_VALUES_* (e.g. $WERF_VALUES_ENV=.helm/values_test.yaml,
Expand Down
11 changes: 6 additions & 5 deletions docs/_includes/reference/cli/werf_bundle_publish.md
Expand Up @@ -280,11 +280,12 @@ werf bundle publish [options]
--use-custom-tag=''
Use a tag alias in helm templates instead of an image content-based tag (NOT
RECOMMENDED).
It is necessary to use the image name shortcut %image% or %image_slug% in the tag
format if there is more than one image in the werf config.
Also, can be defined with $WERF_USE_CUSTOM_TAG (e.g.
$WERF_USE_CUSTOM_TAG="%image%-tag").
For cleaning custom tags and associated content-based tag are treated as one
The alias may contain the following shortcuts:
- %image%, %image_slug% or %image_safe_slug% to use the image name (necessary if there
is more than one image in the werf config);
- %image_content_based_tag% to use a content-based tag.
For cleaning custom tags and associated content-based tag are treated as one.
Also, can be defined with $WERF_USE_CUSTOM_TAG (e.g. $WERF_USE_CUSTOM_TAG="%image%-tag")
--values=[]
Specify helm values in a YAML file or a URL (can specify multiple).
Also, can be defined with $WERF_VALUES_* (e.g. $WERF_VALUES_ENV=.helm/values_test.yaml,
Expand Down
11 changes: 6 additions & 5 deletions docs/_includes/reference/cli/werf_converge.md
Expand Up @@ -337,11 +337,12 @@ werf converge --repo registry.mydomain.com/web --env production
--use-custom-tag=''
Use a tag alias in helm templates instead of an image content-based tag (NOT
RECOMMENDED).
It is necessary to use the image name shortcut %image% or %image_slug% in the tag
format if there is more than one image in the werf config.
Also, can be defined with $WERF_USE_CUSTOM_TAG (e.g.
$WERF_USE_CUSTOM_TAG="%image%-tag").
For cleaning custom tags and associated content-based tag are treated as one
The alias may contain the following shortcuts:
- %image%, %image_slug% or %image_safe_slug% to use the image name (necessary if there
is more than one image in the werf config);
- %image_content_based_tag% to use a content-based tag.
For cleaning custom tags and associated content-based tag are treated as one.
Also, can be defined with $WERF_USE_CUSTOM_TAG (e.g. $WERF_USE_CUSTOM_TAG="%image%-tag")
--values=[]
Specify helm values in a YAML file or a URL (can specify multiple).
Also, can be defined with $WERF_VALUES_* (e.g. $WERF_VALUES_ENV=.helm/values_test.yaml,
Expand Down
Expand Up @@ -149,11 +149,12 @@ werf helm get-autogenerated-values [options]
--use-custom-tag=''
Use a tag alias in helm templates instead of an image content-based tag (NOT
RECOMMENDED).
It is necessary to use the image name shortcut %image% or %image_slug% in the tag
format if there is more than one image in the werf config.
Also, can be defined with $WERF_USE_CUSTOM_TAG (e.g.
$WERF_USE_CUSTOM_TAG="%image%-tag").
For cleaning custom tags and associated content-based tag are treated as one
The alias may contain the following shortcuts:
- %image%, %image_slug% or %image_safe_slug% to use the image name (necessary if there
is more than one image in the werf config);
- %image_content_based_tag% to use a content-based tag.
For cleaning custom tags and associated content-based tag are treated as one.
Also, can be defined with $WERF_USE_CUSTOM_TAG (e.g. $WERF_USE_CUSTOM_TAG="%image%-tag")
--virtual-merge=false
Enable virtual/ephemeral merge commit mode when building current application state
($WERF_VIRTUAL_MERGE by default)
Expand Down
11 changes: 6 additions & 5 deletions docs/_includes/reference/cli/werf_render.md
Expand Up @@ -272,11 +272,12 @@ werf render [options]
--use-custom-tag=''
Use a tag alias in helm templates instead of an image content-based tag (NOT
RECOMMENDED).
It is necessary to use the image name shortcut %image% or %image_slug% in the tag
format if there is more than one image in the werf config.
Also, can be defined with $WERF_USE_CUSTOM_TAG (e.g.
$WERF_USE_CUSTOM_TAG="%image%-tag").
For cleaning custom tags and associated content-based tag are treated as one
The alias may contain the following shortcuts:
- %image%, %image_slug% or %image_safe_slug% to use the image name (necessary if there
is more than one image in the werf config);
- %image_content_based_tag% to use a content-based tag.
For cleaning custom tags and associated content-based tag are treated as one.
Also, can be defined with $WERF_USE_CUSTOM_TAG (e.g. $WERF_USE_CUSTOM_TAG="%image%-tag")
--validate=false
Validate your manifests against the Kubernetes cluster you are currently pointing at
(default $WERF_VALIDATE)
Expand Down
10 changes: 6 additions & 4 deletions pkg/build/build_phase.go
Expand Up @@ -43,9 +43,11 @@ type BuildOptions struct {
ReportFormat ReportFormat

SkipImageMetadataPublication bool
CustomTagFuncList []func(string) string
CustomTagFuncList []CustomTagFunc
}

type CustomTagFunc func(string, string) string

type IntrospectOptions struct {
Targets []IntrospectTarget
}
Expand Down Expand Up @@ -321,7 +323,7 @@ func (phase *BuildPhase) addCustomImageTagsToStagesStorage(ctx context.Context,
return addCustomImageTags(ctx, phase.Conveyor.StorageManager.GetStagesStorage(), img, phase.CustomTagFuncList)
}

func addCustomImageTags(ctx context.Context, stagesStorage storage.StagesStorage, img *Image, customTagFuncList []func(string) string) error {
func addCustomImageTags(ctx context.Context, stagesStorage storage.StagesStorage, img *Image, customTagFuncList []CustomTagFunc) error {
if len(customTagFuncList) == 0 {
return nil
}
Expand All @@ -332,7 +334,7 @@ func addCustomImageTags(ctx context.Context, stagesStorage storage.StagesStorage
}).
DoError(func() error {
for _, tagFunc := range customTagFuncList {
tag := tagFunc(img.GetName())
tag := tagFunc(img.GetName(), img.GetStageID())
if err := addCustomImageTag(ctx, stagesStorage, img, tag); err != nil {
return err
}
Expand Down Expand Up @@ -363,7 +365,7 @@ func (phase *BuildPhase) checkCustomImageTagsExistence(ctx context.Context, img

stageDesc := img.GetLastNonEmptyStage().GetStageImage().Image.GetStageDescription()
for _, tagFunc := range phase.CustomTagFuncList {
tag := tagFunc(img.GetName())
tag := tagFunc(img.GetName(), img.GetStageID())
if err := phase.Conveyor.StorageManager.GetStagesStorage().CheckStageCustomTag(ctx, stageDesc, tag); err != nil {
return fmt.Errorf("check custom tag %q existence failed: %w", tag, err)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/build/conveyor.go
Expand Up @@ -307,7 +307,7 @@ func (c *Conveyor) GetRemoteGitRepo(key string) *git_repo.Remote {
}

type ShouldBeBuiltOptions struct {
CustomTagFuncList []func(string) string
CustomTagFuncList []CustomTagFunc
}

func (c *Conveyor) ShouldBeBuilt(ctx context.Context, opts ShouldBeBuiltOptions) error {
Expand Down
5 changes: 3 additions & 2 deletions pkg/deploy/helm/chart_extender/helpers/service_values.go
Expand Up @@ -13,6 +13,7 @@ import (
"sigs.k8s.io/yaml"

"github.com/werf/logboek"
"github.com/werf/werf/pkg/build"
"github.com/werf/werf/pkg/image"
"github.com/werf/werf/pkg/werf"
)
Expand All @@ -38,7 +39,7 @@ type ServiceValuesOptions struct {
Env string
IsStub bool
StubImagesNames []string
CustomTagFunc func(string) string
CustomTagFunc build.CustomTagFunc
CommitHash string
CommitDate *time.Time

Expand Down Expand Up @@ -98,7 +99,7 @@ func GetServiceValues(ctx context.Context, projectName string, repo string, imag
var image string

if opts.CustomTagFunc != nil {
tag = opts.CustomTagFunc(imageInfoGetter.GetWerfImageName())
tag = opts.CustomTagFunc(imageInfoGetter.GetWerfImageName(), imageInfoGetter.GetTag())
image = strings.Join([]string{repo, tag}, ":")
} else {
tag = imageInfoGetter.GetTag()
Expand Down

0 comments on commit efd1072

Please sign in to comment.