diff --git a/pkg/devfile/generator/generators.go b/pkg/devfile/generator/generators.go index 55636658..547433e5 100644 --- a/pkg/devfile/generator/generators.go +++ b/pkg/devfile/generator/generators.go @@ -1,5 +1,5 @@ // -// Copyright 2022 Red Hat, Inc. +// Copyright 2022-2023 Red Hat, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -238,6 +238,7 @@ func GetDeployment(devfileObj parser.DevfileObj, deployParams DeploymentParams) // PodTemplateParams is a struct that contains the required data to create a podtemplatespec object type PodTemplateParams struct { ObjectMeta metav1.ObjectMeta + Options common.DevfileOptions // PodSecurityAdmissionPolicy is the policy to be respected by the created pod // The pod will be patched, if necessary, to respect the policies PodSecurityAdmissionPolicy psaapi.Policy @@ -249,8 +250,9 @@ type PodTemplateParams struct { // - gets the init container for every preStart devfile event // - patches the pod template and containers to satisfy PodSecurityAdmissionPolicy // - patches the pod template and containers to apply pod and container overrides +// The containers included in the podTemplateSpec can be filtered using podTemplateParams.Options func GetPodTemplateSpec(devfileObj parser.DevfileObj, podTemplateParams PodTemplateParams) (*corev1.PodTemplateSpec, error) { - containers, err := GetContainers(devfileObj, common.DevfileOptions{}) + containers, err := GetContainers(devfileObj, podTemplateParams.Options) if err != nil { return nil, err } diff --git a/pkg/devfile/generator/generators_test.go b/pkg/devfile/generator/generators_test.go index f3fd7a40..9869672e 100644 --- a/pkg/devfile/generator/generators_test.go +++ b/pkg/devfile/generator/generators_test.go @@ -1,5 +1,5 @@ // -// Copyright 2022 Red Hat, Inc. +// Copyright 2022-2023 Red Hat, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package generator import ( + "errors" "fmt" "reflect" "strings" @@ -24,10 +25,13 @@ import ( "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" v1 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" "github.com/devfile/api/v2/pkg/attributes" + "github.com/devfile/library/v2/pkg/devfile" "github.com/devfile/library/v2/pkg/devfile/parser" + context "github.com/devfile/library/v2/pkg/devfile/parser/context" "github.com/devfile/library/v2/pkg/devfile/parser/data" "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common" "github.com/devfile/library/v2/pkg/testingutil" + "github.com/devfile/library/v2/pkg/testingutil/filesystem" "github.com/devfile/library/v2/pkg/util" "github.com/golang/mock/gomock" "github.com/google/go-cmp/cmp" @@ -1345,6 +1349,53 @@ func TestGetPodTemplateSpec(t *testing.T) { }, wantErr: true, }, + { + name: "GetContainers returns err", + args: args{ + devfileObj: func(ctrl *gomock.Controller) parser.DevfileObj { + mockDevfileData := data.NewMockDevfileData(ctrl) + mockDevfileData.EXPECT().GetComponents(gomock.Any()).Return(nil, errors.New("an error")).AnyTimes() + return parser.DevfileObj{ + Data: mockDevfileData, + } + }, + }, + wantErr: true, + }, + { + name: "GetDevfileContainerComponents returns err", + args: args{ + devfileObj: func(ctrl *gomock.Controller) parser.DevfileObj { + containers := []v1alpha2.Component{ + { + Name: "main", + ComponentUnion: v1.ComponentUnion{ + Container: &v1.ContainerComponent{ + Container: v1.Container{ + Image: "an-image", + }, + }, + }, + Attributes: attributes.Attributes{ + ContainerOverridesAttribute: apiext.JSON{Raw: []byte("{\"spec\": \"serviceAccountName\": \"new-service-account\"}")}, + }, + }, + } + events := v1alpha2.Events{} + mockDevfileData := data.NewMockDevfileData(ctrl) + mockDevfileData.EXPECT().GetComponents(gomock.Any()).Return(containers, nil).AnyTimes() + mockDevfileData.EXPECT().GetProjects(gomock.Any()).Return(nil, nil).AnyTimes() + mockDevfileData.EXPECT().GetEvents().Return(events).AnyTimes() + mockDevfileData.EXPECT().GetDevfileContainerComponents(gomock.Any()).Return(nil, errors.New("an error")).AnyTimes() + mockDevfileData.EXPECT().GetAttributes().Return(attributes.Attributes{}, nil) + mockDevfileData.EXPECT().GetSchemaVersion().Return("2.1.0").AnyTimes() + return parser.DevfileObj{ + Data: mockDevfileData, + } + }, + }, + wantErr: true, + }, { name: "Devfile with local container-override on the first container only", args: args{ @@ -1833,6 +1884,68 @@ func TestGetPodTemplateSpec(t *testing.T) { }, }, }, + { + name: "Filter components by name", + args: args{ + devfileObj: func(ctrl *gomock.Controller) parser.DevfileObj { + containers := []v1alpha2.Component{ + { + Name: "main", + ComponentUnion: v1.ComponentUnion{ + Container: &v1.ContainerComponent{ + Container: v1.Container{ + Image: "an-image", + }, + }, + }, + }, + { + Name: "tools", + ComponentUnion: v1.ComponentUnion{ + Container: &v1.ContainerComponent{ + Container: v1.Container{ + Image: "a-tool-image", + }, + }, + }, + }, + } + parserArgs := parser.ParserArgs{ + Data: []byte(`schemaVersion: 2.2.0`), + } + var err error + devfile, _, err := devfile.ParseDevfileAndValidate(parserArgs) + if err != nil { + t.Errorf("error creating devfile: %v", err) + } + devfile.Ctx = context.FakeContext(filesystem.NewFakeFs(), "/devfile.yaml") + devfile.Data.AddComponents(containers) + return devfile + }, + podTemplateParams: PodTemplateParams{ + Options: common.DevfileOptions{ + FilterByName: "tools", + }, + }, + }, + want: &corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "tools", + Image: "a-tool-image", + Env: []corev1.EnvVar{ + {Name: "PROJECTS_ROOT", Value: "/projects"}, + {Name: "PROJECT_SOURCE", Value: "/projects"}, + }, + ImagePullPolicy: corev1.PullAlways, + Ports: []corev1.ContainerPort{}, + }, + }, + InitContainers: []corev1.Container{}, + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {