forked from LaconicNetwork/kompose
Handling Volume at early stage
It will resolve #544 as well as refactor volume handling part.
This commit is contained in:
@@ -491,77 +491,6 @@ func (k *Kubernetes) SortServicesFirst(objs *[]runtime.Object) {
|
||||
*objs = ret
|
||||
}
|
||||
|
||||
func (k *Kubernetes) findDependentVolumes(svcname string, komposeObject kobject.KomposeObject) (volumes []api.Volume, volumeMounts []api.VolumeMount, err error) {
|
||||
// Get all the volumes and volumemounts this particular service is dependent on
|
||||
for _, dependentSvc := range komposeObject.ServiceConfigs[svcname].VolumesFrom {
|
||||
vols, volMounts, err := k.findDependentVolumes(dependentSvc, komposeObject)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "k.findDependentVolumes failed")
|
||||
return nil, nil, err
|
||||
}
|
||||
volumes = append(volumes, vols...)
|
||||
volumeMounts = append(volumeMounts, volMounts...)
|
||||
}
|
||||
// add the volumes info of this service
|
||||
volMounts, vols, _, err := k.ConfigVolumes(svcname, komposeObject.ServiceConfigs[svcname])
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "k.ConfigVolumes failed")
|
||||
return nil, nil, err
|
||||
}
|
||||
volumes = append(volumes, vols...)
|
||||
volumeMounts = append(volumeMounts, volMounts...)
|
||||
return volumes, volumeMounts, nil
|
||||
}
|
||||
|
||||
// VolumesFrom creates volums and volumeMounts for volumes_from
|
||||
func (k *Kubernetes) VolumesFrom(objects *[]runtime.Object, komposeObject kobject.KomposeObject) error {
|
||||
for _, obj := range *objects {
|
||||
switch t := obj.(type) {
|
||||
case *api.ReplicationController:
|
||||
svcName := t.ObjectMeta.Name
|
||||
for _, dependentSvc := range komposeObject.ServiceConfigs[svcName].VolumesFrom {
|
||||
volumes, volumeMounts, err := k.findDependentVolumes(dependentSvc, komposeObject)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "k.findDependentVolumes")
|
||||
}
|
||||
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, err := k.findDependentVolumes(dependentSvc, komposeObject)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "k.findDependentVolumes")
|
||||
}
|
||||
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, err := k.findDependentVolumes(dependentSvc, komposeObject)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "k.findDependentVolumes")
|
||||
}
|
||||
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, err := k.findDependentVolumes(dependentSvc, komposeObject)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "k.findDependentVolumes")
|
||||
}
|
||||
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...)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SortedKeys Ensure the kubernetes objects are in a consistent order
|
||||
func SortedKeys(komposeObject kobject.KomposeObject) []string {
|
||||
var sortedKeys []string
|
||||
|
||||
@@ -47,7 +47,7 @@ func TestCreateService(t *testing.T) {
|
||||
Command: []string{"cmd"},
|
||||
WorkingDir: "dir",
|
||||
Args: []string{"arg1", "arg2"},
|
||||
Volumes: []string{"/tmp/volume"},
|
||||
VolList: []string{"/tmp/volume"},
|
||||
Network: []string{"network1", "network2"}, // not supported
|
||||
Labels: nil,
|
||||
Annotations: map[string]string{"abc": "def"},
|
||||
@@ -91,7 +91,7 @@ func TestCreateServiceWithMemLimit(t *testing.T) {
|
||||
Command: []string{"cmd"},
|
||||
WorkingDir: "dir",
|
||||
Args: []string{"arg1", "arg2"},
|
||||
Volumes: []string{"/tmp/volume"},
|
||||
VolList: []string{"/tmp/volume"},
|
||||
Network: []string{"network1", "network2"}, // not supported
|
||||
Labels: nil,
|
||||
Annotations: map[string]string{"abc": "def"},
|
||||
@@ -140,7 +140,7 @@ func TestCreateServiceWithServiceUser(t *testing.T) {
|
||||
Command: []string{"cmd"},
|
||||
WorkingDir: "dir",
|
||||
Args: []string{"arg1", "arg2"},
|
||||
Volumes: []string{"/tmp/volume"},
|
||||
VolList: []string{"/tmp/volume"},
|
||||
Network: []string{"network1", "network2"}, // not supported
|
||||
Labels: nil,
|
||||
Annotations: map[string]string{"kompose.service.type": "nodeport"},
|
||||
@@ -184,7 +184,7 @@ func TestTransformWithPid(t *testing.T) {
|
||||
Command: []string{"cmd"},
|
||||
WorkingDir: "dir",
|
||||
Args: []string{"arg1", "arg2"},
|
||||
Volumes: []string{"/tmp/volume"},
|
||||
VolList: []string{"/tmp/volume"},
|
||||
Network: []string{"network1", "network2"},
|
||||
Restart: "always",
|
||||
Pid: "host",
|
||||
@@ -220,7 +220,7 @@ func TestTransformWithInvaildPid(t *testing.T) {
|
||||
Command: []string{"cmd"},
|
||||
WorkingDir: "dir",
|
||||
Args: []string{"arg1", "arg2"},
|
||||
Volumes: []string{"/tmp/volume"},
|
||||
VolList: []string{"/tmp/volume"},
|
||||
Network: []string{"network1", "network2"},
|
||||
Restart: "always",
|
||||
Pid: "badvalue",
|
||||
@@ -329,7 +329,8 @@ func TestRecreateStrategyWithVolumesPresent(t *testing.T) {
|
||||
service := kobject.ServiceConfig{
|
||||
ContainerName: "name",
|
||||
Image: "image",
|
||||
Volumes: []string{"/tmp/volume"},
|
||||
VolList: []string{"/tmp/volume"},
|
||||
Volumes: []kobject.Volumes{{SvcName: "app", MountPath: "/tmp/volume", PVCName: "app-claim0"}},
|
||||
}
|
||||
|
||||
komposeObject := kobject.KomposeObject{
|
||||
|
||||
@@ -49,6 +49,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Kubernetes implements Transformer interface and represents Kubernetes transformer
|
||||
@@ -376,56 +377,53 @@ func (k *Kubernetes) ConfigVolumes(name string, service kobject.ServiceConfig) (
|
||||
volumeMounts := []api.VolumeMount{}
|
||||
volumes := []api.Volume{}
|
||||
var PVCs []*api.PersistentVolumeClaim
|
||||
var volumeName string
|
||||
|
||||
// Set a var based on if the user wants to use empty volumes
|
||||
// as opposed to persistent volumes and volume claims
|
||||
useEmptyVolumes := k.Opt.EmptyVols
|
||||
|
||||
var count int
|
||||
//interating over array of `Vols` struct as it contains all necessary information about volumes
|
||||
for _, volume := range service.Volumes {
|
||||
|
||||
volumeName, host, container, mode, err := transformer.ParseVolume(volume)
|
||||
if err != nil {
|
||||
log.Warningf("Failed to configure container volume: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Debug("Volume name %s", volumeName)
|
||||
|
||||
// check if ro/rw mode is defined, default rw
|
||||
readonly := len(mode) > 0 && mode == "ro"
|
||||
readonly := len(volume.Mode) > 0 && volume.Mode == "ro"
|
||||
|
||||
if volumeName == "" {
|
||||
if volume.VolumeName == "" {
|
||||
if useEmptyVolumes {
|
||||
volumeName = fmt.Sprintf("%s-empty%d", name, count)
|
||||
volumeName = strings.Replace(volume.PVCName, "claim", "empty", 1)
|
||||
} else {
|
||||
volumeName = fmt.Sprintf("%s-claim%d", name, count)
|
||||
volumeName = volume.PVCName
|
||||
}
|
||||
count++
|
||||
} else {
|
||||
volumeName = volume.VolumeName
|
||||
}
|
||||
|
||||
// create a new volume mount object and append to list
|
||||
volmount := api.VolumeMount{
|
||||
Name: volumeName,
|
||||
ReadOnly: readonly,
|
||||
MountPath: container,
|
||||
MountPath: volume.Container,
|
||||
}
|
||||
volumeMounts = append(volumeMounts, volmount)
|
||||
|
||||
// Get a volume source based on the type of volume we are using
|
||||
// For PVC we will also create a PVC object and add to list
|
||||
var volsource *api.VolumeSource
|
||||
|
||||
if useEmptyVolumes {
|
||||
volsource = k.ConfigEmptyVolumeSource("volume")
|
||||
} else {
|
||||
|
||||
volsource = k.ConfigPVCVolumeSource(volumeName, readonly)
|
||||
if volume.VFrom == "" {
|
||||
createdPVC, err := k.CreatePVC(volumeName, volume.Mode)
|
||||
|
||||
createdPVC, err := k.CreatePVC(volumeName, mode)
|
||||
if err != nil {
|
||||
return nil, nil, nil, errors.Wrap(err, "k.CreatePVC failed")
|
||||
if err != nil {
|
||||
return nil, nil, nil, errors.Wrap(err, "k.CreatePVC failed")
|
||||
}
|
||||
|
||||
PVCs = append(PVCs, createdPVC)
|
||||
}
|
||||
|
||||
PVCs = append(PVCs, createdPVC)
|
||||
}
|
||||
|
||||
// create a new volume object using the volsource and add to list
|
||||
@@ -435,10 +433,12 @@ func (k *Kubernetes) ConfigVolumes(name string, service kobject.ServiceConfig) (
|
||||
}
|
||||
volumes = append(volumes, vol)
|
||||
|
||||
if len(host) > 0 {
|
||||
log.Warningf("Volume mount on the host %q isn't supported - ignoring path on the host", host)
|
||||
if len(volume.Host) > 0 {
|
||||
log.Warningf("Volume mount on the host %q isn't supported - ignoring path on the host", volume.Host)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return volumeMounts, volumes, PVCs, nil
|
||||
}
|
||||
|
||||
@@ -603,8 +603,7 @@ 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
|
||||
k.VolumesFrom(&allobjects, komposeObject)
|
||||
|
||||
// sort all object so Services are first
|
||||
k.SortServicesFirst(&allobjects)
|
||||
return allobjects, nil
|
||||
|
||||
@@ -40,7 +40,7 @@ func newServiceConfig() kobject.ServiceConfig {
|
||||
Command: []string{"cmd"},
|
||||
WorkingDir: "dir",
|
||||
Args: []string{"arg1", "arg2"},
|
||||
Volumes: []string{"/tmp/volume"},
|
||||
VolList: []string{"/tmp/volume"},
|
||||
Network: []string{"network1", "network2"}, // not supported
|
||||
Labels: nil,
|
||||
Annotations: map[string]string{"abc": "def"},
|
||||
@@ -54,6 +54,7 @@ func newServiceConfig() kobject.ServiceConfig {
|
||||
Tty: true,
|
||||
TmpFs: []string{"/tmp"},
|
||||
Replicas: 2,
|
||||
Volumes: []kobject.Volumes{{SvcName: "app", MountPath: "/tmp/volume", PVCName: "app-claim0"}},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user