Skip to content

Commit

Permalink
fix panic when inferring stack with empty image
Browse files Browse the repository at this point in the history
Signed-off-by: Andrea Falzetti <andrea@okteto.com>
  • Loading branch information
andreafalzetti committed May 23, 2024
1 parent 98675e6 commit f54f07d
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 4 deletions.
25 changes: 21 additions & 4 deletions pkg/model/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import (
oktetoLog "github.com/okteto/okteto/pkg/log"
"github.com/okteto/okteto/pkg/model/forward"
"github.com/spf13/afero"
yaml "gopkg.in/yaml.v2"
"gopkg.in/yaml.v2"
yaml3 "gopkg.in/yaml.v3"
)

Expand Down Expand Up @@ -1052,14 +1052,31 @@ func (m *Manifest) InferFromStack(cwd string) (*Manifest, error) {

svcInfo.Build = buildInfo
} else {
if buildInfo == nil {
buildInfo = &build.Info{}
}

if svcInfo.Image != "" {
buildInfo.Image = svcInfo.Image
}

buildInfo.Context, err = filepath.Rel(cwd, buildInfo.Context)
if err != nil {
oktetoLog.Infof("can not make svc[%s].build.context relative to cwd", svcName)
if len(svcInfo.VolumeMounts) > 0 {
context, err := getBuildContextForComposeWithVolumeMounts(m)
if err != nil {
return nil, err
}

buildInfo.VolumesToInclude = svcInfo.VolumeMounts
buildInfo.Context = context
}

if buildInfo.Context == "" {
buildInfo.Context, err = filepath.Rel(cwd, buildInfo.Context)
if err != nil {
oktetoLog.Infof("can not make svc[%s].build.context relative to cwd", svcName)
}
}

contextAbs := filepath.Join(cwd, buildInfo.Context)
buildInfo.Dockerfile, err = filepath.Rel(contextAbs, buildInfo.Dockerfile)
if err != nil {
Expand Down
120 changes: 120 additions & 0 deletions pkg/model/manifest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,51 @@ func TestInferFromStack(t *testing.T) {
},
},
},
{
name: "infer from stack empty build section and empty image",
currentManifest: &Manifest{
Deploy: &DeployInfo{
Image: constants.OktetoPipelineRunnerImage,
ComposeSection: &ComposeSectionInfo{
Stack: &Stack{
Services: map[string]*Service{
"test": {
Build: nil,
Image: "",
Ports: []Port{
{
HostPort: 8080,
ContainerPort: 8080,
},
},
},
},
},
},
},
},
expectedManifest: &Manifest{
Destroy: &DestroyInfo{},
Deploy: &DeployInfo{
Image: constants.OktetoPipelineRunnerImage,
ComposeSection: &ComposeSectionInfo{
Stack: &Stack{
Services: map[string]*Service{
"test": {
Image: "",
Ports: []Port{
{
HostPort: 8080,
ContainerPort: 8080,
},
},
},
},
},
},
},
},
},
}

for _, tt := range tests {
Expand Down Expand Up @@ -886,6 +931,81 @@ func TestInferFromStackWithVolumeMounts(t *testing.T) {
require.Equal(t, expected, string(dockerfileContent))
}

func TestInferFromStackWithVolumeMountsAndEmptyBuildAndImage(t *testing.T) {
dirtest := filepath.Clean("/stack/dir/")
fs := afero.NewMemMapFs()

oktetoHome, err := filepath.Abs("./tmp/tests")
require.NoError(t, err)
err = fs.MkdirAll(oktetoHome, 0700)
require.NoError(t, err)

// Set the Okteto home to facilitate where the dockerfile will be created
t.Setenv(constants.OktetoFolderEnvVar, oktetoHome)

expectedContext, err := filepath.Abs(".")
require.NoError(t, err)

currentManifest := &Manifest{
Fs: fs,
Dev: ManifestDevs{},
Build: build.ManifestBuild{},
Deploy: &DeployInfo{
Image: constants.OktetoPipelineRunnerImage,
ComposeSection: &ComposeSectionInfo{
Stack: &Stack{
Services: map[string]*Service{
"test": {
Image: "",
VolumeMounts: []build.VolumeMounts{
{
LocalPath: "./nginx.conf",
RemotePath: "/etc/nginx/nginx.conf",
},
},
Ports: []Port{
{
HostPort: 8080,
ContainerPort: 8080,
},
},
},
},
},
},
},
}

expectedVolumesToInclude := []build.VolumeMounts{
{
LocalPath: "./nginx.conf",
RemotePath: "/etc/nginx/nginx.conf",
},
}

result, err := currentManifest.InferFromStack(filepath.Clean(dirtest))
require.NoError(t, err)

testBuildSection := result.Build["test"]
require.Equal(t, expectedContext, testBuildSection.Context)
require.True(t, strings.HasPrefix(testBuildSection.Dockerfile, filepath.Join(oktetoHome, ".dockerfile", "buildkit-")))
require.Empty(t, testBuildSection.Image)
require.ElementsMatch(t, expectedVolumesToInclude, testBuildSection.VolumesToInclude)

serviceSection := result.Deploy.ComposeSection.Stack.Services["test"]
require.Equal(t, expectedContext, serviceSection.Build.Context)
require.True(t, strings.HasPrefix(serviceSection.Build.Dockerfile, filepath.Join(oktetoHome, ".dockerfile", "buildkit-")))
require.Empty(t, serviceSection.Build.Image)
require.ElementsMatch(t, expectedVolumesToInclude, serviceSection.Build.VolumesToInclude)

dockerfileContent, err := afero.ReadFile(fs, testBuildSection.Dockerfile)
require.NoError(t, err)

// Ensure Dockerfile was generated as it is expected in this scenario
expected := "FROM okteto.dev/test:my-tag\nCOPY ./nginx.conf /etc/nginx/nginx.conf\n"
require.Equal(t, expected, string(dockerfileContent))
}

func TestSetManifestDefaultsFromDev(t *testing.T) {
t.Setenv("my_key", "my_value")
tests := []struct {
Expand Down

0 comments on commit f54f07d

Please sign in to comment.