Skip to content

Commit f3ab2d2

Browse files
author
Sujit Kamireddy
committed
bring back deploy changes lost due to merge conflicts
1 parent a95e826 commit f3ab2d2

1 file changed

Lines changed: 103 additions & 4 deletions

File tree

  • cli/azd/extensions/azure.ai.rle/internal/cmd

cli/azd/extensions/azure.ai.rle/internal/cmd/deploy.go

Lines changed: 103 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@ import (
88
"errors"
99
"fmt"
1010
"os"
11+
"os/exec"
12+
"strings"
1113

1214
"github.com/azure/azure-dev/cli/azd/pkg/azdext"
1315
"github.com/spf13/cobra"
1416
)
1517

1618
type rleDeployFlags struct {
17-
project string
18-
image string
19+
project string
20+
image string
21+
registry string
22+
skipBuild bool
1923
}
2024

2125
func newDeployCommand() *cobra.Command {
@@ -97,6 +101,23 @@ func newDeployCommand() *cobra.Command {
97101
image = defaultRegistryLoginServer + "/" + slug(state.Name) + ":latest"
98102
}
99103

104+
// Host-qualify the image so the control plane / ADC can pull it: the disk-image
105+
// conversion uses the image reference verbatim as the pull source, so a bare
106+
// "name:tag" is rewritten to "<registry-login-server>/name:tag".
107+
loginServer, repoTag := splitImageHost(image)
108+
if loginServer == "" {
109+
loginServer = normalizeRegistryLoginServer(flags.registry)
110+
}
111+
if loginServer == "" {
112+
return &azdext.LocalError{
113+
Message: "No container registry was specified for the environment image.",
114+
Code: "rle_registry_required",
115+
Category: azdext.LocalErrorCategoryUser,
116+
Suggestion: "Pass --registry <name> (e.g. devrle) or use a host-qualified image reference.",
117+
}
118+
}
119+
image = loginServer + "/" + repoTag
120+
100121
environmentId := firstNonEmpty(state.EnvironmentId, slug(state.Name))
101122
client := newRleClient(resolveControlPlaneEndpoint(""))
102123
request := v1EnvironmentRequest{
@@ -111,8 +132,41 @@ func newDeployCommand() *cobra.Command {
111132
action = "Updating"
112133
}
113134

114-
if _, err := fmt.Fprintf(cmd.OutOrStdout(), "Skipping build; using existing image '%s'.\n", image); err != nil {
115-
return err
135+
// Build the local Dockerfile and push it to the registry before registering, so the
136+
// environment always points at an image that actually exists in the target ACR.
137+
registryName := registryShortName(loginServer)
138+
switch {
139+
case flags.skipBuild:
140+
if _, err := fmt.Fprintf(cmd.OutOrStdout(),
141+
"Skipping build (--skip-build); using image '%s'.\n", image); err != nil {
142+
return err
143+
}
144+
case !fileExists("Dockerfile"):
145+
if _, err := fmt.Fprintf(cmd.OutOrStdout(),
146+
"No Dockerfile in current directory; skipping build and using image '%s'.\n", image); err != nil {
147+
return err
148+
}
149+
default:
150+
if _, err := fmt.Fprintf(cmd.OutOrStdout(),
151+
"Building and pushing '%s' to registry '%s' (az acr build) ...\n",
152+
repoTag, registryName); err != nil {
153+
return err
154+
}
155+
build := exec.CommandContext(cmd.Context(),
156+
"az", "acr", "build", "--registry", registryName, "--image", repoTag, ".")
157+
build.Stdout = cmd.OutOrStdout()
158+
build.Stderr = cmd.ErrOrStderr()
159+
if err := build.Run(); err != nil {
160+
return &azdext.LocalError{
161+
Message: fmt.Sprintf(
162+
"Failed to build and push image '%s' to registry '%s': %v",
163+
repoTag, registryName, err),
164+
Code: "rle_acr_build_failed",
165+
Category: azdext.LocalErrorCategoryUser,
166+
Suggestion: "Ensure 'az login' is done, you have push access to the registry, " +
167+
"and a valid Dockerfile is present. Use --skip-build to register a prebuilt image.",
168+
}
169+
}
116170
}
117171

118172
if _, err := fmt.Fprintf(cmd.OutOrStdout(), "%s environment '%s' (image=%s) ...\n", action, state.Name, image); err != nil {
@@ -178,9 +232,54 @@ func newDeployCommand() *cobra.Command {
178232
"RLE project name. Defaults to the project saved in .azd-rle.json.")
179233
cmd.Flags().StringVar(&flags.image, "image", "",
180234
"Image reference to deploy (overrides the per-environment default derived from the environment name)")
235+
cmd.Flags().StringVar(&flags.registry, "registry", "devrle",
236+
"Container registry (short name or login server) to build and push the environment image into")
237+
cmd.Flags().BoolVar(&flags.skipBuild, "skip-build", false,
238+
"Skip building/pushing the image and register the existing image reference as-is")
181239
return cmd
182240
}
183241

242+
// splitImageHost splits a container image reference into its registry host (login server)
243+
// and the remaining repository:tag. The leading segment is treated as a host only when it
244+
// looks like one (contains '.' or ':' or is "localhost"); otherwise there is no host.
245+
func splitImageHost(image string) (host string, repoTag string) {
246+
image = strings.TrimSpace(image)
247+
if slash := strings.IndexByte(image, '/'); slash > 0 {
248+
first := image[:slash]
249+
if first == "localhost" || strings.ContainsAny(first, ".:") {
250+
return first, image[slash+1:]
251+
}
252+
}
253+
return "", image
254+
}
255+
256+
// normalizeRegistryLoginServer turns a registry short name ("devrle") into a login server
257+
// ("devrle.azurecr.io"). A value that already contains a '.' is assumed to be a login server.
258+
func normalizeRegistryLoginServer(registry string) string {
259+
registry = strings.TrimSpace(registry)
260+
if registry == "" {
261+
return ""
262+
}
263+
if strings.Contains(registry, ".") {
264+
return registry
265+
}
266+
return registry + ".azurecr.io"
267+
}
268+
269+
// registryShortName returns the ACR short name (the part before ".azurecr.io") for use with
270+
// "az acr build --registry".
271+
func registryShortName(loginServer string) string {
272+
if host, _, ok := strings.Cut(loginServer, "."); ok {
273+
return host
274+
}
275+
return loginServer
276+
}
277+
278+
func fileExists(path string) bool {
279+
info, err := os.Stat(path)
280+
return err == nil && !info.IsDir()
281+
}
282+
184283
type environmentOutput struct {
185284
Id string `json:"id"`
186285
ProjectId string `json:"projectId"`

0 commit comments

Comments
 (0)