Merge pull request #6054 from 7AC/master

bashbrew: account for namespaces when sorting repos
This commit is contained in:
Tianon Gravi 2019-06-14 20:13:49 -07:00 committed by GitHub
commit e36f787052
11 changed files with 56 additions and 42 deletions

View File

@ -18,7 +18,6 @@ func cmdBuild(c *cli.Context) error {
} }
uniq := c.Bool("uniq") uniq := c.Bool("uniq")
namespace := c.String("namespace")
pull := c.String("pull") pull := c.String("pull")
switch pull { switch pull {
case "always", "missing", "never": case "always", "missing", "never":

View File

@ -55,6 +55,9 @@ func cmdCat(c *cli.Context) error {
"arch": func() string { "arch": func() string {
return arch return arch
}, },
"namespace": func() string {
return namespace
},
"archNamespace": func(arch string) string { "archNamespace": func(arch string) string {
return archNamespaces[arch] return archNamespaces[arch]
}, },

View File

@ -50,7 +50,7 @@ func cmdFamily(parents bool, c *cli.Context) error {
continue continue
} }
for _, tag := range r.Tags("", false, entry) { for _, tag := range r.Tags(namespace, false, entry) {
network.AddNode(tag, entry) network.AddNode(tag, entry)
} }
} }
@ -78,7 +78,7 @@ func cmdFamily(parents bool, c *cli.Context) error {
return cli.NewMultiError(fmt.Errorf(`failed fetching/scraping FROM for %q (tags %q, arch %q)`, r.RepoName, entry.TagsString(), entryArch), err) return cli.NewMultiError(fmt.Errorf(`failed fetching/scraping FROM for %q (tags %q, arch %q)`, r.RepoName, entry.TagsString(), entryArch), err)
} }
for _, from := range froms { for _, from := range froms {
for _, tag := range r.Tags("", false, entry) { for _, tag := range r.Tags(namespace, false, entry) {
network.AddEdge(from, tag) network.AddEdge(from, tag)
} }
} }
@ -99,7 +99,7 @@ func cmdFamily(parents bool, c *cli.Context) error {
continue continue
} }
for _, tag := range r.Tags("", uniq, entry) { for _, tag := range r.Tags(namespace, uniq, entry) {
nodes := []topsortDepthNodes{} nodes := []topsortDepthNodes{}
if parents { if parents {
nodes = append(nodes, topsortDepthNodes{ nodes = append(nodes, topsortDepthNodes{

View File

@ -14,7 +14,6 @@ func cmdFrom(c *cli.Context) error {
} }
uniq := c.Bool("uniq") uniq := c.Bool("uniq")
namespace := ""
applyConstraints := c.Bool("apply-constraints") applyConstraints := c.Bool("apply-constraints")
for _, repo := range repos { for _, repo := range repos {

View File

@ -14,7 +14,6 @@ func cmdList(c *cli.Context) error {
} }
uniq := c.Bool("uniq") uniq := c.Bool("uniq")
namespace := ""
applyConstraints := c.Bool("apply-constraints") applyConstraints := c.Bool("apply-constraints")
onlyRepos := c.Bool("repos") onlyRepos := c.Bool("repos")

View File

@ -16,12 +16,15 @@ func cmdPush(c *cli.Context) error {
} }
uniq := c.Bool("uniq") uniq := c.Bool("uniq")
namespace := c.String("namespace") targetNamespace := c.String("target-namespace")
dryRun := c.Bool("dry-run") dryRun := c.Bool("dry-run")
force := c.Bool("force") force := c.Bool("force")
if namespace == "" { if targetNamespace == "" {
return fmt.Errorf(`"--namespace" is a required flag for "push"`) targetNamespace = namespace
}
if targetNamespace == "" {
return fmt.Errorf(`either "--target-namespace" or "--namespace" is a required flag for "push"`)
} }
for _, repo := range repos { for _, repo := range repos {
@ -30,7 +33,7 @@ func cmdPush(c *cli.Context) error {
return cli.NewMultiError(fmt.Errorf(`failed fetching repo %q`, repo), err) return cli.NewMultiError(fmt.Errorf(`failed fetching repo %q`, repo), err)
} }
tagRepo := path.Join(namespace, r.RepoName) tagRepo := path.Join(targetNamespace, r.RepoName)
for _, entry := range r.Entries() { for _, entry := range r.Entries() {
if r.SkipConstraints(entry) { if r.SkipConstraints(entry) {
continue continue

View File

@ -83,13 +83,16 @@ func cmdPutShared(c *cli.Context) error {
return cli.NewMultiError(fmt.Errorf(`failed gathering repo list`), err) return cli.NewMultiError(fmt.Errorf(`failed gathering repo list`), err)
} }
namespace := c.String("namespace")
dryRun := c.Bool("dry-run") dryRun := c.Bool("dry-run")
targetNamespace := c.String("target-namespace")
force := c.Bool("force") force := c.Bool("force")
singleArch := c.Bool("single-arch") singleArch := c.Bool("single-arch")
if namespace == "" { if targetNamespace == "" {
return fmt.Errorf(`"--namespace" is a required flag for "put-shared"`) targetNamespace = namespace
}
if targetNamespace == "" {
return fmt.Errorf(`either "--target-namespace" or "--namespace" is a required flag for "put-shared"`)
} }
for _, repo := range repos { for _, repo := range repos {
@ -98,7 +101,7 @@ func cmdPutShared(c *cli.Context) error {
return cli.NewMultiError(fmt.Errorf(`failed fetching repo %q`, repo), err) return cli.NewMultiError(fmt.Errorf(`failed fetching repo %q`, repo), err)
} }
targetRepo := path.Join(namespace, r.RepoName) targetRepo := path.Join(targetNamespace, r.RepoName)
sharedTagGroups := []manifest.SharedTagGroup{} sharedTagGroups := []manifest.SharedTagGroup{}

View File

@ -14,11 +14,11 @@ func cmdTag(c *cli.Context) error {
} }
uniq := c.Bool("uniq") uniq := c.Bool("uniq")
namespace := c.String("namespace") targetNamespace := c.String("target-namespace")
dryRun := c.Bool("dry-run") dryRun := c.Bool("dry-run")
if namespace == "" { if targetNamespace == "" {
return fmt.Errorf(`"--namespace" is a required flag for "tag"`) return fmt.Errorf(`"--target-namespace" is a required flag for "tag"`)
} }
for _, repo := range repos { for _, repo := range repos {
@ -33,12 +33,13 @@ func cmdTag(c *cli.Context) error {
} }
for _, tag := range r.Tags("", uniq, entry) { for _, tag := range r.Tags("", uniq, entry) {
namespacedTag := path.Join(namespace, tag) sourceTag := path.Join(namespace, tag)
fmt.Printf("Tagging %s\n", namespacedTag) targetTag := path.Join(targetNamespace, tag)
fmt.Printf("Tagging %s\n", targetTag)
if !dryRun { if !dryRun {
err = dockerTag(tag, namespacedTag) err = dockerTag(sourceTag, targetTag)
if err != nil { if err != nil {
return cli.NewMultiError(fmt.Errorf(`failed tagging %q as %q`, tag, namespacedTag), err) return cli.NewMultiError(fmt.Errorf(`failed tagging %q as %q`, sourceTag, targetTag), err)
} }
} }
} }

View File

@ -22,11 +22,11 @@ type FlagsConfigEntry struct {
Cache string Cache string
Debug string Debug string
Unique string Unique string
Namespace string
BuildOrder string BuildOrder string
Pull string Pull string
Arch string Arch string
Namespace string
Constraints []string `delim:"," strip:"\n\r\t "` Constraints []string `delim:"," strip:"\n\r\t "`
ExclusiveConstraints string ExclusiveConstraints string
ApplyConstraints string ApplyConstraints string
@ -50,9 +50,6 @@ func (dst *FlagsConfigEntry) Apply(src FlagsConfigEntry) {
if src.Unique != "" { if src.Unique != "" {
dst.Unique = src.Unique dst.Unique = src.Unique
} }
if src.Namespace != "" {
dst.Namespace = src.Namespace
}
if src.BuildOrder != "" { if src.BuildOrder != "" {
dst.BuildOrder = src.BuildOrder dst.BuildOrder = src.BuildOrder
} }
@ -62,6 +59,9 @@ func (dst *FlagsConfigEntry) Apply(src FlagsConfigEntry) {
if src.Arch != "" { if src.Arch != "" {
dst.Arch = src.Arch dst.Arch = src.Arch
} }
if src.Namespace != "" {
dst.Namespace = src.Namespace
}
if len(src.Constraints) > 0 { if len(src.Constraints) > 0 {
dst.Constraints = src.Constraints[:] dst.Constraints = src.Constraints[:]
} }
@ -84,6 +84,7 @@ func (config FlagsConfigEntry) Vars() map[string]map[string]interface{} {
"debug": config.Debug, "debug": config.Debug,
"arch": config.Arch, "arch": config.Arch,
"namespace": config.Namespace,
"constraint": config.Constraints, "constraint": config.Constraints,
"exclusive-constraints": config.ExclusiveConstraints, "exclusive-constraints": config.ExclusiveConstraints,
@ -92,7 +93,6 @@ func (config FlagsConfigEntry) Vars() map[string]map[string]interface{} {
"local": { "local": {
"uniq": config.Unique, "uniq": config.Unique,
"namespace": config.Namespace,
"build-order": config.BuildOrder, "build-order": config.BuildOrder,
"pull": config.Pull, "pull": config.Pull,

View File

@ -22,6 +22,7 @@ var (
defaultCache string defaultCache string
arch string arch string
namespace string
constraints []string constraints []string
exclusiveConstraints bool exclusiveConstraints bool
@ -32,12 +33,13 @@ var (
// separated so that FlagsConfig.ApplyTo can access them // separated so that FlagsConfig.ApplyTo can access them
flagEnvVars = map[string]string{ flagEnvVars = map[string]string{
"debug": "BASHBREW_DEBUG", "debug": "BASHBREW_DEBUG",
"arch": "BASHBREW_ARCH", "arch": "BASHBREW_ARCH",
"config": "BASHBREW_CONFIG", "namespace": "BASHBREW_NAMESPACE",
"library": "BASHBREW_LIBRARY", "config": "BASHBREW_CONFIG",
"cache": "BASHBREW_CACHE", "library": "BASHBREW_LIBRARY",
"pull": "BASHBREW_PULL", "cache": "BASHBREW_CACHE",
"pull": "BASHBREW_PULL",
"constraint": "BASHBREW_CONSTRAINTS", "constraint": "BASHBREW_CONSTRAINTS",
"arch-namespace": "BASHBREW_ARCH_NAMESPACES", "arch-namespace": "BASHBREW_ARCH_NAMESPACES",
@ -93,6 +95,11 @@ func main() {
EnvVar: flagEnvVars["arch"], EnvVar: flagEnvVars["arch"],
Usage: "the current platform architecture", Usage: "the current platform architecture",
}, },
cli.StringFlag{
Name: "namespace",
EnvVar: flagEnvVars["namespace"],
Usage: "a repo namespace to act upon/in",
},
cli.StringSliceFlag{ cli.StringSliceFlag{
Name: "constraint", Name: "constraint",
EnvVar: flagEnvVars["constraint"], EnvVar: flagEnvVars["constraint"],
@ -156,6 +163,7 @@ func main() {
noSortFlag = c.GlobalBool("no-sort") noSortFlag = c.GlobalBool("no-sort")
arch = c.GlobalString("arch") arch = c.GlobalString("arch")
namespace = c.GlobalString("namespace")
constraints = c.GlobalStringSlice("constraint") constraints = c.GlobalStringSlice("constraint")
exclusiveConstraints = c.GlobalBool("exclusive-constraints") exclusiveConstraints = c.GlobalBool("exclusive-constraints")
@ -189,10 +197,6 @@ func main() {
Name: "uniq, unique", Name: "uniq, unique",
Usage: "only act upon the first tag of each entry", Usage: "only act upon the first tag of each entry",
}, },
"namespace": cli.StringFlag{
Name: "namespace",
Usage: "a repo namespace to act upon/in",
},
"apply-constraints": cli.BoolFlag{ "apply-constraints": cli.BoolFlag{
Name: "apply-constraints", Name: "apply-constraints",
Usage: "apply Constraints as if repos were building", Usage: "apply Constraints as if repos were building",
@ -210,6 +214,10 @@ func main() {
Name: "force", Name: "force",
Usage: "always push (skip the clever Hub API lookups that no-op things sooner if a push doesn't seem necessary)", Usage: "always push (skip the clever Hub API lookups that no-op things sooner if a push doesn't seem necessary)",
}, },
"target-namespace": cli.StringFlag{
Name: "target-namespace",
Usage: `target namespace to act into ("docker tag namespace/repo:tag target-namespace/repo:tag", "docker push target-namespace/repo:tag")`,
},
} }
app.Commands = []cli.Command{ app.Commands = []cli.Command{
@ -239,7 +247,6 @@ func main() {
Flags: []cli.Flag{ Flags: []cli.Flag{
commonFlags["all"], commonFlags["all"],
commonFlags["uniq"], commonFlags["uniq"],
commonFlags["namespace"],
cli.StringFlag{ cli.StringFlag{
Name: "pull", Name: "pull",
Value: "missing", Value: "missing",
@ -257,8 +264,8 @@ func main() {
Flags: []cli.Flag{ Flags: []cli.Flag{
commonFlags["all"], commonFlags["all"],
commonFlags["uniq"], commonFlags["uniq"],
commonFlags["namespace"],
commonFlags["dry-run"], commonFlags["dry-run"],
commonFlags["target-namespace"],
}, },
Before: subcommandBeforeFactory("tag"), Before: subcommandBeforeFactory("tag"),
Action: cmdTag, Action: cmdTag,
@ -269,9 +276,9 @@ func main() {
Flags: []cli.Flag{ Flags: []cli.Flag{
commonFlags["all"], commonFlags["all"],
commonFlags["uniq"], commonFlags["uniq"],
commonFlags["namespace"],
commonFlags["dry-run"], commonFlags["dry-run"],
commonFlags["force"], commonFlags["force"],
commonFlags["target-namespace"],
}, },
Before: subcommandBeforeFactory("push"), Before: subcommandBeforeFactory("push"),
Action: cmdPush, Action: cmdPush,
@ -281,9 +288,9 @@ func main() {
Usage: `update shared tags in the registry (and multi-architecture tags)`, Usage: `update shared tags in the registry (and multi-architecture tags)`,
Flags: []cli.Flag{ Flags: []cli.Flag{
commonFlags["all"], commonFlags["all"],
commonFlags["namespace"],
commonFlags["dry-run"], commonFlags["dry-run"],
commonFlags["force"], commonFlags["force"],
commonFlags["target-namespace"],
cli.BoolFlag{ cli.BoolFlag{
Name: "single-arch", Name: "single-arch",
Usage: `only act on the current architecture (for pushing "amd64/hello-world:latest", for example)`, Usage: `only act on the current architecture (for pushing "amd64/hello-world:latest", for example)`,

View File

@ -79,7 +79,7 @@ func sortRepoObjects(rs []*Repo, applyConstraints bool) ([]*Repo, error) {
for _, r := range rs { for _, r := range rs {
node := r.Identifier() node := r.Identifier()
for _, entry := range r.Entries() { for _, entry := range r.Entries() {
for _, tag := range r.Tags("", false, entry) { for _, tag := range r.Tags(namespace, false, entry) {
if canonicalRepo, ok := canonicalRepos[tag]; ok && canonicalRepo.TagName != "" { if canonicalRepo, ok := canonicalRepos[tag]; ok && canonicalRepo.TagName != "" {
// if we run into a duplicate, we want to prefer a specific tag over a full repo // if we run into a duplicate, we want to prefer a specific tag over a full repo
continue continue
@ -114,7 +114,7 @@ func sortRepoObjects(rs []*Repo, applyConstraints bool) ([]*Repo, error) {
} }
// TODO somehow reconcile/avoid "a:a -> b:b, b:b -> a:c" (which will exhibit here as cyclic) // TODO somehow reconcile/avoid "a:a -> b:b, b:b -> a:c" (which will exhibit here as cyclic)
for _, tag := range r.Tags("", false, entry) { for _, tag := range r.Tags(namespace, false, entry) {
if tagNode, ok := canonicalNodes[tag]; ok { if tagNode, ok := canonicalNodes[tag]; ok {
if tagNode == fromNode { if tagNode == fromNode {
// don't be cyclic // don't be cyclic