Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: add read only containers support #1670

Merged
merged 3 commits into from
Jul 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkg/kobject/kobject.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ type ServiceConfig struct {
WorkingDir string `compose:""`
DomainName string `compose:"domainname"`
HostName string `compose:"hostname"`
ReadOnly bool `compose:"read_only"`
Args []string `compose:"args"`
VolList []string `compose:"volumes"`
Network []string `compose:"network"`
Expand Down
1 change: 1 addition & 0 deletions pkg/loader/compose/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ func dockerComposeToKomposeMapping(composeObject *types.Project) (kobject.Kompos
serviceConfig.Expose = composeServiceConfig.Expose
serviceConfig.Privileged = composeServiceConfig.Privileged
serviceConfig.User = composeServiceConfig.User
serviceConfig.ReadOnly = composeServiceConfig.ReadOnly
serviceConfig.Stdin = composeServiceConfig.StdinOpen
serviceConfig.Tty = composeServiceConfig.Tty
serviceConfig.TmpFs = composeServiceConfig.Tmpfs
Expand Down
5 changes: 5 additions & 0 deletions pkg/transformer/kubernetes/k8sutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,11 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
securityContext.Capabilities = capabilities
}

//set readOnlyRootFilesystem if it is enabled
if service.ReadOnly {
securityContext.ReadOnlyRootFilesystem = &service.ReadOnly
}

// update template only if securityContext is not empty
if *securityContext != (api.SecurityContext{}) {
template.Spec.Containers[0].SecurityContext = securityContext
Expand Down
28 changes: 28 additions & 0 deletions pkg/transformer/kubernetes/k8sutils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -629,3 +629,31 @@ func TestArgsInterpolation(t *testing.T) {
}
}
}

func TestReadOnlyRootFS(t *testing.T) {
// An example service
service := kobject.ServiceConfig{
ContainerName: "name",
Image: "image",
ReadOnly: true,
}

// An example object generated via k8s runtime.Objects()
komposeObject := kobject.KomposeObject{
ServiceConfigs: map[string]kobject.ServiceConfig{"app": service},
}
k := Kubernetes{}
objects, err := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true})
if err != nil {
t.Error(errors.Wrap(err, "k.Transform failed"))
}

for _, obj := range objects {
if deployment, ok := obj.(*appsv1.Deployment); ok {
readOnlyFS := deployment.Spec.Template.Spec.Containers[0].SecurityContext.ReadOnlyRootFilesystem
if *readOnlyFS != true {
t.Errorf("Expected ReadOnlyRootFileSystem %v upon conversion, actual %v", true, readOnlyFS)
}
}
}
}
8 changes: 8 additions & 0 deletions script/test/cmd/tests_new.sh
Original file line number Diff line number Diff line change
Expand Up @@ -277,3 +277,11 @@ convert::expect_success "$os_cmd" "$os_output"
k8s_cmd="kompose -f $KOMPOSE_ROOT/script/test/fixtures/custom-build-push/docker-compose.yaml convert --build-command 'docker build -t ahmedgrati/kompose-test ./script/test/fixtures/custom-build-push' --push-command 'docker push ahmedgrati/kompose-test' --stdout --with-kompose-annotation=false"
k8s_output="$KOMPOSE_ROOT/script/test/fixtures/custom-build-push/output-k8s.yaml"
convert::expect_success "$os_cmd" "$os_output"

# Test support for read only root fs
k8s_cmd="kompose -f $KOMPOSE_ROOT/script/test/fixtures/read-only/docker-compose.yaml convert --stdout --with-kompose-annotation=false"
k8s_output="$KOMPOSE_ROOT/script/test/fixtures/read-only/output-k8s.yaml"
os_cmd="kompose -f $KOMPOSE_ROOT/script/test/fixtures/read-only/docker-compose.yaml convert --stdout --with-kompose-annotation=false --provider openshift"
os_output="$KOMPOSE_ROOT/script/test/fixtures/read-only/output-os.yaml"
convert::expect_success "$k8s_cmd" "$k8s_output"
convert::expect_success "$os_cmd" "$os_output"
6 changes: 6 additions & 0 deletions script/test/fixtures/read-only/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
services:
test:
image: alpine
read_only: true
ports:
- 80:80
52 changes: 52 additions & 0 deletions script/test/fixtures/read-only/output-k8s.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
io.kompose.service: test
name: test
spec:
ports:
- name: "80"
port: 80
targetPort: 80
selector:
io.kompose.service: test
status:
loadBalancer: {}

---
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
io.kompose.service: test
name: test
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: test
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
io.kompose.network/read-only-default: "true"
io.kompose.service: test
spec:
containers:
- image: alpine
name: test
ports:
- containerPort: 80
hostPort: 80
protocol: TCP
resources: {}
securityContext:
readOnlyRootFilesystem: true
restartPolicy: Always
status: {}

93 changes: 93 additions & 0 deletions script/test/fixtures/read-only/output-os.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
io.kompose.service: test
name: test
spec:
ports:
- name: "80"
port: 80
targetPort: 80
selector:
io.kompose.service: test
status:
loadBalancer: {}

---
apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
creationTimestamp: null
labels:
io.kompose.service: test
name: test
spec:
replicas: 1
selector:
io.kompose.service: test
strategy:
resources: {}
template:
metadata:
creationTimestamp: null
labels:
io.kompose.network/read-only-default: "true"
io.kompose.service: test
spec:
containers:
- image: ' '
name: test
ports:
- containerPort: 80
hostPort: 80
protocol: TCP
resources: {}
securityContext:
readOnlyRootFilesystem: true
restartPolicy: Always
test: false
triggers:
- type: ConfigChange
- imageChangeParams:
automatic: true
containerNames:
- test
from:
kind: ImageStreamTag
name: test:latest
type: ImageChange
status:
availableReplicas: 0
latestVersion: 0
observedGeneration: 0
replicas: 0
unavailableReplicas: 0
updatedReplicas: 0

---
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
creationTimestamp: null
labels:
io.kompose.service: test
name: test
spec:
lookupPolicy:
local: false
tags:
- annotations: null
from:
kind: DockerImage
name: alpine
generation: null
importPolicy: {}
name: latest
referencePolicy:
type: ""
status:
dockerImageRepository: ""