forked from LaconicNetwork/kompose
merge master branch
This commit is contained in:
commit
daa85e2027
@ -181,6 +181,13 @@ WARNING: Unsupported key ContainerName - ignoring
|
|||||||
WARNING: Unsupported key Dockerfile - ignoring
|
WARNING: Unsupported key Dockerfile - ignoring
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Bash completion
|
||||||
|
Running this below command in order to benefit from bash completion
|
||||||
|
|
||||||
|
```
|
||||||
|
$ PROG=kompose source script/bash_autocomplete
|
||||||
|
```
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
### Building with `go`
|
### Building with `go`
|
||||||
|
|||||||
148
cli/app/app.go
148
cli/app/app.go
@ -37,6 +37,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/util/intstr"
|
"k8s.io/kubernetes/pkg/util/intstr"
|
||||||
|
|
||||||
"github.com/fatih/structs"
|
"github.com/fatih/structs"
|
||||||
@ -260,7 +261,7 @@ func createOutFile(out string) *os.File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Init RC object
|
// Init RC object
|
||||||
func initRC(name string, service *project.ServiceConfig) *api.ReplicationController {
|
func initRC(name string, service *project.ServiceConfig, replicas int) *api.ReplicationController {
|
||||||
rc := &api.ReplicationController{
|
rc := &api.ReplicationController{
|
||||||
TypeMeta: unversioned.TypeMeta{
|
TypeMeta: unversioned.TypeMeta{
|
||||||
Kind: "ReplicationController",
|
Kind: "ReplicationController",
|
||||||
@ -271,7 +272,7 @@ func initRC(name string, service *project.ServiceConfig) *api.ReplicationControl
|
|||||||
//Labels: map[string]string{"service": name},
|
//Labels: map[string]string{"service": name},
|
||||||
},
|
},
|
||||||
Spec: api.ReplicationControllerSpec{
|
Spec: api.ReplicationControllerSpec{
|
||||||
Replicas: 1,
|
Replicas: int32(replicas),
|
||||||
Selector: map[string]string{"service": name},
|
Selector: map[string]string{"service": name},
|
||||||
Template: &api.PodTemplateSpec{
|
Template: &api.PodTemplateSpec{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
@ -565,8 +566,14 @@ func ProjectKuberConvert(p *project.Project, c *cli.Context) {
|
|||||||
createRS := c.BoolT("replicaset")
|
createRS := c.BoolT("replicaset")
|
||||||
createChart := c.BoolT("chart")
|
createChart := c.BoolT("chart")
|
||||||
fromBundles := c.BoolT("from-bundles")
|
fromBundles := c.BoolT("from-bundles")
|
||||||
|
replicas := c.Int("replicationcontroller")
|
||||||
singleOutput := len(outFile) != 0 || toStdout
|
singleOutput := len(outFile) != 0 || toStdout
|
||||||
|
|
||||||
|
// Create Deployment by default if no controller has be set
|
||||||
|
if !createD && !createDS && !createRS && replicas == 0 {
|
||||||
|
createD = true
|
||||||
|
}
|
||||||
|
|
||||||
// Validate the flags
|
// Validate the flags
|
||||||
if len(outFile) != 0 && toStdout {
|
if len(outFile) != 0 && toStdout {
|
||||||
logrus.Fatalf("Error: --out and --stdout can't be set at the same time")
|
logrus.Fatalf("Error: --out and --stdout can't be set at the same time")
|
||||||
@ -585,6 +592,9 @@ func ProjectKuberConvert(p *project.Project, c *cli.Context) {
|
|||||||
if createRS {
|
if createRS {
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
|
if replicas != 0 {
|
||||||
|
count++
|
||||||
|
}
|
||||||
if count > 1 {
|
if count > 1 {
|
||||||
logrus.Fatalf("Error: only one type of Kubernetes controller can be generated when --out or --stdout is specified")
|
logrus.Fatalf("Error: only one type of Kubernetes controller can be generated when --out or --stdout is specified")
|
||||||
}
|
}
|
||||||
@ -636,7 +646,7 @@ func ProjectKuberConvert(p *project.Project, c *cli.Context) {
|
|||||||
|
|
||||||
checkUnsupportedKey(*service)
|
checkUnsupportedKey(*service)
|
||||||
|
|
||||||
rc := initRC(name, service)
|
rc := initRC(name, service, replicas)
|
||||||
sc := initSC(name, service)
|
sc := initSC(name, service)
|
||||||
dc := initDC(name, service)
|
dc := initDC(name, service)
|
||||||
ds := initDS(name, service)
|
ds := initDS(name, service)
|
||||||
@ -648,62 +658,20 @@ func ProjectKuberConvert(p *project.Project, c *cli.Context) {
|
|||||||
logrus.Fatalf(err)
|
logrus.Fatalf(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rc.Spec.Template.Spec.Containers[0].Env = envs
|
|
||||||
dc.Spec.Template.Spec.Containers[0].Env = envs
|
|
||||||
ds.Spec.Template.Spec.Containers[0].Env = envs
|
|
||||||
rs.Spec.Template.Spec.Containers[0].Env = envs
|
|
||||||
|
|
||||||
// Configure the container command.
|
// Configure the container command.
|
||||||
var cmds []string
|
var cmds []string
|
||||||
for _, cmd := range service.Command.Slice() {
|
for _, cmd := range service.Command.Slice() {
|
||||||
cmds = append(cmds, cmd)
|
cmds = append(cmds, cmd)
|
||||||
}
|
}
|
||||||
rc.Spec.Template.Spec.Containers[0].Command = cmds
|
|
||||||
dc.Spec.Template.Spec.Containers[0].Command = cmds
|
|
||||||
ds.Spec.Template.Spec.Containers[0].Command = cmds
|
|
||||||
rs.Spec.Template.Spec.Containers[0].Command = cmds
|
|
||||||
|
|
||||||
// Configure the container working dir.
|
|
||||||
rc.Spec.Template.Spec.Containers[0].WorkingDir = service.WorkingDir
|
|
||||||
dc.Spec.Template.Spec.Containers[0].WorkingDir = service.WorkingDir
|
|
||||||
ds.Spec.Template.Spec.Containers[0].WorkingDir = service.WorkingDir
|
|
||||||
rs.Spec.Template.Spec.Containers[0].WorkingDir = service.WorkingDir
|
|
||||||
|
|
||||||
// Configure the container volumes.
|
// Configure the container volumes.
|
||||||
volumesMount, volumes := configVolumes(service)
|
volumesMount, volumes := configVolumes(service)
|
||||||
|
|
||||||
rc.Spec.Template.Spec.Containers[0].VolumeMounts = volumesMount
|
|
||||||
dc.Spec.Template.Spec.Containers[0].VolumeMounts = volumesMount
|
|
||||||
ds.Spec.Template.Spec.Containers[0].VolumeMounts = volumesMount
|
|
||||||
rs.Spec.Template.Spec.Containers[0].VolumeMounts = volumesMount
|
|
||||||
|
|
||||||
rc.Spec.Template.Spec.Volumes = volumes
|
|
||||||
dc.Spec.Template.Spec.Volumes = volumes
|
|
||||||
ds.Spec.Template.Spec.Volumes = volumes
|
|
||||||
rs.Spec.Template.Spec.Volumes = volumes
|
|
||||||
|
|
||||||
// Configure the container privileged mode
|
|
||||||
if service.Privileged == true {
|
|
||||||
securitycontexts := &api.SecurityContext{
|
|
||||||
Privileged: &service.Privileged,
|
|
||||||
}
|
|
||||||
rc.Spec.Template.Spec.Containers[0].SecurityContext = securitycontexts
|
|
||||||
dc.Spec.Template.Spec.Containers[0].SecurityContext = securitycontexts
|
|
||||||
ds.Spec.Template.Spec.Containers[0].SecurityContext = securitycontexts
|
|
||||||
rs.Spec.Template.Spec.Containers[0].SecurityContext = securitycontexts
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure the container ports.
|
// Configure the container ports.
|
||||||
ports, err := configPorts(name, service)
|
ports, err := configPorts(name, service)
|
||||||
if err != "" {
|
if err != "" {
|
||||||
logrus.Fatalf(err)
|
logrus.Fatalf(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rc.Spec.Template.Spec.Containers[0].Ports = ports
|
|
||||||
dc.Spec.Template.Spec.Containers[0].Ports = ports
|
|
||||||
ds.Spec.Template.Spec.Containers[0].Ports = ports
|
|
||||||
rs.Spec.Template.Spec.Containers[0].Ports = ports
|
|
||||||
|
|
||||||
// Configure the service ports.
|
// Configure the service ports.
|
||||||
servicePorts, err := configServicePorts(name, service)
|
servicePorts, err := configServicePorts(name, service)
|
||||||
if err != "" {
|
if err != "" {
|
||||||
@ -717,38 +685,48 @@ func ProjectKuberConvert(p *project.Project, c *cli.Context) {
|
|||||||
for key, value := range service.Labels.MapParts() {
|
for key, value := range service.Labels.MapParts() {
|
||||||
labels[key] = value
|
labels[key] = value
|
||||||
}
|
}
|
||||||
rc.Spec.Template.ObjectMeta.Labels = labels
|
|
||||||
dc.Spec.Template.ObjectMeta.Labels = labels
|
|
||||||
ds.Spec.Template.ObjectMeta.Labels = labels
|
|
||||||
rs.Spec.Template.ObjectMeta.Labels = labels
|
|
||||||
|
|
||||||
rc.ObjectMeta.Labels = labels
|
|
||||||
dc.ObjectMeta.Labels = labels
|
|
||||||
ds.ObjectMeta.Labels = labels
|
|
||||||
rs.ObjectMeta.Labels = labels
|
|
||||||
sc.ObjectMeta.Labels = labels
|
sc.ObjectMeta.Labels = labels
|
||||||
|
|
||||||
// Configure the container restart policy.
|
// fillTemplate fills the pod template with the value calculated from config
|
||||||
switch service.Restart {
|
fillTemplate := func(template *api.PodTemplateSpec) {
|
||||||
case "", "always":
|
template.Spec.Containers[0].Env = envs
|
||||||
rc.Spec.Template.Spec.RestartPolicy = api.RestartPolicyAlways
|
template.Spec.Containers[0].Command = cmds
|
||||||
dc.Spec.Template.Spec.RestartPolicy = api.RestartPolicyAlways
|
template.Spec.Containers[0].WorkingDir = service.WorkingDir
|
||||||
ds.Spec.Template.Spec.RestartPolicy = api.RestartPolicyAlways
|
template.Spec.Containers[0].VolumeMounts = volumesMount
|
||||||
rs.Spec.Template.Spec.RestartPolicy = api.RestartPolicyAlways
|
template.Spec.Volumes = volumes
|
||||||
case "no":
|
// Configure the container privileged mode
|
||||||
rc.Spec.Template.Spec.RestartPolicy = api.RestartPolicyNever
|
if service.Privileged == true {
|
||||||
dc.Spec.Template.Spec.RestartPolicy = api.RestartPolicyNever
|
template.Spec.Containers[0].SecurityContext = &api.SecurityContext{
|
||||||
ds.Spec.Template.Spec.RestartPolicy = api.RestartPolicyNever
|
Privileged: &service.Privileged,
|
||||||
rs.Spec.Template.Spec.RestartPolicy = api.RestartPolicyNever
|
}
|
||||||
case "on-failure":
|
}
|
||||||
rc.Spec.Template.Spec.RestartPolicy = api.RestartPolicyOnFailure
|
template.Spec.Containers[0].Ports = ports
|
||||||
dc.Spec.Template.Spec.RestartPolicy = api.RestartPolicyOnFailure
|
template.ObjectMeta.Labels = labels
|
||||||
ds.Spec.Template.Spec.RestartPolicy = api.RestartPolicyOnFailure
|
// Configure the container restart policy.
|
||||||
rs.Spec.Template.Spec.RestartPolicy = api.RestartPolicyOnFailure
|
switch service.Restart {
|
||||||
default:
|
case "", "always":
|
||||||
logrus.Fatalf("Unknown restart policy %s for service %s", service.Restart, name)
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update each supported controllers
|
||||||
|
updateController(rc, fillTemplate, fillObjectMeta)
|
||||||
|
updateController(rs, fillTemplate, fillObjectMeta)
|
||||||
|
updateController(dc, fillTemplate, fillObjectMeta)
|
||||||
|
updateController(ds, fillTemplate, fillObjectMeta)
|
||||||
|
|
||||||
// convert datarc to json / yaml
|
// convert datarc to json / yaml
|
||||||
datarc, err := transformer(rc, "replication controller", generateYaml)
|
datarc, err := transformer(rc, "replication controller", generateYaml)
|
||||||
if err != "" {
|
if err != "" {
|
||||||
@ -831,8 +809,7 @@ func ProjectKuberConvert(p *project.Project, c *cli.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can create RC when we either don't print to --out or --stdout, or we don't create any other controllers
|
if replicas != 0 {
|
||||||
if !singleOutput || (!createD && !createDS && !createRS) {
|
|
||||||
for k, v := range mReplicationControllers {
|
for k, v := range mReplicationControllers {
|
||||||
print(k, "rc", v, toStdout, generateYaml, f)
|
print(k, "rc", v, toStdout, generateYaml, f)
|
||||||
}
|
}
|
||||||
@ -843,7 +820,7 @@ func ProjectKuberConvert(p *project.Project, c *cli.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if createChart {
|
if createChart {
|
||||||
err := generateHelm(composeFile, svcnames, generateYaml)
|
err := generateHelm(composeFile, svcnames, generateYaml, createD, createDS, createRS, replicas)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatalf("Failed to create Chart data: %s\n", err)
|
logrus.Fatalf("Failed to create Chart data: %s\n", err)
|
||||||
}
|
}
|
||||||
@ -964,3 +941,24 @@ func ProjectKuberUp(p *project.Project, c *cli.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -32,7 +32,7 @@ import (
|
|||||||
/**
|
/**
|
||||||
* Generate Helm Chart configuration
|
* Generate Helm Chart configuration
|
||||||
*/
|
*/
|
||||||
func generateHelm(filename string, svcnames []string, generateYaml bool) error {
|
func generateHelm(filename string, svcnames []string, generateYaml, createD, createDS, createRS bool, replicas int) error {
|
||||||
type ChartDetails struct {
|
type ChartDetails struct {
|
||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
@ -89,26 +89,35 @@ home:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Copy all related json/yaml files into the newly created manifests directory */
|
/* Copy all related json/yaml files into the newly created manifests directory */
|
||||||
// TODO: support copying controller files other than rc?
|
|
||||||
// TODO: support copying the file specified by --out?
|
// TODO: support copying the file specified by --out?
|
||||||
for _, svcname := range svcnames {
|
for _, svcname := range svcnames {
|
||||||
extension := ".json"
|
extension := ".json"
|
||||||
if generateYaml {
|
if generateYaml {
|
||||||
extension = ".yaml"
|
extension = ".yaml"
|
||||||
}
|
}
|
||||||
infile, err := ioutil.ReadFile(svcname + "-rc" + extension)
|
if createD {
|
||||||
if err != nil {
|
if err = cpToChart(manifestDir, svcname, "deployment", extension); err != nil {
|
||||||
logrus.Infof("Error reading %s: %s\n", svcname+"-rc"+extension, err)
|
return err
|
||||||
return err
|
}
|
||||||
}
|
}
|
||||||
|
if createDS {
|
||||||
err = ioutil.WriteFile(manifestDir+string(os.PathSeparator)+svcname+"-rc"+extension, infile, 0644)
|
if err = cpToChart(manifestDir, svcname, "daemonset", extension); err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return err
|
}
|
||||||
|
}
|
||||||
|
if (replicas != 0) {
|
||||||
|
if err = cpToChart(manifestDir, svcname, "replicationcontroller", extension); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if createRS {
|
||||||
|
if err = cpToChart(manifestDir, svcname, "replicaset", extension); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The svc file is optional */
|
/* The svc file is optional */
|
||||||
infile, err = ioutil.ReadFile(svcname + "-svc" + extension)
|
infile, err := ioutil.ReadFile(svcname + "-svc" + extension)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -121,3 +130,13 @@ home:
|
|||||||
fmt.Fprintf(os.Stdout, "chart created in %q\n", "."+string(os.PathSeparator)+dirName+string(os.PathSeparator))
|
fmt.Fprintf(os.Stdout, "chart created in %q\n", "."+string(os.PathSeparator)+dirName+string(os.PathSeparator))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cpToChart(manifestDir, svcname, trailing, extension string) error {
|
||||||
|
infile, err := ioutil.ReadFile(svcname + "-" + trailing + extension)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Infof("Error reading %s: %s\n", svcname+"-"+trailing+extension, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ioutil.WriteFile(manifestDir+string(os.PathSeparator)+svcname+"-"+trailing+extension, infile, 0644)
|
||||||
|
}
|
||||||
|
|||||||
@ -40,15 +40,19 @@ func ConvertCommand(factory app.ProjectFactory) cli.Command {
|
|||||||
Usage: "Specify file name in order to save objects into",
|
Usage: "Specify file name in order to save objects into",
|
||||||
EnvVar: "OUTPUT_FILE",
|
EnvVar: "OUTPUT_FILE",
|
||||||
},
|
},
|
||||||
// TODO: validate the flags and make sure only one type is specified
|
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "deployment,d",
|
Name: "deployment,d",
|
||||||
Usage: "Generate a deployment resource file",
|
Usage: "Generate a deployment resource file (default on)",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "daemonset,ds",
|
Name: "daemonset,ds",
|
||||||
Usage: "Generate a daemonset resource file",
|
Usage: "Generate a daemonset resource file",
|
||||||
},
|
},
|
||||||
|
cli.IntFlag{
|
||||||
|
Name: "replicationcontroller,rc",
|
||||||
|
Value: 0,
|
||||||
|
Usage: "Specify replicas in order to generate a replication controller resource file",
|
||||||
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "replicaset,rs",
|
Name: "replicaset,rs",
|
||||||
Usage: "Generate a replicaset resource file",
|
Usage: "Generate a replicaset resource file",
|
||||||
|
|||||||
@ -35,6 +35,7 @@ func main() {
|
|||||||
app.Version = version.VERSION + " (" + version.GITCOMMIT + ")"
|
app.Version = version.VERSION + " (" + version.GITCOMMIT + ")"
|
||||||
app.Author = "Skippbox Compose Contributors"
|
app.Author = "Skippbox Compose Contributors"
|
||||||
app.Email = "https://github.com/skippbox/kompose"
|
app.Email = "https://github.com/skippbox/kompose"
|
||||||
|
app.EnableBashCompletion = true
|
||||||
app.Before = cliApp.BeforeApp
|
app.Before = cliApp.BeforeApp
|
||||||
app.Flags = append(command.CommonFlags())
|
app.Flags = append(command.CommonFlags())
|
||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
|
|||||||
14
script/bash_autocomplete
Normal file
14
script/bash_autocomplete
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
: ${PROG:=$(basename ${BASH_SOURCE})}
|
||||||
|
|
||||||
|
_cli_bash_autocomplete() {
|
||||||
|
local cur opts base
|
||||||
|
COMPREPLY=()
|
||||||
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
|
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion )
|
||||||
|
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -F _cli_bash_autocomplete $PROG
|
||||||
Loading…
Reference in New Issue
Block a user