Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package okteto for openSUSE:Factory checked in at 2023-08-09 17:25:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/okteto (Old) and /work/SRC/openSUSE:Factory/.okteto.new.11712 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "okteto" Wed Aug 9 17:25:02 2023 rev:58 rq:1102919 version:2.18.2 Changes: -------- --- /work/SRC/openSUSE:Factory/okteto/okteto.changes 2023-08-06 16:30:23.844005446 +0200 +++ /work/SRC/openSUSE:Factory/.okteto.new.11712/okteto.changes 2023-08-09 17:25:08.469338390 +0200 @@ -1,0 +2,7 @@ +Tue Aug 08 14:08:51 UTC 2023 - ka...@b1-systems.de + +- Update to version 2.18.2: + * fix: compose not getting image expansion from build (#3890) + (#3892) + +------------------------------------------------------------------- Old: ---- okteto-2.18.1.obscpio New: ---- okteto-2.18.2.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ okteto.spec ++++++ --- /var/tmp/diff_new_pack.Ljx0Un/_old 2023-08-09 17:25:09.745346334 +0200 +++ /var/tmp/diff_new_pack.Ljx0Un/_new 2023-08-09 17:25:09.749346359 +0200 @@ -19,7 +19,7 @@ %define __arch_install_post export NO_BRP_STRIP_DEBUG=true Name: okteto -Version: 2.18.1 +Version: 2.18.2 Release: 0 Summary: Develop your applications directly in your Kubernetes Cluster License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.Ljx0Un/_old 2023-08-09 17:25:09.777346534 +0200 +++ /var/tmp/diff_new_pack.Ljx0Un/_new 2023-08-09 17:25:09.785346583 +0200 @@ -3,10 +3,10 @@ <param name="url">https://github.com/okteto/okteto</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">2.18.1</param> + <param name="revision">2.18.2</param> <param name="versionformat">@PARENT_TAG@</param> <param name="changesgenerate">enable</param> - <param name="match-tag">2.18.1</param> + <param name="match-tag">2.18.2</param> </service> <service name="set_version" mode="disabled"> <param name="basename">okteto</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.Ljx0Un/_old 2023-08-09 17:25:09.801346683 +0200 +++ /var/tmp/diff_new_pack.Ljx0Un/_new 2023-08-09 17:25:09.805346708 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/okteto/okteto</param> - <param name="changesrevision">b49c71d933ab7241c45957c9cf66eb373e566a0c</param></service></servicedata> + <param name="changesrevision">61a36008866f51293ec03020e2bd45017f257edc</param></service></servicedata> (No newline at EOF) ++++++ okteto-2.18.1.obscpio -> okteto-2.18.2.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/okteto-2.18.1/cmd/deploy/deploy.go new/okteto-2.18.2/cmd/deploy/deploy.go --- old/okteto-2.18.1/cmd/deploy/deploy.go 2023-08-04 12:31:05.000000000 +0200 +++ new/okteto-2.18.2/cmd/deploy/deploy.go 2023-08-08 12:27:22.000000000 +0200 @@ -278,7 +278,7 @@ oktetoLog.SetStage("Load manifest") manifest, err := dc.GetManifest(deployOptions.ManifestPath) if err != nil { - return err + return fmt.Errorf("failed to load manifest: %w", err) } deployOptions.Manifest = manifest oktetoLog.Debug("found okteto manifest") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/okteto-2.18.1/integration/commands/deploy.go new/okteto-2.18.2/integration/commands/deploy.go --- old/okteto-2.18.1/integration/commands/deploy.go 2023-08-04 12:31:05.000000000 +0200 +++ new/okteto-2.18.2/integration/commands/deploy.go 2023-08-08 12:27:22.000000000 +0200 @@ -14,7 +14,6 @@ package commands import ( - "bufio" "fmt" "log" "os" @@ -52,28 +51,21 @@ IsRemote bool } -// RunOktetoDeploy runs an okteto deploy command -func RunOktetoDeploy(oktetoPath string, deployOptions *DeployOptions) error { +// GetOktetoDeployCmdOutput runs an okteto deploy command +func GetOktetoDeployCmdOutput(oktetoPath string, deployOptions *DeployOptions) ([]byte, error) { cmd := getDeployCmd(oktetoPath, deployOptions) log.Printf("Running '%s'", cmd.String()) - stdout, err := cmd.StdoutPipe() + output, err := cmd.CombinedOutput() if err != nil { - log.Printf("error getting stdout pipe: %s", err) - return err + return output, err } - if err := cmd.Start(); err != nil { - return err - } - go func() { - - scanner := bufio.NewScanner(stdout) - // optionally, resize scanner's capacity for lines over 64K, see next example - for scanner.Scan() { - log.Println(scanner.Text()) - } - }() - err = cmd.Wait() log.Printf("okteto deploy success") + return output, nil +} + +// RunOktetoDeploy runs an okteto deploy command +func RunOktetoDeploy(oktetoPath string, deployOptions *DeployOptions) error { + _, err := GetOktetoDeployCmdOutput(oktetoPath, deployOptions) return err } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/okteto-2.18.1/integration/deploy/compose_test.go new/okteto-2.18.2/integration/deploy/compose_test.go --- old/okteto-2.18.1/integration/deploy/compose_test.go 2023-08-04 12:31:05.000000000 +0200 +++ new/okteto-2.18.2/integration/deploy/compose_test.go 2023-08-08 12:27:22.000000000 +0200 @@ -22,6 +22,7 @@ "log" "os" "path/filepath" + "strings" "testing" "github.com/okteto/okteto/integration" @@ -109,7 +110,7 @@ ` composeTemplateByManifest2 = `services: app: - image: okteto.dev/app:okteto + image: ${OKTETO_BUILD_APP_IMAGE} entrypoint: python -m http.server 8080 ports: - 8080 @@ -500,6 +501,54 @@ _, err = integration.GetService(context.Background(), testNamespace, "nginx", c) require.True(t, k8sErrors.IsNotFound(err)) } +func TestComposeDependsOnNonExistingService(t *testing.T) { + t.Parallel() + oktetoPath, err := integration.GetOktetoPath() + require.NoError(t, err) + + dir := t.TempDir() + + composePath := filepath.Join(dir, "docker-compose.yml") + composeContent := []byte(` +services: + app: + image: alpine + depends_on: + - nginx +`) + err = os.WriteFile(composePath, composeContent, 0600) + require.NoError(t, err) + + testNamespace := integration.GetTestNamespace("TestNotPanic", user) + namespaceOpts := &commands.NamespaceOptions{ + Namespace: testNamespace, + OktetoHome: dir, + Token: token, + } + require.NoError(t, commands.RunOktetoCreateNamespace(oktetoPath, namespaceOpts)) + defer commands.RunOktetoDeleteNamespace(oktetoPath, namespaceOpts) + + deployOptions := &commands.DeployOptions{ + Workdir: dir, + Namespace: testNamespace, + OktetoHome: dir, + Token: token, + } + output, err := commands.GetOktetoDeployCmdOutput(oktetoPath, deployOptions) + require.Error(t, err) + require.Contains(t, strings.ToLower(string(output)), "invalid depends_on: service 'app' depends on service 'nginx' which is undefined.") + + deployOptionsWithFile := &commands.DeployOptions{ + Workdir: dir, + Namespace: testNamespace, + OktetoHome: dir, + Token: token, + ManifestPath: "docker-compose.yml", + } + output, err = commands.GetOktetoDeployCmdOutput(oktetoPath, deployOptionsWithFile) + require.Error(t, err) + require.Contains(t, strings.ToLower(string(output)), "invalid depends_on: service 'app' depends on service 'nginx' which is undefined.") +} func createComposeScenarioByManifest(dir string) error { if err := os.Mkdir(filepath.Join(dir, "nginx"), 0700); err != nil { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/okteto-2.18.1/pkg/cmd/stack/deploy.go new/okteto-2.18.2/pkg/cmd/stack/deploy.go --- old/okteto-2.18.1/pkg/cmd/stack/deploy.go 2023-08-04 12:31:05.000000000 +0200 +++ new/okteto-2.18.2/pkg/cmd/stack/deploy.go 2023-08-08 12:27:22.000000000 +0200 @@ -863,6 +863,9 @@ return fmt.Errorf("service '%s' is not defined. Defined services are: [%s]", svcToDeploy, strings.Join(definedSvcs, ", ")) } } + if err := s.Services.ValidateDependsOn(servicesToDeploy); err != nil { + return err + } return nil } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/okteto-2.18.1/pkg/model/manifest.go new/okteto-2.18.2/pkg/model/manifest.go --- old/okteto-2.18.1/pkg/model/manifest.go 2023-08-04 12:31:05.000000000 +0200 +++ new/okteto-2.18.2/pkg/model/manifest.go 2023-08-08 12:27:22.000000000 +0200 @@ -411,7 +411,8 @@ for _, composeInfo := range stackManifest.Deploy.ComposeSection.ComposesInfo { composeFiles = append(composeFiles, composeInfo.File) } - s, stackErr := LoadStack("", composeFiles, true) + // We need to ensure that LoadStack has false because we don't want to expand env vars + s, stackErr := LoadStack("", composeFiles, false) if stackErr != nil { // if err is from validation, then return the stackErr if errors.Is(stackErr, errDependsOn) { @@ -441,7 +442,8 @@ stackFiles = append(stackFiles, composeInfo.File) } // LoadStack should perform validation of the stack read from the file on compose section - s, err := LoadStack("", stackFiles, true) + // We need to ensure that LoadStack has false because we don't want to expand env vars + s, err := LoadStack("", stackFiles, false) if err != nil { return nil, err } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/okteto-2.18.1/pkg/model/manifest_test.go new/okteto-2.18.2/pkg/model/manifest_test.go --- old/okteto-2.18.1/pkg/model/manifest_test.go 2023-08-04 12:31:05.000000000 +0200 +++ new/okteto-2.18.2/pkg/model/manifest_test.go 2023-08-08 12:27:22.000000000 +0200 @@ -875,16 +875,6 @@ composeBytes: nil, expectedErr: discovery.ErrOktetoManifestNotFound, }, - { - name: "manifestPath to a invalid compose file - depends_on error", - manifestBytes: nil, - composeBytes: []byte(`services: - api: - image: test - depends_on: - - frontend`), - expectedErr: errDependsOn, - }, } for _, tt := range tests { tt := tt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/okteto-2.18.1/pkg/model/stack.go new/okteto-2.18.2/pkg/model/stack.go --- old/okteto-2.18.1/pkg/model/stack.go 2023-08-04 12:31:05.000000000 +0200 +++ new/okteto-2.18.2/pkg/model/stack.go 2023-08-08 12:27:22.000000000 +0200 @@ -39,7 +39,7 @@ var ( errBadStackName = "must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character" deprecatedManifests = []string{"stack.yml", "stack.yaml"} - errDependsOn = errors.New("Invalid depends_on") + errDependsOn = errors.New("invalid depends_on") ) // Stack represents an okteto stack @@ -59,6 +59,14 @@ // ComposeServices represents the services declared in the compose type ComposeServices map[string]*Service +func (cs ComposeServices) getNames() []string { + names := []string{} + for k := range cs { + names = append(names, k) + } + return names +} + // Service represents an okteto stack service type Service struct { Build *BuildInfo `yaml:"build,omitempty"` @@ -478,7 +486,7 @@ } svc.ignoreSyncVolumes() } - return validateDependsOn(s) + return s.Services.ValidateDependsOn(s.Services.getNames()) } // validateStackName checks if the name is compliant @@ -496,22 +504,51 @@ return nil } -func validateDependsOn(s *Stack) error { - for svcName, svc := range s.Services { +type errDependsOnItself struct { + service string +} + +func (e *errDependsOnItself) Error() string { + return fmt.Sprintf("%s: Service '%s' depends cannot depend of itself.", errDependsOn.Error(), e.service) +} + +func (e *errDependsOnItself) Unwrap() error { + return errDependsOn +} + +type errDependsOnUndefined struct { + svc string + dependentSvc string +} + +func (e *errDependsOnUndefined) Error() string { + return fmt.Sprintf("%s: Service '%s' depends on service '%s' which is undefined.", errDependsOn.Error(), e.svc, e.dependentSvc) +} + +func (e *errDependsOnUndefined) Unwrap() error { + return errDependsOn +} + +func (cs ComposeServices) ValidateDependsOn(svcs []string) error { + for _, svcName := range svcs { + svc, ok := cs[svcName] + if !ok { + return fmt.Errorf("service '%s' is not defined in the stack", svcName) + } for dependentSvc, condition := range svc.DependsOn { if svcName == dependentSvc { - return fmt.Errorf("%w: Service '%s' depends can not depend of itself.", errDependsOn, svcName) + return &errDependsOnItself{service: svcName} } - if _, ok := s.Services[dependentSvc]; !ok { + if _, ok := cs[dependentSvc]; !ok { return fmt.Errorf("%w: Service '%s' depends on service '%s' which is undefined.", errDependsOn, svcName, dependentSvc) } - if condition.Condition == DependsOnServiceCompleted && !s.Services[dependentSvc].IsJob() { + if condition.Condition == DependsOnServiceCompleted && !cs[dependentSvc].IsJob() { return fmt.Errorf("%w: Service '%s' is not a job. Please make sure the 'restart_policy' is not set to 'always' in service '%s' ", errDependsOn, dependentSvc, dependentSvc) } } } - dependencyCycle := getDependentCyclic(s.Services.toGraph()) + dependencyCycle := getDependentCyclic(cs.toGraph()) if len(dependencyCycle) > 0 { svcsDependents := fmt.Sprintf("%s and %s", strings.Join(dependencyCycle[:len(dependencyCycle)-1], ", "), dependencyCycle[len(dependencyCycle)-1]) return fmt.Errorf("%w: There was a cyclic dependendecy between %s.", errDependsOn, svcsDependents) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/okteto-2.18.1/pkg/model/stack_test.go new/okteto-2.18.2/pkg/model/stack_test.go --- old/okteto-2.18.1/pkg/model/stack_test.go 2023-08-04 12:31:05.000000000 +0200 +++ new/okteto-2.18.2/pkg/model/stack_test.go 2023-08-08 12:27:22.000000000 +0200 @@ -1336,3 +1336,88 @@ } } + +func TestValidateServices(t *testing.T) { + tc := []struct { + name string + services ComposeServices + expected error + }{ + { + name: "no cycle - no connections", + services: ComposeServices{ + "a": &Service{}, + "b": &Service{}, + "c": &Service{}, + }, + expected: nil, + }, + { + name: "no cycle - connections", + services: ComposeServices{ + "a": &Service{ + DependsOn: DependsOn{ + "b": DependsOnConditionSpec{}, + }, + }, + "b": &Service{ + DependsOn: DependsOn{ + "c": DependsOnConditionSpec{}, + }, + }, + "c": &Service{}, + }, + expected: nil, + }, + { + name: "cycle - connections itself", + services: ComposeServices{ + "a": &Service{ + DependsOn: DependsOn{ + "a": DependsOnConditionSpec{}, + }, + }, + }, + expected: errDependsOn, + }, + { + name: "no cycle - undefined dependency", + services: ComposeServices{ + "a": &Service{ + DependsOn: DependsOn{ + "b": DependsOnConditionSpec{}, + }, + }, + }, + expected: errDependsOn, + }, + { + name: "cycle - indirect cycle", + services: ComposeServices{ + "a": &Service{ + DependsOn: DependsOn{ + "b": DependsOnConditionSpec{}, + }, + }, + "b": &Service{ + DependsOn: DependsOn{ + "c": DependsOnConditionSpec{}, + }, + }, + "c": &Service{ + DependsOn: DependsOn{ + "a": DependsOnConditionSpec{}, + }, + }, + }, + expected: errDependsOn, + }, + } + for _, tt := range tc { + t.Run(tt.name, func(t *testing.T) { + err := tt.services.ValidateDependsOn(tt.services.getNames()) + assert.ErrorIs(t, err, tt.expected) + }) + } + +} ++++++ okteto.obsinfo ++++++ --- /var/tmp/diff_new_pack.Ljx0Un/_old 2023-08-09 17:25:10.149348850 +0200 +++ /var/tmp/diff_new_pack.Ljx0Un/_new 2023-08-09 17:25:10.153348874 +0200 @@ -1,5 +1,5 @@ name: okteto -version: 2.18.1 -mtime: 1691145065 -commit: b49c71d933ab7241c45957c9cf66eb373e566a0c +version: 2.18.2 +mtime: 1691490442 +commit: 61a36008866f51293ec03020e2bd45017f257edc ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/okteto/vendor.tar.gz /work/SRC/openSUSE:Factory/.okteto.new.11712/vendor.tar.gz differ: char 5, line 1