Skip to content
Permalink
Browse files
feat(bundle): implement 'bundle copy' command
```
werf bundle copy --repo REPO [--tag latest] --to NEWREPO [--to-tag NEWTAG]
```

Signed-off-by: Timofey Kirillov <timofey.kirillov@flant.com>
  • Loading branch information
distorhead committed Apr 28, 2022
1 parent aabfcea commit 16dbd2e8e9a2f3e15bb85f598a009b479a636188
@@ -81,8 +81,8 @@ If one or more IMAGE_NAME parameters specified, werf will build only these image

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

common.SetupDockerConfig(&commonCmdData, cmd, "Command needs granted permissions to read, pull and push images into the specified repo, to pull base images")
common.SetupInsecureRegistry(&commonCmdData, cmd)
@@ -214,8 +214,7 @@ func run(ctx context.Context, containerBackend container_backend.ContainerBacken
}
defer tmp_manager.ReleaseProjectDir(projectTmpDir)

stagesStorageAddress := common.GetOptionalStagesStorageAddress(&commonCmdData)
stagesStorage, err := common.GetStagesStorage(stagesStorageAddress, containerBackend, &commonCmdData)
stagesStorage, err := common.GetStagesStorage(containerBackend, &commonCmdData)
if err != nil {
return err
}
@@ -61,8 +61,8 @@ func NewCmd() *cobra.Command {
common.SetupTmpDir(&commonCmdData, cmd, common.SetupTmpDirOptions{})
common.SetupHomeDir(&commonCmdData, cmd, common.SetupHomeDirOptions{})

common.SetupStagesStorageOptions(&commonCmdData, cmd) // FIXME
common.SetupFinalStagesStorageOptions(&commonCmdData, cmd)
common.SetupRepoOptions(&commonCmdData, cmd, common.RepoDataOptions{})
common.SetupFinalRepo(&commonCmdData, cmd)

common.SetupDockerConfig(&commonCmdData, cmd, "Command needs granted permissions to read, pull and push images into the specified repo, to pull base images")
common.SetupInsecureRegistry(&commonCmdData, cmd)
@@ -128,7 +128,7 @@ func runApply() error {
return err
}

repoAddress, err := common.GetStagesStorageAddress(&commonCmdData)
repoAddress, err := commonCmdData.Repo.GetAddress()
if err != nil {
return err
}
@@ -0,0 +1,116 @@
package copy

import (
"fmt"
"os"

"github.com/spf13/cobra"
helm_v3 "helm.sh/helm/v3/cmd/helm"

"github.com/werf/werf/cmd/werf/common"
"github.com/werf/werf/pkg/deploy/bundles"
"github.com/werf/werf/pkg/werf"
"github.com/werf/werf/pkg/werf/global_warnings"
)

var cmdData struct {
Repo *common.RepoData
Tag string
To *common.RepoData
ToTag string
}

var commonCmdData common.CmdData

func NewCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "copy",
Short: "Copy published bundle into another location",
Long: common.GetLongCommandDescription(`Take latest bundle from the specified container registry using specified version tag and copy it either into a different tag within the same container registry or into another container registry.`),
DisableFlagsInUseLine: true,
Annotations: map[string]string{
common.CmdEnvAnno: common.EnvsDescription(),
},
RunE: func(cmd *cobra.Command, args []string) error {
defer global_warnings.PrintGlobalWarnings(common.GetContext())

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

common.LogVersion()

return common.LogRunningTime(runCopy)
},
}

common.SetupTmpDir(&commonCmdData, cmd, common.SetupTmpDirOptions{})
common.SetupHomeDir(&commonCmdData, cmd, common.SetupHomeDirOptions{})

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

cmdData.Repo = common.NewRepoData("repo", common.RepoDataOptions{OnlyAddress: true})
cmdData.Repo.SetupCmd(cmd)

cmdData.To = common.NewRepoData("to", common.RepoDataOptions{OnlyAddress: true})
cmdData.To.SetupCmd(cmd)

common.SetupLogOptions(&commonCmdData, cmd)
common.SetupLogProjectDir(&commonCmdData, cmd)
common.SetupPlatform(&commonCmdData, cmd)

defaultTag := os.Getenv("WERF_TAG")
if defaultTag == "" {
defaultTag = "latest"
}
cmd.Flags().StringVarP(&cmdData.Tag, "tag", "", defaultTag, "Provide from tag version of the bundle to copy ($WERF_TAG or latest by default)")
cmd.Flags().StringVarP(&cmdData.ToTag, "to-tag", "", "", "Provide to tag version of the bundle to copy ($WERF_TO_TAG or same as --tag by default)")

return cmd
}

func runCopy() error {
ctx := common.GetContext()

if err := werf.Init(*commonCmdData.TmpDir, *commonCmdData.HomeDir); err != nil {
return fmt.Errorf("initialization error: %w", err)
}

if err := common.DockerRegistryInit(ctx, &commonCmdData); err != nil {
return err
}

helm_v3.Settings.Debug = *commonCmdData.LogDebug

bundlesRegistryClient, err := common.NewBundlesRegistryClient(ctx, &commonCmdData)
if err != nil {
return err
}

if *cmdData.Repo.Address == "" {
return fmt.Errorf("--repo=ADDRESS param required")
}
if *cmdData.To.Address == "" {
return fmt.Errorf("--to=ADDRESS param required")
}

fromRegistry, err := cmdData.Repo.CreateDockerRegistry(*commonCmdData.InsecureRegistry, *commonCmdData.SkipTlsVerifyRegistry)
if err != nil {
return fmt.Errorf("error creating container registry accessor for repo %s: %w", *cmdData.Repo.Address, err)
}

fromTag := cmdData.Tag
toTag := cmdData.ToTag
if toTag == "" {
toTag = fromTag
}

fromRef := fmt.Sprintf("%s:%s", *cmdData.Repo.Address, fromTag)
toRef := fmt.Sprintf("%s:%s", *cmdData.To.Address, toTag)

return bundles.Copy(ctx, fromRef, toRef, bundlesRegistryClient, fromRegistry)
}
@@ -5,7 +5,7 @@ import (
"os"

"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm"
helm_v3 "helm.sh/helm/v3/cmd/helm"

"github.com/werf/werf/cmd/werf/common"
"github.com/werf/werf/pkg/deploy/bundles"
@@ -50,8 +50,8 @@ func NewCmd() *cobra.Command {
common.SetupInsecureHelmDependencies(&commonCmdData, cmd)
common.SetupSkipTlsVerifyRegistry(&commonCmdData, cmd)

common.SetupStagesStorageOptions(&commonCmdData, cmd) // FIXME
common.SetupFinalStagesStorageOptions(&commonCmdData, cmd)
common.SetupRepoOptions(&commonCmdData, cmd, common.RepoDataOptions{})
common.SetupFinalRepo(&commonCmdData, cmd)

common.SetupLogOptions(&commonCmdData, cmd)
common.SetupLogProjectDir(&commonCmdData, cmd)
@@ -77,7 +77,7 @@ func runDownload() error {
return err
}

repoAddress, err := common.GetStagesStorageAddress(&commonCmdData)
repoAddress, err := commonCmdData.Repo.GetAddress()
if err != nil {
return err
}
@@ -82,8 +82,8 @@ func NewCmd() *cobra.Command {

common.SetupSecondaryStagesStorageOptions(&commonCmdData, cmd)
common.SetupCacheStagesStorageOptions(&commonCmdData, cmd)
common.SetupStagesStorageOptions(&commonCmdData, cmd)
common.SetupFinalStagesStorageOptions(&commonCmdData, cmd)
common.SetupRepoOptions(&commonCmdData, cmd, common.RepoDataOptions{})
common.SetupFinalRepo(&commonCmdData, cmd)

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)
@@ -223,16 +223,11 @@ func runExport(ctx context.Context) error {

logboek.LogOptionalLn()

repoAddress, err := common.GetStagesStorageAddress(&commonCmdData)
if err != nil {
return err
}

var imagesInfoGetters []*image.InfoGetter
var imagesRepository string

if len(werfConfig.StapelImages) != 0 || len(werfConfig.ImagesFromDockerfile) != 0 {
stagesStorage, err := common.GetStagesStorage(repoAddress, containerBackend, &commonCmdData)
stagesStorage, err := common.GetStagesStorage(containerBackend, &commonCmdData)
if err != nil {
return err
}
@@ -88,8 +88,8 @@ Published into container registry bundle can be rolled out by the "werf bundle"

common.SetupSecondaryStagesStorageOptions(&commonCmdData, cmd)
common.SetupCacheStagesStorageOptions(&commonCmdData, cmd)
common.SetupStagesStorageOptions(&commonCmdData, cmd)
common.SetupFinalStagesStorageOptions(&commonCmdData, cmd)
common.SetupRepoOptions(&commonCmdData, cmd, common.RepoDataOptions{})
common.SetupFinalRepo(&commonCmdData, cmd)

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)
@@ -239,7 +239,7 @@ func runPublish(ctx context.Context) error {

logboek.LogOptionalLn()

repoAddress, err := common.GetStagesStorageAddress(&commonCmdData)
repoAddress, err := commonCmdData.Repo.GetAddress()
if err != nil {
return err
}
@@ -253,7 +253,7 @@ func runPublish(ctx context.Context) error {
var imagesRepository string

if len(werfConfig.StapelImages) != 0 || len(werfConfig.ImagesFromDockerfile) != 0 {
stagesStorage, err := common.GetStagesStorage(repoAddress, containerBackend, &commonCmdData)
stagesStorage, err := common.GetStagesStorage(containerBackend, &commonCmdData)
if err != nil {
return err
}
@@ -9,7 +9,7 @@ import (

uuid "github.com/satori/go.uuid"
"github.com/spf13/cobra"
"helm.sh/helm/v3/cmd/helm"
helm_v3 "helm.sh/helm/v3/cmd/helm"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader"
@@ -64,8 +64,8 @@ func NewCmd() *cobra.Command {
common.SetupTmpDir(&commonCmdData, cmd, common.SetupTmpDirOptions{})
common.SetupHomeDir(&commonCmdData, cmd, common.SetupHomeDirOptions{})

common.SetupStagesStorageOptions(&commonCmdData, cmd)
common.SetupFinalStagesStorageOptions(&commonCmdData, cmd)
common.SetupRepoOptions(&commonCmdData, cmd, common.RepoDataOptions{})
common.SetupFinalRepo(&commonCmdData, cmd)

common.SetupDockerConfig(&commonCmdData, cmd, "Command needs granted permissions to read, pull and push images into the specified repo, to pull base images")
common.SetupInsecureRegistry(&commonCmdData, cmd)
@@ -114,17 +114,17 @@ func runRender(ctx context.Context) error {
var isLocal bool
switch {
case cmdData.BundleDir != "":
if *commonCmdData.StagesStorage != "" {
if *commonCmdData.Repo.Address != "" {
return fmt.Errorf("only one of --bundle-dir or --repo should be specified, but both provided")
}
if *commonCmdData.FinalStagesStorage != "" {
if *commonCmdData.FinalRepo.Address != "" {
return fmt.Errorf("only one of --bundle-dir or --final-repo should be specified, but both provided")
}

isLocal = true
case *commonCmdData.StagesStorage == storage.LocalStorageAddress:
case *commonCmdData.Repo.Address == storage.LocalStorageAddress:
return fmt.Errorf("--repo %s is not allowed, specify remote storage address", storage.LocalStorageAddress)
case *commonCmdData.StagesStorage != "":
case *commonCmdData.Repo.Address != "":
isLocal = false
default:
return fmt.Errorf("either --bundle-dir or --repo required")
@@ -165,7 +165,7 @@ func runRender(ctx context.Context) error {
return err
}

repoAddress, err := common.GetStagesStorageAddress(&commonCmdData)
repoAddress, err := commonCmdData.Repo.GetAddress()
if err != nil {
return err
}
@@ -65,8 +65,8 @@ It is safe to run this command periodically (daily is enough) by automated clean

common.SetupSecondaryStagesStorageOptions(&commonCmdData, cmd)
common.SetupCacheStagesStorageOptions(&commonCmdData, cmd)
common.SetupStagesStorageOptions(&commonCmdData, cmd)
common.SetupFinalStagesStorageOptions(&commonCmdData, cmd)
common.SetupRepoOptions(&commonCmdData, cmd, common.RepoDataOptions{})
common.SetupFinalRepo(&commonCmdData, cmd)
common.SetupParallelOptions(&commonCmdData, cmd, common.DefaultCleanupParallelTasksLimit)

common.SetupDockerConfig(&commonCmdData, cmd, "Command needs granted permissions to read, pull and delete images from the specified repo")
@@ -189,14 +189,14 @@ func runCleanup(ctx context.Context) error {

projectName := werfConfig.Meta.Project

stagesStorageAddress, err := common.GetStagesStorageAddress(&commonCmdData)
_, err = commonCmdData.Repo.GetAddress()
if err != nil {
logboek.Context(ctx).Default().LogLnDetails(`The "werf cleanup" command is only used to cleaning the container registry. In case you need to clean the runner or the localhost, use the commands of the "werf host" group.
It is worth noting that auto-cleaning is enabled by default, and manual use is usually not required (if not, we would appreciate feedback and creating an issue https://github.com/werf/werf/issues/new).`)

return err
}
stagesStorage, err := common.GetStagesStorage(stagesStorageAddress, containerBackend, &commonCmdData)
stagesStorage, err := common.GetStagesStorage(containerBackend, &commonCmdData)
if err != nil {
return err
}

0 comments on commit 16dbd2e

Please sign in to comment.