make loader, transformer as interfaces

This commit is contained in:
Tuna 2016-08-08 00:00:55 +07:00
parent d532b29d95
commit f10d6afecf
10 changed files with 548 additions and 320 deletions

View File

@ -34,12 +34,16 @@ import (
"github.com/skippbox/kompose/pkg/kobject"
"github.com/skippbox/kompose/pkg/loader"
"github.com/skippbox/kompose/pkg/loader/bundle"
"github.com/skippbox/kompose/pkg/loader/compose"
"github.com/skippbox/kompose/pkg/transformer"
"github.com/docker/libcompose/lookup"
"github.com/docker/libcompose/config"
"github.com/docker/libcompose/project"
"fmt"
"strings"
"github.com/skippbox/kompose/pkg/transformer/kubernetes"
"github.com/skippbox/kompose/pkg/transformer/openshift"
)
const (
@ -450,16 +454,18 @@ func Convert(c *cli.Context) {
}
// loader parses input from file into komposeObject.
var l loader.Loader
switch inputFormat {
case "bundle":
komposeObject = loader.LoadBundle(file)
l = new(bundle.Bundle)
case "compose":
komposeObject = loader.LoadCompose(file)
l = new(compose.Compose)
default:
logrus.Fatalf("Input file format is not supported")
}
komposeObject = l.LoadFile(file)
opt := kobject.ConvertOptions{
ToStdout: toStdout,
CreateD: createD,
@ -476,10 +482,18 @@ func Convert(c *cli.Context) {
validateFlags(opt, singleOutput, dabFile, inputFile)
// transformer maps komposeObject to provider(K8S, OpenShift) primitives
mServices, mDeployments, mDaemonSets, mReplicationControllers, mDeploymentConfigs, svcnames := transformer.Transform(komposeObject, opt)
var t transformer.Transformer
if !createDeploymentConfig {
t = new(kubernetes.Kubernetes)
} else {
t = new(openshift.OpenShift)
}
mServices, mDeployments, mDaemonSets, mReplicationControllers, mDeploymentConfigs, svcnames := t.Transform(komposeObject, opt)
// Print output
transformer.PrintControllers(mServices, mDeployments, mDaemonSets, mReplicationControllers, mDeploymentConfigs, svcnames, opt, f)
transformer.PrintControllers(mServices, mDeployments, mDaemonSets, mReplicationControllers, mDeploymentConfigs, svcnames, opt)
}
// Up brings up deployment, svc.

View File

@ -14,16 +14,20 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package loader
package bundle
import (
"io/ioutil"
"strings"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/client/bundlefile"
"github.com/skippbox/kompose/pkg/kobject"
"io/ioutil"
"strings"
)
type Bundle struct {
}
// load Image from bundles file
func loadImage(service bundlefile.Service) (string, string) {
character := "@"
@ -93,7 +97,7 @@ func loadPortsfromBundle(service bundlefile.Service) ([]kobject.Ports, string) {
}
// load Bundlefile into KomposeObject
func LoadBundle(file string) kobject.KomposeObject {
func (b *Bundle) LoadFile(file string) kobject.KomposeObject {
komposeObject := kobject.KomposeObject{
ServiceConfigs: make(map[string]kobject.ServiceConfig),
}

View File

@ -14,21 +14,25 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package loader
package compose
import (
"github.com/Sirupsen/logrus"
"github.com/docker/libcompose/docker"
"github.com/docker/libcompose/project"
"github.com/skippbox/kompose/pkg/kobject"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/docker/libcompose/lookup"
"os"
"github.com/Sirupsen/logrus"
"github.com/docker/libcompose/config"
"path/filepath"
"github.com/docker/libcompose/docker"
"github.com/docker/libcompose/lookup"
"github.com/docker/libcompose/project"
"github.com/skippbox/kompose/pkg/kobject"
)
type Compose struct {
}
// load Environment Variable from compose file
func loadEnvVarsfromCompose(e map[string]string) []kobject.EnvVar {
envs := []kobject.EnvVar{}
@ -81,7 +85,7 @@ func loadPortsFromCompose(composePorts []string) ([]kobject.Ports, string) {
}
// load Docker Compose file into KomposeObject
func LoadCompose(file string) kobject.KomposeObject {
func (c *Compose) LoadFile(file string) kobject.KomposeObject {
komposeObject := kobject.KomposeObject{
ServiceConfigs: make(map[string]kobject.ServiceConfig),
}

23
pkg/loader/loader.go Normal file
View File

@ -0,0 +1,23 @@
/*
Copyright 2016 Skippbox, Ltd All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package loader
import "github.com/skippbox/kompose/pkg/kobject"
type Loader interface {
LoadFile(file string) kobject.KomposeObject
}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package transformer
package kubernetes
import (
"bytes"
@ -29,7 +29,7 @@ import (
/**
* Generate Helm Chart configuration
*/
func generateHelm(filename string, outFiles []string) error {
func GenerateHelm(filename string, svcnames []string, generateYaml, createD, createDS, createRC bool, outFile string) error {
type ChartDetails struct {
Name string
}

View File

@ -0,0 +1,176 @@
/*
Copyright 2016 Skippbox, Ltd All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package kubernetes
import (
"fmt"
"os"
"github.com/Sirupsen/logrus"
deployapi "github.com/openshift/origin/pkg/deploy/api"
"github.com/skippbox/kompose/pkg/kobject"
"github.com/skippbox/kompose/pkg/transformer"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/runtime"
)
type Kubernetes struct {
}
func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.ConvertOptions) (map[string][]byte, map[string][]byte, map[string][]byte, map[string][]byte, map[string][]byte, []string){
mServices := make(map[string][]byte)
mReplicationControllers := make(map[string][]byte)
mDeployments := make(map[string][]byte)
mDaemonSets := make(map[string][]byte)
var svcnames []string
for name, service := range komposeObject.ServiceConfigs {
svcnames = append(svcnames, name)
rc := transformer.InitRC(name, service, opt.Replicas)
sc := transformer.InitSC(name, service)
dc := transformer.InitDC(name, service, opt.Replicas)
ds := transformer.InitDS(name, service)
// Configure the environment variables.
envs := transformer.ConfigEnvs(name, service)
// Configure the container command.
cmds := transformer.ConfigCommands(service)
// Configure the container volumes.
volumesMount, volumes := transformer.ConfigVolumes(service)
// Configure the container ports.
ports := transformer.ConfigPorts(name, service)
// Configure the service ports.
servicePorts := transformer.ConfigServicePorts(name, service)
sc.Spec.Ports = servicePorts
// Configure label
labels := transformer.ConfigLabels(name)
sc.ObjectMeta.Labels = labels
// Configure annotations
annotations := transformer.ConfigAnnotations(service)
sc.ObjectMeta.Annotations = annotations
// fillTemplate fills the pod template with the value calculated from config
fillTemplate := func(template *api.PodTemplateSpec) {
template.Spec.Containers[0].Env = envs
template.Spec.Containers[0].Command = cmds
template.Spec.Containers[0].WorkingDir = service.WorkingDir
template.Spec.Containers[0].VolumeMounts = volumesMount
template.Spec.Volumes = volumes
// Configure the container privileged mode
if service.Privileged == true {
template.Spec.Containers[0].SecurityContext = &api.SecurityContext{
Privileged: &service.Privileged,
}
}
template.Spec.Containers[0].Ports = ports
template.ObjectMeta.Labels = labels
// Configure the container restart policy.
switch service.Restart {
case "", "always":
template.Spec.RestartPolicy = api.RestartPolicyAlways
case "no":
template.Spec.RestartPolicy = api.RestartPolicyNever
case "on-failure":
template.Spec.RestartPolicy = api.RestartPolicyOnFailure
default:
logrus.Fatalf("Unknown restart policy %s for service %s", service.Restart, name)
}
}
// fillObjectMeta fills the metadata with the value calculated from config
fillObjectMeta := func(meta *api.ObjectMeta) {
meta.Labels = labels
meta.Annotations = annotations
}
// Update each supported controllers
UpdateController(rc, fillTemplate, fillObjectMeta)
UpdateController(dc, fillTemplate, fillObjectMeta)
UpdateController(ds, fillTemplate, fillObjectMeta)
// convert datarc to json / yaml
datarc, err := transformer.TransformData(rc, opt.GenerateYaml)
if err != nil {
logrus.Fatalf(err.Error())
}
// convert datadc to json / yaml
datadc, err := transformer.TransformData(dc, opt.GenerateYaml)
if err != nil {
logrus.Fatalf(err.Error())
}
// convert datads to json / yaml
datads, err := transformer.TransformData(ds, opt.GenerateYaml)
if err != nil {
logrus.Fatalf(err.Error())
}
var datasvc []byte
// If ports not provided in configuration we will not make service
if len(ports) == 0 {
logrus.Warningf("[%s] Service cannot be created because of missing port.", name)
} else if len(ports) != 0 {
// convert datasvc to json / yaml
datasvc, err = transformer.TransformData(sc, opt.GenerateYaml)
if err != nil {
logrus.Fatalf(err.Error())
}
}
mServices[name] = datasvc
mReplicationControllers[name] = datarc
mDeployments[name] = datadc
mDaemonSets[name] = datads
}
return mServices, mDeployments, mDaemonSets, mReplicationControllers, nil, svcnames
}
// updateController updates the given object with the given pod template update function and ObjectMeta update function
func UpdateController(obj runtime.Object, updateTemplate func(*api.PodTemplateSpec), updateMeta func(meta *api.ObjectMeta)) {
switch t := obj.(type) {
case *api.ReplicationController:
if t.Spec.Template == nil {
t.Spec.Template = &api.PodTemplateSpec{}
}
updateTemplate(t.Spec.Template)
updateMeta(&t.ObjectMeta)
case *extensions.Deployment:
updateTemplate(&t.Spec.Template)
updateMeta(&t.ObjectMeta)
case *extensions.ReplicaSet:
updateTemplate(&t.Spec.Template)
updateMeta(&t.ObjectMeta)
case *extensions.DaemonSet:
updateTemplate(&t.Spec.Template)
updateMeta(&t.ObjectMeta)
case *deployapi.DeploymentConfig:
updateTemplate(t.Spec.Template)
updateMeta(&t.ObjectMeta)
}
}

View File

@ -1,58 +0,0 @@
/*
Copyright 2016 Skippbox, Ltd All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package transformer
import (
"github.com/skippbox/kompose/pkg/kobject"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
deployapi "github.com/openshift/origin/pkg/deploy/api"
)
// initDeploymentConfig initialize OpenShifts DeploymentConfig object
func initDeploymentConfig(name string, service kobject.ServiceConfig, replicas int) *deployapi.DeploymentConfig {
dc := &deployapi.DeploymentConfig{
TypeMeta: unversioned.TypeMeta{
Kind: "DeploymentConfig",
APIVersion: "v1",
},
ObjectMeta: api.ObjectMeta{
Name: name,
Labels: map[string]string{"service": name},
},
Spec: deployapi.DeploymentConfigSpec{
Replicas: int32(replicas),
Selector: map[string]string{"service": name},
//UniqueLabelKey: p.Name,
Template: &api.PodTemplateSpec{
ObjectMeta: api.ObjectMeta{
Labels: map[string]string{"service": name},
},
Spec: api.PodSpec{
Containers: []api.Container{
{
Name: name,
Image: service.Image,
},
},
},
},
},
}
return dc
}

View File

@ -0,0 +1,195 @@
/*
Copyright 2016 Skippbox, Ltd All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package openshift
import (
"github.com/Sirupsen/logrus"
deployapi "github.com/openshift/origin/pkg/deploy/api"
"github.com/skippbox/kompose/pkg/kobject"
"github.com/skippbox/kompose/pkg/transformer"
"github.com/skippbox/kompose/pkg/transformer/kubernetes"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
)
type OpenShift struct {
}
// initDeploymentConfig initialize OpenShifts DeploymentConfig object
func initDeploymentConfig(name string, service kobject.ServiceConfig, replicas int) *deployapi.DeploymentConfig {
dc := &deployapi.DeploymentConfig{
TypeMeta: unversioned.TypeMeta{
Kind: "DeploymentConfig",
APIVersion: "v1",
},
ObjectMeta: api.ObjectMeta{
Name: name,
Labels: map[string]string{"service": name},
},
Spec: deployapi.DeploymentConfigSpec{
Replicas: int32(replicas),
Selector: map[string]string{"service": name},
//UniqueLabelKey: p.Name,
Template: &api.PodTemplateSpec{
ObjectMeta: api.ObjectMeta{
Labels: map[string]string{"service": name},
},
Spec: api.PodSpec{
Containers: []api.Container{
{
Name: name,
Image: service.Image,
},
},
},
},
},
}
return dc
}
func (k *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.ConvertOptions) (map[string][]byte, map[string][]byte, map[string][]byte, map[string][]byte, map[string][]byte, []string){
mServices := make(map[string][]byte)
mReplicationControllers := make(map[string][]byte)
mDeployments := make(map[string][]byte)
mDaemonSets := make(map[string][]byte)
// OpenShift DeploymentConfigs
mDeploymentConfigs := make(map[string][]byte)
var svcnames []string
for name, service := range komposeObject.ServiceConfigs {
svcnames = append(svcnames, name)
rc := transformer.InitRC(name, service, opt.Replicas)
sc := transformer.InitSC(name, service)
dc := transformer.InitDC(name, service, opt.Replicas)
ds := transformer.InitDS(name, service)
osDC := initDeploymentConfig(name, service, opt.Replicas) // OpenShift DeploymentConfigs
// Configure the environment variables.
envs := transformer.ConfigEnvs(name, service)
// Configure the container command.
cmds := transformer.ConfigCommands(service)
// Configure the container volumes.
volumesMount, volumes := transformer.ConfigVolumes(service)
// Configure the container ports.
ports := transformer.ConfigPorts(name, service)
// Configure the service ports.
servicePorts := transformer.ConfigServicePorts(name, service)
sc.Spec.Ports = servicePorts
// Configure label
labels := transformer.ConfigLabels(name)
sc.ObjectMeta.Labels = labels
// Configure annotations
annotations := transformer.ConfigAnnotations(service)
sc.ObjectMeta.Annotations = annotations
// fillTemplate fills the pod template with the value calculated from config
fillTemplate := func(template *api.PodTemplateSpec) {
template.Spec.Containers[0].Env = envs
template.Spec.Containers[0].Command = cmds
template.Spec.Containers[0].WorkingDir = service.WorkingDir
template.Spec.Containers[0].VolumeMounts = volumesMount
template.Spec.Volumes = volumes
// Configure the container privileged mode
if service.Privileged == true {
template.Spec.Containers[0].SecurityContext = &api.SecurityContext{
Privileged: &service.Privileged,
}
}
template.Spec.Containers[0].Ports = ports
template.ObjectMeta.Labels = labels
// Configure the container restart policy.
switch service.Restart {
case "", "always":
template.Spec.RestartPolicy = api.RestartPolicyAlways
case "no":
template.Spec.RestartPolicy = api.RestartPolicyNever
case "on-failure":
template.Spec.RestartPolicy = api.RestartPolicyOnFailure
default:
logrus.Fatalf("Unknown restart policy %s for service %s", service.Restart, name)
}
}
// fillObjectMeta fills the metadata with the value calculated from config
fillObjectMeta := func(meta *api.ObjectMeta) {
meta.Labels = labels
meta.Annotations = annotations
}
// Update each supported controllers
kubernetes.UpdateController(rc, fillTemplate, fillObjectMeta)
kubernetes.UpdateController(dc, fillTemplate, fillObjectMeta)
kubernetes.UpdateController(ds, fillTemplate, fillObjectMeta)
// OpenShift DeploymentConfigs
kubernetes.UpdateController(osDC, fillTemplate, fillObjectMeta)
// convert datarc to json / yaml
datarc, err := transformer.TransformData(rc, opt.GenerateYaml)
if err != nil {
logrus.Fatalf(err.Error())
}
// convert datadc to json / yaml
datadc, err := transformer.TransformData(dc, opt.GenerateYaml)
if err != nil {
logrus.Fatalf(err.Error())
}
// convert datads to json / yaml
datads, err := transformer.TransformData(ds, opt.GenerateYaml)
if err != nil {
logrus.Fatalf(err.Error())
}
var datasvc []byte
// If ports not provided in configuration we will not make service
if len(ports) == 0 {
logrus.Warningf("[%s] Service cannot be created because of missing port.", name)
} else if len(ports) != 0 {
// convert datasvc to json / yaml
datasvc, err = transformer.TransformData(sc, opt.GenerateYaml)
if err != nil {
logrus.Fatalf(err.Error())
}
}
// convert OpenShift DeploymentConfig to json / yaml
dataDeploymentConfig, err := transformer.TransformData(osDC, opt.GenerateYaml)
if err != nil {
logrus.Fatalf(err.Error())
}
mServices[name] = datasvc
mReplicationControllers[name] = datarc
mDeployments[name] = datadc
mDaemonSets[name] = datads
mDeploymentConfigs[name] = dataDeploymentConfig
}
return mServices, mDeployments, mDaemonSets, mReplicationControllers, mDeploymentConfigs, svcnames
}

View File

@ -0,0 +1,24 @@
/*
Copyright 2016 Skippbox, Ltd All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package transformer
import "github.com/skippbox/kompose/pkg/kobject"
type Transformer interface {
Transform(kobject.KomposeObject, kobject.ConvertOptions) (map[string][]byte, map[string][]byte, map[string][]byte, map[string][]byte, map[string][]byte, []string)
}

View File

@ -1,45 +1,30 @@
/*
Copyright 2016 Skippbox, Ltd All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package transformer
import (
"encoding/json"
"fmt"
"github.com/Sirupsen/logrus"
"github.com/ghodss/yaml"
"github.com/skippbox/kompose/pkg/kobject"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/util/intstr"
"io/ioutil"
"math/rand"
"os"
"strconv"
"strings"
deployapi "github.com/openshift/origin/pkg/deploy/api"
"io/ioutil"
"github.com/Sirupsen/logrus"
"github.com/ghodss/yaml"
"github.com/skippbox/kompose/pkg/kobject"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/intstr"
"github.com/skippbox/kompose/pkg/transformer/kubernetes"
)
const letterBytes = "abcdefghijklmnopqrstuvwxyz0123456789"
// RandStringBytes generates randomly n-character string
func RandStringBytes(n int) string {
func randStringBytes(n int) string {
b := make([]byte, n)
for i := range b {
b[i] = letterBytes[rand.Intn(len(letterBytes))]
@ -61,7 +46,7 @@ func createOutFile(out string) *os.File {
}
// Init RC object
func initRC(name string, service kobject.ServiceConfig, replicas int) *api.ReplicationController {
func InitRC(name string, service kobject.ServiceConfig, replicas int) *api.ReplicationController {
rc := &api.ReplicationController{
TypeMeta: unversioned.TypeMeta{
Kind: "ReplicationController",
@ -93,7 +78,7 @@ func initRC(name string, service kobject.ServiceConfig, replicas int) *api.Repli
}
// Init SC object
func initSC(name string, service kobject.ServiceConfig) *api.Service {
func InitSC(name string, service kobject.ServiceConfig) *api.Service {
sc := &api.Service{
TypeMeta: unversioned.TypeMeta{
Kind: "Service",
@ -111,7 +96,7 @@ func initSC(name string, service kobject.ServiceConfig) *api.Service {
}
// Init DC object
func initDC(name string, service kobject.ServiceConfig, replicas int) *extensions.Deployment {
func InitDC(name string, service kobject.ServiceConfig, replicas int) *extensions.Deployment {
dc := &extensions.Deployment{
TypeMeta: unversioned.TypeMeta{
Kind: "Deployment",
@ -146,7 +131,7 @@ func initDC(name string, service kobject.ServiceConfig, replicas int) *extension
}
// Init DS object
func initDS(name string, service kobject.ServiceConfig) *extensions.DaemonSet {
func InitDS(name string, service kobject.ServiceConfig) *extensions.DaemonSet {
ds := &extensions.DaemonSet{
TypeMeta: unversioned.TypeMeta{
Kind: "DaemonSet",
@ -175,7 +160,7 @@ func initDS(name string, service kobject.ServiceConfig) *extensions.DaemonSet {
}
// Configure the environment variables.
func configEnvs(name string, service kobject.ServiceConfig) []api.EnvVar {
func ConfigEnvs(name string, service kobject.ServiceConfig) []api.EnvVar {
envs := []api.EnvVar{}
for _, v := range service.Environment {
envs = append(envs, api.EnvVar{
@ -187,8 +172,18 @@ func configEnvs(name string, service kobject.ServiceConfig) []api.EnvVar {
return envs
}
// Configure the container commands
func ConfigCommands(service kobject.ServiceConfig) []string {
var cmds []string
for _, cmd := range service.Command {
cmds = append(cmds, cmd)
}
return cmds
}
// Configure the container volumes.
func configVolumes(service kobject.ServiceConfig) ([]api.VolumeMount, []api.Volume) {
func ConfigVolumes(service kobject.ServiceConfig) ([]api.VolumeMount, []api.Volume) {
volumesMount := []api.VolumeMount{}
volumes := []api.Volume{}
volumeSource := api.VolumeSource{}
@ -201,7 +196,7 @@ func configVolumes(service kobject.ServiceConfig) ([]api.VolumeMount, []api.Volu
// if volume name isn't specified, set it to a random string of 20 chars
if len(name) == 0 {
name = RandStringBytes(20)
name = randStringBytes(20)
}
// check if ro/rw mode is defined, default rw
readonly := len(mode) > 0 && mode == "ro"
@ -256,7 +251,7 @@ func isPath(substring string) bool {
}
// Configure the container ports.
func configPorts(name string, service kobject.ServiceConfig) []api.ContainerPort {
func ConfigPorts(name string, service kobject.ServiceConfig) []api.ContainerPort {
ports := []api.ContainerPort{}
for _, port := range service.Port {
var p api.Protocol
@ -278,7 +273,7 @@ func configPorts(name string, service kobject.ServiceConfig) []api.ContainerPort
}
// Configure the container service ports.
func configServicePorts(name string, service kobject.ServiceConfig) []api.ServicePort {
func ConfigServicePorts(name string, service kobject.ServiceConfig) []api.ServicePort {
servicePorts := []api.ServicePort{}
for _, port := range service.Port {
if port.HostPort == 0 {
@ -306,8 +301,23 @@ func configServicePorts(name string, service kobject.ServiceConfig) []api.Servic
return servicePorts
}
// Configure label
func ConfigLabels(name string) map[string]string {
return map[string]string{"service": name}
}
// Configure annotations
func ConfigAnnotations(service kobject.ServiceConfig) map[string]string {
annotations := map[string]string{}
for key, value := range service.Annotations {
annotations[key] = value
}
return annotations
}
// Transform data to json/yaml
func transformer(obj runtime.Object, GenerateYaml bool) ([]byte, error) {
func TransformData(obj runtime.Object, GenerateYaml bool) ([]byte, error) {
// Convert to versioned object
objectVersion := obj.GetObjectKind().GroupVersionKind()
version := unversioned.GroupVersion{Group: objectVersion.Group, Version: objectVersion.Version}
@ -328,145 +338,37 @@ func transformer(obj runtime.Object, GenerateYaml bool) ([]byte, error) {
return data, nil
}
func Transform(komposeObject *kobject.KomposeObject, opt kobject.ConvertOptions) (map[string][]byte, map[string][]byte, map[string][]byte, map[string][]byte, map[string][]byte, []string) {
mServices := make(map[string][]byte)
mReplicationControllers := make(map[string][]byte)
mDeployments := make(map[string][]byte)
mDaemonSets := make(map[string][]byte)
// OpenShift DeploymentConfigs
mDeploymentConfigs := make(map[string][]byte)
func print(name, trailing string, data []byte, toStdout, generateYaml bool, f *os.File) {
file := fmt.Sprintf("%s-%s.json", name, trailing)
if generateYaml {
file = fmt.Sprintf("%s-%s.yaml", name, trailing)
}
separator := ""
if generateYaml {
separator = "---"
}
if toStdout {
fmt.Fprintf(os.Stdout, "%s%s\n", string(data), separator)
} else if f != nil {
// Write all content to a single file f
if _, err := f.WriteString(fmt.Sprintf("%s%s\n", string(data), separator)); err != nil {
logrus.Fatalf("Failed to write %s to file: %v", trailing, err)
}
f.Sync()
} else {
// Write content separately to each file
if err := ioutil.WriteFile(file, []byte(data), 0644); err != nil {
logrus.Fatalf("Failed to write %s: %v", trailing, err)
}
fmt.Fprintf(os.Stdout, "file %q created\n", file)
}
}
func PrintControllers(mServices, mDeployments, mDaemonSets, mReplicationControllers, mDeploymentConfigs map[string][]byte, svcnames []string, opt kobject.ConvertOptions) {
f := createOutFile(opt.OutFile)
defer f.Close()
var svcnames []string
for name, service := range komposeObject.ServiceConfigs {
svcnames = append(svcnames, name)
rc := initRC(name, service, opt.Replicas)
sc := initSC(name, service)
dc := initDC(name, service, opt.Replicas)
ds := initDS(name, service)
osDC := initDeploymentConfig(name, service, opt.Replicas) // OpenShift DeploymentConfigs
// Configure the environment variables.
envs := configEnvs(name, service)
// Configure the container command.
var cmds []string
for _, cmd := range service.Command {
cmds = append(cmds, cmd)
}
// Configure the container volumes.
volumesMount, volumes := configVolumes(service)
// Configure the container ports.
ports := configPorts(name, service)
// Configure the service ports.
servicePorts := configServicePorts(name, service)
sc.Spec.Ports = servicePorts
// Configure label
labels := map[string]string{"service": name}
sc.ObjectMeta.Labels = labels
// Configure annotations
annotations := map[string]string{}
for key, value := range service.Annotations {
annotations[key] = value
}
sc.ObjectMeta.Annotations = annotations
// fillTemplate fills the pod template with the value calculated from config
fillTemplate := func(template *api.PodTemplateSpec) {
template.Spec.Containers[0].Env = envs
template.Spec.Containers[0].Command = cmds
template.Spec.Containers[0].WorkingDir = service.WorkingDir
template.Spec.Containers[0].VolumeMounts = volumesMount
template.Spec.Volumes = volumes
// Configure the container privileged mode
if service.Privileged == true {
template.Spec.Containers[0].SecurityContext = &api.SecurityContext{
Privileged: &service.Privileged,
}
}
template.Spec.Containers[0].Ports = ports
template.ObjectMeta.Labels = labels
// Configure the container restart policy.
switch service.Restart {
case "", "always":
template.Spec.RestartPolicy = api.RestartPolicyAlways
case "no":
template.Spec.RestartPolicy = api.RestartPolicyNever
case "on-failure":
template.Spec.RestartPolicy = api.RestartPolicyOnFailure
default:
logrus.Fatalf("Unknown restart policy %s for service %s", service.Restart, name)
}
}
// fillObjectMeta fills the metadata with the value calculated from config
fillObjectMeta := func(meta *api.ObjectMeta) {
meta.Labels = labels
meta.Annotations = annotations
}
// Update each supported controllers
updateController(rc, fillTemplate, fillObjectMeta)
updateController(dc, fillTemplate, fillObjectMeta)
updateController(ds, fillTemplate, fillObjectMeta)
// OpenShift DeploymentConfigs
updateController(osDC, fillTemplate, fillObjectMeta)
// convert datarc to json / yaml
datarc, err := transformer(rc, opt.GenerateYaml)
if err != nil {
logrus.Fatalf(err.Error())
}
// convert datadc to json / yaml
datadc, err := transformer(dc, opt.GenerateYaml)
if err != nil {
logrus.Fatalf(err.Error())
}
// convert datads to json / yaml
datads, err := transformer(ds, opt.GenerateYaml)
if err != nil {
logrus.Fatalf(err.Error())
}
var datasvc []byte
// If ports not provided in configuration we will not make service
if len(ports) == 0 {
logrus.Warningf("[%s] Service cannot be created because of missing port.", name)
} else if len(ports) != 0 {
// convert datasvc to json / yaml
datasvc, err = transformer(sc, opt.GenerateYaml)
if err != nil {
logrus.Fatalf(err.Error())
}
}
// convert OpenShift DeploymentConfig to json / yaml
dataDeploymentConfig, err := transformer(osDC, opt.GenerateYaml)
if err != nil {
logrus.Fatalf(err.Error())
}
mServices[name] = datasvc
mReplicationControllers[name] = datarc
mDeployments[name] = datadc
mDaemonSets[name] = datads
mDeploymentConfigs[name] = dataDeploymentConfig
}
return mServices, mDeployments, mDaemonSets, mReplicationControllers, mDeploymentConfigs, svcnames
}
func PrintControllers(mServices, mDeployments, mDaemonSets, mReplicationControllers, mDeploymentConfigs map[string][]byte, svcnames []string, opt kobject.ConvertOptions, f *os.File) {
for k, v := range mServices {
if v != nil {
print(k, "svc", v, opt.ToStdout, opt.GenerateYaml, f)
@ -497,65 +399,9 @@ func PrintControllers(mServices, mDeployments, mDaemonSets, mReplicationControll
}
if opt.CreateChart {
err := generateHelm(opt.InputFile, svcnames, opt.GenerateYaml, opt.CreateD, opt.CreateDS, opt.CreateRC, opt.OutFile)
err := kubernetes.GenerateHelm(opt.InputFile, svcnames, opt.GenerateYaml, opt.CreateD, opt.CreateDS, opt.CreateRC, opt.OutFile)
if err != nil {
logrus.Fatalf("Failed to create Chart data: %v", err)
}
}
if opt.CreateDeploymentConfig {
for k, v := range mDeploymentConfigs {
print(k, "deploymentconfig", v, opt.ToStdout, opt.GenerateYaml, f)
logrus.Fatalf("Failed to create Chart data: %s\n", err)
}
}
}
// updateController updates the given object with the given pod template update function and ObjectMeta update function
func updateController(obj runtime.Object, updateTemplate func(*api.PodTemplateSpec), updateMeta func(meta *api.ObjectMeta)) {
switch t := obj.(type) {
case *api.ReplicationController:
if t.Spec.Template == nil {
t.Spec.Template = &api.PodTemplateSpec{}
}
updateTemplate(t.Spec.Template)
updateMeta(&t.ObjectMeta)
case *extensions.Deployment:
updateTemplate(&t.Spec.Template)
updateMeta(&t.ObjectMeta)
case *extensions.ReplicaSet:
updateTemplate(&t.Spec.Template)
updateMeta(&t.ObjectMeta)
case *extensions.DaemonSet:
updateTemplate(&t.Spec.Template)
updateMeta(&t.ObjectMeta)
case *deployapi.DeploymentConfig:
updateTemplate(t.Spec.Template)
updateMeta(&t.ObjectMeta)
}
}
func print(name, trailing string, data []byte, toStdout, generateYaml bool, f *os.File) {
file := fmt.Sprintf("%s-%s.json", name, trailing)
if generateYaml {
file = fmt.Sprintf("%s-%s.yaml", name, trailing)
}
separator := ""
if generateYaml {
separator = "---"
}
if toStdout {
fmt.Fprintf(os.Stdout, "%s%s\n", string(data), separator)
} else if f != nil {
// Write all content to a single file f
if _, err := f.WriteString(fmt.Sprintf("%s%s\n", string(data), separator)); err != nil {
logrus.Fatalf("Failed to write %s to file: %v", trailing, err)
}
f.Sync()
} else {
// Write content separately to each file
if err := ioutil.WriteFile(file, []byte(data), 0644); err != nil {
logrus.Fatalf("Failed to write %s: %v", trailing, err)
}
fmt.Fprintf(os.Stdout, "file %q created\n", file)
}
}