Skip to content

Commit 20d5614

Browse files
author
Simon Emms
committed
[installer]: output all images to allow easy mirroring of containers
The output gives the original image name and tag and generates the new image name to be used
1 parent 1074744 commit 20d5614

File tree

1 file changed

+149
-0
lines changed

1 file changed

+149
-0
lines changed

installer/cmd/render-mirror.go

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
// Copyright (c) 2021 Gitpod GmbH. All rights reserved.
2+
// Licensed under the GNU Affero General Public License (AGPL).
3+
// See License-AGPL.txt in the project root for license information.
4+
5+
package cmd
6+
7+
import (
8+
"encoding/json"
9+
"fmt"
10+
"github.com/gitpod-io/gitpod/installer/pkg/common"
11+
"github.com/spf13/cobra"
12+
"regexp"
13+
"sigs.k8s.io/yaml"
14+
"sort"
15+
"strings"
16+
)
17+
18+
type mirrorRepo struct {
19+
Original string `json:"original"`
20+
Target string `json:"target"`
21+
}
22+
23+
var mirrorOpts struct {
24+
ExcludeThirdParty bool
25+
Output string
26+
}
27+
28+
var outputTypes = []string{"yaml", "json"}
29+
30+
// mirrorCmd represents the mirror command
31+
var mirrorCmd = &cobra.Command{
32+
Use: "mirror",
33+
Short: "Renders a list of images used so they can be mirrored to a third-party registry",
34+
Long: `Renders a list of images used so they can be mirrored to a third-party registry
35+
36+
A config file is required which can be generated with the init command.
37+
38+
The output can then be used to iterate over each image. A script can
39+
be written to pull from the "original" path and then tag and push the
40+
image to the "target" repo`,
41+
Example: `
42+
# YAML
43+
gitpod-installer render mirror --config config.yaml > mirror.yaml
44+
45+
# JSON
46+
gitpod-installer render mirror --config config.yaml -o json > mirror.json
47+
48+
# Pull original and push to target
49+
for row in $(gitpod-installer render mirror --config ./config.yaml ./versions.yaml -o json | jq -c '.[]'); do
50+
original=$(echo $row | jq -r '.original')
51+
target=$(echo $row | jq -r '.target')
52+
docker pull $original
53+
docker tag $original $target
54+
docker push $target
55+
done`,
56+
RunE: func(cmd *cobra.Command, args []string) error {
57+
// Validate output type
58+
var output string
59+
for _, i := range outputTypes {
60+
if mirrorOpts.Output == i {
61+
output = i
62+
}
63+
}
64+
if output == "" {
65+
return fmt.Errorf("unknown output type: %s", mirrorOpts.Output)
66+
}
67+
68+
_, cfgVersion, cfg, err := loadConfig(renderOpts.ConfigFN)
69+
if err != nil {
70+
return err
71+
}
72+
73+
// Get the target repository from the config
74+
targetRepo := strings.TrimRight(cfg.Repository, "/")
75+
76+
// Use the default Gitpod registry to pull from
77+
cfg.Repository = common.GitpodContainerRegistry
78+
79+
k8s, err := renderKubernetesObjects(cfgVersion, cfg)
80+
if err != nil {
81+
return err
82+
}
83+
84+
images := make([]mirrorRepo, 0)
85+
re := regexp.MustCompile("image:(.*)")
86+
87+
for _, item := range k8s {
88+
img := re.FindString(item)
89+
90+
if img != "" {
91+
// Remove "image":
92+
img = re.ReplaceAllString(img, "$1")
93+
// Remove whitespace
94+
img = strings.TrimSpace(img)
95+
// Remove wrapping quotes
96+
img = strings.Trim(img, "\"")
97+
98+
// Convert target
99+
target := img
100+
if strings.Contains(img, cfg.Repository) {
101+
// This is the Gitpod registry
102+
target = strings.Replace(target, cfg.Repository, targetRepo, 1)
103+
} else if !mirrorOpts.ExcludeThirdParty {
104+
// Wrap third-party images - remove the first part
105+
thirdPartyImg := strings.Join(strings.Split(img, "/")[1:], "/")
106+
target = fmt.Sprintf("%s/%s", targetRepo, thirdPartyImg)
107+
}
108+
109+
images = append(images, mirrorRepo{
110+
Original: img,
111+
Target: target,
112+
})
113+
}
114+
}
115+
116+
sort.Slice(images, func(i, j int) bool {
117+
scoreI := images[i].Original
118+
scoreJ := images[j].Original
119+
120+
return scoreI < scoreJ
121+
})
122+
123+
switch output {
124+
case "yaml":
125+
fc, err := yaml.Marshal(images)
126+
if err != nil {
127+
return err
128+
}
129+
130+
fmt.Printf("---\n# Gitpod\n%s", string(fc))
131+
case "json":
132+
fc, err := json.MarshalIndent(images, "", " ")
133+
if err != nil {
134+
return err
135+
}
136+
137+
fmt.Println(string(fc))
138+
}
139+
140+
return nil
141+
},
142+
}
143+
144+
func init() {
145+
renderCmd.AddCommand(mirrorCmd)
146+
147+
mirrorCmd.Flags().BoolVar(&mirrorOpts.ExcludeThirdParty, "exclude-third-party", false, "exclude non-Gitpod images")
148+
mirrorCmd.Flags().StringVarP(&mirrorOpts.Output, "output", "o", "yaml", fmt.Sprintf("output type - [%s]", strings.Join(outputTypes, ", ")))
149+
}

0 commit comments

Comments
 (0)