Merge pull request #312 from procrypt/multiple_files

added support for multiple-compose files
This commit is contained in:
Suraj Deshmukh 2017-01-03 17:45:48 +05:30 committed by GitHub
commit b059c44774
18 changed files with 739 additions and 34 deletions

View File

@ -47,7 +47,7 @@ var convertCmd = &cobra.Command{
CreateChart: ConvertChart,
GenerateYaml: ConvertYaml,
Replicas: ConvertReplicas,
InputFile: GlobalFile,
InputFiles: GlobalFiles,
OutFile: ConvertOut,
Provider: strings.ToLower(GlobalProvider),
CreateD: ConvertDeployment,

View File

@ -39,7 +39,7 @@ var downCmd = &cobra.Command{
// Create the Convert options.
DownOpt = kobject.ConvertOptions{
Replicas: DownReplicas,
InputFile: GlobalFile,
InputFiles: GlobalFiles,
Provider: strings.ToLower(GlobalProvider),
EmptyVols: DownEmptyVols,
}

View File

@ -40,8 +40,9 @@ func (errorOnWarningHook) Fire(entry *logrus.Entry) error {
}
var (
GlobalBundle, GlobalFile, GlobalProvider string
GlobalBundle, GlobalProvider string
GlobalVerbose, GlobalSuppressWarnings, GlobalErrorOnWarning bool
GlobalFiles []string
)
var RootCmd = &cobra.Command{
@ -86,7 +87,7 @@ func init() {
RootCmd.PersistentFlags().BoolVarP(&GlobalVerbose, "verbose", "v", false, "verbose output")
RootCmd.PersistentFlags().BoolVar(&GlobalSuppressWarnings, "suppress-warnings", false, "Suppress all warnings")
RootCmd.PersistentFlags().BoolVar(&GlobalErrorOnWarning, "error-on-warning", false, "Treat any warning as an error")
RootCmd.PersistentFlags().StringVarP(&GlobalFile, "file", "f", "docker-compose.yml", "Specify an alternative compose file")
RootCmd.PersistentFlags().StringArrayVarP(&GlobalFiles, "file", "f", []string{}, "Specify an alternative compose file")
RootCmd.PersistentFlags().StringVarP(&GlobalBundle, "bundle", "b", "", "Specify a Distributed Application GlobalBundle (DAB) file")
RootCmd.PersistentFlags().StringVar(&GlobalProvider, "provider", "kubernetes", "Specify a provider. Kubernetes or OpenShift.")
}

View File

@ -39,7 +39,7 @@ var upCmd = &cobra.Command{
// Create the Convert options.
UpOpt = kobject.ConvertOptions{
Replicas: UpReplicas,
InputFile: GlobalFile,
InputFiles: GlobalFiles,
Provider: strings.ToLower(GlobalProvider),
EmptyVols: UpEmptyVols,
}

View File

@ -62,6 +62,31 @@ db-deployment.json docker-compose.yml docker-gitlab.yml redis-deployme
db-svc.json docker-compose-bundle.dab docker-voting.yml redis-svc.json result-svc.json vote-svc.json worker-svc.json
```
You can also provide multiple docker-compose files at the same time:
```console
$ kompose -f docker-compose.yml -f docker-guestbook.yml convert
file "frontend-service.json" created
file "mlbparks-service.json" created
file "mongodb-service.json" created
file "redis-master-service.json" created
file "redis-slave-service.json" created
file "frontend-deployment.json" created
file "mlbparks-deployment.json" created
file "mongodb-deployment.json" created
file "mongodb-claim0-persistentvolumeclaim.json" created
file "redis-master-deployment.json" created
file "redis-slave-deployment.json" created
$ ls
mlbparks-deployment.json mongodb-service.json redis-slave-service.jsonmlbparks-service.json
frontend-deployment.json mongodb-claim0-persistentvolumeclaim.json redis-master-service.json
frontend-service.json mongodb-deployment.json redis-slave-deployment.json
redis-master-deployment.json
```
When multiple docker-compose files are provided the configuration is merged. Any configuration that is common will be over ridden by subsequent file.
Using `--bundle, --dab` to specify a DAB file as below:
```console

View File

@ -114,7 +114,7 @@ func ValidateFlags(bundle string, args []string, cmd *cobra.Command, opt *kobjec
if len(bundle) > 0 {
inputFormat = "bundle"
opt.InputFile = bundle
opt.InputFiles = []string{bundle}
}
if len(bundle) > 0 && isFileSet {
@ -185,7 +185,7 @@ func Convert(opt kobject.ConvertOptions) {
komposeObject := kobject.KomposeObject{
ServiceConfigs: make(map[string]kobject.ServiceConfig),
}
komposeObject = l.LoadFile(opt.InputFile)
komposeObject = l.LoadFile(opt.InputFiles)
// Get a transformer that maps komposeObject to provider's primitives
t := getTransformer(opt)
@ -211,7 +211,7 @@ func Up(opt kobject.ConvertOptions) {
komposeObject := kobject.KomposeObject{
ServiceConfigs: make(map[string]kobject.ServiceConfig),
}
komposeObject = l.LoadFile(opt.InputFile)
komposeObject = l.LoadFile(opt.InputFiles)
// Get the transformer
t := getTransformer(opt)
@ -237,7 +237,7 @@ func Down(opt kobject.ConvertOptions) {
komposeObject := kobject.KomposeObject{
ServiceConfigs: make(map[string]kobject.ServiceConfig),
}
komposeObject = l.LoadFile(opt.InputFile)
komposeObject = l.LoadFile(opt.InputFiles)
// Get the transformer
t := getTransformer(opt)

View File

@ -39,7 +39,7 @@ type ConvertOptions struct {
GenerateYaml bool
EmptyVols bool
Replicas int
InputFile string
InputFiles []string
OutFile string
Provider string
}

View File

@ -173,12 +173,12 @@ func loadPorts(service Service) ([]kobject.Ports, string) {
}
// load dab file into KomposeObject
func (b *Bundle) LoadFile(file string) kobject.KomposeObject {
func (b *Bundle) LoadFile(files []string) kobject.KomposeObject {
komposeObject := kobject.KomposeObject{
ServiceConfigs: make(map[string]kobject.ServiceConfig),
LoadedFrom: "bundle",
}
file := files[0]
buf, err := ioutil.ReadFile(file)
if err != nil {
logrus.Fatalf("Failed to read bundles file: %s ", err)

View File

@ -221,16 +221,16 @@ func loadPorts(composePorts []string) ([]kobject.Ports, error) {
}
// load compose file into KomposeObject
func (c *Compose) LoadFile(file string) kobject.KomposeObject {
func (c *Compose) LoadFile(files []string) kobject.KomposeObject {
komposeObject := kobject.KomposeObject{
ServiceConfigs: make(map[string]kobject.ServiceConfig),
LoadedFrom: "compose",
}
context := &project.Context{}
if file == "" {
file = "docker-compose.yml"
if len(files) == 0 {
files = append(files, "docker-compose.yml")
}
context.ComposeFiles = []string{file}
context.ComposeFiles = files
if context.ResourceLookup == nil {
context.ResourceLookup = &lookup.FileResourceLookup{}

View File

@ -26,7 +26,7 @@ import (
)
type Loader interface {
LoadFile(file string) kobject.KomposeObject
LoadFile(files []string) kobject.KomposeObject
///Name() string
}

View File

@ -46,11 +46,12 @@ import (
/**
* Generate Helm Chart configuration
*/
func generateHelm(filename string, outFiles []string) error {
func generateHelm(filenames []string, outFiles []string) error {
type ChartDetails struct {
Name string
}
// Let assume all the docker-compose files are in the same directory
filename := filenames[0]
extension := filepath.Ext(filename)
dirName := filename[0 : len(filename)-len(extension)]
details := ChartDetails{dirName}
@ -231,7 +232,7 @@ func PrintList(objects []runtime.Object, opt kobject.ConvertOptions) error {
}
}
if opt.CreateChart {
generateHelm(opt.InputFile, files)
generateHelm(opt.InputFiles, files)
}
return nil
}

View File

@ -112,7 +112,9 @@ func getGitCurrentBranch(composeFileDir string) (string, error) {
}
// getComposeFileDir returns compose file directory
func getComposeFileDir(inputFile string) (string, error) {
func getComposeFileDir(inputFiles []string) (string, error) {
// Lets assume all the docker-compose files are in the same directory
inputFile := inputFiles[0]
if strings.Index(inputFile, "/") != 0 {
workDir, err := os.Getwd()
if err != nil {
@ -332,7 +334,7 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
// buildconfig needs to be added to objects after imagestream because of this Openshift bug: https://github.com/openshift/origin/issues/4518
if service.Build != "" {
if !hasBuild {
composeFileDir, err = getComposeFileDir(opt.InputFile)
composeFileDir, err = getComposeFileDir(opt.InputFiles)
if err != nil {
logrus.Warningf("Error in detecting compose file's directory.")
continue

View File

@ -214,17 +214,17 @@ func TestGetComposeFileDir(t *testing.T) {
wd, _ := os.Getwd()
testCases := map[string]struct {
inputFile string
inputFiles []string
output string
}{
"Get compose file dir for relative input file path": {"foo/bar.yaml", filepath.Join(wd, "foo")},
"Get compose file dir for abs input file path": {"/abs/path/to/compose.yaml", "/abs/path/to"},
"Get compose file dir for relative input file path": {[]string{"foo/bar.yaml"}, filepath.Join(wd, "foo")},
"Get compose file dir for abs input file path": {[]string{"/abs/path/to/compose.yaml"}, "/abs/path/to"},
}
for name, test := range testCases {
t.Log("Test case: ", name)
output, err = getComposeFileDir(test.inputFile)
output, err = getComposeFileDir(test.inputFiles)
if err != nil {
t.Errorf("Expected success, got error: %#v", err)

View File

@ -98,6 +98,11 @@ convert::expect_failure "kompose -f $KOMPOSE_ROOT/script/test/fixtures/bundles/f
# Test related to kompose --bundle convert to ensure that docker bundles are converted properly
convert::expect_success "kompose --bundle $KOMPOSE_ROOT/script/test/fixtures/bundles/dab/docker-compose-bundle.dab convert --stdout" "$KOMPOSE_ROOT/script/test/fixtures/bundles/dab/output-k8s.json"
# Test related to multiple-compose files
# Kubernets test
convert::expect_success_and_warning "kompose -f $KOMPOSE_ROOT/script/test/fixtures/multiple-compose-files/docker-k8s.yml -f $KOMPOSE_ROOT/script/test/fixtures/multiple-compose-files/docker-os.yml convert --stdout" "$KOMPOSE_ROOT/script/test/fixtures/multiple-compose-files/output-k8s.json" "Unsupported depends_on key - ignoring"
convert::expect_success_and_warning "kompose --provider=openshift -f $KOMPOSE_ROOT/script/test/fixtures/multiple-compose-files/docker-k8s.yml -f $KOMPOSE_ROOT/script/test/fixtures/multiple-compose-files/docker-os.yml convert --stdout" "$KOMPOSE_ROOT/script/test/fixtures/multiple-compose-files/output-openshift.json" "Unsupported depends_on key - ignoring"
######
# Test related to kompose --bundle convert to ensure that DSB bundles are converted properly
convert::expect_success_and_warning "kompose --bundle $KOMPOSE_ROOT/script/test/fixtures/bundles/dsb/docker-voting-bundle.dsb convert --stdout" "$KOMPOSE_ROOT/script/test/fixtures/bundles/dsb/output-k8s.json" "Service cannot be created because of missing port."
@ -170,5 +175,4 @@ convert::files_exist "kompose -f $KOMPOSE_ROOT/examples/docker-compose.yml conve
# Behavior with -o <dirname>/<dirname>/<filename>
convert::files_exist "kompose -f $KOMPOSE_ROOT/examples/docker-compose.yml convert -o output_dir/output_dir_nested/output_file" "$TEMP_DIR/output_dir/output_dir_nested" "$TEMP_DIR/output_dir/output_dir_nested/output_file"
exit $EXIT_STATUS

View File

@ -0,0 +1,27 @@
version: "2"
services:
mariadb:
image: centos/mariadb
ports:
- "3306"
environment:
MYSQL_ROOT_PASSWORD: kubernetes
MYSQL_DATABASE: kubernetes
MYSQL_PASSWORD: kubernetes
MYSQL_USER: kubernetes
volumes:
- /var/lib/mysql
etherpad:
image: centos/etherpad
ports:
- "80:9001"
depends_on:
- mariadb
environment:
DB_HOST: kubernetes
DB_DBID: kubernetes
DB_PASS: kubernetes
DB_PORT: kubernetes
DB_USER: kubernetes

View File

@ -0,0 +1,27 @@
version: "2"
services:
mariadb:
image: centos/mariadb
ports:
- "3307"
environment:
MYSQL_ROOT_PASSWORD: openshift
MYSQL_DATABASE: openshift
MYSQL_PASSWORD: openshift
MYSQL_USER: openshift
volumes:
- /var/lib/mysql
etherpad:
image: centos/etherpad
ports:
- "80:9001"
depends_on:
- mariadb
environment:
DB_HOST: openshift
DB_DBID: openshift
DB_PASS: openshift
DB_PORT: openshift
DB_USER: openshift

View File

@ -0,0 +1,257 @@
{
"kind": "List",
"apiVersion": "v1",
"metadata": {},
"items": [
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "etherpad",
"creationTimestamp": null,
"labels": {
"service": "etherpad"
}
},
"spec": {
"ports": [
{
"name": "80",
"protocol": "TCP",
"port": 80,
"targetPort": 9001
},
{
"name": "80",
"protocol": "TCP",
"port": 80,
"targetPort": 9001
}
],
"selector": {
"service": "etherpad"
}
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "mariadb",
"creationTimestamp": null,
"labels": {
"service": "mariadb"
}
},
"spec": {
"ports": [
{
"name": "3306",
"protocol": "TCP",
"port": 3306,
"targetPort": 3306
},
{
"name": "3307",
"protocol": "TCP",
"port": 3307,
"targetPort": 3307
}
],
"selector": {
"service": "mariadb"
}
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "Deployment",
"apiVersion": "extensions/v1beta1",
"metadata": {
"name": "etherpad",
"creationTimestamp": null
},
"spec": {
"replicas": 1,
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"service": "etherpad"
}
},
"spec": {
"containers": [
{
"name": "etherpad",
"image": "centos/etherpad",
"ports": [
{
"containerPort": 9001,
"protocol": "TCP"
},
{
"containerPort": 9001,
"protocol": "TCP"
}
],
"env": [
{
"name": "DB_USER",
"value": "openshift"
},
{
"name": "DB_DBID",
"value": "openshift"
},
{
"name": "DB_HOST",
"value": "openshift"
},
{
"name": "DB_PASS",
"value": "openshift"
},
{
"name": "DB_PORT",
"value": "openshift"
}
],
"resources": {}
}
],
"restartPolicy": "Always"
}
},
"strategy": {}
},
"status": {}
},
{
"kind": "Deployment",
"apiVersion": "extensions/v1beta1",
"metadata": {
"name": "mariadb",
"creationTimestamp": null
},
"spec": {
"replicas": 1,
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"service": "mariadb"
}
},
"spec": {
"volumes": [
{
"name": "mariadb-claim0",
"persistentVolumeClaim": {
"claimName": "mariadb-claim0"
}
},
{
"name": "mariadb-claim1",
"persistentVolumeClaim": {
"claimName": "mariadb-claim1"
}
}
],
"containers": [
{
"name": "mariadb",
"image": "centos/mariadb",
"ports": [
{
"containerPort": 3306,
"protocol": "TCP"
},
{
"containerPort": 3307,
"protocol": "TCP"
}
],
"env": [
{
"name": "MYSQL_PASSWORD",
"value": "openshift"
},
{
"name": "MYSQL_ROOT_PASSWORD",
"value": "openshift"
},
{
"name": "MYSQL_USER",
"value": "openshift"
},
{
"name": "MYSQL_DATABASE",
"value": "openshift"
}
],
"resources": {},
"volumeMounts": [
{
"name": "mariadb-claim0",
"mountPath": "/var/lib/mysql"
},
{
"name": "mariadb-claim1",
"mountPath": "/var/lib/mysql"
}
]
}
],
"restartPolicy": "Always"
}
},
"strategy": {}
},
"status": {}
},
{
"kind": "PersistentVolumeClaim",
"apiVersion": "v1",
"metadata": {
"name": "mariadb-claim0",
"creationTimestamp": null
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "100Mi"
}
}
},
"status": {}
},
{
"kind": "PersistentVolumeClaim",
"apiVersion": "v1",
"metadata": {
"name": "mariadb-claim1",
"creationTimestamp": null
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "100Mi"
}
}
},
"status": {}
}
]
}

View File

@ -0,0 +1,361 @@
{
"kind": "List",
"apiVersion": "v1",
"metadata": {},
"items": [
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "etherpad",
"creationTimestamp": null,
"labels": {
"service": "etherpad"
}
},
"spec": {
"ports": [
{
"name": "80",
"protocol": "TCP",
"port": 80,
"targetPort": 9001
},
{
"name": "80",
"protocol": "TCP",
"port": 80,
"targetPort": 9001
}
],
"selector": {
"service": "etherpad"
}
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "mariadb",
"creationTimestamp": null,
"labels": {
"service": "mariadb"
}
},
"spec": {
"ports": [
{
"name": "3306",
"protocol": "TCP",
"port": 3306,
"targetPort": 3306
},
{
"name": "3307",
"protocol": "TCP",
"port": 3307,
"targetPort": 3307
}
],
"selector": {
"service": "mariadb"
}
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "DeploymentConfig",
"apiVersion": "v1",
"metadata": {
"name": "etherpad",
"creationTimestamp": null,
"labels": {
"service": "etherpad"
}
},
"spec": {
"strategy": {
"resources": {}
},
"triggers": [
{
"type": "ConfigChange"
},
{
"type": "ImageChange",
"imageChangeParams": {
"automatic": true,
"containerNames": [
"etherpad"
],
"from": {
"kind": "ImageStreamTag",
"name": "etherpad:latest"
}
}
}
],
"replicas": 1,
"test": false,
"selector": {
"service": "etherpad"
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"service": "etherpad"
}
},
"spec": {
"containers": [
{
"name": "etherpad",
"image": " ",
"ports": [
{
"containerPort": 9001,
"protocol": "TCP"
},
{
"containerPort": 9001,
"protocol": "TCP"
}
],
"env": [
{
"name": "DB_DBID",
"value": "openshift"
},
{
"name": "DB_HOST",
"value": "openshift"
},
{
"name": "DB_PASS",
"value": "openshift"
},
{
"name": "DB_PORT",
"value": "openshift"
},
{
"name": "DB_USER",
"value": "openshift"
}
],
"resources": {}
}
],
"restartPolicy": "Always"
}
}
},
"status": {}
},
{
"kind": "ImageStream",
"apiVersion": "v1",
"metadata": {
"name": "etherpad",
"creationTimestamp": null
},
"spec": {
"tags": [
{
"name": "latest",
"annotations": null,
"from": {
"kind": "DockerImage",
"name": "centos/etherpad"
},
"generation": null,
"importPolicy": {}
}
]
},
"status": {
"dockerImageRepository": ""
}
},
{
"kind": "DeploymentConfig",
"apiVersion": "v1",
"metadata": {
"name": "mariadb",
"creationTimestamp": null,
"labels": {
"service": "mariadb"
}
},
"spec": {
"strategy": {
"resources": {}
},
"triggers": [
{
"type": "ConfigChange"
},
{
"type": "ImageChange",
"imageChangeParams": {
"automatic": true,
"containerNames": [
"mariadb"
],
"from": {
"kind": "ImageStreamTag",
"name": "mariadb:latest"
}
}
}
],
"replicas": 1,
"test": false,
"selector": {
"service": "mariadb"
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"service": "mariadb"
}
},
"spec": {
"volumes": [
{
"name": "mariadb-claim0",
"persistentVolumeClaim": {
"claimName": "mariadb-claim0"
}
},
{
"name": "mariadb-claim1",
"persistentVolumeClaim": {
"claimName": "mariadb-claim1"
}
}
],
"containers": [
{
"name": "mariadb",
"image": " ",
"ports": [
{
"containerPort": 3306,
"protocol": "TCP"
},
{
"containerPort": 3307,
"protocol": "TCP"
}
],
"env": [
{
"name": "MYSQL_DATABASE",
"value": "openshift"
},
{
"name": "MYSQL_PASSWORD",
"value": "openshift"
},
{
"name": "MYSQL_ROOT_PASSWORD",
"value": "openshift"
},
{
"name": "MYSQL_USER",
"value": "openshift"
}
],
"resources": {},
"volumeMounts": [
{
"name": "mariadb-claim0",
"mountPath": "/var/lib/mysql"
},
{
"name": "mariadb-claim1",
"mountPath": "/var/lib/mysql"
}
]
}
],
"restartPolicy": "Always"
}
}
},
"status": {}
},
{
"kind": "ImageStream",
"apiVersion": "v1",
"metadata": {
"name": "mariadb",
"creationTimestamp": null
},
"spec": {
"tags": [
{
"name": "latest",
"annotations": null,
"from": {
"kind": "DockerImage",
"name": "centos/mariadb"
},
"generation": null,
"importPolicy": {}
}
]
},
"status": {
"dockerImageRepository": ""
}
},
{
"kind": "PersistentVolumeClaim",
"apiVersion": "v1",
"metadata": {
"name": "mariadb-claim0",
"creationTimestamp": null
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "100Mi"
}
}
},
"status": {}
},
{
"kind": "PersistentVolumeClaim",
"apiVersion": "v1",
"metadata": {
"name": "mariadb-claim1",
"creationTimestamp": null
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "100Mi"
}
}
},
"status": {}
}
]
}