Adds support for environment variable substitution for source container image (#4254)

Fixes: #4124
This commit is contained in:
Wallace Breza 2024-08-27 10:23:39 -07:00 коммит произвёл GitHub
Родитель 6220b73ca8
Коммит fef0c5cf7d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
9 изменённых файлов: 22 добавлений и 13 удалений

Просмотреть файл

@ -352,7 +352,7 @@ func Test_ContainerHelper_Deploy(t *testing.T) {
)
serviceConfig := createTestServiceConfig("./src/api", ContainerAppTarget, ServiceLanguageTypeScript)
serviceConfig.Image = tt.image
serviceConfig.Image = osutil.NewExpandableString(tt.image)
serviceConfig.RelativePath = tt.project
serviceConfig.Docker.Registry = tt.registry
@ -521,7 +521,7 @@ func Test_ContainerHelper_ConfiguredImage(t *testing.T) {
if tt.serviceName != "" {
serviceConfig.Name = tt.serviceName
}
serviceConfig.Image = tt.sourceImage
serviceConfig.Image = osutil.NewExpandableString(tt.sourceImage)
serviceConfig.Docker.Registry = tt.registry
serviceConfig.Docker.Image = tt.image
serviceConfig.Docker.Tag = tt.tag

Просмотреть файл

@ -345,7 +345,12 @@ func (p *dockerProject) Package(
// If we don't have an image ID from a docker build then an external source image is being used
if imageId == "" {
sourceImage, err := docker.ParseContainerImage(serviceConfig.Image)
sourceImageValue, err := serviceConfig.Image.Envsubst(p.env.Getenv)
if err != nil {
return nil, fmt.Errorf("substituting environment variables in image: %w", err)
}
sourceImage, err := docker.ParseContainerImage(sourceImageValue)
if err != nil {
return nil, fmt.Errorf("parsing source container image: %w", err)
}

Просмотреть файл

@ -392,7 +392,7 @@ func Test_DockerProject_Build(t *testing.T) {
serviceConfig := createTestServiceConfig(tt.project, ContainerAppTarget, tt.language)
serviceConfig.Project.Path = temp
serviceConfig.Docker = tt.dockerOptions
serviceConfig.Image = tt.image
serviceConfig.Image = osutil.NewExpandableString(tt.image)
if tt.hasDockerFile {
err := os.MkdirAll(serviceConfig.Path(), osutil.PermissionDirectory)
@ -536,7 +536,7 @@ func Test_DockerProject_Package(t *testing.T) {
// Set the custom test options
serviceConfig.Docker = tt.docker
serviceConfig.RelativePath = tt.project
serviceConfig.Image = tt.image
serviceConfig.Image = osutil.NewExpandableString(tt.image)
if serviceConfig.RelativePath != "" {
npmProject := NewNpmProject(npm.NewCli(mockContext.CommandRunner), env)
@ -544,7 +544,10 @@ func Test_DockerProject_Package(t *testing.T) {
}
buildOutputPath := ""
if serviceConfig.Image == "" && serviceConfig.RelativePath != "" {
sourceImage, err := serviceConfig.Image.Envsubst(env.Getenv)
require.NoError(t, err)
if sourceImage == "" && serviceConfig.RelativePath != "" {
buildOutputPath = "IMAGE_ID"
}

Просмотреть файл

@ -106,7 +106,7 @@ func Parse(ctx context.Context, yamlContent string) (*ProjectConfig, error) {
// TODO: Move parsing/validation requirements for service targets into their respective components.
// When working within container based applications users may be using external/pre-built images instead of source
// In this case it is valid to have not specified a language but would be required to specify a source image
if svc.Host == ContainerAppTarget && svc.Language == ServiceLanguageNone && svc.Image == "" {
if svc.Host == ContainerAppTarget && svc.Language == ServiceLanguageNone && svc.Image.Empty() {
return nil, fmt.Errorf("parsing service %s: must specify language or image", svc.Name)
}
}

Просмотреть файл

@ -27,7 +27,7 @@ type ServiceConfig struct {
// The output path for build artifacts
OutputPath string `yaml:"dist,omitempty"`
// The source image to use for container based applications
Image string `yaml:"image,omitempty"`
Image osutil.ExpandableString `yaml:"image,omitempty"`
// The optional docker options for configuring the output image
Docker DockerProjectOptions `yaml:"docker,omitempty"`
// The optional K8S / AKS options

Просмотреть файл

@ -530,7 +530,7 @@ func (sm *serviceManager) GetFrameworkService(ctx context.Context, serviceConfig
var frameworkService FrameworkService
// Publishing from an existing image currently follows the same lifecycle as a docker project
if serviceConfig.Language == ServiceLanguageNone && serviceConfig.Image != "" {
if serviceConfig.Language == ServiceLanguageNone && !serviceConfig.Image.Empty() {
serviceConfig.Language = ServiceLanguageDocker
}

Просмотреть файл

@ -16,6 +16,7 @@ import (
"github.com/azure/azure-dev/cli/azd/pkg/environment"
"github.com/azure/azure-dev/cli/azd/pkg/exec"
"github.com/azure/azure-dev/cli/azd/pkg/ext"
"github.com/azure/azure-dev/cli/azd/pkg/osutil"
"github.com/azure/azure-dev/cli/azd/pkg/tools"
"github.com/azure/azure-dev/cli/azd/test/mocks"
"github.com/azure/azure-dev/cli/azd/test/mocks/mockarmresources"
@ -240,7 +241,7 @@ func Test_ServiceManager_GetFrameworkService(t *testing.T) {
env := environment.New("test")
sm := createServiceManager(mockContext, env, ServiceOperationCache{})
serviceConfig := createTestServiceConfig("", ServiceTargetFake, ServiceLanguageNone)
serviceConfig.Image = "nginx"
serviceConfig.Image = osutil.NewExpandableString("nginx")
framework, err := sm.GetFrameworkService(*mockContext.Context, serviceConfig)
require.NoError(t, err)

Просмотреть файл

@ -85,7 +85,7 @@
},
"image": {
"type": "string",
"title": "Optional. The source image to be used for the container image instead of building from source.",
"title": "Optional. The source image to be used for the container image instead of building from source. Supports environment variable substitution.",
"description": "If omitted, container image will be built from source specified in the 'project' property. Setting both 'project' and 'image' is invalid."
},
"host": {

Просмотреть файл

@ -78,9 +78,9 @@
"type": "string",
"title": "Path to the service source code directory"
},
"image": {
"image": {
"type": "string",
"title": "Optional. The source image to be used for the container image instead of building from source.",
"title": "Optional. The source image to be used for the container image instead of building from source. Supports environment variable substitution.",
"description": "If omitted, container image will be built from source specified in the 'project' property. Setting both 'project' and 'image' is invalid."
},
"host": {