Skip to content
This repository has been archived by the owner on May 3, 2022. It is now read-only.

Commit

Permalink
Image relocation
Browse files Browse the repository at this point in the history
Fixes #668
  • Loading branch information
glyn committed Mar 20, 2019
1 parent adcaa3a commit 2ba0c67
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 1 deletion.
3 changes: 2 additions & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,6 @@
[[constraint]]
name = "github.com/docker/go"
version = "1.5.1-1"

[[constraint]]
name = "k8s.io/apimachinery"
155 changes: 155 additions & 0 deletions cmd/duffle/relocate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*
* Copyright 2019 The original author or authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package main

import (
"fmt"
"io"
"strconv"
"strings"

"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/util/validation"

"github.com/deislabs/duffle/pkg/loader"
)

const relocateDesc = `
Relocates the images referenced by a bundle and creates a new bundle with an updated image map.
The --repository-prefix flag determines the repositories for the relocated images.
Each image tagged with a name starting with the given prefix and pushed to the repository.
For example, if the repository-prefix is example.com/user, the image istio/proxyv2 is relocated
to a name starting with example.com/user/ and pushed to a repository hosted by example.com.
`

type relocateCmd struct {
bundle string
dest string
repoPrefix string
out io.Writer
//verbose bool
//insecure bool
}

func newRelocateCmd(w io.Writer) *cobra.Command {
relocate := &relocateCmd{out: w}

cmd := &cobra.Command{
Use: "relocate [INPUT-BUNDLE] [OUTPUT-BUNDLE]",
Short: "relocate images in a CNAB bundle",
Long: relocateDesc,
Example: `duffle relocate helloworld hellorelocated --repository-prefix example.com/user`,
Args: cobra.ExactArgs(2),
PreRunE: func(cmd *cobra.Command, args []string) error {
// validate --repository-prefix if it is set, otherwise allow flag omission to be diagnosed as such
if cmd.Flags().Changed("repository-prefix") {
if err := FlagValidRepository("repository-prefix")(cmd); err != nil {
return err
}
}

return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
relocate.bundle = args[0]
relocate.dest = args[1]

return relocate.run()
},
}

f := cmd.Flags()
f.StringVarP(&relocate.repoPrefix, "repository-prefix", "r", "", "a prefix for relocated image names")
cmd.MarkFlagRequired("repository-prefix")
//f.BoolVarP(&relocate.verbose, "verbose", "v", false, "Verbose output")
//f.BoolVarP(&relocate.insecure, "insecure", "k", false, "Do not verify the bundle (INSECURE)")

return cmd
}

func (ex *relocateCmd) run() error {
bundlefile, l, err := ex.setup()
if err != nil {
return err
}
if err := ex.Relocate(bundlefile, l); err != nil {
return err
}

return nil
}

func (ex *relocateCmd) Relocate(bundlefile string, l loader.Loader) error {
return nil
}

func (ex *relocateCmd) setup() (string, loader.Loader, error) {
//bundlefile, err := resolveBundleFilePath(ex.bundle, ex.home.String(), ex.bundleIsFile, ex.insecure)
//if err != nil {
// return "", nil, err
//}
//
//l, err := getLoader(ex.home.String(), ex.insecure)
//if err != nil {
// return "", nil, err
//}

return "", nil, nil
}

type FlagsValidator func(cmd *cobra.Command) error

func FlagValidRepository(flagName string) FlagsValidator {
return func(cmd *cobra.Command) error {
repositoryValue := cmd.Flag(flagName).Value.String()

if strings.HasSuffix(repositoryValue, "/") || strings.Contains(repositoryValue, "//") {
return fmt.Errorf("invalid repository: %s", repositoryValue)
}

for i, part := range strings.Split(repositoryValue, "/") {
if i != 0 {
if strings.ContainsAny(part, ":@\" ") {
return fmt.Errorf("invalid repository: %s", repositoryValue)
}
continue
}

authorityParts := strings.Split(part, ":")
if len(authorityParts) > 2 {
return fmt.Errorf("invalid repository hostname: %s", part)
}
if errs := validation.IsDNS1123Subdomain(authorityParts[0]); len(errs) > 0 {
return fmt.Errorf("invalid repository hostname: %s", strings.Join(errs, "; "))
}
if len(authorityParts) == 2 {
portNumber, err := strconv.Atoi(authorityParts[1])
if err != nil {
return fmt.Errorf("invalid repository port number: %s", authorityParts[1])
}

if errs := validation.IsValidPortNum(portNumber); len(errs) > 0 {
return fmt.Errorf("invalid repository port number: %s", strings.Join(errs, "; "))
}
}
}

return nil
}
}
1 change: 1 addition & 0 deletions cmd/duffle/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func newRootCmd(outputRedirect io.Writer) *cobra.Command {
cmd.AddCommand(newListCmd(outLog))
cmd.AddCommand(newPullCmd(outLog))
cmd.AddCommand(newPushCmd(outLog))
cmd.AddCommand(newRelocateCmd(outLog))
cmd.AddCommand(newSearchCmd(outLog))
cmd.AddCommand(newVersionCmd(outLog))
cmd.AddCommand(newInstallCmd(outLog))
Expand Down

0 comments on commit 2ba0c67

Please sign in to comment.