@@ -10,11 +10,11 @@ import (
1010 "path"
1111 "regexp"
1212 "strings"
13-
13+
1414 "github.com/loft-sh/devspace/pkg/util/encoding"
1515 "github.com/loft-sh/utils/pkg/command"
1616 "github.com/sirupsen/logrus"
17-
17+
1818 "github.com/loft-sh/devspace/pkg/devspace/config/versions/latest"
1919 "github.com/loft-sh/devspace/pkg/devspace/docker"
2020 "github.com/loft-sh/devspace/pkg/devspace/generator"
@@ -41,19 +41,19 @@ func (m *manager) AddImage(imageName, image, projectNamespace, dockerfile string
4141 skip = "Skip / I don't know"
4242 err error
4343 )
44-
44+
4545 imageConfig := & latest.Image {
4646 Image : strings .ToLower (image ),
4747 Dockerfile : dockerfile ,
4848 }
49-
49+
5050 buildMethods := []string {subPathDockerfile }
51-
51+
5252 stat , err := os .Stat (imageConfig .Dockerfile )
5353 if err == nil && ! stat .IsDir () {
5454 buildMethods = []string {rootLevelDockerfile , differentDockerfile }
5555 }
56-
56+
5757 buildMethod , err := m .log .Question (& survey.QuestionOptions {
5858 Question : "How should DevSpace build the container image for this project?" ,
5959 DefaultValue : buildMethods [0 ],
@@ -62,15 +62,15 @@ func (m *manager) AddImage(imageName, image, projectNamespace, dockerfile string
6262 if err != nil {
6363 return err
6464 }
65-
65+
6666 if buildMethod == customBuild {
6767 buildCommand , err := m .log .Question (& survey.QuestionOptions {
6868 Question : "Please enter your build command without the image (e.g. `gradle jib --image` => DevSpace will append the image name automatically)" ,
6969 })
7070 if err != nil {
7171 return err
7272 }
73-
73+
7474 imageConfig .Custom = & latest.CustomConfig {
7575 Command : buildCommand + " --tag=$(get_image --only=tag " + imageName + ")" ,
7676 }
@@ -82,7 +82,7 @@ func (m *manager) AddImage(imageName, image, projectNamespace, dockerfile string
8282 if value == "" {
8383 return nil
8484 }
85-
85+
8686 stat , err := os .Stat (value )
8787 if err == nil && ! stat .IsDir () {
8888 return nil
@@ -93,7 +93,7 @@ func (m *manager) AddImage(imageName, image, projectNamespace, dockerfile string
9393 if err != nil {
9494 return err
9595 }
96-
96+
9797 if imageConfig .Dockerfile != "" {
9898 imageConfig .Context , err = m .log .Question (& survey.QuestionOptions {
9999 Question : "What is the build context for building this image?" ,
@@ -114,35 +114,35 @@ func (m *manager) AddImage(imageName, image, projectNamespace, dockerfile string
114114 }
115115 }
116116 }
117-
117+
118118 if image == "" && buildMethod != skip {
119119 kubeClient , err := kubectl .NewDefaultClient ()
120120 if err != nil {
121121 return err
122122 }
123-
123+
124124 // Get docker client
125125 dockerClient , err := m .factory .NewDockerClientWithMinikube (context .TODO (), kubeClient , true , m .log )
126126 if err != nil {
127127 return errors .Errorf ("Cannot create docker client: %v" , err )
128128 }
129-
129+
130130 // Check if user is logged into docker hub
131131 isLoggedIntoDockerHub := false
132132 authConfig , err := dockerClient .GetAuthConfig (context .TODO (), dockerHubHostname , true )
133133 if err == nil && authConfig .Username != "" {
134134 useDockerHub = useDockerHub + fmt .Sprintf (registryUsernameHint , authConfig .Username )
135135 isLoggedIntoDockerHub = true
136136 }
137-
137+
138138 // Check if user is logged into GitHub
139139 isLoggedIntoGitHub := false
140140 authConfig , err = dockerClient .GetAuthConfig (context .TODO (), generator .GithubContainerRegistry , true )
141141 if err == nil && authConfig .Username != "" {
142142 useGithubRegistry = useGithubRegistry + fmt .Sprintf (registryUsernameHint , authConfig .Username )
143143 isLoggedIntoGitHub = true
144144 }
145-
145+
146146 // Set registry select options according to logged in status of dockerhub and github
147147 registryOptions := []string {skipRegistry , useDockerHub , useGithubRegistry , useOtherRegistry }
148148 if isLoggedIntoGitHub {
@@ -152,7 +152,7 @@ func (m *manager) AddImage(imageName, image, projectNamespace, dockerfile string
152152 registryDefaultOption = useDockerHub
153153 registryOptions = []string {useDockerHub , useGithubRegistry , useOtherRegistry , skipRegistry }
154154 }
155-
155+
156156 selectedRegistry , err := m .log .Question (& survey.QuestionOptions {
157157 Question : "If you were to push any images, which container registry would you want to push to?" ,
158158 DefaultValue : registryDefaultOption ,
@@ -161,7 +161,7 @@ func (m *manager) AddImage(imageName, image, projectNamespace, dockerfile string
161161 if err != nil {
162162 return err
163163 }
164-
164+
165165 if selectedRegistry == skipRegistry {
166166 imageConfig .Image = "my-image-registry.tld/username" + "/" + imageName
167167 } else {
@@ -174,48 +174,48 @@ func (m *manager) AddImage(imageName, image, projectNamespace, dockerfile string
174174 registryHostname , err = m .log .Question (& survey.QuestionOptions {
175175 Question : "Please provide the registry hostname without the image path (e.g. gcr.io, ghcr.io, ecr.io)" ,
176176 DefaultValue : "gcr.io" ,
177- ValidationRegexPattern : "^(?!-) [a-z0-9-]{1,63 }(\\ .[a-z0-9-]{1,63})*$" ,
177+ ValidationRegexPattern : `^[a-z0-9] [a-z0-9-]{0,62 }(\.[a-z0-9-]{1,63})*$` ,
178178 ValidationMessage : "Error parsing registry hostname: must only include letters, digits, dots and hyphens and cannot exceed 253 characters." ,
179179 })
180180 if err != nil {
181181 return err
182182 }
183183 }
184-
184+
185185 registryUsername , err := m .addPullSecretConfig (dockerClient , strings .Trim (registryHostname + "/username/app" , "/" ))
186186 if err != nil {
187187 return err
188188 }
189-
189+
190190 if registryUsername == "" {
191191 registryUsername = "username"
192192 }
193-
193+
194194 if selectedRegistry == useDockerHub {
195195 imageConfig .Image = registryUsername + "/" + imageName
196196 } else {
197197 if projectNamespace == "" {
198198 projectNamespace = registryUsername
199199 }
200-
200+
201201 if regexp .MustCompile (`^(.+\.)?gcr.io$` ).Match ([]byte (registryHostname )) {
202202 projectNamespace = "project"
203203 project , err := command .Output (context .TODO (), "" , expand .ListEnviron (os .Environ ()... ), "gcloud" , "config" , "get-value" , "project" )
204204 if err == nil {
205205 projectNamespace = strings .TrimSpace (string (project ))
206206 }
207207 }
208-
208+
209209 imageConfig .Image = registryHostname + "/" + projectNamespace + "/" + imageName
210210 }
211211 }
212212 }
213-
213+
214214 if buildMethod == skip {
215215 imageConfig .Image = "username/app"
216216 imageConfig .Dockerfile = "./Dockerfile"
217217 }
218-
218+
219219 m .config .Images [imageName ] = imageConfig
220220 return nil
221221}
@@ -226,50 +226,50 @@ func (m *manager) addPullSecretConfig(dockerClient docker.Client, image string)
226226 if err != nil {
227227 return "" , err
228228 }
229-
229+
230230 registryHostname , err := pullsecrets .GetRegistryFromImageName (image )
231231 if err != nil {
232232 return "" , err
233233 }
234-
234+
235235 registryHostnamePrintable := registryHostname
236236 if registryHostnamePrintable == "" {
237237 registryHostnamePrintable = dockerHubHostname
238238 }
239-
239+
240240 usernameQuestion := fmt .Sprintf ("What is your username for %s? (optional, Enter to skip)" , registryHostnamePrintable )
241241 passwordQuestion := fmt .Sprintf ("What is your password for %s? (optional, Enter to skip)" , registryHostnamePrintable )
242242 if strings .Contains (registryHostname , "ghcr.io" ) || strings .Contains (registryHostname , "github.com" ) {
243243 usernameQuestion = "What is your GitHub username? (optional, Enter to skip)"
244244 passwordQuestion = "Please enter a GitHub personal access token (optional, Enter to skip)"
245245 }
246-
246+
247247 registryUsername := ""
248248 registryPassword := ""
249249 retry := false
250-
250+
251251 m .log .WriteString (logrus .WarnLevel , "\n " )
252-
252+
253253 for {
254254 m .log .Info ("Checking registry authentication for " + registryHostnamePrintable + "..." )
255255 authConfig , err := dockerClient .Login (context .TODO (), registryHostname , registryUsername , registryPassword , true , retry , retry )
256256 if err == nil && (authConfig .Username != "" || authConfig .Password != "" ) {
257257 registryUsername = authConfig .Username
258-
258+
259259 m .log .Donef ("Great! You are authenticated with %s" , registryHostnamePrintable )
260260 break
261261 }
262-
262+
263263 m .log .WriteString (logrus .WarnLevel , "\n " )
264264 m .log .Warnf ("Unable to find registry credentials for %s" , registryHostnamePrintable )
265265 m .log .Warnf ("Running `%s` for you to authenticate with the registry (optional)" , strings .TrimSpace ("docker login " + registryHostname ))
266-
266+
267267 registryUsername , err = m .log .Question (& survey.QuestionOptions {
268268 Question : usernameQuestion ,
269269 ValidationRegexPattern : "^[^A-Z\\ s]+\\ .[^A-Z\\ s]+$" ,
270270 ValidationMessage : "Error parsing registry username: must only include lowercase letters." ,
271271 })
272-
272+
273273 if err != nil {
274274 return "" , err
275275 }
@@ -283,46 +283,46 @@ func (m *manager) addPullSecretConfig(dockerClient docker.Client, image string)
283283 return "" , err
284284 }
285285 }
286-
286+
287287 m .log .WriteString (logrus .WarnLevel , "\n " )
288-
288+
289289 // Check if docker is running
290290 _ , runErr := command .Output (context .TODO (), "" , expand .ListEnviron (os .Environ ()... ), "docker" , "version" )
291-
291+
292292 // If Docker is available, ask if we should retry registry login
293293 if runErr == nil && registryUsername != "" {
294294 retry = true
295295 }
296-
296+
297297 if ! retry {
298298 m .log .Warn ("Skip validating image registry credentials." )
299299 m .log .Warn ("You may ignore this warning. Pushing images to a registry is *not* required." )
300-
300+
301301 usernameVar := "REGISTRY_USERNAME"
302302 passwordVar := "REGISTRY_PASSWORD"
303-
303+
304304 m .config .PullSecrets = map [string ]* latest.PullSecretConfig {
305305 encoding .Convert (registryHostname ): {
306306 Registry : registryHostname ,
307307 Username : fmt .Sprintf ("${%s}" , usernameVar ),
308308 Password : fmt .Sprintf ("${%s}" , passwordVar ),
309309 },
310310 }
311-
311+
312312 if m .config .Vars == nil {
313313 m .config .Vars = map [string ]* latest.Variable {}
314314 }
315315 m .config .Vars [passwordVar ] = & latest.Variable {
316316 Name : passwordVar ,
317317 Password : true ,
318318 }
319-
319+
320320 m .localCache .SetVar (usernameVar , registryUsername )
321321 m .localCache .SetVar (passwordVar , registryPassword )
322-
322+
323323 break
324324 }
325325 }
326-
326+
327327 return registryUsername , nil
328328}
0 commit comments