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

support for volumes_from docker-compose construct #190

Merged
merged 1 commit into from
Oct 23, 2016
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
2 changes: 1 addition & 1 deletion pkg/kobject/kobject.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ var unsupportedKey = map[string]int{
"ShmSize": 0,
"StopSignal": 0,
"VolumeDriver": 0,
"VolumesFrom": 0,
"Uts": 0,
"ReadOnly": 0,
"StdinOpen": 0,
Expand Down Expand Up @@ -150,6 +149,7 @@ type ServiceConfig struct {
Privileged bool
Restart string
User string
VolumesFrom []string
}

// EnvVar holds the environment variable struct of a container
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 @@ -193,6 +193,7 @@ func (c *Compose) LoadFile(file string) kobject.KomposeObject {
serviceConfig.Privileged = composeServiceConfig.Privileged
serviceConfig.Restart = composeServiceConfig.Restart
serviceConfig.User = composeServiceConfig.User
serviceConfig.VolumesFrom = composeServiceConfig.VolumesFrom

komposeObject.ServiceConfigs[name] = serviceConfig
}
Expand Down
50 changes: 50 additions & 0 deletions pkg/transformer/kubernetes/k8sutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,3 +333,53 @@ func SortServicesFirst(objs *[]runtime.Object) {
ret = append(ret, others...)
*objs = ret
}

func findDependentVolumes(svcname string, komposeObject kobject.KomposeObject) (volumes []api.Volume, volumeMounts []api.VolumeMount) {
// Get all the volumes and volumemounts this particular service is dependent on
for _, dependentSvc := range komposeObject.ServiceConfigs[svcname].VolumesFrom {
vols, volMounts := findDependentVolumes(dependentSvc, komposeObject)
volumes = append(volumes, vols...)
volumeMounts = append(volumeMounts, volMounts...)
}
// add the volumes info of this service
volMounts, vols, _ := ConfigVolumes(svcname, komposeObject.ServiceConfigs[svcname])
volumes = append(volumes, vols...)
volumeMounts = append(volumeMounts, volMounts...)
return
}

func VolumesFrom(objects *[]runtime.Object, komposeObject kobject.KomposeObject) {

for _, obj := range *objects {
switch t := obj.(type) {
case *api.ReplicationController:
svcName := t.ObjectMeta.Name
for _, dependentSvc := range komposeObject.ServiceConfigs[svcName].VolumesFrom {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should make it better by reducing copied block of code

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would appreciate help on this part of code repetition! I also asked about it once on slack!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. Probably we can use a common function to return a api.PodTemplateSpec struct for all cases. Then you don't have to repeat the for _, dependentSvc... loop. That's not much but yeah I mean somehow it looks better a little bit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because all resources in 4 cases contains api.PodTemplateSpec in their structs

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But here I am adding data to the existing t.Spec.Template.Spec.Volumes and t.Spec.Template.Spec.Containers[0].VolumeMounts so returning common blank struct won't help IMO.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK so I will check it and probably make an enhanced PR later. Let's get it merged. Thanks @surajssd 👍

volumes, volumeMounts := findDependentVolumes(dependentSvc, komposeObject)
t.Spec.Template.Spec.Volumes = append(t.Spec.Template.Spec.Volumes, volumes...)
t.Spec.Template.Spec.Containers[0].VolumeMounts = append(t.Spec.Template.Spec.Containers[0].VolumeMounts, volumeMounts...)
}
case *extensions.Deployment:
svcName := t.ObjectMeta.Name
for _, dependentSvc := range komposeObject.ServiceConfigs[svcName].VolumesFrom {
volumes, volumeMounts := findDependentVolumes(dependentSvc, komposeObject)
t.Spec.Template.Spec.Volumes = append(t.Spec.Template.Spec.Volumes, volumes...)
t.Spec.Template.Spec.Containers[0].VolumeMounts = append(t.Spec.Template.Spec.Containers[0].VolumeMounts, volumeMounts...)
}
case *extensions.DaemonSet:
svcName := t.ObjectMeta.Name
for _, dependentSvc := range komposeObject.ServiceConfigs[svcName].VolumesFrom {
volumes, volumeMounts := findDependentVolumes(dependentSvc, komposeObject)
t.Spec.Template.Spec.Volumes = append(t.Spec.Template.Spec.Volumes, volumes...)
t.Spec.Template.Spec.Containers[0].VolumeMounts = append(t.Spec.Template.Spec.Containers[0].VolumeMounts, volumeMounts...)
}
case *deployapi.DeploymentConfig:
svcName := t.ObjectMeta.Name
for _, dependentSvc := range komposeObject.ServiceConfigs[svcName].VolumesFrom {
volumes, volumeMounts := findDependentVolumes(dependentSvc, komposeObject)
t.Spec.Template.Spec.Volumes = append(t.Spec.Template.Spec.Volumes, volumes...)
t.Spec.Template.Spec.Containers[0].VolumeMounts = append(t.Spec.Template.Spec.Containers[0].VolumeMounts, volumeMounts...)
}
}
}
}
2 changes: 2 additions & 0 deletions pkg/transformer/kubernetes/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.

allobjects = append(allobjects, objects...)
}
// If docker-compose has a volumes_from directive it will be handled here
VolumesFrom(&allobjects, komposeObject)
// sort all object so Services are first
SortServicesFirst(&allobjects)
return allobjects
Expand Down
2 changes: 2 additions & 0 deletions pkg/transformer/openshift/openshift.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ func (k *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C

allobjects = append(allobjects, objects...)
}
// If docker-compose has a volumes_from directive it will be handled here
kubernetes.VolumesFrom(&allobjects, komposeObject)
// sort all object so Services are first
kubernetes.SortServicesFirst(&allobjects)
return allobjects
Expand Down
11 changes: 10 additions & 1 deletion script/test/cmd/tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ convert::expect_success "kompose --provider=openshift -f $KOMPOSE_ROOT/script/te
# kubernetes test
convert::expect_success "kompose -f $KOMPOSE_ROOT/script/test/fixtures/volume-mounts/simple-vol-mounts/docker-compose.yml convert --stdout" "$KOMPOSE_ROOT/script/test/fixtures/volume-mounts/simple-vol-mounts/output-k8s.json"
# openshift test
convert::expect_success "kompose --provider=openshift -f $KOMPOSE_ROOT/script/test/fixtures/volume-mounts/simple-vol-mounts/docker-compose.yml convert --stdout --dc" "$KOMPOSE_ROOT/script/test/fixtures/volume-mounts/simple-vol-mounts/output-os.json"
convert::expect_success "kompose --provider=openshift -f $KOMPOSE_ROOT/script/test/fixtures/volume-mounts/simple-vol-mounts/docker-compose.yml convert --stdout" "$KOMPOSE_ROOT/script/test/fixtures/volume-mounts/simple-vol-mounts/output-os.json"


######
# Tests related to docker-compose file in /script/test/fixtures/volume-mounts/volumes-from
# kubernetes test
convert::expect_success_and_warning "kompose -f $KOMPOSE_ROOT/script/test/fixtures/volume-mounts/volumes-from/docker-compose.yml convert --stdout" "$KOMPOSE_ROOT/script/test/fixtures/volume-mounts/volumes-from/output-k8s.json" "ignoring path on the host"
# openshift test
convert::expect_success_and_warning "kompose --provider=openshift -f $KOMPOSE_ROOT/script/test/fixtures/volume-mounts/volumes-from/docker-compose.yml convert --stdout" "$KOMPOSE_ROOT/script/test/fixtures/volume-mounts/volumes-from/output-os.json" "ignoring path on the host"


exit $EXIT_STATUS
20 changes: 20 additions & 0 deletions script/test/fixtures/volume-mounts/volumes-from/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
version: "2"

services:
web:
image: centos/httpd
volumes:
- "./app:/src/app"
ports:
- "3030:3000"
command: nodemon -L app/bin/www

nginx:
restart: always
image: nginx
ports:
- "80:80"
volumes:
- /www/public
volumes_from:
- web
216 changes: 216 additions & 0 deletions script/test/fixtures/volume-mounts/volumes-from/output-k8s.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
{
"kind": "List",
"apiVersion": "v1",
"metadata": {},
"items": [
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "web",
"creationTimestamp": null,
"labels": {
"service": "web"
}
},
"spec": {
"ports": [
{
"name": "3030",
"protocol": "TCP",
"port": 3030,
"targetPort": 3000
}
],
"selector": {
"service": "web"
}
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "nginx",
"creationTimestamp": null,
"labels": {
"service": "nginx"
}
},
"spec": {
"ports": [
{
"name": "80",
"protocol": "TCP",
"port": 80,
"targetPort": 80
}
],
"selector": {
"service": "nginx"
}
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "Deployment",
"apiVersion": "extensions/v1beta1",
"metadata": {
"name": "web",
"creationTimestamp": null
},
"spec": {
"replicas": 1,
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"service": "web"
}
},
"spec": {
"volumes": [
{
"name": "web-claim0",
"persistentVolumeClaim": {
"claimName": "web-claim0"
}
}
],
"containers": [
{
"name": "web",
"image": "centos/httpd",
"args": [
"nodemon",
"-L",
"app/bin/www"
],
"ports": [
{
"containerPort": 3000,
"protocol": "TCP"
}
],
"resources": {},
"volumeMounts": [
{
"name": "web-claim0",
"mountPath": "/src/app"
}
]
}
],
"restartPolicy": "Always"
}
},
"strategy": {}
},
"status": {}
},
{
"kind": "PersistentVolumeClaim",
"apiVersion": "v1",
"metadata": {
"name": "web-claim0",
"creationTimestamp": null
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "100Mi"
}
}
},
"status": {}
},
{
"kind": "Deployment",
"apiVersion": "extensions/v1beta1",
"metadata": {
"name": "nginx",
"creationTimestamp": null
},
"spec": {
"replicas": 1,
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"service": "nginx"
}
},
"spec": {
"volumes": [
{
"name": "nginx-claim0",
"persistentVolumeClaim": {
"claimName": "nginx-claim0"
}
},
{
"name": "web-claim0",
"persistentVolumeClaim": {
"claimName": "web-claim0"
}
}
],
"containers": [
{
"name": "nginx",
"image": "nginx",
"ports": [
{
"containerPort": 80,
"protocol": "TCP"
}
],
"resources": {},
"volumeMounts": [
{
"name": "nginx-claim0",
"mountPath": "/www/public"
},
{
"name": "web-claim0",
"mountPath": "/src/app"
}
]
}
],
"restartPolicy": "Always"
}
},
"strategy": {}
},
"status": {}
},
{
"kind": "PersistentVolumeClaim",
"apiVersion": "v1",
"metadata": {
"name": "nginx-claim0",
"creationTimestamp": null
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "100Mi"
}
}
},
"status": {}
}
]
}
Loading