-
Notifications
You must be signed in to change notification settings - Fork 88
/
copy_images.go
128 lines (108 loc) · 4.21 KB
/
copy_images.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package kotsadm
import (
"context"
"fmt"
"os"
"github.com/containers/image/v5/copy"
"github.com/containers/image/v5/transports/alltransports"
imagev5types "github.com/containers/image/v5/types"
"github.com/distribution/distribution/v3/reference"
"github.com/pkg/errors"
"github.com/replicatedhq/kots/pkg/docker/registry"
"github.com/replicatedhq/kots/pkg/image"
"github.com/replicatedhq/kots/pkg/k8sutil"
kotsadmobjects "github.com/replicatedhq/kots/pkg/kotsadm/objects"
"github.com/replicatedhq/kots/pkg/kotsadm/types"
kotsadmtypes "github.com/replicatedhq/kots/pkg/kotsadm/types"
"k8s.io/client-go/kubernetes"
)
// Copies Admin Console images from public registry to private registry
func CopyImages(options types.PushImagesOptions, kotsNamespace string) error {
clientset, err := k8sutil.GetClientset()
if err != nil {
return errors.Wrap(err, "failed to get clientset")
}
// Minimal info needed to get the right image names
deployOptions := kotsadmtypes.DeployOptions{
IsOpenShift: k8sutil.IsOpenShift(clientset),
RegistryConfig: kotsadmtypes.RegistryConfig{
OverrideRegistry: options.Registry.Endpoint,
OverrideNamespace: options.Registry.Namespace,
Username: options.Registry.Username,
Password: options.Registry.Password,
},
}
sourceImages := kotsadmobjects.GetOriginalAdminConsoleImages(deployOptions)
destImages := kotsadmobjects.GetAdminConsoleImages(deployOptions)
for imageName, sourceImage := range sourceImages {
destImage := destImages[imageName]
if destImage == "" {
return errors.Errorf("failed to find image %s in destination list", imageName)
}
writeProgressLine(options.ProgressWriter, fmt.Sprintf("Copying %s to %s", sourceImage, destImage))
sourceCtx, err := getCopyImagesSourceContext(clientset, kotsNamespace)
if err != nil {
return errors.Wrap(err, "failed to get source context")
}
srcRef, err := alltransports.ParseImageName(fmt.Sprintf("docker://%s", sourceImage))
if err != nil {
return errors.Wrapf(err, "failed to parse source image name %s", sourceImage)
}
destStr := fmt.Sprintf("docker://%s", destImage)
destRef, err := alltransports.ParseImageName(destStr)
if err != nil {
return errors.Wrapf(err, "failed to parse dest image name %s", destStr)
}
destCtx := &imagev5types.SystemContext{
DockerInsecureSkipTLSVerify: imagev5types.OptionalBoolTrue,
DockerDisableV1Ping: true,
}
username, password := options.Registry.Username, options.Registry.Password
registryHost := reference.Domain(destRef.DockerReference())
if registry.IsECREndpoint(registryHost) && username != "AWS" {
login, err := registry.GetECRLogin(registryHost, username, password)
if err != nil {
return errors.Wrap(err, "failed to get ECR login")
}
username = login.Username
password = login.Password
}
if username != "" && password != "" {
destCtx.DockerAuthConfig = &imagev5types.DockerAuthConfig{
Username: username,
Password: password,
}
}
_, err = image.CopyImageWithGC(context.Background(), destRef, srcRef, ©.Options{
RemoveSignatures: true,
SignBy: "",
ReportWriter: options.ProgressWriter,
SourceCtx: sourceCtx,
DestinationCtx: destCtx,
ForceManifestMIMEType: "",
})
if err != nil {
return errors.Wrapf(err, "failed to copy %s to %s: %v", sourceImage, destImage, err)
}
}
return nil
}
func getCopyImagesSourceContext(clientset kubernetes.Interface, kotsNamespace string) (*imagev5types.SystemContext, error) {
sourceCtx := &imagev5types.SystemContext{DockerDisableV1Ping: true}
// allow pulling images from http/invalid https docker repos
// intended for development only, _THIS MAKES THINGS INSECURE_
if os.Getenv("KOTSADM_INSECURE_SRCREGISTRY") == "true" {
sourceCtx.DockerInsecureSkipTLSVerify = imagev5types.OptionalBoolTrue
}
credentials, err := registry.GetDockerHubCredentials(clientset, kotsNamespace)
if err != nil {
return nil, errors.Wrap(err, "failed to get docker hub credentials")
}
if credentials.Username != "" && credentials.Password != "" {
sourceCtx.DockerAuthConfig = &imagev5types.DockerAuthConfig{
Username: credentials.Username,
Password: credentials.Password,
}
}
return sourceCtx, nil
}