Skip to content

Commit

Permalink
readonly-for-pipeline (#1103)
Browse files Browse the repository at this point in the history
* Pipeline jobs created with readonly file-systems

* Fixed unit-tests

* Extended volume size
  • Loading branch information
satr authored May 2, 2024
1 parent 6fc1bda commit e0b7788
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 11 deletions.
1 change: 0 additions & 1 deletion pipeline-runner/internal/tekton/tekton.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ func getJobVolumes() []corev1.Volume {
},
},
}

return volumes
}

Expand Down
4 changes: 3 additions & 1 deletion pipeline-runner/model/pipelineInfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"strings"
"time"

"github.com/equinor/radix-common/utils/pointers"
"github.com/equinor/radix-common/utils/slice"
application "github.com/equinor/radix-operator/pkg/apis/applicationconfig"
dnsaliasconfig "github.com/equinor/radix-operator/pkg/apis/config/dnsalias"
Expand Down Expand Up @@ -129,7 +130,8 @@ func InitPipeline(pipelineType *pipeline.Definition,
containerSecContext := securitycontext.Container(securitycontext.WithContainerDropAllCapabilities(),
securitycontext.WithContainerSeccompProfileType(corev1.SeccompProfileTypeRuntimeDefault),
securitycontext.WithContainerRunAsGroup(defaults.SecurityContextRunAsGroup),
securitycontext.WithContainerRunAsUser(defaults.SecurityContextRunAsUser))
securitycontext.WithContainerRunAsUser(defaults.SecurityContextRunAsUser),
securitycontext.WithReadOnlyRootFileSystem(pointers.Ptr(true)))

pipelineArguments.ContainerSecurityContext = *containerSecContext
pipelineArguments.PodSecurityContext = *podSecContext
Expand Down
36 changes: 32 additions & 4 deletions pipeline-runner/steps/build_acr.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ import (
)

const (
buildSecretsMountPath = "/build-secrets"
privateImageHubMountPath = "/radix-private-image-hubs"
buildahRegistryAuthFile = "/home/build/auth.json"
azureServicePrincipleContext = "/radix-image-builder/.azure"
buildSecretsMountPath = "/build-secrets"
privateImageHubMountPath = "/radix-private-image-hubs"
buildahRegistryAuthFile = "/home/build/auth.json"
azureServicePrincipleContext = "/radix-image-builder/.azure"
RadixImageBuilderHomeVolumeName = "radix-image-builder-home"
RadixImageBuilderTmpVolumeName = "radix-image-builder-tmp"
)

func (step *BuildStepImplementation) buildContainerImageBuildingJobs(pipelineInfo *model.PipelineInfo, buildSecrets []corev1.EnvVar) ([]*batchv1.Job, error) {
Expand Down Expand Up @@ -159,6 +161,22 @@ func getContainerImageBuildingJobVolumes(defaultMode *int32, buildSecrets []core
},
},
},
{
Name: RadixImageBuilderTmpVolumeName,
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{
SizeLimit: resource.NewScaledQuantity(1, resource.Mega),
},
},
},
{
Name: RadixImageBuilderHomeVolumeName,
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{
SizeLimit: resource.NewScaledQuantity(5, resource.Mega),
},
},
},
}

if len(buildSecrets) > 0 {
Expand Down Expand Up @@ -394,6 +412,16 @@ func getContainerImageBuildingJobVolumeMounts(buildSecrets []corev1.EnvVar, moun
MountPath: azureServicePrincipleContext,
ReadOnly: true,
},
{
Name: RadixImageBuilderTmpVolumeName, // image-builder creates a script there
MountPath: "/tmp",
ReadOnly: false,
},
{
Name: RadixImageBuilderHomeVolumeName, // .azure folder is created in the user home folder
MountPath: "/home/radix-image-builder",
ReadOnly: false,
},
}

if mountPrivateImageHubAuth {
Expand Down
13 changes: 9 additions & 4 deletions pipeline-runner/steps/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
prometheusfake "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/fake"
"github.com/stretchr/testify/suite"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kubefake "k8s.io/client-go/kubernetes/fake"
)
Expand Down Expand Up @@ -163,6 +164,8 @@ func (s *buildTestSuite) Test_BuildDeploy_JobSpecAndDeploymentConsistent() {
{Name: git.GitSSHKeyVolumeName, VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: git.GitSSHKeyVolumeName, DefaultMode: pointers.Ptr[int32](256)}}},
{Name: defaults.AzureACRServicePrincipleSecretName, VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: defaults.AzureACRServicePrincipleSecretName}}},
{Name: defaults.PrivateImageHubSecretName, VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: defaults.PrivateImageHubSecretName}}},
{Name: steps.RadixImageBuilderTmpVolumeName, VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{SizeLimit: resource.NewScaledQuantity(1, resource.Mega)}}},
{Name: steps.RadixImageBuilderHomeVolumeName, VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{SizeLimit: resource.NewScaledQuantity(5, resource.Mega)}}},
}
s.ElementsMatch(expectedVolumes, job.Spec.Template.Spec.Volumes)

Expand All @@ -187,6 +190,8 @@ func (s *buildTestSuite) Test_BuildDeploy_JobSpecAndDeploymentConsistent() {
expectedBuildVolumeMounts := []corev1.VolumeMount{
{Name: git.BuildContextVolumeName, MountPath: git.Workspace},
{Name: defaults.AzureACRServicePrincipleSecretName, MountPath: "/radix-image-builder/.azure", ReadOnly: true},
{Name: steps.RadixImageBuilderTmpVolumeName, MountPath: "/tmp", ReadOnly: false},
{Name: steps.RadixImageBuilderHomeVolumeName, MountPath: "/home/radix-image-builder", ReadOnly: false},
}
s.ElementsMatch(expectedBuildVolumeMounts, job.Spec.Template.Spec.Containers[0].VolumeMounts)
expectedEnv := []corev1.EnvVar{
Expand Down Expand Up @@ -1339,13 +1344,13 @@ func (s *buildTestSuite) Test_BuildJobSpec_WithBuildSecrets() {
jobs, _ := s.kubeClient.BatchV1().Jobs(utils.GetAppNamespace(appName)).List(context.Background(), metav1.ListOptions{})
s.Require().Len(jobs.Items, 1)
job := jobs.Items[0]
s.Len(job.Spec.Template.Spec.Volumes, 5)
s.Len(job.Spec.Template.Spec.Volumes, 7)
expectedVolumes := []corev1.Volume{
{Name: defaults.BuildSecretsName, VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: defaults.BuildSecretsName}}},
}
s.Subset(job.Spec.Template.Spec.Volumes, expectedVolumes)
s.Require().Len(job.Spec.Template.Spec.Containers, 1)
s.Len(job.Spec.Template.Spec.Containers[0].VolumeMounts, 3)
s.Len(job.Spec.Template.Spec.Containers[0].VolumeMounts, 5)
expectedVolumeMounts := []corev1.VolumeMount{
{Name: defaults.BuildSecretsName, MountPath: "/build-secrets", ReadOnly: true},
}
Expand Down Expand Up @@ -1565,13 +1570,13 @@ func (s *buildTestSuite) Test_BuildJobSpec_BuildKit_WithBuildSecrets() {
jobs, _ := s.kubeClient.BatchV1().Jobs(utils.GetAppNamespace(appName)).List(context.Background(), metav1.ListOptions{})
s.Require().Len(jobs.Items, 1)
job := jobs.Items[0]
s.Len(job.Spec.Template.Spec.Volumes, 5)
s.Len(job.Spec.Template.Spec.Volumes, 7)
expectedVolumes := []corev1.Volume{
{Name: defaults.BuildSecretsName, VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: defaults.BuildSecretsName}}},
}
s.Subset(job.Spec.Template.Spec.Volumes, expectedVolumes)
s.Require().Len(job.Spec.Template.Spec.Containers, 1)
s.Len(job.Spec.Template.Spec.Containers[0].VolumeMounts, 4)
s.Len(job.Spec.Template.Spec.Containers[0].VolumeMounts, 6)
expectedVolumeMounts := []corev1.VolumeMount{
{Name: defaults.BuildSecretsName, MountPath: "/build-secrets", ReadOnly: true},
}
Expand Down
1 change: 1 addition & 0 deletions pkg/apis/job/job_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ func (s *RadixJobTestSuite) TestObjectSynced_PipelineJobCreated() {
Privileged: pointers.Ptr(false),
AllowPrivilegeEscalation: pointers.Ptr(false),
RunAsNonRoot: pointers.Ptr(true),
ReadOnlyRootFilesystem: pointers.Ptr(true),
RunAsUser: pointers.Ptr[int64](1000),
RunAsGroup: pointers.Ptr[int64](1000),
Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}},
Expand Down
4 changes: 3 additions & 1 deletion pkg/apis/job/kubejob.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strings"

"github.com/equinor/radix-common/utils/maps"
"github.com/equinor/radix-common/utils/pointers"
"github.com/equinor/radix-operator/pkg/apis/defaults"
"github.com/equinor/radix-operator/pkg/apis/kube"
pipelineJob "github.com/equinor/radix-operator/pkg/apis/pipeline"
Expand Down Expand Up @@ -103,7 +104,8 @@ func (job *Job) getPipelineJobConfig() (*batchv1.Job, error) {
securitycontext.WithContainerDropAllCapabilities(),
securitycontext.WithContainerSeccompProfileType(corev1.SeccompProfileTypeRuntimeDefault),
securitycontext.WithContainerRunAsGroup(runAsGroup),
securitycontext.WithContainerRunAsUser(runAsUser)),
securitycontext.WithContainerRunAsUser(runAsUser),
securitycontext.WithReadOnlyRootFileSystem(pointers.Ptr(true))),
},
},
RestartPolicy: "Never",
Expand Down
1 change: 1 addition & 0 deletions pkg/apis/utils/git/clone.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package git

import (
"fmt"

corev1 "k8s.io/api/core/v1"
)

Expand Down

0 comments on commit e0b7788

Please sign in to comment.