forked from LaconicNetwork/kompose
return errors instead of logrus.Fatal calls
This commit refactors the code to remove more or less
all occurences of logrus.Fatalf() from the code under
pkg/ except for app.go where all the errors are being
handled currently.
This is being done since random logrus.Fatalf() calls
all around the code was making handling the errors,
unit testing and troubleshooting a bit more painful.
logrus.Fatalf() calls are either replaced by
return errors.New("new error")
or
return errors.Wrap(err, "annonate error")
calls, and the function signatures are accordingly
changed to accomodate the new return values.
The unit tests which previously used to check
if logrus.Fatalf() calls worked fine have also
been fixed to only check for errors now.
Fixes #416
This commit is contained in:
parent
d05e8c522a
commit
5cb598fa5b
@ -35,6 +35,7 @@ import (
|
||||
|
||||
"os"
|
||||
|
||||
"github.com/fsouza/go-dockerclient/external/github.com/Sirupsen/logrus"
|
||||
"github.com/kubernetes-incubator/kompose/pkg/kobject"
|
||||
"github.com/kubernetes-incubator/kompose/pkg/loader"
|
||||
"github.com/kubernetes-incubator/kompose/pkg/transformer"
|
||||
@ -211,16 +212,26 @@ func Convert(opt kobject.ConvertOptions) {
|
||||
komposeObject := kobject.KomposeObject{
|
||||
ServiceConfigs: make(map[string]kobject.ServiceConfig),
|
||||
}
|
||||
komposeObject = l.LoadFile(opt.InputFiles)
|
||||
komposeObject, err = l.LoadFile(opt.InputFiles)
|
||||
if err != nil {
|
||||
logrus.Fatalf(err.Error())
|
||||
}
|
||||
|
||||
// Get a transformer that maps komposeObject to provider's primitives
|
||||
t := getTransformer(opt)
|
||||
|
||||
// Do the transformation
|
||||
objects := t.Transform(komposeObject, opt)
|
||||
objects, err := t.Transform(komposeObject, opt)
|
||||
|
||||
if err != nil {
|
||||
logrus.Fatalf(err.Error())
|
||||
}
|
||||
|
||||
// Print output
|
||||
kubernetes.PrintList(objects, opt)
|
||||
err = kubernetes.PrintList(objects, opt)
|
||||
if err != nil {
|
||||
logrus.Fatalf(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// Up brings up deployment, svc.
|
||||
@ -237,7 +248,10 @@ func Up(opt kobject.ConvertOptions) {
|
||||
komposeObject := kobject.KomposeObject{
|
||||
ServiceConfigs: make(map[string]kobject.ServiceConfig),
|
||||
}
|
||||
komposeObject = l.LoadFile(opt.InputFiles)
|
||||
komposeObject, err = l.LoadFile(opt.InputFiles)
|
||||
if err != nil {
|
||||
logrus.Fatalf(err.Error())
|
||||
}
|
||||
|
||||
// Get the transformer
|
||||
t := getTransformer(opt)
|
||||
@ -263,7 +277,10 @@ func Down(opt kobject.ConvertOptions) {
|
||||
komposeObject := kobject.KomposeObject{
|
||||
ServiceConfigs: make(map[string]kobject.ServiceConfig),
|
||||
}
|
||||
komposeObject = l.LoadFile(opt.InputFiles)
|
||||
komposeObject, err = l.LoadFile(opt.InputFiles)
|
||||
if err != nil {
|
||||
logrus.Fatalf(err.Error())
|
||||
}
|
||||
|
||||
// Get the transformer
|
||||
t := getTransformer(opt)
|
||||
|
||||
@ -29,6 +29,7 @@ import (
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/fatih/structs"
|
||||
"github.com/kubernetes-incubator/kompose/pkg/kobject"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Bundle is docker bundle file loader, implements Loader interface
|
||||
@ -106,16 +107,16 @@ func checkUnsupportedKey(bundleStruct *Bundlefile) []string {
|
||||
}
|
||||
|
||||
// load image from dab file
|
||||
func loadImage(service Service) (string, string) {
|
||||
func loadImage(service Service) (string, error) {
|
||||
character := "@"
|
||||
if strings.Contains(service.Image, character) {
|
||||
return service.Image[0:strings.Index(service.Image, character)], ""
|
||||
return service.Image[0:strings.Index(service.Image, character)], nil
|
||||
}
|
||||
return "", "Invalid image format"
|
||||
return "", errors.New("Invalid image format")
|
||||
}
|
||||
|
||||
// load environment variables from dab file
|
||||
func loadEnvVars(service Service) ([]kobject.EnvVar, string) {
|
||||
func loadEnvVars(service Service) ([]kobject.EnvVar, error) {
|
||||
envs := []kobject.EnvVar{}
|
||||
for _, env := range service.Env {
|
||||
character := "="
|
||||
@ -144,15 +145,15 @@ func loadEnvVars(service Service) ([]kobject.EnvVar, string) {
|
||||
Value: value,
|
||||
})
|
||||
} else {
|
||||
return envs, "Invalid container env " + env
|
||||
return envs, errors.New("Invalid container env")
|
||||
}
|
||||
}
|
||||
}
|
||||
return envs, ""
|
||||
return envs, nil
|
||||
}
|
||||
|
||||
// load ports from dab file
|
||||
func loadPorts(service Service) ([]kobject.Ports, string) {
|
||||
func loadPorts(service Service) ([]kobject.Ports, error) {
|
||||
ports := []kobject.Ports{}
|
||||
for _, port := range service.Ports {
|
||||
var p api.Protocol
|
||||
@ -170,11 +171,11 @@ func loadPorts(service Service) ([]kobject.Ports, string) {
|
||||
Protocol: p,
|
||||
})
|
||||
}
|
||||
return ports, ""
|
||||
return ports, nil
|
||||
}
|
||||
|
||||
// LoadFile loads dab file into KomposeObject
|
||||
func (b *Bundle) LoadFile(files []string) kobject.KomposeObject {
|
||||
func (b *Bundle) LoadFile(files []string) (kobject.KomposeObject, error) {
|
||||
komposeObject := kobject.KomposeObject{
|
||||
ServiceConfigs: make(map[string]kobject.ServiceConfig),
|
||||
LoadedFrom: "bundle",
|
||||
@ -182,12 +183,12 @@ func (b *Bundle) LoadFile(files []string) kobject.KomposeObject {
|
||||
file := files[0]
|
||||
buf, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read bundles file: %s ", err)
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "ioutil.ReadFile failed, Failed to read bundles file")
|
||||
}
|
||||
reader := strings.NewReader(string(buf))
|
||||
bundle, err := loadFile(reader)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to parse bundles file: %s", err)
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "loadFile failed, Failed to parse bundles file")
|
||||
}
|
||||
|
||||
noSupKeys := checkUnsupportedKey(bundle)
|
||||
@ -204,20 +205,20 @@ func (b *Bundle) LoadFile(files []string) kobject.KomposeObject {
|
||||
serviceConfig.Annotations = service.Labels
|
||||
|
||||
image, err := loadImage(service)
|
||||
if err != "" {
|
||||
log.Fatalf("Failed to load image from bundles file: " + err)
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "loadImage failed, Failed to load image from bundles file")
|
||||
}
|
||||
serviceConfig.Image = image
|
||||
|
||||
envs, err := loadEnvVars(service)
|
||||
if err != "" {
|
||||
log.Fatalf("Failed to load envvar from bundles file: " + err)
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "loadEnvVars failed, Failed to load envvar from bundles file")
|
||||
}
|
||||
serviceConfig.Environment = envs
|
||||
|
||||
ports, err := loadPorts(service)
|
||||
if err != "" {
|
||||
log.Fatalf("Failed to load ports from bundles file: " + err)
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "loadPorts failed, Failed to load ports from bundles file")
|
||||
}
|
||||
serviceConfig.Port = ports
|
||||
|
||||
@ -228,7 +229,7 @@ func (b *Bundle) LoadFile(files []string) kobject.KomposeObject {
|
||||
komposeObject.ServiceConfigs[name] = serviceConfig
|
||||
}
|
||||
|
||||
return komposeObject
|
||||
return komposeObject, nil
|
||||
}
|
||||
|
||||
// LoadFile loads a bundlefile from a path to the file
|
||||
|
||||
@ -33,6 +33,7 @@ import (
|
||||
"github.com/docker/libcompose/project"
|
||||
"github.com/fatih/structs"
|
||||
"github.com/kubernetes-incubator/kompose/pkg/kobject"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Compose is docker compose file loader, implements Loader interface
|
||||
@ -275,7 +276,7 @@ func loadPorts(composePorts []string) ([]kobject.Ports, error) {
|
||||
}
|
||||
|
||||
// LoadFile loads compose file into KomposeObject
|
||||
func (c *Compose) LoadFile(files []string) kobject.KomposeObject {
|
||||
func (c *Compose) LoadFile(files []string) (kobject.KomposeObject, error) {
|
||||
komposeObject := kobject.KomposeObject{
|
||||
ServiceConfigs: make(map[string]kobject.ServiceConfig),
|
||||
LoadedFrom: "compose",
|
||||
@ -290,7 +291,7 @@ func (c *Compose) LoadFile(files []string) kobject.KomposeObject {
|
||||
if context.EnvironmentLookup == nil {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}
|
||||
return kobject.KomposeObject{}, nil
|
||||
}
|
||||
context.EnvironmentLookup = &lookup.ComposableEnvLookup{
|
||||
Lookups: []config.EnvironmentLookup{
|
||||
@ -306,7 +307,7 @@ func (c *Compose) LoadFile(files []string) kobject.KomposeObject {
|
||||
composeObject := project.NewProject(context, nil, nil)
|
||||
err := composeObject.Parse()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to load compose file: %v", err)
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "composeObject.Parse() failed, Failed to load compose file")
|
||||
}
|
||||
|
||||
noSupKeys := checkUnsupportedKey(composeObject)
|
||||
@ -329,7 +330,7 @@ func (c *Compose) LoadFile(files []string) kobject.KomposeObject {
|
||||
// load ports
|
||||
ports, err := loadPorts(composeServiceConfig.Ports)
|
||||
if err != nil {
|
||||
log.Fatalf("%q failed to load ports from compose file: %v", name, err)
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "loadPorts failed. "+name+" failed to load ports from compose file")
|
||||
}
|
||||
serviceConfig.Port = ports
|
||||
|
||||
@ -347,7 +348,12 @@ func (c *Compose) LoadFile(files []string) kobject.KomposeObject {
|
||||
for key, value := range composeServiceConfig.Labels {
|
||||
switch key {
|
||||
case "kompose.service.type":
|
||||
serviceConfig.ServiceType = handleServiceType(value)
|
||||
serviceType, err := handleServiceType(value)
|
||||
if err != nil {
|
||||
return kobject.KomposeObject{}, errors.Wrap(err, "handleServiceType failed")
|
||||
}
|
||||
|
||||
serviceConfig.ServiceType = serviceType
|
||||
case "kompose.service.expose":
|
||||
serviceConfig.ExposeService = strings.ToLower(value)
|
||||
}
|
||||
@ -373,20 +379,19 @@ func (c *Compose) LoadFile(files []string) kobject.KomposeObject {
|
||||
komposeObject.ServiceConfigs[name] = serviceConfig
|
||||
}
|
||||
|
||||
return komposeObject
|
||||
return komposeObject, nil
|
||||
}
|
||||
|
||||
func handleServiceType(ServiceType string) string {
|
||||
func handleServiceType(ServiceType string) (string, error) {
|
||||
switch strings.ToLower(ServiceType) {
|
||||
case "", "clusterip":
|
||||
return string(api.ServiceTypeClusterIP)
|
||||
return string(api.ServiceTypeClusterIP), nil
|
||||
case "nodeport":
|
||||
return string(api.ServiceTypeNodePort)
|
||||
return string(api.ServiceTypeNodePort), nil
|
||||
case "loadbalancer":
|
||||
return string(api.ServiceTypeLoadBalancer)
|
||||
return string(api.ServiceTypeLoadBalancer), nil
|
||||
default:
|
||||
log.Fatalf("Unknown value '%s', supported values are 'NodePort, ClusterIP or LoadBalancer'", ServiceType)
|
||||
return ""
|
||||
return "", errors.New("Unknown value " + ServiceType + " , supported values are 'NodePort, ClusterIP or LoadBalancer'")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@ import (
|
||||
"github.com/docker/libcompose/config"
|
||||
"github.com/docker/libcompose/project"
|
||||
"github.com/docker/libcompose/yaml"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Test if service types are parsed properly on user input
|
||||
@ -47,7 +48,10 @@ func TestHandleServiceType(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
result := handleServiceType(tt.labelValue)
|
||||
result, err := handleServiceType(tt.labelValue)
|
||||
if err != nil {
|
||||
t.Error(errors.Wrap(err, "handleServiceType failed"))
|
||||
}
|
||||
if result != tt.serviceType {
|
||||
t.Errorf("Expected %q, got %q", tt.serviceType, result)
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ import (
|
||||
|
||||
// Loader interface defines loader that loads files and converts it to kobject representation
|
||||
type Loader interface {
|
||||
LoadFile(files []string) kobject.KomposeObject
|
||||
LoadFile(files []string) (kobject.KomposeObject, error)
|
||||
///Name() string
|
||||
}
|
||||
|
||||
|
||||
@ -39,6 +39,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
|
||||
deployapi "github.com/openshift/origin/pkg/deploy/api"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
)
|
||||
|
||||
@ -92,7 +93,7 @@ home:
|
||||
|
||||
t, err := template.New("ChartTmpl").Parse(chart)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to generate Chart.yaml template: %s\n", err)
|
||||
return errors.Wrap(err, "Failed to generate Chart.yaml template, template.New failed")
|
||||
}
|
||||
var chartData bytes.Buffer
|
||||
_ = t.Execute(&chartData, details)
|
||||
@ -127,26 +128,26 @@ func cpFileToChart(manifestDir, filename string) error {
|
||||
}
|
||||
|
||||
// Check if given path is a directory
|
||||
func isDir(name string) bool {
|
||||
func isDir(name string) (bool, error) {
|
||||
|
||||
// Open file to get stat later
|
||||
f, err := os.Open(name)
|
||||
if err != nil {
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// Get file attributes and information
|
||||
fileStat, err := f.Stat()
|
||||
if err != nil {
|
||||
log.Fatalf("error retrieving file information: %v", err)
|
||||
return false, errors.Wrap(err, "error retrieving file information, f.Stat failed")
|
||||
}
|
||||
|
||||
// Check if given path is a directory
|
||||
if fileStat.IsDir() {
|
||||
return true
|
||||
return true, nil
|
||||
}
|
||||
return false
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// PrintList will take the data converted and decide on the commandline attributes given
|
||||
@ -156,10 +157,17 @@ func PrintList(objects []runtime.Object, opt kobject.ConvertOptions) error {
|
||||
var dirName string
|
||||
|
||||
// Check if output file is a directory
|
||||
if isDir(opt.OutFile) {
|
||||
isDirVal, err := isDir(opt.OutFile)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "isDir failed")
|
||||
}
|
||||
if isDirVal {
|
||||
dirName = opt.OutFile
|
||||
} else {
|
||||
f = transformer.CreateOutFile(opt.OutFile)
|
||||
f, err = transformer.CreateOutFile(opt.OutFile)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "transformer.CreateOutFile failed")
|
||||
}
|
||||
defer f.Close()
|
||||
}
|
||||
|
||||
@ -189,7 +197,11 @@ func PrintList(objects []runtime.Object, opt kobject.ConvertOptions) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error in marshalling the List: %v", err)
|
||||
}
|
||||
files = append(files, transformer.Print("", dirName, "", data, opt.ToStdout, opt.GenerateJSON, f))
|
||||
printVal, err := transformer.Print("", dirName, "", data, opt.ToStdout, opt.GenerateJSON, f)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "transformer.Print failed")
|
||||
}
|
||||
files = append(files, printVal)
|
||||
} else {
|
||||
var file string
|
||||
// create a separate file for each provider
|
||||
@ -212,13 +224,19 @@ func PrintList(objects []runtime.Object, opt kobject.ConvertOptions) error {
|
||||
// cast it to correct type - api.ObjectMeta
|
||||
objectMeta := val.FieldByName("ObjectMeta").Interface().(api.ObjectMeta)
|
||||
|
||||
file = transformer.Print(objectMeta.Name, dirName, strings.ToLower(typeMeta.Kind), data, opt.ToStdout, opt.GenerateJSON, f)
|
||||
file, err = transformer.Print(objectMeta.Name, dirName, strings.ToLower(typeMeta.Kind), data, opt.ToStdout, opt.GenerateJSON, f)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "transformer.Print failed")
|
||||
}
|
||||
|
||||
files = append(files, file)
|
||||
}
|
||||
}
|
||||
if opt.CreateChart {
|
||||
generateHelm(opt.InputFiles, files)
|
||||
err = generateHelm(opt.InputFiles, files)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "generateHelm failed")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -309,12 +327,16 @@ func (k *Kubernetes) CreateHeadlessService(name string, service kobject.ServiceC
|
||||
}
|
||||
|
||||
// UpdateKubernetesObjects loads configurations to k8s objects
|
||||
func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.ServiceConfig, objects *[]runtime.Object) {
|
||||
func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.ServiceConfig, objects *[]runtime.Object) error {
|
||||
// Configure the environment variables.
|
||||
envs := k.ConfigEnvs(name, service)
|
||||
|
||||
// Configure the container volumes.
|
||||
volumesMount, volumes, pvc := k.ConfigVolumes(name, service)
|
||||
volumesMount, volumes, pvc, err := k.ConfigVolumes(name, service)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "k.ConfigVolumes failed")
|
||||
}
|
||||
|
||||
if pvc != nil {
|
||||
// Looping on the slice pvc instead of `*objects = append(*objects, pvc...)`
|
||||
// because the type of objects and pvc is different, but when doing append
|
||||
@ -331,7 +353,7 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
|
||||
annotations := transformer.ConfigAnnotations(service)
|
||||
|
||||
// fillTemplate fills the pod template with the value calculated from config
|
||||
fillTemplate := func(template *api.PodTemplateSpec) {
|
||||
fillTemplate := func(template *api.PodTemplateSpec) error {
|
||||
if len(service.ContainerName) > 0 {
|
||||
template.Spec.Containers[0].Name = service.ContainerName
|
||||
}
|
||||
@ -384,8 +406,9 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
|
||||
case "on-failure":
|
||||
template.Spec.RestartPolicy = api.RestartPolicyOnFailure
|
||||
default:
|
||||
log.Fatalf("Unknown restart policy %s for service %s", service.Restart, name)
|
||||
return errors.New("Unknown restart policy " + service.Restart + " for service" + name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// fillObjectMeta fills the metadata with the value calculated from config
|
||||
@ -395,8 +418,10 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
|
||||
|
||||
// update supported controller
|
||||
for _, obj := range *objects {
|
||||
k.UpdateController(obj, fillTemplate, fillObjectMeta)
|
||||
|
||||
err = k.UpdateController(obj, fillTemplate, fillObjectMeta)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "k.UpdateController failed")
|
||||
}
|
||||
if len(service.Volumes) > 0 {
|
||||
switch objType := obj.(type) {
|
||||
case *extensions.Deployment:
|
||||
@ -406,6 +431,7 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SortServicesFirst - the objects that we get can be in any order this keeps services first
|
||||
@ -426,52 +452,73 @@ func (k *Kubernetes) SortServicesFirst(objs *[]runtime.Object) {
|
||||
*objs = ret
|
||||
}
|
||||
|
||||
func (k *Kubernetes) findDependentVolumes(svcname string, komposeObject kobject.KomposeObject) (volumes []api.Volume, volumeMounts []api.VolumeMount) {
|
||||
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 := k.findDependentVolumes(dependentSvc, komposeObject)
|
||||
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, _ := k.ConfigVolumes(svcname, komposeObject.ServiceConfigs[svcname])
|
||||
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
|
||||
return volumes, volumeMounts, nil
|
||||
}
|
||||
|
||||
// VolumesFrom creates volums and volumeMounts for volumes_from
|
||||
func (k *Kubernetes) VolumesFrom(objects *[]runtime.Object, komposeObject kobject.KomposeObject) {
|
||||
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 := k.findDependentVolumes(dependentSvc, komposeObject)
|
||||
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 := k.findDependentVolumes(dependentSvc, komposeObject)
|
||||
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 := k.findDependentVolumes(dependentSvc, komposeObject)
|
||||
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 := k.findDependentVolumes(dependentSvc, komposeObject)
|
||||
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
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ import (
|
||||
"github.com/kubernetes-incubator/kompose/pkg/kobject"
|
||||
"github.com/kubernetes-incubator/kompose/pkg/testutils"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
)
|
||||
@ -63,7 +64,10 @@ func TestCreateService(t *testing.T) {
|
||||
ServiceConfigs: map[string]kobject.ServiceConfig{"app": service},
|
||||
}
|
||||
k := Kubernetes{}
|
||||
objects := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 3})
|
||||
objects, err := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 3})
|
||||
if err != nil {
|
||||
t.Error(errors.Wrap(err, "k.Transform failed"))
|
||||
}
|
||||
|
||||
// Test the creation of the service
|
||||
svc := k.CreateService("foo", service, objects)
|
||||
@ -107,7 +111,10 @@ func TestCreateServiceWithMemLimit(t *testing.T) {
|
||||
ServiceConfigs: map[string]kobject.ServiceConfig{"app": service},
|
||||
}
|
||||
k := Kubernetes{}
|
||||
objects := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 3})
|
||||
objects, err := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 3})
|
||||
if err != nil {
|
||||
t.Error(errors.Wrap(err, "k.Transform failed"))
|
||||
}
|
||||
|
||||
// Retrieve the deployment object and test that it matches the MemLimit value
|
||||
for _, obj := range objects {
|
||||
@ -155,7 +162,10 @@ func TestCreateServiceWithServiceUser(t *testing.T) {
|
||||
}
|
||||
k := Kubernetes{}
|
||||
|
||||
objects := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 1})
|
||||
objects, err := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 1})
|
||||
if err != nil {
|
||||
t.Error(errors.Wrap(err, "k.Transform failed"))
|
||||
}
|
||||
|
||||
for _, obj := range objects {
|
||||
if deploy, ok := obj.(*extensions.Deployment); ok {
|
||||
@ -188,19 +198,28 @@ func TestIsDir(t *testing.T) {
|
||||
f.Close()
|
||||
|
||||
// Check output if directory exists
|
||||
output := isDir(tempDir)
|
||||
output, err := isDir(tempDir)
|
||||
if err != nil {
|
||||
t.Error(errors.Wrap(err, "isDir failed"))
|
||||
}
|
||||
if output != true {
|
||||
t.Errorf("directory %v exists but isDir() returned %v", tempDir, output)
|
||||
}
|
||||
|
||||
// Check output if file is provided
|
||||
output = isDir(tempFile)
|
||||
output, err = isDir(tempFile)
|
||||
if err != nil {
|
||||
t.Error(errors.Wrap(err, "isDir failed"))
|
||||
}
|
||||
if output != false {
|
||||
t.Errorf("%v is a file but isDir() returned %v", tempDir, output)
|
||||
}
|
||||
|
||||
// Check output if path does not exist
|
||||
output = isDir(tempAbsentDirPath)
|
||||
output, err = isDir(tempAbsentDirPath)
|
||||
if err != nil {
|
||||
t.Error(errors.Wrap(err, "isDir failed"))
|
||||
}
|
||||
if output != false {
|
||||
t.Errorf("Directory %v does not exist, but isDir() returned %v", tempAbsentDirPath, output)
|
||||
}
|
||||
@ -224,7 +243,10 @@ func TestServiceWithoutPort(t *testing.T) {
|
||||
}
|
||||
k := Kubernetes{}
|
||||
|
||||
objects := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 1})
|
||||
objects, err := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 1})
|
||||
if err != nil {
|
||||
t.Error(errors.Wrap(err, "k.Transform failed"))
|
||||
}
|
||||
if err := testutils.CheckForHeadless(objects); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -245,7 +267,10 @@ func TestRecreateStrategyWithVolumesPresent(t *testing.T) {
|
||||
}
|
||||
k := Kubernetes{}
|
||||
|
||||
objects := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 1})
|
||||
objects, err := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 1})
|
||||
if err != nil {
|
||||
t.Error(errors.Wrap(err, "k.Transform failed"))
|
||||
}
|
||||
for _, obj := range objects {
|
||||
if deployment, ok := obj.(*extensions.Deployment); ok {
|
||||
if deployment.Spec.Strategy.Type != extensions.RecreateDeploymentStrategyType {
|
||||
|
||||
@ -46,6 +46,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
//"k8s.io/kubernetes/pkg/controller/daemon"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Kubernetes implements Transformer interface and represents Kubernetes transformer
|
||||
@ -237,10 +238,10 @@ func (k *Kubernetes) initIngress(name string, service kobject.ServiceConfig, por
|
||||
}
|
||||
|
||||
// CreatePVC initializes PersistentVolumeClaim
|
||||
func (k *Kubernetes) CreatePVC(name string, mode string) *api.PersistentVolumeClaim {
|
||||
func (k *Kubernetes) CreatePVC(name string, mode string) (*api.PersistentVolumeClaim, error) {
|
||||
size, err := resource.ParseQuantity("100Mi")
|
||||
if err != nil {
|
||||
log.Fatalf("Error parsing size")
|
||||
return nil, errors.Wrap(err, "resource.ParseQuantity failed, Error parsing size")
|
||||
}
|
||||
|
||||
pvc := &api.PersistentVolumeClaim{
|
||||
@ -265,7 +266,7 @@ func (k *Kubernetes) CreatePVC(name string, mode string) *api.PersistentVolumeCl
|
||||
} else {
|
||||
pvc.Spec.AccessModes = []api.PersistentVolumeAccessMode{api.ReadWriteOnce}
|
||||
}
|
||||
return pvc
|
||||
return pvc, nil
|
||||
}
|
||||
|
||||
// ConfigPorts configures the container ports.
|
||||
@ -324,7 +325,7 @@ func (k *Kubernetes) ConfigServicePorts(name string, service kobject.ServiceConf
|
||||
}
|
||||
|
||||
// ConfigVolumes configure the container volumes.
|
||||
func (k *Kubernetes) ConfigVolumes(name string, service kobject.ServiceConfig) ([]api.VolumeMount, []api.Volume, []*api.PersistentVolumeClaim) {
|
||||
func (k *Kubernetes) ConfigVolumes(name string, service kobject.ServiceConfig) ([]api.VolumeMount, []api.Volume, []*api.PersistentVolumeClaim, error) {
|
||||
volumeMounts := []api.VolumeMount{}
|
||||
volumes := []api.Volume{}
|
||||
var PVCs []*api.PersistentVolumeClaim
|
||||
@ -371,7 +372,13 @@ func (k *Kubernetes) ConfigVolumes(name string, service kobject.ServiceConfig) (
|
||||
volsource = k.ConfigEmptyVolumeSource()
|
||||
} else {
|
||||
volsource = k.ConfigPVCVolumeSource(volumeName, readonly)
|
||||
PVCs = append(PVCs, k.CreatePVC(volumeName, mode))
|
||||
|
||||
createdPVC, err := k.CreatePVC(volumeName, mode)
|
||||
if err != nil {
|
||||
return nil, nil, nil, errors.Wrap(err, "k.CreatePVC failed")
|
||||
}
|
||||
|
||||
PVCs = append(PVCs, createdPVC)
|
||||
}
|
||||
|
||||
// create a new volume object using the volsource and add to list
|
||||
@ -385,7 +392,7 @@ func (k *Kubernetes) ConfigVolumes(name string, service kobject.ServiceConfig) (
|
||||
log.Warningf("Volume mount on the host %q isn't supported - ignoring path on the host", host)
|
||||
}
|
||||
}
|
||||
return volumeMounts, volumes, PVCs
|
||||
return volumeMounts, volumes, PVCs, nil
|
||||
}
|
||||
|
||||
// ConfigEmptyVolumeSource is helper function to create an EmptyDir api.VolumeSource
|
||||
@ -452,7 +459,7 @@ func (k *Kubernetes) InitPod(name string, service kobject.ServiceConfig) *api.Po
|
||||
|
||||
// Transform maps komposeObject to k8s objects
|
||||
// returns object that are already sorted in the way that Services are first
|
||||
func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.ConvertOptions) []runtime.Object {
|
||||
func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.ConvertOptions) ([]runtime.Object, error) {
|
||||
|
||||
noSupKeys := k.CheckUnsupportedKey(&komposeObject, unsupportedKey)
|
||||
for _, keyName := range noSupKeys {
|
||||
@ -477,7 +484,7 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
|
||||
if service.Restart == "no" || service.Restart == "on-failure" {
|
||||
// Error out if Controller Object is specified with restart: 'on-failure'
|
||||
if opt.IsDeploymentFlag || opt.IsDaemonSetFlag || opt.IsReplicationControllerFlag {
|
||||
log.Fatalf("Controller object cannot be specified with restart: 'on-failure'")
|
||||
return nil, errors.New("Controller object cannot be specified with restart: 'on-failure'")
|
||||
}
|
||||
pod := k.InitPod(name, service)
|
||||
objects = append(objects, pod)
|
||||
@ -505,38 +512,54 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
|
||||
k.VolumesFrom(&allobjects, komposeObject)
|
||||
// sort all object so Services are first
|
||||
k.SortServicesFirst(&allobjects)
|
||||
return allobjects
|
||||
return allobjects, nil
|
||||
}
|
||||
|
||||
// UpdateController updates the given object with the given pod template update function and ObjectMeta update function
|
||||
func (k *Kubernetes) UpdateController(obj runtime.Object, updateTemplate func(*api.PodTemplateSpec), updateMeta func(meta *api.ObjectMeta)) {
|
||||
func (k *Kubernetes) UpdateController(obj runtime.Object, updateTemplate func(*api.PodTemplateSpec) error, updateMeta func(meta *api.ObjectMeta)) (err error) {
|
||||
switch t := obj.(type) {
|
||||
case *api.ReplicationController:
|
||||
if t.Spec.Template == nil {
|
||||
t.Spec.Template = &api.PodTemplateSpec{}
|
||||
}
|
||||
updateTemplate(t.Spec.Template)
|
||||
err = updateTemplate(t.Spec.Template)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "updateTemplate failed")
|
||||
}
|
||||
updateMeta(&t.ObjectMeta)
|
||||
case *extensions.Deployment:
|
||||
updateTemplate(&t.Spec.Template)
|
||||
err = updateTemplate(&t.Spec.Template)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "updateTemplate failed")
|
||||
}
|
||||
updateMeta(&t.ObjectMeta)
|
||||
case *extensions.DaemonSet:
|
||||
updateTemplate(&t.Spec.Template)
|
||||
err = updateTemplate(&t.Spec.Template)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "updateTemplate failed")
|
||||
}
|
||||
updateMeta(&t.ObjectMeta)
|
||||
case *deployapi.DeploymentConfig:
|
||||
updateTemplate(t.Spec.Template)
|
||||
err = updateTemplate(t.Spec.Template)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "updateTemplate failed")
|
||||
}
|
||||
updateMeta(&t.ObjectMeta)
|
||||
case *api.Pod:
|
||||
p := api.PodTemplateSpec{
|
||||
ObjectMeta: t.ObjectMeta,
|
||||
Spec: t.Spec,
|
||||
}
|
||||
updateTemplate(&p)
|
||||
err = updateTemplate(&p)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "updateTemplate failed")
|
||||
}
|
||||
t.Spec = p.Spec
|
||||
t.ObjectMeta = p.ObjectMeta
|
||||
case *buildapi.BuildConfig:
|
||||
updateMeta(&t.ObjectMeta)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetKubernetesClient creates the k8s Client, returns k8s client and namespace
|
||||
@ -560,7 +583,11 @@ func (k *Kubernetes) GetKubernetesClient() (*client.Client, string, error) {
|
||||
// Deploy submits deployment and svc to k8s endpoint
|
||||
func (k *Kubernetes) Deploy(komposeObject kobject.KomposeObject, opt kobject.ConvertOptions) error {
|
||||
//Convert komposeObject
|
||||
objects := k.Transform(komposeObject, opt)
|
||||
objects, err := k.Transform(komposeObject, opt)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "k.Transform failed")
|
||||
}
|
||||
|
||||
pvcStr := " "
|
||||
if !opt.EmptyVols {
|
||||
@ -622,7 +649,11 @@ func (k *Kubernetes) Deploy(komposeObject kobject.KomposeObject, opt kobject.Con
|
||||
// Undeploy deletes deployed objects from Kubernetes cluster
|
||||
func (k *Kubernetes) Undeploy(komposeObject kobject.KomposeObject, opt kobject.ConvertOptions) error {
|
||||
//Convert komposeObject
|
||||
objects := k.Transform(komposeObject, opt)
|
||||
objects, err := k.Transform(komposeObject, opt)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "k.Transform failed")
|
||||
}
|
||||
|
||||
client, namespace, err := k.GetKubernetesClient()
|
||||
if err != nil {
|
||||
|
||||
@ -27,10 +27,9 @@ import (
|
||||
"github.com/kubernetes-incubator/kompose/pkg/kobject"
|
||||
"github.com/kubernetes-incubator/kompose/pkg/transformer"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func newServiceConfig() kobject.ServiceConfig {
|
||||
@ -239,7 +238,10 @@ func TestKomposeConvertIngress(t *testing.T) {
|
||||
}
|
||||
|
||||
// Run Transform
|
||||
objs := k.Transform(test.komposeObject, test.opt)
|
||||
objs, err := k.Transform(test.komposeObject, test.opt)
|
||||
if err != nil {
|
||||
t.Error(errors.Wrap(err, "k.Transform failed"))
|
||||
}
|
||||
|
||||
// Check results
|
||||
for _, obj := range objs {
|
||||
@ -282,7 +284,10 @@ func TestKomposeConvert(t *testing.T) {
|
||||
t.Log("Test case:", name)
|
||||
k := Kubernetes{}
|
||||
// Run Transform
|
||||
objs := k.Transform(test.komposeObject, test.opt)
|
||||
objs, err := k.Transform(test.komposeObject, test.opt)
|
||||
if err != nil {
|
||||
t.Error(errors.Wrap(err, "k.Transform failed"))
|
||||
}
|
||||
if len(objs) != test.expectedNumObjs {
|
||||
t.Errorf("Expected %d objects returned, got %d", test.expectedNumObjs, len(objs))
|
||||
}
|
||||
@ -402,7 +407,10 @@ func TestConvertRestartOptions(t *testing.T) {
|
||||
for name, test := range testCases {
|
||||
t.Log("Test Case:", name)
|
||||
|
||||
objs := k.Transform(test.svc, opt)
|
||||
objs, err := k.Transform(test.svc, opt)
|
||||
if err != nil {
|
||||
t.Error(errors.Wrap(err, "k.Transform failed"))
|
||||
}
|
||||
|
||||
if len(objs) != 1 {
|
||||
t.Errorf("Expected only one pod, more elements generated.")
|
||||
@ -454,13 +462,6 @@ func TestUnsupportedKeys(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
// Here we are testing a function which results in `logus.Fatalf()` when a condition is met, which further call `os.Exit()` and exits the process.
|
||||
// If we write a test in the usual way that will call the function,
|
||||
// it will exit the process and the running process is actually the test process and our test would fail.
|
||||
// So to test the function resulting in `os.Exit()` we need invoke go test again in a separate process through `exec.Command`,
|
||||
// limiting execution to the TestRestartOnFailure test using `-test.run=TestRestartOnFailure` flag set.
|
||||
// The `TestRestartOnFailure` doing is two things simultaneously,
|
||||
// it is going to the be the test itself and second it will a be `subprocess` that the test runs.
|
||||
func TestRestartOnFailure(t *testing.T) {
|
||||
|
||||
kobjectWithRestartOnFailure := newKomposeObject()
|
||||
@ -483,24 +484,11 @@ func TestRestartOnFailure(t *testing.T) {
|
||||
for name, test := range testCase {
|
||||
t.Log("Test case:", name)
|
||||
k := Kubernetes{}
|
||||
if os.Getenv("BE_CRASHER") == "1" {
|
||||
k.Transform(test.komposeObject, test.opt)
|
||||
_, err := k.Transform(test.komposeObject, test.opt)
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error, got %v instead", err)
|
||||
}
|
||||
}
|
||||
|
||||
// cmd := exec.Command(os.Args[0], "-test.run=TestRestartOnFailure") will execute the test binary
|
||||
// with the flag -test.run=TestRestartOnFailure and set the environment variable BE_CRASHER=1.
|
||||
cmd := exec.Command(os.Args[0], "-test.run=TestRestartOnFailure")
|
||||
cmd.Env = append(os.Environ(), "BE_CRASHER=1")
|
||||
|
||||
// err := cmd.Run() will re-execute the test binary and this time os.Getenv("BE_CRASHER") == "1"
|
||||
// will return true and we can call o.Transform(test.komposeObject, test.opt).
|
||||
// so that the test binary that calls itself and execute the code on behalf of the parent process.
|
||||
err := cmd.Run()
|
||||
if e, ok := err.(*exec.ExitError); ok && !e.Success() {
|
||||
return
|
||||
}
|
||||
t.Fatalf("Process ran with err %v, want exit status 1", err)
|
||||
}
|
||||
|
||||
func TestInitPodSpec(t *testing.T) {
|
||||
|
||||
@ -44,6 +44,7 @@ import (
|
||||
deploymentconfigreaper "github.com/openshift/origin/pkg/deploy/cmd"
|
||||
imageapi "github.com/openshift/origin/pkg/image/api"
|
||||
routeapi "github.com/openshift/origin/pkg/route/api"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
)
|
||||
@ -170,10 +171,10 @@ func (o *OpenShift) initImageStream(name string, service kobject.ServiceConfig)
|
||||
}
|
||||
|
||||
// initBuildConfig initialize Openshifts BuildConfig Object
|
||||
func initBuildConfig(name string, service kobject.ServiceConfig, composeFileDir string, repo string, branch string) *buildapi.BuildConfig {
|
||||
func initBuildConfig(name string, service kobject.ServiceConfig, composeFileDir string, repo string, branch string) (*buildapi.BuildConfig, error) {
|
||||
contextDir, err := getAbsBuildContext(service.Build, composeFileDir)
|
||||
if err != nil {
|
||||
log.Fatalf("[%s] Buildconfig cannot be created due to error in creating build context.", name)
|
||||
return nil, errors.Wrap(err, name+"buildconfig cannot be created due to error in creating build context, getAbsBuildContext failed")
|
||||
}
|
||||
|
||||
bc := &buildapi.BuildConfig{
|
||||
@ -210,7 +211,7 @@ func initBuildConfig(name string, service kobject.ServiceConfig, composeFileDir
|
||||
},
|
||||
},
|
||||
}
|
||||
return bc
|
||||
return bc, nil
|
||||
}
|
||||
|
||||
// initDeploymentConfig initialize OpenShifts DeploymentConfig object
|
||||
@ -295,7 +296,7 @@ func (o *OpenShift) initRoute(name string, service kobject.ServiceConfig, port i
|
||||
|
||||
// Transform maps komposeObject to openshift objects
|
||||
// returns objects that are already sorted in the way that Services are first
|
||||
func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.ConvertOptions) []runtime.Object {
|
||||
func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.ConvertOptions) ([]runtime.Object, error) {
|
||||
noSupKeys := o.Kubernetes.CheckUnsupportedKey(&komposeObject, unsupportedKey)
|
||||
for _, keyName := range noSupKeys {
|
||||
log.Warningf("OpenShift provider doesn't support %s key - ignoring", keyName)
|
||||
@ -315,7 +316,7 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
|
||||
if service.Restart == "no" || service.Restart == "on-failure" {
|
||||
// Error out if Controller Object is specified with restart: 'on-failure'
|
||||
if opt.IsDeploymentConfigFlag {
|
||||
log.Fatalf("Controller object cannot be specified with restart: 'on-failure'")
|
||||
return nil, errors.New("Controller object cannot be specified with restart: 'on-failure'")
|
||||
}
|
||||
pod := o.InitPod(name, service)
|
||||
objects = append(objects, pod)
|
||||
@ -337,26 +338,30 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
|
||||
continue
|
||||
}
|
||||
if !hasGitBinary() && (buildRepo == "" || buildBranch == "") {
|
||||
log.Fatalf("Git is not installed! Please install Git to create buildconfig, else supply source repository and branch to use for build using '--build-repo', '--build-branch' options respectively")
|
||||
return nil, errors.New("Git is not installed! Please install Git to create buildconfig, else supply source repository and branch to use for build using '--build-repo', '--build-branch' options respectively")
|
||||
}
|
||||
if buildBranch == "" {
|
||||
buildBranch, err = getGitCurrentBranch(composeFileDir)
|
||||
if err != nil {
|
||||
log.Fatalf("Buildconfig cannot be created because current git branch couldn't be detected.")
|
||||
return nil, errors.Wrap(err, "Buildconfig cannot be created because current git branch couldn't be detected.")
|
||||
}
|
||||
}
|
||||
if opt.BuildRepo == "" {
|
||||
if err != nil {
|
||||
log.Fatalf("Buildconfig cannot be created because remote for current git branch couldn't be detected.")
|
||||
return nil, errors.Wrap(err, "Buildconfig cannot be created because remote for current git branch couldn't be detected.")
|
||||
}
|
||||
buildRepo, err = getGitCurrentRemoteURL(composeFileDir)
|
||||
if err != nil {
|
||||
log.Fatalf("Buildconfig cannot be created because git remote origin repo couldn't be detected.")
|
||||
return nil, errors.Wrap(err, "Buildconfig cannot be created because git remote origin repo couldn't be detected.")
|
||||
}
|
||||
}
|
||||
hasBuild = true
|
||||
}
|
||||
objects = append(objects, initBuildConfig(name, service, composeFileDir, buildRepo, buildBranch)) // Openshift BuildConfigs
|
||||
bc, err := initBuildConfig(name, service, composeFileDir, buildRepo, buildBranch)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "initBuildConfig failed")
|
||||
}
|
||||
objects = append(objects, bc) // Openshift BuildConfigs
|
||||
}
|
||||
|
||||
// If ports not provided in configuration we will not make service
|
||||
@ -384,7 +389,7 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
|
||||
o.VolumesFrom(&allobjects, komposeObject)
|
||||
// sort all object so Services are first
|
||||
o.SortServicesFirst(&allobjects)
|
||||
return allobjects
|
||||
return allobjects, nil
|
||||
}
|
||||
|
||||
// Create OpenShift client, returns OpenShift client
|
||||
@ -403,7 +408,12 @@ func (o *OpenShift) getOpenShiftClient() (*oclient.Client, error) {
|
||||
// Deploy transofrms and deploys kobject to OpenShift
|
||||
func (o *OpenShift) Deploy(komposeObject kobject.KomposeObject, opt kobject.ConvertOptions) error {
|
||||
//Convert komposeObject
|
||||
objects := o.Transform(komposeObject, opt)
|
||||
objects, err := o.Transform(komposeObject, opt)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "o.Transform failed")
|
||||
}
|
||||
|
||||
pvcStr := " "
|
||||
if !opt.EmptyVols {
|
||||
pvcStr = " and PersistentVolumeClaims "
|
||||
@ -480,7 +490,11 @@ func (o *OpenShift) Deploy(komposeObject kobject.KomposeObject, opt kobject.Conv
|
||||
//Undeploy removes deployed artifacts from OpenShift cluster
|
||||
func (o *OpenShift) Undeploy(komposeObject kobject.KomposeObject, opt kobject.ConvertOptions) error {
|
||||
//Convert komposeObject
|
||||
objects := o.Transform(komposeObject, opt)
|
||||
objects, err := o.Transform(komposeObject, opt)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "o.Transform failed")
|
||||
}
|
||||
|
||||
oclient, err := o.getOpenShiftClient()
|
||||
if err != nil {
|
||||
|
||||
@ -29,7 +29,7 @@ import (
|
||||
"github.com/kubernetes-incubator/kompose/pkg/kobject"
|
||||
"github.com/kubernetes-incubator/kompose/pkg/testutils"
|
||||
"github.com/kubernetes-incubator/kompose/pkg/transformer/kubernetes"
|
||||
"os/exec"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func newServiceConfig() kobject.ServiceConfig {
|
||||
@ -292,7 +292,10 @@ func TestInitBuildConfig(t *testing.T) {
|
||||
sc := kobject.ServiceConfig{
|
||||
Build: "./build",
|
||||
}
|
||||
bc := initBuildConfig(serviceName, sc, composeFileDir, repo, branch)
|
||||
bc, err := initBuildConfig(serviceName, sc, composeFileDir, repo, branch)
|
||||
if err != nil {
|
||||
t.Error(errors.Wrap(err, "initBuildConfig failed"))
|
||||
}
|
||||
|
||||
testCases := map[string]struct {
|
||||
field string
|
||||
@ -324,20 +327,16 @@ func TestServiceWithoutPort(t *testing.T) {
|
||||
}
|
||||
o := OpenShift{Kubernetes: kubernetes.Kubernetes{}}
|
||||
|
||||
objects := o.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 1})
|
||||
objects, err := o.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 1})
|
||||
if err != nil {
|
||||
t.Error(errors.Wrap(err, "o.Transform failed"))
|
||||
}
|
||||
if err := testutils.CheckForHeadless(objects); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Here we are testing a function which results in `logus.Fatalf()` when a condition is met, which further call `os.Exit()` and exits the process.
|
||||
// If we write a test in the usual way that will call the function,
|
||||
// it will exit the process and the running process is actually the test process and our test would fail.
|
||||
// So to test the function resulting in `os.Exit()` we need invoke go test again in a separate process through `exec.Command`,
|
||||
// limiting execution to the TestRestartOnFailure test using `-test.run=TestRestartOnFailure` flag set.
|
||||
// The `TestRestartOnFailure` doing is two things simultaneously,
|
||||
// it is going to the be the test itself and second it will a be `subprocess` that the test runs.
|
||||
func TestRestartOnFailure(t *testing.T) {
|
||||
|
||||
service := kobject.ServiceConfig{
|
||||
@ -361,24 +360,13 @@ func TestRestartOnFailure(t *testing.T) {
|
||||
for name, test := range testCase {
|
||||
t.Log("Test case:", name)
|
||||
o := OpenShift{}
|
||||
if os.Getenv("BE_CRASHER") == "1" {
|
||||
o.Transform(test.komposeObject, test.opt)
|
||||
|
||||
_, err := o.Transform(test.komposeObject, test.opt)
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error, got %v instead", err)
|
||||
}
|
||||
}
|
||||
|
||||
// cmd := exec.Command(os.Args[0], "-test.run=TestRestartOnFailure") will execute the test binary
|
||||
// with the flag -test.run=TestRestartOnFailure and set the environment variable BE_CRASHER=1
|
||||
cmd := exec.Command(os.Args[0], "-test.run=TestRestartOnFailure")
|
||||
cmd.Env = append(os.Environ(), "BE_CRASHER=1")
|
||||
|
||||
// err := cmd.Run() will re-execute the test binary and this time os.Getenv("BE_CRASHER") == "1".
|
||||
// will return true and we can call o.Transform(test.komposeObject, test.opt).
|
||||
// so that the test binary that calls itself and execute the code on behalf of the parent process.
|
||||
err := cmd.Run()
|
||||
if e, ok := err.(*exec.ExitError); ok && !e.Success() {
|
||||
return
|
||||
}
|
||||
t.Fatalf("Process ran with err %v, want exit status 1", err)
|
||||
}
|
||||
|
||||
// Tests if deployment strategy is being set to Recreate when volumes are
|
||||
@ -395,7 +383,10 @@ func TestRecreateStrategyWithVolumesPresent(t *testing.T) {
|
||||
|
||||
o := OpenShift{Kubernetes: kubernetes.Kubernetes{}}
|
||||
|
||||
objects := o.Transform(komposeObject, kobject.ConvertOptions{CreateDeploymentConfig: true, Replicas: 1})
|
||||
objects, err := o.Transform(komposeObject, kobject.ConvertOptions{CreateDeploymentConfig: true, Replicas: 1})
|
||||
if err != nil {
|
||||
t.Error(errors.Wrap(err, "o.Transform failed"))
|
||||
}
|
||||
for _, obj := range objects {
|
||||
if deploymentConfig, ok := obj.(*deployapi.DeploymentConfig); ok {
|
||||
if deploymentConfig.Spec.Strategy.Type != deployapi.DeploymentStrategyTypeRecreate {
|
||||
|
||||
@ -24,7 +24,7 @@ import (
|
||||
// Transformer interface defines transformer that is converting kobject to other resources
|
||||
type Transformer interface {
|
||||
// Transform converts KomposeObject to transformer specific objects.
|
||||
Transform(kobject.KomposeObject, kobject.ConvertOptions) []runtime.Object
|
||||
Transform(kobject.KomposeObject, kobject.ConvertOptions) ([]runtime.Object, error)
|
||||
// Deploy deploys KomposeObject to provider
|
||||
Deploy(komposeObject kobject.KomposeObject, opt kobject.ConvertOptions) error
|
||||
// Undeploy deletes/undeploys KomposeObject from provider
|
||||
|
||||
@ -30,6 +30,7 @@ import (
|
||||
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
@ -47,16 +48,16 @@ func RandStringBytes(n int) string {
|
||||
}
|
||||
|
||||
// CreateOutFile creates the file to write to if --out is specified
|
||||
func CreateOutFile(out string) *os.File {
|
||||
func CreateOutFile(out string) (*os.File, error) {
|
||||
var f *os.File
|
||||
var err error
|
||||
if len(out) != 0 {
|
||||
f, err = os.Create(out)
|
||||
if err != nil {
|
||||
log.Fatalf("error creating file: %v", err)
|
||||
return nil, errors.Wrap(err, "error creating file, os.Create failed")
|
||||
}
|
||||
}
|
||||
return f
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// ParseVolume parses a given volume, which might be [name:][host:]container[:access_mode]
|
||||
@ -151,7 +152,7 @@ func TransformData(obj runtime.Object, GenerateJSON bool) ([]byte, error) {
|
||||
}
|
||||
|
||||
// Print either prints to stdout or to file/s
|
||||
func Print(name, path string, trailing string, data []byte, toStdout, generateJSON bool, f *os.File) string {
|
||||
func Print(name, path string, trailing string, data []byte, toStdout, generateJSON bool, f *os.File) (string, error) {
|
||||
file := ""
|
||||
if generateJSON {
|
||||
file = fmt.Sprintf("%s-%s.json", name, trailing)
|
||||
@ -160,20 +161,20 @@ func Print(name, path string, trailing string, data []byte, toStdout, generateJS
|
||||
}
|
||||
if toStdout {
|
||||
fmt.Fprintf(os.Stdout, "%s\n", string(data))
|
||||
return ""
|
||||
return "", nil
|
||||
} else if f != nil {
|
||||
// Write all content to a single file f
|
||||
if _, err := f.WriteString(fmt.Sprintf("%s\n", string(data))); err != nil {
|
||||
log.Fatalf("Failed to write %s to file: %v", trailing, err)
|
||||
return "", errors.Wrap(err, "f.WriteString failed, Failed to write %s to file: "+trailing)
|
||||
}
|
||||
f.Sync()
|
||||
} else {
|
||||
// Write content separately to each file
|
||||
file = filepath.Join(path, file)
|
||||
if err := ioutil.WriteFile(file, []byte(data), 0644); err != nil {
|
||||
log.Fatalf("Failed to write %s: %v", trailing, err)
|
||||
return "", errors.Wrap(err, "Failed to write %s: "+trailing)
|
||||
}
|
||||
log.Printf("file %q created", file)
|
||||
}
|
||||
return file
|
||||
return file, nil
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user