Fix OpenShift tests for build and push

This commit is contained in:
Anush Shetty
2017-08-09 19:15:44 +05:30
73 changed files with 3118 additions and 1768 deletions
+10
View File
@@ -0,0 +1,10 @@
{
"maxReviewers": 2,
"numFilesToCheck": 5,
"message": "@pullRequester, thank you for the pull request! We'll ping some people to review your PR. @reviewers, please review this.",
"fileBlacklist": ["*.md"],
"userBlacklist": ["ngtuna", "janetkuo", "sebgoa", "dustymabe", "gitlawr"],
"actions": ["opened", "labeled"],
"skipAlreadyMentionedPR": true,
"createReviewRequest": true
}
+1 -1
View File
@@ -5,7 +5,7 @@ sudo: required
language: go language: go
# make this also work for forks # make this also work for forks
go_import_path: github.com/kubernetes-incubator/kompose go_import_path: github.com/kubernetes/kompose
matrix: matrix:
include: include:
+642 -529
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -25,4 +25,4 @@ Note: Code-related PR's require two ACK's / LGTM's from a maintainer while doc-r
### Adding dependencies ### Adding dependencies
If your patch depends on new packages, add that package with [`glide`](https://github.com/Masterminds/glide). Follow the [instructions to add a dependency](https://github.com/kubernetes-incubator/kompose/blob/master/docs/development.md#glide-glide-vc-and-dependency-management). If your patch depends on new packages, add that package with [`glide`](https://github.com/Masterminds/glide). Follow the [instructions to add a dependency](https://github.com/kubernetes/kompose/blob/master/docs/development.md#glide-glide-vc-and-dependency-management).
Vendored
+13
View File
@@ -0,0 +1,13 @@
@Library('github.com/fabric8io/fabric8-pipeline-library@master')
def dummy
goTemplate{
dockerNode{
goMake{
githubOrganisation = 'kubernetes-incubator'
dockerOrganisation = 'fabric8'
project = 'kompose'
makeCommand = "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/go/bin:/usr/local/glide:/usr/local/:/go/bin:/home/jenkins/go/bin \
&& bash script/test/cmd/fix_detached_head.sh && make test"
}
}
}
+5 -3
View File
@@ -15,7 +15,7 @@
GITCOMMIT := $(shell git rev-parse --short HEAD) GITCOMMIT := $(shell git rev-parse --short HEAD)
BUILD_FLAGS := -ldflags="-w -X github.com/kubernetes-incubator/kompose/cmd.GITCOMMIT=$(GITCOMMIT)" BUILD_FLAGS := -ldflags="-w -X github.com/kubernetes/kompose/cmd.GITCOMMIT=$(GITCOMMIT)"
PKGS = $(shell glide novendor) PKGS = $(shell glide novendor)
TEST_IMAGE := kompose/tests:latest TEST_IMAGE := kompose/tests:latest
@@ -53,7 +53,7 @@ test-unit-cover:
go test -i -race -cover $(PKGS) go test -i -race -cover $(PKGS)
# go test doesn't support colleting coverage across multiple packages, # go test doesn't support colleting coverage across multiple packages,
# generate go test commands using go list and run go test for every package separately # generate go test commands using go list and run go test for every package separately
go list -f '"go test -race -cover -v -coverprofile={{.Dir}}/.coverprofile {{.ImportPath}}"' github.com/kubernetes-incubator/kompose/... | grep -v "vendor" | xargs -L 1 -P4 sh -c go list -f '"go test -race -cover -v -coverprofile={{.Dir}}/.coverprofile {{.ImportPath}}"' github.com/kubernetes/kompose/... | grep -v "vendor" | xargs -L 1 -P4 sh -c
# run openshift up/down tests # run openshift up/down tests
@@ -110,4 +110,6 @@ test-image:
test-container: test-container:
docker run -v `pwd`:/opt/tmp/kompose:ro -it $(TEST_IMAGE) docker run -v `pwd`:/opt/tmp/kompose:ro -it $(TEST_IMAGE)
.PHONE: test-ci
test-ci:
./script/test_ci/test.sh
+31 -32
View File
@@ -1,6 +1,6 @@
# Kompose (Kubernetes + Compose) # Kompose (Kubernetes + Compose)
[![Build Status Widget]][Build Status] [![Coverage Status Widget]][Coverage Status] [![GoDoc Widget]][GoDoc] [![Slack Widget]][Slack] [![Build Status Widget]][Build Status] [![Coverage Status Widget]][Coverage Status] [![GoDoc Widget]][GoDoc] [![GoReportCard Widget]][GoReportCardResult] [![Slack Widget]][Slack]
`kompose` is a tool to help users who are familiar with `docker-compose` move to [Kubernetes](http://kubernetes.io). `kompose` takes a Docker Compose file and translates it into Kubernetes resources. `kompose` is a tool to help users who are familiar with `docker-compose` move to [Kubernetes](http://kubernetes.io). `kompose` takes a Docker Compose file and translates it into Kubernetes resources.
@@ -8,10 +8,10 @@
## Use Case ## Use Case
Convert [`docker-compose.yaml`](https://raw.githubusercontent.com/kubernetes-incubator/kompose/master/examples/docker-compose.yaml) into Kubernetes deployments and services with one simple command: Convert [`docker-compose.yaml`](https://raw.githubusercontent.com/kubernetes/kompose/master/examples/docker-compose.yaml) into Kubernetes deployments and services with one simple command:
```sh ```sh
kompose convert -f docker-compose.yaml $ kompose convert -f docker-compose.yaml
INFO Kubernetes file "frontend-service.yaml" created INFO Kubernetes file "frontend-service.yaml" created
INFO Kubernetes file "redis-master-service.yaml" created INFO Kubernetes file "redis-master-service.yaml" created
INFO Kubernetes file "redis-slave-service.yaml" created INFO Kubernetes file "redis-slave-service.yaml" created
@@ -26,34 +26,36 @@ Other examples are provided in the _examples_ [directory](./examples).
We have multiple ways to install Kompose. Our prefered method is downloading the binary from the latest GitHub release. We have multiple ways to install Kompose. Our prefered method is downloading the binary from the latest GitHub release.
Our entire list of installation methods are located in our [setup.md](/docs/setup.md) document. Our entire list of installation methods are located in our [installation.md](/docs/installation.md) document.
Installation methods: Installation methods:
- [Binary (Prefered method)](README.md) - [Binary (Prefered method)](README.md)
- [Go](/docs/setup.md#go) - [Go](/docs/installation.md#go)
- [CentOS](/docs/setup.md#centos) - [CentOS](/docs/installation.md#centos)
- [Fedora](/docs/setup.md#fedora) - [Fedora](/docs/installation.md#fedora)
- [macOS (Homebrew)](/docs/setup.md#macos) - [macOS (Homebrew)](/docs/installation.md#macos)
- [Windows](docs/installation.md#windows)
#### Binary installation #### Binary installation
Kompose is released via GitHub on a three-week cycle, you can see all current releases on the [GitHub release page](https://github.com/kubernetes-incubator/kompose/releases). Kompose is released via GitHub on a three-week cycle, you can see all current releases on the [GitHub release page](https://github.com/kubernetes/kompose/releases).
__Linux and macOS:__
```sh ```sh
# Linux # Linux
curl -L https://github.com/kubernetes-incubator/kompose/releases/download/v0.7.0/kompose-linux-amd64 -o kompose curl -L https://github.com/kubernetes/kompose/releases/download/v1.0.0/kompose-linux-amd64 -o kompose
# macOS # macOS
curl -L https://github.com/kubernetes-incubator/kompose/releases/download/v0.7.0/kompose-darwin-amd64 -o kompose curl -L https://github.com/kubernetes/kompose/releases/download/v1.0.0/kompose-darwin-amd64 -o kompose
# Windows
curl -L https://github.com/kubernetes-incubator/kompose/releases/download/v0.7.0/kompose-windows-amd64.exe -o kompose.exe
chmod +x kompose chmod +x kompose
sudo mv ./kompose /usr/local/bin/kompose sudo mv ./kompose /usr/local/bin/kompose
``` ```
Alternatively, you can download the less-bandwidth intense [tarball](https://github.com/kubernetes-incubator/kompose/releases). __Windows:__
Download from [GitHub](https://github.com/kubernetes/kompose/releases/download/v1.0.0/kompose-windows-amd64.exe) and add the binary to your PATH.
## Shell autocompletion ## Shell autocompletion
@@ -101,12 +103,12 @@ $ make cross
## Documentation ## Documentation
Documentation can be found at our [kompose.io](http://kompose.io) website or our [docs](https://github.com/kubernetes-incubator/kompose/tree/master/docs) folder. Documentation can be found at our [kompose.io](http://kompose.io) website or our [docs](https://github.com/kubernetes/kompose/tree/master/docs) folder.
Here is a list of all available docs: Here is a list of all available docs:
- [Quick start](docs/quickstart.md) - [Quick start](docs/quickstart.md)
- [Setup](docs/setup.md) - [Installation](docs/installation.md)
- [User guide](docs/user-guide.md) - [User guide](docs/user-guide.md)
- [Conversion](docs/conversion.md) - [Conversion](docs/conversion.md)
- [Architecture](docs/architecture.md) - [Architecture](docs/architecture.md)
@@ -114,18 +116,13 @@ Here is a list of all available docs:
## Community, Discussion, Contribution, and Support ## Community, Discussion, Contribution, and Support
`kompose` is a work in progress, we will see how far it takes us. We welcome any pull request to make it even better. __Issues:__ If you find any issues, please [file it](https://github.com/kubernetes/kompose/issues).
If you find any issues, please [file it](https://github.com/kubernetes-incubator/kompose/issues).
As part of the Kubernetes ecosystem, we follow the Kubernetes community principles. More information can be found on the [community page](http://kubernetes.io/community/). __Kubernetes Community:__ As part of the Kubernetes ecosystem, we follow the Kubernetes community principles. More information can be found on the [community page](http://kubernetes.io/community/).
You can reach the maintainers of this project on [Slack](http://slack.kubernetes.io) in channel #kompose __Kubernetes Incubation:__ Kompose is being incubated into the Kubernetes community via [SIG-APPS](https://github.com/kubernetes/community/tree/master/sig-apps) on [kubernetes/community](https://github.com/kubernetes/community). [@ericchiang](https://github.com/ericchiang) is acting champion for [incubation](https://github.com/kubernetes/community/blob/master/incubator.md).
`kompose` is being incubated into the Kubernetes community via [SIG-APPS](https://github.com/kubernetes/community/tree/master/sig-apps) on [kubernetes/community](https://github.com/kubernetes/community). __Chat (Slack):__ We're fairly active on [Slack](http://slack.kubernetes.io#kompose) and you can find us in the #kompose channel.
[@ericchiang](https://github.com/ericchiang) is acting champion for [incubation](https://github.com/kubernetes/community/blob/master/incubator.md).
We do a biweekly community meeting which is [open to the public](https://bluejeans.com/404059616). Each week we outline what we have talked about in an [agenda doc](https://docs.google.com/document/d/1I5I21Cp_JZ9Az5MgMcu6Hl7m8WQ1Eqk_WeQLHenNom0/edit?usp=sharing). This meeting occurs every two weeks on Wednesday 18:00-19:00 GMT.
## Road Map ## Road Map
@@ -135,11 +132,13 @@ An up-to-date roadmap of upcoming releases is located at [ROADMAP.md](/ROADMAP.m
Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md). Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md).
[Build Status]: https://travis-ci.org/kubernetes-incubator/kompose [Build Status]: https://travis-ci.org/kubernetes/kompose
[Build Status Widget]: https://travis-ci.org/kubernetes-incubator/kompose.svg?branch=master [Build Status Widget]: https://travis-ci.org/kubernetes/kompose.svg?branch=master
[GoDoc]: https://godoc.org/github.com/kubernetes-incubator/kompose [GoDoc]: https://godoc.org/github.com/kubernetes/kompose
[GoDoc Widget]: https://godoc.org/github.com/kubernetes-incubator/kompose?status.svg [GoDoc Widget]: https://godoc.org/github.com/kubernetes/kompose?status.svg
[Slack]: http://slack.kubernetes.io#kompose [Slack]: http://slack.kubernetes.io#kompose
[Slack Widget]: https://s3.eu-central-1.amazonaws.com/ngtuna/join-us-on-slack.png [Slack Widget]: https://s3.eu-central-1.amazonaws.com/ngtuna/join-us-on-slack.png
[Coverage Status Widget]: https://coveralls.io/repos/github/kubernetes-incubator/kompose/badge.svg?branch=master [Coverage Status Widget]: https://coveralls.io/repos/github/kubernetes/kompose/badge.svg?branch=master
[Coverage Status]: https://coveralls.io/github/kubernetes-incubator/kompose?branch=master [Coverage Status]: https://coveralls.io/github/kubernetes/kompose?branch=master
[GoReportCard Widget]: https://goreportcard.com/badge/github.com/kubernetes/kompose
[GoReportCardResult]: https://goreportcard.com/report/github.com/kubernetes/kompose
+9 -9
View File
@@ -6,25 +6,25 @@ Here we outline our roadmap which encompasses our goals in reaching _1.0.0_.
__Release schedule:__ Kompose is on time-based release cycle. On a 3-4 week cycle, usually ending on the last week of each month. __Release schedule:__ Kompose is on time-based release cycle. On a 3-4 week cycle, usually ending on the last week of each month.
### [Kompose 0.6.0](https://github.com/kubernetes-incubator/kompose/releases/tag/v0.6.0) ### [Kompose 0.6.0](https://github.com/kubernetes/kompose/releases/tag/v0.6.0)
- [X] Adding more support for more currently unsupported docker-compose keys (cap_add and cap_drop added) [#580](https://github.com/kubernetes-incubator/kompose/pull/580) - [X] Adding more support for more currently unsupported docker-compose keys (cap_add and cap_drop added) [#580](https://github.com/kubernetes/kompose/pull/580)
- [X] Improved edge-cases for deployment (namespace + insecure-repository parameters added) [#547](https://github.com/kubernetes-incubator/kompose/pull/547) - [X] Improved edge-cases for deployment (namespace + insecure-repository parameters added) [#547](https://github.com/kubernetes/kompose/pull/547)
### [Kompose 0.7.0](https://github.com/kubernetes-incubator/kompose/releases/tag/v0.7.0) ### [Kompose 0.7.0](https://github.com/kubernetes/kompose/releases/tag/v0.7.0)
- [X] Args support added to `build` key [#424](https://github.com/kubernetes-incubator/kompose/pull/424) - [X] Args support added to `build` key [#424](https://github.com/kubernetes/kompose/pull/424)
- [X] Conversion bug fixes [#613](https://github.com/kubernetes-incubator/kompose/pull/613) [#606](https://github.com/kubernetes-incubator/kompose/pull/606) [#578](https://github.com/kubernetes-incubator/kompose/pull/578) - [X] Conversion bug fixes [#613](https://github.com/kubernetes/kompose/pull/613) [#606](https://github.com/kubernetes/kompose/pull/606) [#578](https://github.com/kubernetes/kompose/pull/578)
### Kompose 0.8.0 (end of June) ### Kompose 0.8.0 (end of June)
- [X] Basic support for docker-compose v3 format [#580](https://github.com/kubernetes-incubator/kompose/issues/412) [#600](https://github.com/kubernetes-incubator/kompose/pull/600) - [X] Basic support for docker-compose v3 format [#580](https://github.com/kubernetes/kompose/issues/412) [#600](https://github.com/kubernetes/kompose/pull/600)
- [X] Initial support for building and pushing containers locally [#97](https://github.com/kubernetes-incubator/kompose/issues/97) [#521](https://github.com/kubernetes-incubator/kompose/pull/521) - [X] Initial support for building and pushing containers locally [#97](https://github.com/kubernetes/kompose/issues/97) [#521](https://github.com/kubernetes/kompose/pull/521)
### Kompose 0.9.0 (end of July) ### Kompose 0.9.0 (end of July)
- [ ] Improved support for docker-compose v3 format - [ ] Improved support for docker-compose v3 format
- [ ] Kompose consumable as Go library [#464](https://github.com/kubernetes-incubator/kompose/issues/464) - [ ] Kompose consumable as Go library [#464](https://github.com/kubernetes/kompose/issues/464)
### Kompose 1.0.0 (???) ### Kompose 1.0.0 (???)
+1 -1
View File
@@ -10,7 +10,7 @@ Choose which version of the repo you want to build. For kompose it was 0.3.0 and
Run the following to generate spec file: Run the following to generate spec file:
```sh ```sh
gofed repo2spec --detect github.com/kubernetes-incubator/kompose --commit 135165b39c55d29a5426479ded81eddd56bfbaf4 --with-extra --with-build -f gofed repo2spec --detect github.com/kubernetes/kompose --commit 135165b39c55d29a5426479ded81eddd56bfbaf4 --with-extra --with-build -f
``` ```
The spec file is now located at: The spec file is now located at:
+1
View File
@@ -0,0 +1 @@
1.0.0
-2
View File
@@ -45,8 +45,6 @@ func Generate(cmd *cobra.Command, args []string) error {
return fmt.Errorf("Too many arguments. Expected only the shell type. ex. kompose completion [bash|zsh]") return fmt.Errorf("Too many arguments. Expected only the shell type. ex. kompose completion [bash|zsh]")
} }
shell := args[0] shell := args[0]
if shell != "bash" && shell != "zsh" {
}
// Generate bash through cobra if selected // Generate bash through cobra if selected
if shell == "bash" { if shell == "bash" {
+5 -4
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -20,8 +20,8 @@ import (
"strings" "strings"
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/kompose/pkg/app" "github.com/kubernetes/kompose/pkg/app"
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@@ -82,12 +82,13 @@ var convertCmd = &cobra.Command{
IsDeploymentFlag: cmd.Flags().Lookup("deployment").Changed, IsDeploymentFlag: cmd.Flags().Lookup("deployment").Changed,
IsDaemonSetFlag: cmd.Flags().Lookup("daemon-set").Changed, IsDaemonSetFlag: cmd.Flags().Lookup("daemon-set").Changed,
IsReplicationControllerFlag: cmd.Flags().Lookup("replication-controller").Changed, IsReplicationControllerFlag: cmd.Flags().Lookup("replication-controller").Changed,
IsReplicaSetFlag: cmd.Flags().Lookup("replicas").Changed,
IsDeploymentConfigFlag: cmd.Flags().Lookup("deployment-config").Changed, IsDeploymentConfigFlag: cmd.Flags().Lookup("deployment-config").Changed,
} }
// Validate before doing anything else. Use "bundle" if passed in. // Validate before doing anything else. Use "bundle" if passed in.
app.ValidateFlags(GlobalBundle, args, cmd, &ConvertOpt) app.ValidateFlags(GlobalBundle, args, cmd, &ConvertOpt)
app.ValidateComposeFile(cmd, &ConvertOpt) app.ValidateComposeFile(&ConvertOpt)
}, },
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
+4 -4
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -19,8 +19,8 @@ package cmd
import ( import (
"strings" "strings"
"github.com/kubernetes-incubator/kompose/pkg/app" "github.com/kubernetes/kompose/pkg/app"
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@@ -45,7 +45,7 @@ var downCmd = &cobra.Command{
} }
// Validate before doing anything else. // Validate before doing anything else.
app.ValidateComposeFile(cmd, &DownOpt) app.ValidateComposeFile(&DownOpt)
}, },
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
app.Down(DownOpt) app.Down(DownOpt)
+3 -3
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -103,7 +103,7 @@ func init() {
RootCmd.PersistentFlags().StringVarP(&GlobalBundle, "bundle", "b", "", "Specify a Distributed Application Bundle (DAB) file") RootCmd.PersistentFlags().StringVarP(&GlobalBundle, "bundle", "b", "", "Specify a Distributed Application Bundle (DAB) file")
RootCmd.PersistentFlags().StringVar(&GlobalProvider, "provider", "kubernetes", "Specify a provider. Kubernetes or OpenShift.") RootCmd.PersistentFlags().StringVar(&GlobalProvider, "provider", "kubernetes", "Specify a provider. Kubernetes or OpenShift.")
// Mark DAB / bundle as deprecated, see issue: https://github.com/kubernetes-incubator/kompose/issues/390 // Mark DAB / bundle as deprecated, see issue: https://github.com/kubernetes/kompose/issues/390
// As DAB is still EXPERIMENTAL // As DAB is still EXPERIMENTAL
RootCmd.PersistentFlags().MarkDeprecated("bundle", "DAB / Bundle is deprecated, see: https://github.com/kubernetes-incubator/kompose/issues/390") RootCmd.PersistentFlags().MarkDeprecated("bundle", "DAB / Bundle is deprecated, see: https://github.com/kubernetes/kompose/issues/390")
} }
+4 -4
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -20,8 +20,8 @@ import (
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
"strings" "strings"
"github.com/kubernetes-incubator/kompose/pkg/app" "github.com/kubernetes/kompose/pkg/app"
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@@ -60,7 +60,7 @@ var upCmd = &cobra.Command{
} }
// Validate before doing anything else. // Validate before doing anything else.
app.ValidateComposeFile(cmd, &UpOpt) app.ValidateComposeFile(&UpOpt)
}, },
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
app.Up(UpOpt) app.Up(UpOpt)
+3 -3
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -24,9 +24,9 @@ import (
var ( var (
// VERSION is version number that wil be displayed when running ./kompose version // VERSION is version number that wil be displayed when running ./kompose version
VERSION = "0.7.0" VERSION = "1.0.0"
// GITCOMMIT is hash of the commit that wil be displayed when running ./kompose version // GITCOMMIT is hash of the commit that wil be displayed when running ./kompose version
// this will be overwritten when running build like this: go build -ldflags="-X github.com/kubernetes-incubator/kompose/cmd.GITCOMMIT=$(GITCOMMIT)" // this will be overwritten when running build like this: go build -ldflags="-X github.com/kubernetes/kompose/cmd.GITCOMMIT=$(GITCOMMIT)"
// HEAD is default indicating that this was not set during build // HEAD is default indicating that this was not set during build
GITCOMMIT = "HEAD" GITCOMMIT = "HEAD"
) )
+2 -2
View File
@@ -1,4 +1,4 @@
# Internal Design # Architecture and Internal Design
`kompose` has 3 stages: Loader, Transformer and Outputter. Each Stage should have well defined interface so it is easy to write new Loader, Transformer or Outputters and plug it in. Currently only Loader and Transformer interfaces are defined. `kompose` has 3 stages: Loader, Transformer and Outputter. Each Stage should have well defined interface so it is easy to write new Loader, Transformer or Outputters and plug it in. Currently only Loader and Transformer interfaces are defined.
@@ -24,7 +24,7 @@ Every loader “implementation” should be placed into `kompose/pkg/loader` (li
## KomposeObject ## KomposeObject
`KomposeObject` is Kompose internal representation of all containers loaded from input file. First version of `KomposeObject` looks like this (source: [kobject.go](https://github.com/kubernetes-incubator/kompose/blob/master/pkg/kobject/kobject.go)): `KomposeObject` is Kompose internal representation of all containers loaded from input file. First version of `KomposeObject` looks like this (source: [kobject.go](https://github.com/kubernetes/kompose/blob/master/pkg/kobject/kobject.go)):
```go ```go
// KomposeObject holds the generic struct of Kompose transformation // KomposeObject holds the generic struct of Kompose transformation
+54 -39
View File
@@ -1,65 +1,80 @@
# Conversion reference # Conversion Matrix
This document outlines all possible conversion details regarding `docker-compose.yaml` values to Kubernetes / OpenShift artifacts. This includes version 1, 2 and 3 of Docker Compose. This document outlines all possible conversion details regarding `docker-compose.yaml` values to Kubernetes / OpenShift artifacts. This convers *major* versions of Docker Compose such as 1, 2 and 3.
__Note:__ due to the fast-pace nature of Docker Compose version revisions, minor versions such as 2.1, 2.2, 3.1, 3.2 or 3.3 are not supported until they are cut into a major version release such as 2 or 3.
__Glossary:__
__Y:__ Converts
__N:__ Not yet implemented
__N/A:__ Not applicable / no 1-1 conversion
| Value | Support | K8s / OpenShift | Notes | | Value | Support | K8s / OpenShift | Notes |
|-------------------|---------|------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| |-------------------|---------|------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|
| SERVICE | | | | | __Service__ | | | |
| build | Y | OpenShift: BuildConfig | Converts, but local builds are not yet supported. See issue 97 | | build | Y | Builds/Pushes to Docker repository. See `--build` parameter | Only supported on Version 1/2 of Docker Compose |
| cap_add, cap_drop | Y | Pod.Spec.Container.SecurityContext.Capabilities.Add/Drop | | | cap_add, cap_drop | Y | Pod.Spec.Container.SecurityContext.Capabilities.Add/Drop | |
| command | Y | Pod.Spec.Container.Command | | | command | Y | Pod.Spec.Container.Command | |
| cgroup_parent | N | | No compatibility with Kubernetes / OpenShift. Limited use-cases with Docker. | | cgroup_parent | N/A | | Not supported within Kubernetes. See issue https://github.com/kubernetes/kubernetes/issues/11986 |
| container_name | Y | Mapped to both Metadata.Name and Deployment.Spec.Containers.Name | | | container_name | Y | Metadata.Name + Deployment.Spec.Containers.Name | |
| deploy | N | | Upcoming support started | | devices | N/A | | Not supported within Kubernetes, See issue https://github.com/kubernetes/kubernetes/issues/5607 |
| devices | N | | Not supported within Kubernetes, see this issue | | depends_on | N/A | | No 1-1 mapping, Kubernetes uses a flat architecture |
| depends_on | N | | | | dns | N/A | | Not used within Kubernetes. Kubernetes uses a managed DNS server |
| dns | N | | | | dns_search | N/A | | See `dns` key |
| dns_search | N | | |
| tmpfs | Y | Pod.Spec.Containers.Volumes.EmptyDir | Creates emptyDirvolume with medium set to Memory & mounts given directory inside container | | tmpfs | Y | Pod.Spec.Containers.Volumes.EmptyDir | Creates emptyDirvolume with medium set to Memory & mounts given directory inside container |
| entrypoint | Y | Pod.Spec.Container.Command | Same as command | | entrypoint | Y | Pod.Spec.Container.Command | Same as command |
| env_file | N | | | | env_file | N | | |
| environment | Y | Pod.Spec.Container.Env | | | environment | Y | Pod.Spec.Container.Env | |
| expose | Y | Service.Spec.Ports | | | expose | Y | Service.Spec.Ports | |
| extends | Y | | Extends by utilizing the same image supplied | | extends | Y | | Extends by utilizing the same image supplied |
| external_links | N | | | | external_links | N/A | | Kubernetes uses a flat-structure for all containers and thus external_links does not have a 1-1 conversion |
| extra_hosts | N | | | | extra_hosts | N | | |
| group_add | N | | | | group_add | N | | |
| healthcheck | N | | | | healthcheck | N | | |
| image | Y | Deployment.Spec.Containers.Image | | | image | Y | Deployment.Spec.Containers.Image | |
| isolation | N | | | | isolation | N/A | | Not applicable as this applies to Windows with HyperV support |
| labels | Y | Metadata.Annotations | | | labels | Y | Metadata.Annotations | |
| links | N | | | | links | N/A | | All containers in the same pod are accessible in Kubernetes |
| logging | N | | | | logging | N/A | | Kubernetes has built-in logging support at the node-level |
| network_mode | N | | | | network_mode | N/A | | Kubernetes uses it's own cluster networking |
| networks | N | | | | networks | N/A | | See `networks` key |
| pid | Y | Pod.Spec.HostPID | | | pid | Y | Pod.Spec.HostPID | |
| ports | Y | Service.Spec.Ports | | | ports | Y | Service.Spec.Ports | |
| security_opt | N | | | | security_opt | N/A | | Kubernetes uses it's own container naming scheme |
| stop_grace_period | Y | Pod.Spec.TerminationGracePeriodSeconds | | | stop_grace_period | Y | Pod.Spec.TerminationGracePeriodSeconds | |
| stop_signal | N | | | | stop_signal | N/A | | Not supported within Kubernetes. See issue https://github.com/kubernetes/kubernetes/issues/30051 |
| sysctls | N | | | | sysctls | N | | |
| ulimits | N | | See this issue on the k8s repo | | ulimits | N/A | | Not supported within Kubernetes. See issue https://github.com/kubernetes/kubernetes/issues/3595 |
| userns_mode | N | | | | userns_mode | N/A | | Not supported within Kubernetes and ignored in Docker Compose Version 3 |
| volumes | Y | PersistentVolumeClaim | Creates a PersistentVolumeClaim. Can only be created if there is already a PersistentVolume within the cluster | | volumes | Y | PersistentVolumeClaim | Creates a PersistentVolumeClaim. Can only be created if there is already a PersistentVolume within the cluster |
| volume_driver | N | | | | volume_driver | N/A | | Different plugins for different volumes, see: https://kubernetes.io/docs/concepts/storage/volumes/ |
| volumes_from | Y | PersistentVolumeClaim | Creates a PersistentVolumeClaim that is both shared by deployment and deployment config (OpenShift) | | volumes_from | Y | PersistentVolumeClaim | Creates a PersistentVolumeClaim that is both shared by deployment and deployment config (OpenShift) |
| cpu_shares | N | | | | cpu_shares | Y | | No direct mapping, use `resources` key within Docker Compose Version 3 `deploy` |
| cpu_quota | N | | | | cpu_quota | Y | | No direct mapping, use `resources` key within Docker Compose Version 3 `deploy` |
| cpuset | N | | | | cpuset | Y | | No direct mapping, use `resources` key within Docker Compose Version 3 `deploy` |
| mem_limit | Y | Containers.Resources.Limits.Memory | | | mem_limit | Y | Containers.Resources.Limits.Memory | Maps, but recommended to use `resources` key within Version 3 `deploy` |
| memswap_limit | N | | Use mem_limit | | memswap_limit | N/A | | Removed in V3+, use mem_limit |
| | | | | | | | | |
| VOLUME | | | | | __Deploy__ | | | |
| driver | N | | | | mode | N | | |
| driver_opts | N | | | | replicas | Y | Deployment.Spec.Replicas / DeploymentConfig.Spec.Replicas | |
| external | N | | | | placement | N | | |
| update_config | N | | |
| resources | Y | Containers.Resources.Limits / Containers.Resources.Requests | Supports memory/cpu limits as well as memory/cpu requests |
| restart_policy | Y | Pod generation | This generated a Pod, see the [user guide on restart](http://kompose.io/user-guide/#restart) |
| labels | N | | | | labels | N | | |
| | | | | | | | | |
| NETWORK | | | | | __Volume__ | N/A | | |
| driver | N | | | | driver | N/A | | |
| driver_opts | N | | | | driver_opts | N/A | | |
| enable_ipv6 | N | | | | external | N/A | | |
| ipam | N | | | | labels | N/A | | |
| internal | N | | | | | | | |
| labels | N | | | | __Network__ | N/A | | |
| external | N | | | | driver | N/A | | |
| driver_opts | N/A | | |
| enable_ipv6 | N/A | | |
| ipam | N/A | | |
| internal | N/A | | |
| labels | N/A | | |
| external | N/A | | |
+6 -6
View File
@@ -2,12 +2,12 @@
## Building Kompose ## Building Kompose
Read about building kompose [here](https://github.com/kubernetes-incubator/kompose#building). Read about building kompose [here](https://github.com/kubernetes/kompose#building).
## Workflow ## Workflow
### Fork the main repository ### Fork the main repository
1. Go to https://github.com/kubernetes-incubator/kompose 1. Go to https://github.com/kubernetes/kompose
2. Click the "Fork" button (at the top right) 2. Click the "Fork" button (at the top right)
### Clone your fork ### Clone your fork
@@ -15,9 +15,9 @@ Read about building kompose [here](https://github.com/kubernetes-incubator/kompo
The commands below require that you have $GOPATH. We highly recommended you put Kompose' code into your $GOPATH. The commands below require that you have $GOPATH. We highly recommended you put Kompose' code into your $GOPATH.
```console ```console
git clone https://github.com/$YOUR_GITHUB_USERNAME/kompose.git $GOPATH/src/github.com/kubernetes-incubator/kompose git clone https://github.com/$YOUR_GITHUB_USERNAME/kompose.git $GOPATH/src/github.com/kubernetes/kompose
cd $GOPATH/src/github.com/kubernetes-incubator/kompose cd $GOPATH/src/github.com/kubernetes/kompose
git remote add upstream 'https://github.com/kubernetes-incubator/kompose' git remote add upstream 'https://github.com/kubernetes/kompose'
``` ```
### Create a branch and make changes ### Create a branch and make changes
@@ -34,7 +34,7 @@ git fetch upstream
git rebase upstream/master git rebase upstream/master
``` ```
Note: If you have write access to the main repository at github.com/kubernetes-incubator/kompose, you should modify your git configuration so that you can't accidentally push to upstream: Note: If you have write access to the main repository at github.com/kubernetes/kompose, you should modify your git configuration so that you can't accidentally push to upstream:
```console ```console
git remote set-url --push upstream no_push git remote set-url --push upstream no_push
+18 -10
View File
@@ -4,30 +4,31 @@ We have multiple ways to install Kompose. Our prefered method is downloading the
#### GitHub release #### GitHub release
Kompose is released via GitHub on a three-week cycle, you can see all current releases on the [GitHub release page](https://github.com/kubernetes-incubator/kompose/releases). Kompose is released via GitHub on a three-week cycle, you can see all current releases on the [GitHub release page](https://github.com/kubernetes/kompose/releases).
__Linux and macOS:__
```sh ```sh
# Linux # Linux
curl -L https://github.com/kubernetes-incubator/kompose/releases/download/v0.7.0/kompose-linux-amd64 -o kompose curl -L https://github.com/kubernetes/kompose/releases/download/v1.0.0/kompose-linux-amd64 -o kompose
# macOS # macOS
curl -L https://github.com/kubernetes-incubator/kompose/releases/download/v0.7.0/kompose-darwin-amd64 -o kompose curl -L https://github.com/kubernetes/kompose/releases/download/v1.0.0/kompose-darwin-amd64 -o kompose
# Windows
curl -L https://github.com/kubernetes-incubator/kompose/releases/download/v0.7.0/kompose-windows-amd64.exe -o kompose.exe
chmod +x kompose chmod +x kompose
sudo mv ./kompose /usr/local/bin/kompose sudo mv ./kompose /usr/local/bin/kompose
``` ```
Alternatively, you can download the [tarball](https://github.com/kubernetes-incubator/kompose/releases). __Windows:__
Download from [GitHub](https://github.com/kubernetes/kompose/releases/download/v1.0.0/kompose-windows-amd64.exe) and add the binary to your PATH.
#### Go #### Go
Installing using `go get` pulls from the master branch with the latest development changes. Installing using `go get` pulls from the master branch with the latest development changes.
```sh ```sh
go get -u github.com/kubernetes-incubator/kompose go get -u github.com/kubernetes/kompose
``` ```
#### CentOS #### CentOS
@@ -36,12 +37,13 @@ Kompose is in [EPEL](https://fedoraproject.org/wiki/EPEL) CentOS repository.
If you don't have [EPEL](https://fedoraproject.org/wiki/EPEL) repository already installed and enabled you can do it by running `sudo yum install epel-release` If you don't have [EPEL](https://fedoraproject.org/wiki/EPEL) repository already installed and enabled you can do it by running `sudo yum install epel-release`
If you have [EPEL](https://fedoraproject.org/wiki/EPEL) enabled in your system, you can install Kompose like any other package. If you have [EPEL](https://fedoraproject.org/wiki/EPEL) enabled in your system, you can install Kompose like any other package.
```bash ```bash
sudo yum -y install kompose sudo yum -y install kompose
``` ```
#### Fedora #### Fedora
Kompose is in Fedora 24 and 25 repositories. You can install it just like any other package. Kompose is in Fedora 24, 25 and 26 repositories. You can install it just like any other package.
```bash ```bash
sudo dnf -y install kompose sudo dnf -y install kompose
@@ -52,5 +54,11 @@ On macOS you can install latest release via [Homebrew](https://brew.sh):
```bash ```bash
brew install kompose brew install kompose
```
#### Windows
Kompose can be installed via [Chocolatey](https://chocolatey.org/packages/kubernetes-kompose)
```console
choco install kubernetes-kompose
``` ```
+33
View File
@@ -0,0 +1,33 @@
# Integrations
There are some projects out there known to use Kompose integrated in some form or another
### Kompose UI by Jad Chamoun (ICANN) and Joe Haddad (Anghami)
__Description:__ "A web interface to convert Docker Compose files to Kubernetes YAML"
__Link:__ [https://github.com/JadCham/komposeui](https://github.com/JadCham/komposeui)
### Kompose Docker Container by Cloudfind
__Description:__ "A Docker container for the Kompose translator for docker-compose"
__Link:__ [https://github.com/cloudfind/kompose-docker](https://github.com/JadCham/komposeui)
### KPM by CoreOS
__Description:__ "KPM is a tool to deploy and manage application stacks on Kubernetes"
__Link:__ [https://github.com/coreos/kpm](https://github.com/coreos/kpm)
### Docker Image for Adobe Enterprise Manager by Adfinis SysGroup AG
__Description:__ "Docker Image for Adobe Enterprise Manager"
__Link:__ [https://github.com/adfinis-sygroup/aem-docker/tree/master](https://github.com/adfinis-sygroup/aem-docker/tree/master)
### Kompose Ansible Playbook by Chris Houseknecht (Red Hat)
__Description:__ "Download and unarchive the latest kompose release asset for your OS"
__Link:__ [https://github.com/chouseknecht/kompose-install-role](https://github.com/chouseknecht/kompose-install-role)
+6 -8
View File
@@ -2,8 +2,6 @@
What's Kompose? It's a conversion tool for all things compose (namely Docker Compose) to container orchestrators (Kubernetes or OpenShift). What's Kompose? It's a conversion tool for all things compose (namely Docker Compose) to container orchestrators (Kubernetes or OpenShift).
Whether you have a `docker-compose.yaml` or a `docker-compose.dab`, it doesn't matter. Kompose will get you up-and-running on Kubernetes.
In three simple steps, we'll take you from Docker Compose to Kubernetes. In three simple steps, we'll take you from Docker Compose to Kubernetes.
__1. Take a sample docker-compose.yaml file__ __1. Take a sample docker-compose.yaml file__
@@ -38,7 +36,7 @@ services:
__2. Run `kompose up` in the same directory__ __2. Run `kompose up` in the same directory__
```bash ```bash
kompose up $ kompose up
We are going to create Kubernetes Deployments, Services and PersistentVolumeClaims for your Dockerized application. We are going to create Kubernetes Deployments, Services and PersistentVolumeClaims for your Dockerized application.
If you need different kind of resources, use the 'kompose convert' and 'kubectl create -f' commands instead. If you need different kind of resources, use the 'kompose convert' and 'kubectl create -f' commands instead.
@@ -55,7 +53,7 @@ __Alternatively, you can run `kompose convert` and deploy with `kubectl`__
__2.1. Run `kompose convert` in the same directory__ __2.1. Run `kompose convert` in the same directory__
```bash ```bash
kompose convert $ kompose convert
INFO Kubernetes file "frontend-service.yaml" created INFO Kubernetes file "frontend-service.yaml" created
INFO Kubernetes file "redis-master-service.yaml" created INFO Kubernetes file "redis-master-service.yaml" created
INFO Kubernetes file "redis-slave-service.yaml" created INFO Kubernetes file "redis-slave-service.yaml" created
@@ -67,7 +65,7 @@ INFO Kubernetes file "redis-slave-deployment.yaml" created
__2.2. And start it on Kubernetes!__ __2.2. And start it on Kubernetes!__
```bash ```bash
kubectl create -f frontend-service.yaml,redis-master-service.yaml,redis-slave-service.yaml,frontend-deployment.yaml,redis-master-deployment.yaml,redis-slave-deployment.yaml $ kubectl create -f frontend-service.yaml,redis-master-service.yaml,redis-slave-service.yaml,frontend-deployment.yaml,redis-master-deployment.yaml,redis-slave-deployment.yaml
service "frontend" created service "frontend" created
service "redis-master" created service "redis-master" created
service "redis-slave" created service "redis-slave" created
@@ -83,13 +81,13 @@ Now that your service has been deployed, let's access it.
If you're already using `minikube` for your development process: If you're already using `minikube` for your development process:
```bash ```bash
minikube service frontend $ minikube service frontend
``` ```
Otherwise, let's look up what IP your service is using! Otherwise, let's look up what IP your service is using!
```sh ```sh
kubectl describe svc frontend $ kubectl describe svc frontend
Name: frontend Name: frontend
Namespace: default Namespace: default
Labels: service=frontend Labels: service=frontend
@@ -108,5 +106,5 @@ No events.
If you're using a cloud provider, your IP will be listed next to `LoadBalancer Ingress`. If you're using a cloud provider, your IP will be listed next to `LoadBalancer Ingress`.
```sh ```sh
curl http://123.45.67.89 $ curl http://123.45.67.89
``` ```
+84 -98
View File
@@ -1,48 +1,27 @@
# User Guide # User Guide
- [Usage](#user-guide) - CLI
* [Kompose convert](#kompose-convert) - [`kompose convert`](#kompose-convert)
* [Kompose up](#kompose-up) - [`kompose up`](#kompose-up)
* [Kompose down](#kompose-down) - [`kompose down`](#kompose-down)
- [Alternate formats](#alternate-formats) - Documentation
- [Unsupported docker-compose configuration options](#unsupported-docker-compose-configuration-options) - [Build and Push Docker Images](#build-and-push-docker-images)
- [Alternative Conversions](#alternative-conversions)
- [Labels](#labels)
- [Restart](#restart)
- [Docker Compose Versions](#docker-compose-versions)
Kompose has support for two providers: OpenShift and Kubernetes. Kompose has support for two providers: OpenShift and Kubernetes.
You can choose targeted provider either using global option `--provider`, or by setting environment variable `PROVIDER`. You can choose a targeted provider using global option `--provider`. If no provider is specified, Kubernetes is set by default.
By setting environment variable `PROVIDER` you can permanently switch to OpenShift provider without need to always specify `--provider openshift` option.
If no provider is specified Kubernetes is default provider.
## Kompose convert ## `kompose convert`
Currently Kompose supports to transform either Docker Compose file (both of v1 and v2) and [experimental Distributed Application Bundles](https://blog.docker.com/2016/06/docker-app-bundle/) into Kubernetes and OpenShift objects. Kompose supports conversion of V1, V2, and V3 Docker Compose files into Kubernetes and OpenShift objects.
There is a couple of sample files in the `examples/` directory for testing.
You will convert the compose or dab file to Kubernetes or OpenShift objects with `kompose convert`.
### Kubernetes ### Kubernetes
```console
$ cd examples/
$ ls ```sh
docker-compose.yml docker-compose-bundle.dab docker-gitlab.yml docker-voting.yml
$ kompose -f docker-gitlab.yml convert
INFO Kubernetes file "redisio-svc.yaml" created
INFO Kubernetes file "gitlab-svc.yaml" created
INFO Kubernetes file "postgresql-svc.yaml" created
INFO Kubernetes file "gitlab-deployment.yaml" created
INFO Kubernetes file "postgresql-deployment.yaml" created
INFO Kubernetes file "redisio-deployment.yaml" created
$ ls *.yaml
gitlab-deployment.yaml postgresql-deployment.yaml redis-deployment.yaml redisio-svc.yaml web-deployment.yaml
gitlab-svc.yaml postgresql-svc.yaml redisio-deployment.yaml redis-svc.yaml web-svc.yaml
```
You can try with a Docker Compose version 2 like this:
```console
$ kompose --file docker-voting.yml convert $ kompose --file docker-voting.yml convert
WARN Unsupported key networks - ignoring WARN Unsupported key networks - ignoring
WARN Unsupported key build - ignoring WARN Unsupported key build - ignoring
@@ -59,12 +38,12 @@ INFO Kubernetes file "db-deployment.yaml" created
$ ls $ ls
db-deployment.yaml docker-compose.yml docker-gitlab.yml redis-deployment.yaml result-deployment.yaml vote-deployment.yaml worker-deployment.yaml db-deployment.yaml docker-compose.yml docker-gitlab.yml redis-deployment.yaml result-deployment.yaml vote-deployment.yaml worker-deployment.yaml
db-svc.yaml docker-compose-bundle.dab docker-voting.yml redis-svc.yaml result-svc.yaml vote-svc.yaml worker-svc.yaml db-svc.yaml docker-voting.yml redis-svc.yaml result-svc.yaml vote-svc.yaml worker-svc.yaml
``` ```
You can also provide multiple docker-compose files at the same time: You can also provide multiple docker-compose files at the same time:
```console ```sh
$ kompose -f docker-compose.yml -f docker-guestbook.yml convert $ kompose -f docker-compose.yml -f docker-guestbook.yml convert
INFO Kubernetes file "frontend-service.yaml" created INFO Kubernetes file "frontend-service.yaml" created
INFO Kubernetes file "mlbparks-service.yaml" created INFO Kubernetes file "mlbparks-service.yaml" created
@@ -87,20 +66,9 @@ redis-master-deployment.yaml
When multiple docker-compose files are provided the configuration is merged. Any configuration that is common will be over ridden by subsequent file. 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
$ kompose --bundle docker-compose-bundle.dab convert
WARN: Unsupported key networks - ignoring
INFO Kubernetes file "redis-svc.yaml" created
INFO Kubernetes file "web-svc.yaml" created
INFO Kubernetes file "web-deployment.yaml" created
INFO Kubernetes file "redis-deployment.yaml" created
```
### OpenShift ### OpenShift
```console ```sh
$ kompose --provider openshift --file docker-voting.yml convert $ kompose --provider openshift --file docker-voting.yml convert
WARN [worker] Service cannot be created because of missing port. WARN [worker] Service cannot be created because of missing port.
INFO OpenShift file "vote-service.yaml" created INFO OpenShift file "vote-service.yaml" created
@@ -119,21 +87,9 @@ INFO OpenShift file "result-deploymentconfig.yaml" created
INFO OpenShift file "result-imagestream.yaml" created INFO OpenShift file "result-imagestream.yaml" created
``` ```
In similar way you can convert DAB files to OpenShift.
```console
$ kompose --bundle docker-compose-bundle.dab --provider openshift convert
WARN: Unsupported key networks - ignoring
INFO OpenShift file "redis-svc.yaml" created
INFO OpenShift file "web-svc.yaml" created
INFO OpenShift file "web-deploymentconfig.yaml" created
INFO OpenShift file "web-imagestream.yaml" created
INFO OpenShift file "redis-deploymentconfig.yaml" created
INFO OpenShift file "redis-imagestream.yaml" created
```
It also supports creating buildconfig for build directive in a service. By default, it uses the remote repo for the current git branch as the source repo, and the current branch as the source branch for the build. You can specify a different source repo and branch using ``--build-repo`` and ``--build-branch`` options respectively. It also supports creating buildconfig for build directive in a service. By default, it uses the remote repo for the current git branch as the source repo, and the current branch as the source branch for the build. You can specify a different source repo and branch using ``--build-repo`` and ``--build-branch`` options respectively.
```console ```sh
$ kompose --provider openshift --file buildconfig/docker-compose.yml convert $ kompose --provider openshift --file buildconfig/docker-compose.yml convert
WARN [foo] Service cannot be created because of missing port. WARN [foo] Service cannot be created because of missing port.
INFO OpenShift Buildconfig using git@github.com:rtnpro/kompose.git::master as source. INFO OpenShift Buildconfig using git@github.com:rtnpro/kompose.git::master as source.
@@ -144,13 +100,13 @@ INFO OpenShift file "foo-buildconfig.yaml" created
**Note**: If you are manually pushing the Openshift artifacts using ``oc create -f``, you need to ensure that you push the imagestream artifact before the buildconfig artifact, to workaround this Openshift issue: https://github.com/openshift/origin/issues/4518 . **Note**: If you are manually pushing the Openshift artifacts using ``oc create -f``, you need to ensure that you push the imagestream artifact before the buildconfig artifact, to workaround this Openshift issue: https://github.com/openshift/origin/issues/4518 .
## Kompose up ## `kompose up`
Kompose supports a straightforward way to deploy your "composed" application to Kubernetes or OpenShift via `kompose up`. Kompose supports a straightforward way to deploy your "composed" application to Kubernetes or OpenShift via `kompose up`.
### Kubernetes ### Kubernetes
```console ```sh
$ kompose --file ./examples/docker-guestbook.yml up $ kompose --file ./examples/docker-guestbook.yml up
We are going to create Kubernetes deployments and services for your Dockerized application. We are going to create Kubernetes deployments and services for your Dockerized application.
If you need different kind of resources, use the 'kompose convert' and 'kubectl create -f' commands instead. If you need different kind of resources, use the 'kompose convert' and 'kubectl create -f' commands instead.
@@ -186,8 +142,8 @@ Note:
- Only deployments and services are generated and deployed to Kubernetes. If you need different kind of resources, use the 'kompose convert' and 'kubectl create -f' commands instead. - Only deployments and services are generated and deployed to Kubernetes. If you need different kind of resources, use the 'kompose convert' and 'kubectl create -f' commands instead.
### OpenShift ### OpenShift
```console ```sh
$kompose --file ./examples/docker-guestbook.yml --provider openshift up $ kompose --file ./examples/docker-guestbook.yml --provider openshift up
We are going to create OpenShift DeploymentConfigs and Services for your Dockerized application. We are going to create OpenShift DeploymentConfigs and Services for your Dockerized application.
If you need different kind of resources, use the 'kompose convert' and 'oc create -f' commands instead. If you need different kind of resources, use the 'kompose convert' and 'oc create -f' commands instead.
@@ -221,11 +177,11 @@ is/redis-slave 172.30.12.200:5000/fff/redis-slave v1
Note: Note:
- You must have a running OpenShift cluster with a pre-configured `oc` context (`oc login`) - You must have a running OpenShift cluster with a pre-configured `oc` context (`oc login`)
## Kompose down ## `kompose down`
Once you have deployed "composed" application to Kubernetes, `kompose down` will help you to take the application out by deleting its deployments and services. If you need to remove other resources, use the 'kubectl' command. Once you have deployed "composed" application to Kubernetes, `$ kompose down` will help you to take the application out by deleting its deployments and services. If you need to remove other resources, use the 'kubectl' command.
```console ```sh
$ kompose --file docker-guestbook.yml down $ kompose --file docker-guestbook.yml down
INFO Successfully deleted service: redis-master INFO Successfully deleted service: redis-master
INFO Successfully deleted deployment: redis-master INFO Successfully deleted deployment: redis-master
@@ -237,11 +193,58 @@ INFO Successfully deleted deployment: frontend
Note: Note:
- You must have a running Kubernetes cluster with a pre-configured kubectl context. - You must have a running Kubernetes cluster with a pre-configured kubectl context.
## Alternate formats ## Build and Push Docker Images
Kompose supports both building and pushing Docker images. When using the `build` key within your Docker Compose file, your image will:
- Automatically be built with Docker using the `image` key specified within your file
- Be pushed to the correct Docker repository using local credentials (located at `.docker/config`)
Using an [example Docker Compose file](https://raw.githubusercontent.com/kubernetes/kompose/master/examples/buildconfig/docker-compose.yml):
```yaml
version: "2"
services:
foo:
build: "./build"
image: docker.io/foo/bar
```
Using `kompose up` with a `build` key:
```sh
$ kompose up
INFO Build key detected. Attempting to build and push image 'docker.io/foo/bar'
INFO Building image 'docker.io/foo/bar' from directory 'build'
INFO Image 'docker.io/foo/bar' from directory 'build' built successfully
INFO Pushing image 'foo/bar:latest' to registry 'docker.io'
INFO Attempting authentication credentials 'https://index.docker.io/v1/
INFO Successfully pushed image 'foo/bar:latest' to registry 'docker.io'
INFO We are going to create Kubernetes Deployments, Services and PersistentVolumeClaims for your Dockerized application. If you need different kind of resources, use the 'kompose convert' and 'kubectl create -f' commands instead.
INFO Deploying application in "default" namespace
INFO Successfully created Service: foo
INFO Successfully created Deployment: foo
Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods,pvc' for details.
```
In order to disable the functionality, or choose to use BuildConfig generation (with OpenShift) `--build (local|build-config|none)` can be passed.
```sh
# Disable building/pushing Docker images
$ kompose up --build none
# Generate Build Config artifacts for OpenShift
$ kompose up --provider openshift --build build-config
```
## Alternative Conversions
The default `kompose` transformation will generate Kubernetes [Deployments](http://kubernetes.io/docs/user-guide/deployments/) and [Services](http://kubernetes.io/docs/user-guide/services/), in yaml format. You have alternative option to generate json with `-j`. Also, you can alternatively generate [Replication Controllers](http://kubernetes.io/docs/user-guide/replication-controller/) objects, [Deamon Sets](http://kubernetes.io/docs/admin/daemons/), or [Helm](https://github.com/helm/helm) charts. The default `kompose` transformation will generate Kubernetes [Deployments](http://kubernetes.io/docs/user-guide/deployments/) and [Services](http://kubernetes.io/docs/user-guide/services/), in yaml format. You have alternative option to generate json with `-j`. Also, you can alternatively generate [Replication Controllers](http://kubernetes.io/docs/user-guide/replication-controller/) objects, [Deamon Sets](http://kubernetes.io/docs/admin/daemons/), or [Helm](https://github.com/helm/helm) charts.
```console ```sh
$ kompose convert -j $ kompose convert -j
INFO Kubernetes file "redis-svc.json" created INFO Kubernetes file "redis-svc.json" created
INFO Kubernetes file "web-svc.json" created INFO Kubernetes file "web-svc.json" created
@@ -250,7 +253,7 @@ INFO Kubernetes file "web-deployment.json" created
``` ```
The `*-deployment.json` files contain the Deployment objects. The `*-deployment.json` files contain the Deployment objects.
```console ```sh
$ kompose convert --replication-controller $ kompose convert --replication-controller
INFO Kubernetes file "redis-svc.yaml" created INFO Kubernetes file "redis-svc.yaml" created
INFO Kubernetes file "web-svc.yaml" created INFO Kubernetes file "web-svc.yaml" created
@@ -260,7 +263,7 @@ INFO Kubernetes file "web-replicationcontroller.yaml" created
The `*-replicationcontroller.yaml` files contain the Replication Controller objects. If you want to specify replicas (default is 1), use `--replicas` flag: `$ kompose convert --replication-controller --replicas 3` The `*-replicationcontroller.yaml` files contain the Replication Controller objects. If you want to specify replicas (default is 1), use `--replicas` flag: `$ kompose convert --replication-controller --replicas 3`
```console ```sh
$ kompose convert --daemon-set $ kompose convert --daemon-set
INFO Kubernetes file "redis-svc.yaml" created INFO Kubernetes file "redis-svc.yaml" created
INFO Kubernetes file "web-svc.yaml" created INFO Kubernetes file "web-svc.yaml" created
@@ -272,7 +275,7 @@ The `*-daemonset.yaml` files contain the Daemon Set objects
If you want to generate a Chart to be used with [Helm](https://github.com/kubernetes/helm) simply do: If you want to generate a Chart to be used with [Helm](https://github.com/kubernetes/helm) simply do:
```console ```sh
$ kompose convert -c $ kompose convert -c
INFO Kubernetes file "web-svc.yaml" created INFO Kubernetes file "web-svc.yaml" created
INFO Kubernetes file "redis-svc.yaml" created INFO Kubernetes file "redis-svc.yaml" created
@@ -293,28 +296,6 @@ docker-compose
The chart structure is aimed at providing a skeleton for building your Helm charts. The chart structure is aimed at providing a skeleton for building your Helm charts.
## Unsupported docker-compose configuration options
Currently `kompose` does not support some Docker Compose options, which are listed on the [conversion](/docs/conversion.md) document.
For example:
```console
$ cat nginx.yml
nginx:
image: nginx
dockerfile: foobar
build: ./foobar
cap_add:
- ALL
container_name: foobar
$ kompose -f nginx.yml convert
WARN Unsupported key build - ignoring
WARN Unsupported key cap_add - ignoring
WARN Unsupported key dockerfile - ignoring
```
## Labels ## Labels
`kompose` supports Kompose-specific labels within the `docker-compose.yml` file in order to explicitly define a service's behavior upon conversion. `kompose` supports Kompose-specific labels within the `docker-compose.yml` file in order to explicitly define a service's behavior upon conversion.
@@ -394,11 +375,16 @@ services:
restart: "on-failure" restart: "on-failure"
``` ```
#### Warning about Deployment Config's #### Warning about Deployment Config's
If the Docker Compose file has a volume specified for a service, the Deployment (Kubernetes) or DeploymentConfig (OpenShift) strategy is changed to "Recreate" instead of "RollingUpdate" (default). This is done to avoid multiple instances of a service from accessing a volume at the same time. If the Docker Compose file has a volume specified for a service, the Deployment (Kubernetes) or DeploymentConfig (OpenShift) strategy is changed to "Recreate" instead of "RollingUpdate" (default). This is done to avoid multiple instances of a service from accessing a volume at the same time.
If the Docker Compose file has service name with `_` in it (eg.`web_service`), then it will be replaced by `-` and the service name will be renamed accordingly (eg.`web-service`). Kompose does this because "Kubernetes" doesn't allow `_` in object name. If the Docker Compose file has service name with `_` in it (eg.`web_service`), then it will be replaced by `-` and the service name will be renamed accordingly (eg.`web-service`). Kompose does this because "Kubernetes" doesn't allow `_` in object name.
Please note that changing service name might break some `docker-compose` files. Please note that changing service name might break some `docker-compose` files.
## Docker Compose Versions
Kompose supports Docker Compose versions: 1, 2 and 3. We have limited support on versions 2.1 and 3.2 due to their experimental nature.
A full list on compatibility between all three versions is listed in our [conversion document](/docs/conversion.md) including a list of all incompatible Docker Compose keys.
+1 -1
View File
@@ -3,4 +3,4 @@ version: "2"
services: services:
foo: foo:
build: "./build" build: "./build"
image: docker.io/cdrage/foobar image: docker.io/foo/bar
+19
View File
@@ -0,0 +1,19 @@
version: "3"
services:
web:
image: tuna/docker-counter23
ports:
- "5000:5000"
deploy:
replicas: 1
restart_policy:
condition: any
labels:
kompose.service.type: NodePort
redis:
image: redis:3.0
ports:
- "6379"
+24
View File
@@ -0,0 +1,24 @@
version: "3"
services:
redis-master:
image: gcr.io/google_containers/redis:e2e
ports:
- "6379"
redis-slave:
image: gcr.io/google_samples/gb-redisslave:v1
ports:
- "6379"
environment:
- GET_HOSTS_FROM=dns
frontend:
image: gcr.io/google-samples/gb-frontend:v4
ports:
- "80:80"
environment:
- GET_HOSTS_FROM=dns
labels:
kompose.service.type: LoadBalancer
Generated
+4 -4
View File
@@ -1,5 +1,5 @@
hash: e33ffcc6bb6fbd6496e430ef69139c47d0b4e79c6255c7184d2ec7307d7a55d1 hash: e33ffcc6bb6fbd6496e430ef69139c47d0b4e79c6255c7184d2ec7307d7a55d1
updated: 2017-06-16T17:40:15.118961307+05:30 updated: 2017-06-20T14:23:11.012556696-04:00
imports: imports:
- name: cloud.google.com/go - name: cloud.google.com/go
version: 3b1ae45394a234c385be014e9a488f2bb6eef821 version: 3b1ae45394a234c385be014e9a488f2bb6eef821
@@ -375,7 +375,7 @@ imports:
- name: github.com/opencontainers/go-digest - name: github.com/opencontainers/go-digest
version: 279bed98673dd5bef374d3b6e4b09e2af76183bf version: 279bed98673dd5bef374d3b6e4b09e2af76183bf
- name: github.com/opencontainers/image-spec - name: github.com/opencontainers/image-spec
version: df6f3c57dafbbf39d98c24fa6ab509183cfa3efc version: d207df434d113728dc3373cb3a905f00b482a858
subpackages: subpackages:
- specs-go - specs-go
- specs-go/v1 - specs-go/v1
@@ -456,13 +456,13 @@ imports:
- name: github.com/spf13/cast - name: github.com/spf13/cast
version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4 version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4
- name: github.com/spf13/cobra - name: github.com/spf13/cobra
version: b4dbd37a01839e0653eec12aa4bbb2a2ce7b2a37 version: 99b5d838ca16c25cc4944e323684f8415e8b10ba
- name: github.com/spf13/jwalterweatherman - name: github.com/spf13/jwalterweatherman
version: 0efa5202c04663c757d84f90f5219c1250baf94f version: 0efa5202c04663c757d84f90f5219c1250baf94f
- name: github.com/spf13/pflag - name: github.com/spf13/pflag
version: e57e3eeb33f795204c1ca35f56c44f83227c6e66 version: e57e3eeb33f795204c1ca35f56c44f83227c6e66
- name: github.com/spf13/viper - name: github.com/spf13/viper
version: a1ecfa6a20bd4ef9e9caded262ee1b1b26847675 version: c1de95864d73a5465492829d7cb2dd422b19ac96
- name: github.com/ugorji/go - name: github.com/ugorji/go
version: f4485b318aadd133842532f841dc205a8e339d74 version: f4485b318aadd133842532f841dc205a8e339d74
subpackages: subpackages:
+2 -2
View File
@@ -1,5 +1,5 @@
package: github.com/kubernetes-incubator/kompose package: github.com/kubernetes/kompose
homepage: https://github.com/kubernetes-incubator/kompose homepage: https://github.com/kubernetes/kompose
licence: Apache-2.0 licence: Apache-2.0
import: import:
+2 -2
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@ limitations under the License.
package main package main
import "github.com/kubernetes-incubator/kompose/cmd" import "github.com/kubernetes/kompose/cmd"
func main() { func main() {
cmd.Execute() cmd.Execute()
+8 -8
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -34,11 +34,11 @@ import (
"os" "os"
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/loader" "github.com/kubernetes/kompose/pkg/loader"
"github.com/kubernetes-incubator/kompose/pkg/transformer" "github.com/kubernetes/kompose/pkg/transformer"
"github.com/kubernetes-incubator/kompose/pkg/transformer/kubernetes" "github.com/kubernetes/kompose/pkg/transformer/kubernetes"
"github.com/kubernetes-incubator/kompose/pkg/transformer/openshift" "github.com/kubernetes/kompose/pkg/transformer/openshift"
) )
const ( const (
@@ -118,7 +118,7 @@ func ValidateFlags(bundle string, args []string, cmd *cobra.Command, opt *kobjec
if len(bundle) > 0 { if len(bundle) > 0 {
inputFormat = "bundle" inputFormat = "bundle"
log.Fatalf("DAB / bundle (--bundle | -b) is no longer supported. See issue: https://github.com/kubernetes-incubator/kompose/issues/390") log.Fatalf("DAB / bundle (--bundle | -b) is no longer supported. See issue: https://github.com/kubernetes/kompose/issues/390")
opt.InputFiles = []string{bundle} opt.InputFiles = []string{bundle}
} }
@@ -136,7 +136,7 @@ func ValidateFlags(bundle string, args []string, cmd *cobra.Command, opt *kobjec
} }
// ValidateComposeFile validated the compose file provided for conversion // ValidateComposeFile validated the compose file provided for conversion
func ValidateComposeFile(cmd *cobra.Command, opt *kobject.ConvertOptions) { func ValidateComposeFile(opt *kobject.ConvertOptions) {
if len(opt.InputFiles) == 0 { if len(opt.InputFiles) == 0 {
// Here docker-compose is the input // Here docker-compose is the input
opt.InputFiles = []string{"docker-compose.yml"} opt.InputFiles = []string{"docker-compose.yml"}
+29 -9
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -53,6 +53,7 @@ type ConvertOptions struct {
IsDeploymentFlag bool IsDeploymentFlag bool
IsDaemonSetFlag bool IsDaemonSetFlag bool
IsReplicationControllerFlag bool IsReplicationControllerFlag bool
IsReplicaSetFlag bool
IsDeploymentConfigFlag bool IsDeploymentConfigFlag bool
IsNamespaceFlag bool IsNamespaceFlag bool
} }
@@ -60,20 +61,23 @@ type ConvertOptions struct {
// ServiceConfig holds the basic struct of a container // ServiceConfig holds the basic struct of a container
type ServiceConfig struct { type ServiceConfig struct {
// use tags to mark from what element this value comes // use tags to mark from what element this value comes
ContainerName string ContainerName string
Image string `compose:"image" bundle:"Image"` Image string `compose:"image" bundle:"Image"`
Environment []EnvVar `compose:"environment" bundle:"Env"` Environment []EnvVar `compose:"environment" bundle:"Env"`
Port []Ports `compose:"ports" bundle:"Ports"` Port []Ports `compose:"ports" bundle:"Ports"`
Command []string `compose:"command" bundle:"Command"` Command []string `compose:"command" bundle:"Command"`
WorkingDir string `compose:"" bundle:"WorkingDir"` WorkingDir string `compose:"" bundle:"WorkingDir"`
Args []string `compose:"args" bundle:"Args"` Args []string `compose:"args" bundle:"Args"`
Volumes []string `compose:"volumes" bundle:"Volumes"` // VolList is list of volumes extracted from docker-compose file
VolList []string `compose:"volumes" bundle:"Volumes"`
Network []string `compose:"network" bundle:"Networks"` Network []string `compose:"network" bundle:"Networks"`
Labels map[string]string `compose:"labels" bundle:"Labels"` Labels map[string]string `compose:"labels" bundle:"Labels"`
Annotations map[string]string `compose:"" bundle:""` Annotations map[string]string `compose:"" bundle:""`
CPUSet string `compose:"cpuset" bundle:""` CPUSet string `compose:"cpuset" bundle:""`
CPUShares int64 `compose:"cpu_shares" bundle:""` CPUShares int64 `compose:"cpu_shares" bundle:""`
CPUQuota int64 `compose:"cpu_quota" bundle:""` CPUQuota int64 `compose:"cpu_quota" bundle:""`
CPULimit int64 `compose:"" bundle:""`
CPUReservation int64 `compose:"" bundle:""`
CapAdd []string `compose:"cap_add" bundle:""` CapAdd []string `compose:"cap_add" bundle:""`
CapDrop []string `compose:"cap_drop" bundle:""` CapDrop []string `compose:"cap_drop" bundle:""`
Expose []string `compose:"expose" bundle:""` Expose []string `compose:"expose" bundle:""`
@@ -90,8 +94,12 @@ type ServiceConfig struct {
Stdin bool `compose:"stdin_open" bundle:""` Stdin bool `compose:"stdin_open" bundle:""`
Tty bool `compose:"tty" bundle:""` Tty bool `compose:"tty" bundle:""`
MemLimit yaml.MemStringorInt `compose:"mem_limit" bundle:""` MemLimit yaml.MemStringorInt `compose:"mem_limit" bundle:""`
MemReservation yaml.MemStringorInt `compose:"" bundle:""`
TmpFs []string `compose:"tmpfs" bundle:""` TmpFs []string `compose:"tmpfs" bundle:""`
Dockerfile string `compose:"dockerfile" bundle:""` Dockerfile string `compose:"dockerfile" bundle:""`
Replicas int `compose:"replicas" bundle:""`
// Volumes is a struct which contains all information about each volume
Volumes []Volumes `compose:"" bundle:""`
} }
// EnvVar holds the environment variable struct of a container // EnvVar holds the environment variable struct of a container
@@ -107,3 +115,15 @@ type Ports struct {
HostIP string HostIP string
Protocol api.Protocol Protocol api.Protocol
} }
// Volumes holds the volume struct of container
type Volumes struct {
SvcName string // Service name to which volume is linked
MountPath string // Mountpath extracted from docker-compose file
VFrom string // denotes service name from which volume is coming
VolumeName string // name of volume if provided explicitly
Host string // host machine address
Container string // Mountpath
Mode string // access mode for volume
PVCName string // name of PVC
}
+2 -2
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -28,7 +28,7 @@ import (
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
"github.com/fatih/structs" "github.com/fatih/structs"
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
+1 -1
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
+2 -2
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@ import (
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
"github.com/docker/libcompose/project" "github.com/docker/libcompose/project"
"github.com/fatih/structs" "github.com/fatih/structs"
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
+2 -2
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"github.com/docker/cli/cli/compose/types" "github.com/docker/cli/cli/compose/types"
+2 -2
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"github.com/pkg/errors" "github.com/pkg/errors"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
) )
+118 -5
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -30,7 +30,8 @@ import (
"github.com/docker/libcompose/config" "github.com/docker/libcompose/config"
"github.com/docker/libcompose/lookup" "github.com/docker/libcompose/lookup"
"github.com/docker/libcompose/project" "github.com/docker/libcompose/project"
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/transformer"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@@ -205,7 +206,7 @@ func libComposeToKomposeMapping(composeObject *project.Project) (kobject.Kompose
envs := loadEnvVars(composeServiceConfig.Environment) envs := loadEnvVars(composeServiceConfig.Environment)
serviceConfig.Environment = envs serviceConfig.Environment = envs
//Validate dockerfile path // Validate dockerfile path
if filepath.IsAbs(serviceConfig.Dockerfile) { if filepath.IsAbs(serviceConfig.Dockerfile) {
log.Fatalf("%q defined in service %q is an absolute path, it must be a relative path.", serviceConfig.Dockerfile, name) log.Fatalf("%q defined in service %q is an absolute path, it must be a relative path.", serviceConfig.Dockerfile, name)
} }
@@ -222,7 +223,7 @@ func libComposeToKomposeMapping(composeObject *project.Project) (kobject.Kompose
if composeServiceConfig.Volumes != nil { if composeServiceConfig.Volumes != nil {
for _, volume := range composeServiceConfig.Volumes.Volumes { for _, volume := range composeServiceConfig.Volumes.Volumes {
v := normalizeServiceNames(volume.String()) v := normalizeServiceNames(volume.String())
serviceConfig.Volumes = append(serviceConfig.Volumes, v) serviceConfig.VolList = append(serviceConfig.VolList, v)
} }
} }
@@ -268,12 +269,124 @@ func libComposeToKomposeMapping(composeObject *project.Project) (kobject.Kompose
log.Infof("Service name in docker-compose has been changed from %q to %q", name, normalizeServiceNames(name)) log.Infof("Service name in docker-compose has been changed from %q to %q", name, normalizeServiceNames(name))
} }
} }
// This will handle volume at earlier stage itself, it will resolves problems occurred due to `volumes_from` key
handleVolume(&komposeObject)
return komposeObject, nil return komposeObject, nil
} }
// This function will retrieve volumes for each service, as well as it will parse volume information and store it in Volumes struct
func handleVolume(komposeObject *kobject.KomposeObject) {
for name, _ := range komposeObject.ServiceConfigs {
// retrieve volumes of service
vols, err := retrieveVolume(name, *komposeObject)
if err != nil {
errors.Wrap(err, "could not retrieve volume")
}
// We can't assign value to struct field in map while iterating over it, so temporary variable `temp` is used here
var temp = komposeObject.ServiceConfigs[name]
temp.Volumes = vols
komposeObject.ServiceConfigs[name] = temp
}
}
func checkLabelsPorts(noOfPort int, labels string, svcName string) error { func checkLabelsPorts(noOfPort int, labels string, svcName string) error {
if noOfPort == 0 && labels == "NodePort" || labels == "LoadBalancer" { if noOfPort == 0 && (labels == "NodePort" || labels == "LoadBalancer") {
return errors.Errorf("%s defined in service %s with no ports present. Issues may occur when bringing up artifacts.", labels, svcName) return errors.Errorf("%s defined in service %s with no ports present. Issues may occur when bringing up artifacts.", labels, svcName)
} }
return nil return nil
} }
// returns all volumes associated with service, if `volumes_from` key is used, we have to retrieve volumes from the services which are mentioned there. Hence, recursive function is used here.
func retrieveVolume(svcName string, komposeObject kobject.KomposeObject) (volume []kobject.Volumes, err error) {
// if volumes-from key is present
if komposeObject.ServiceConfigs[svcName].VolumesFrom != nil {
// iterating over services from `volumes-from`
for _, depSvc := range komposeObject.ServiceConfigs[svcName].VolumesFrom {
// recursive call for retrieving volumes of services from `volumes-from`
dVols, err := retrieveVolume(depSvc, komposeObject)
if err != nil {
return nil, errors.Wrapf(err, "could not retrieve the volume")
}
var cVols []kobject.Volumes
cVols, err = ParseVols(komposeObject.ServiceConfigs[svcName].VolList, svcName)
if err != nil {
return nil, errors.Wrapf(err, "error generting current volumes")
}
for _, cv := range cVols {
// check whether volumes of current service is same or not as that of dependent volumes coming from `volumes-from`
ok, dv := getVol(cv, dVols)
if ok {
// change current volumes service name to dependent service name
if dv.VFrom == "" {
cv.VFrom = dv.SvcName
cv.SvcName = dv.SvcName
} else {
cv.VFrom = dv.VFrom
cv.SvcName = dv.SvcName
}
cv.PVCName = dv.PVCName
}
volume = append(volume, cv)
}
// iterating over dependent volumes
for _, dv := range dVols {
// check whether dependent volume is already present or not
if checkVolDependent(dv, volume) {
// if found, add service name to `VFrom`
dv.VFrom = dv.SvcName
volume = append(volume, dv)
}
}
}
} else {
// if `volumes-from` is not present
volume, err = ParseVols(komposeObject.ServiceConfigs[svcName].VolList, svcName)
if err != nil {
return nil, errors.Wrapf(err, "error generting current volumes")
}
}
return
}
// checkVolDependent returns false if dependent volume is present
func checkVolDependent(dv kobject.Volumes, volume []kobject.Volumes) bool {
for _, vol := range volume {
if vol.PVCName == dv.PVCName {
return false
}
}
return true
}
func ParseVols(volNames []string, svcName string) ([]kobject.Volumes, error) {
var volumes []kobject.Volumes
var err error
for i, vn := range volNames {
var v kobject.Volumes
v.VolumeName, v.Host, v.Container, v.Mode, err = transformer.ParseVolume(vn)
if err != nil {
return nil, errors.Wrapf(err, "could not parse volume %q: %v", vn, err)
}
v.SvcName = svcName
v.MountPath = fmt.Sprintf("%s:%s", v.Host, v.Container)
v.PVCName = fmt.Sprintf("%s-claim%d", v.SvcName, i)
volumes = append(volumes, v)
}
return volumes, nil
}
// for dependent volumes, returns true and the respective volume if mountpath are same
func getVol(toFind kobject.Volumes, Vols []kobject.Volumes) (bool, kobject.Volumes) {
for _, dv := range Vols {
if toFind.MountPath == dv.MountPath {
return true, dv
}
}
return false, kobject.Volumes{}
}
+46 -12
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -17,19 +17,22 @@ limitations under the License.
package compose package compose
import ( import (
libcomposeyaml "github.com/docker/libcompose/yaml"
"io/ioutil" "io/ioutil"
"strconv"
"strings" "strings"
libcomposeyaml "github.com/docker/libcompose/yaml"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"github.com/docker/cli/cli/compose/loader" "github.com/docker/cli/cli/compose/loader"
"github.com/docker/cli/cli/compose/types" "github.com/docker/cli/cli/compose/types"
log "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/pkg/errors"
"os" "os"
log "github.com/Sirupsen/logrus"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/pkg/errors"
) )
// converts os.Environ() ([]string) to map[string]string // converts os.Environ() ([]string) to map[string]string
@@ -183,7 +186,6 @@ func dockerComposeToKomposeMapping(composeObject *types.Config) (kobject.Kompose
serviceConfig.CapDrop = composeServiceConfig.CapDrop serviceConfig.CapDrop = composeServiceConfig.CapDrop
serviceConfig.Expose = composeServiceConfig.Expose serviceConfig.Expose = composeServiceConfig.Expose
serviceConfig.Privileged = composeServiceConfig.Privileged serviceConfig.Privileged = composeServiceConfig.Privileged
serviceConfig.Restart = composeServiceConfig.Restart
serviceConfig.User = composeServiceConfig.User serviceConfig.User = composeServiceConfig.User
serviceConfig.Stdin = composeServiceConfig.StdinOpen serviceConfig.Stdin = composeServiceConfig.StdinOpen
serviceConfig.Tty = composeServiceConfig.Tty serviceConfig.Tty = composeServiceConfig.Tty
@@ -192,15 +194,46 @@ func dockerComposeToKomposeMapping(composeObject *types.Config) (kobject.Kompose
serviceConfig.Command = composeServiceConfig.Entrypoint serviceConfig.Command = composeServiceConfig.Entrypoint
serviceConfig.Args = composeServiceConfig.Command serviceConfig.Args = composeServiceConfig.Command
// This is a bit messy since we use yaml.MemStringorInt //
// TODO: Refactor yaml.MemStringorInt in kobject.go to int64 // Deploy keys
// Since Deploy.Resources.Limits does not initialize, we must check type Resources before continuing //
if (composeServiceConfig.Deploy.Resources != types.Resources{}) { if (composeServiceConfig.Deploy.Resources != types.Resources{}) {
// memory:
// TODO: Refactor yaml.MemStringorInt in kobject.go to int64
// Since Deploy.Resources.Limits does not initialize, we must check type Resources before continuing
serviceConfig.MemLimit = libcomposeyaml.MemStringorInt(composeServiceConfig.Deploy.Resources.Limits.MemoryBytes) serviceConfig.MemLimit = libcomposeyaml.MemStringorInt(composeServiceConfig.Deploy.Resources.Limits.MemoryBytes)
serviceConfig.MemReservation = libcomposeyaml.MemStringorInt(composeServiceConfig.Deploy.Resources.Reservations.MemoryBytes)
// cpu:
// convert to k8s format, for example: 0.5 = 500m
// See: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
// "The expression 0.1 is equivalent to the expression 100m, which can be read as “one hundred millicpu”."
cpuLimit, err := strconv.ParseFloat(composeServiceConfig.Deploy.Resources.Limits.NanoCPUs, 64)
if err != nil {
return kobject.KomposeObject{}, errors.Wrap(err, "Unable to convert cpu limits resources value")
}
serviceConfig.CPULimit = int64(cpuLimit * 1000)
cpuReservation, err := strconv.ParseFloat(composeServiceConfig.Deploy.Resources.Reservations.NanoCPUs, 64)
if err != nil {
return kobject.KomposeObject{}, errors.Wrap(err, "Unable to convert cpu limits reservation value")
}
serviceConfig.CPUReservation = int64(cpuReservation * 1000)
} }
// POOF. volumes_From is gone in v3. docker/cli will error out of volumes_from is added in v3 // restart-policy:
// serviceConfig.VolumesFrom = composeServiceConfig.VolumesFrom if composeServiceConfig.Deploy.RestartPolicy != nil {
serviceConfig.Restart = composeServiceConfig.Deploy.RestartPolicy.Condition
}
// replicas:
if composeServiceConfig.Deploy.Replicas != nil {
serviceConfig.Replicas = int(*composeServiceConfig.Deploy.Replicas)
}
// TODO: Build is not yet supported, see: // TODO: Build is not yet supported, see:
// https://github.com/docker/cli/blob/master/cli/compose/types/types.go#L9 // https://github.com/docker/cli/blob/master/cli/compose/types/types.go#L9
@@ -224,7 +257,7 @@ func dockerComposeToKomposeMapping(composeObject *types.Config) (kobject.Kompose
// Parse the volumes // Parse the volumes
// Again, in v3, we use the "long syntax" for volumes in terms of parsing // Again, in v3, we use the "long syntax" for volumes in terms of parsing
// https://docs.docker.com/compose/compose-file/#long-syntax-2 // https://docs.docker.com/compose/compose-file/#long-syntax-2
serviceConfig.Volumes = loadV3Volumes(composeServiceConfig.Volumes) serviceConfig.VolList = loadV3Volumes(composeServiceConfig.Volumes)
// Label handler // Label handler
// Labels used to influence conversion of kompose will be handled // Labels used to influence conversion of kompose will be handled
@@ -251,6 +284,7 @@ func dockerComposeToKomposeMapping(composeObject *types.Config) (kobject.Kompose
// Final step, add to the array! // Final step, add to the array!
komposeObject.ServiceConfigs[normalizeServiceNames(name)] = serviceConfig komposeObject.ServiceConfigs[normalizeServiceNames(name)] = serviceConfig
} }
handleVolume(&komposeObject)
return komposeObject, nil return komposeObject, nil
} }
+4 -4
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -19,9 +19,9 @@ package loader
import ( import (
"fmt" "fmt"
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/loader/bundle" "github.com/kubernetes/kompose/pkg/loader/bundle"
"github.com/kubernetes-incubator/kompose/pkg/loader/compose" "github.com/kubernetes/kompose/pkg/loader/compose"
) )
// Loader interface defines loader that loads files and converts it to kobject representation // Loader interface defines loader that loads files and converts it to kobject representation
+41 -90
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -31,8 +31,8 @@ import (
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/transformer" "github.com/kubernetes/kompose/pkg/transformer"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/unversioned"
@@ -343,12 +343,9 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
if len(service.TmpFs) > 0 { if len(service.TmpFs) > 0 {
TmpVolumesMount, TmpVolumes := k.ConfigTmpfs(name, service) TmpVolumesMount, TmpVolumes := k.ConfigTmpfs(name, service)
for _, volume := range TmpVolumes { volumes = append(volumes, TmpVolumes...)
volumes = append(volumes, volume)
} volumesMount = append(volumesMount, TmpVolumesMount...)
for _, vMount := range TmpVolumesMount {
volumesMount = append(volumesMount, vMount)
}
} }
@@ -392,14 +389,39 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
} }
// Configure the resource limits // Configure the resource limits
if service.MemLimit != 0 { if service.MemLimit != 0 || service.CPULimit != 0 {
memoryResourceList := api.ResourceList{ resourceLimit := api.ResourceList{}
api.ResourceMemory: *resource.NewQuantity(
int64(service.MemLimit), "RandomStringForFormat")} if service.MemLimit != 0 {
template.Spec.Containers[0].Resources.Limits = memoryResourceList resourceLimit[api.ResourceMemory] = *resource.NewQuantity(int64(service.MemLimit), "RandomStringForFormat")
}
if service.CPULimit != 0 {
resourceLimit[api.ResourceCPU] = *resource.NewQuantity(service.CPULimit, "RandomStringForFormat")
}
template.Spec.Containers[0].Resources.Limits = resourceLimit
} }
// Configure the resource requests
if service.MemReservation != 0 || service.CPUReservation != 0 {
resourceRequests := api.ResourceList{}
if service.MemReservation != 0 {
resourceRequests[api.ResourceMemory] = *resource.NewQuantity(int64(service.MemReservation), "RandomStringForFormat")
}
if service.CPUReservation != 0 {
resourceRequests[api.ResourceCPU] = *resource.NewQuantity(service.CPUReservation, "RandomStringForFormat")
}
template.Spec.Containers[0].Resources.Requests = resourceRequests
}
// Configure resource reservations
podSecurityContext := &api.PodSecurityContext{} podSecurityContext := &api.PodSecurityContext{}
//set pid namespace mode //set pid namespace mode
if service.Pid != "" { if service.Pid != "" {
if service.Pid == "host" { if service.Pid == "host" {
@@ -411,7 +433,7 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
// Setup security context // Setup security context
securityContext := &api.SecurityContext{} securityContext := &api.SecurityContext{}
if service.Privileged == true { if service.Privileged {
securityContext.Privileged = &service.Privileged securityContext.Privileged = &service.Privileged
} }
if service.User != "" { if service.User != "" {
@@ -441,9 +463,9 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
// Configure the container restart policy. // Configure the container restart policy.
switch service.Restart { switch service.Restart {
case "", "always": case "", "always", "any":
template.Spec.RestartPolicy = api.RestartPolicyAlways template.Spec.RestartPolicy = api.RestartPolicyAlways
case "no": case "no", "none":
template.Spec.RestartPolicy = api.RestartPolicyNever template.Spec.RestartPolicy = api.RestartPolicyNever
case "on-failure": case "on-failure":
template.Spec.RestartPolicy = api.RestartPolicyOnFailure template.Spec.RestartPolicy = api.RestartPolicyOnFailure
@@ -494,78 +516,7 @@ func (k *Kubernetes) SortServicesFirst(objs *[]runtime.Object) {
*objs = ret *objs = ret
} }
func (k *Kubernetes) findDependentVolumes(svcname string, komposeObject kobject.KomposeObject) (volumes []api.Volume, volumeMounts []api.VolumeMount, err error) { // SortedKeys Ensure the kubernetes objects are in a consistent order
// Get all the volumes and volumemounts this particular service is dependent on
for _, dependentSvc := range komposeObject.ServiceConfigs[svcname].VolumesFrom {
vols, volMounts, err := k.findDependentVolumes(dependentSvc, komposeObject)
if err != nil {
err = errors.Wrap(err, "k.findDependentVolumes failed")
return nil, nil, err
}
volumes = append(volumes, vols...)
volumeMounts = append(volumeMounts, volMounts...)
}
// add the volumes info of this service
volMounts, vols, _, err := k.ConfigVolumes(svcname, komposeObject.ServiceConfigs[svcname])
if err != nil {
err = errors.Wrap(err, "k.ConfigVolumes failed")
return nil, nil, err
}
volumes = append(volumes, vols...)
volumeMounts = append(volumeMounts, volMounts...)
return volumes, volumeMounts, nil
}
// VolumesFrom creates volums and volumeMounts for volumes_from
func (k *Kubernetes) VolumesFrom(objects *[]runtime.Object, komposeObject kobject.KomposeObject) error {
for _, obj := range *objects {
switch t := obj.(type) {
case *api.ReplicationController:
svcName := t.ObjectMeta.Name
for _, dependentSvc := range komposeObject.ServiceConfigs[svcName].VolumesFrom {
volumes, volumeMounts, err := k.findDependentVolumes(dependentSvc, komposeObject)
if err != nil {
return errors.Wrap(err, "k.findDependentVolumes")
}
t.Spec.Template.Spec.Volumes = append(t.Spec.Template.Spec.Volumes, volumes...)
t.Spec.Template.Spec.Containers[0].VolumeMounts = append(t.Spec.Template.Spec.Containers[0].VolumeMounts, volumeMounts...)
}
case *extensions.Deployment:
svcName := t.ObjectMeta.Name
for _, dependentSvc := range komposeObject.ServiceConfigs[svcName].VolumesFrom {
volumes, volumeMounts, err := k.findDependentVolumes(dependentSvc, komposeObject)
if err != nil {
return errors.Wrap(err, "k.findDependentVolumes")
}
t.Spec.Template.Spec.Volumes = append(t.Spec.Template.Spec.Volumes, volumes...)
t.Spec.Template.Spec.Containers[0].VolumeMounts = append(t.Spec.Template.Spec.Containers[0].VolumeMounts, volumeMounts...)
}
case *extensions.DaemonSet:
svcName := t.ObjectMeta.Name
for _, dependentSvc := range komposeObject.ServiceConfigs[svcName].VolumesFrom {
volumes, volumeMounts, err := k.findDependentVolumes(dependentSvc, komposeObject)
if err != nil {
return errors.Wrap(err, "k.findDependentVolumes")
}
t.Spec.Template.Spec.Volumes = append(t.Spec.Template.Spec.Volumes, volumes...)
t.Spec.Template.Spec.Containers[0].VolumeMounts = append(t.Spec.Template.Spec.Containers[0].VolumeMounts, volumeMounts...)
}
case *deployapi.DeploymentConfig:
svcName := t.ObjectMeta.Name
for _, dependentSvc := range komposeObject.ServiceConfigs[svcName].VolumesFrom {
volumes, volumeMounts, err := k.findDependentVolumes(dependentSvc, komposeObject)
if err != nil {
return errors.Wrap(err, "k.findDependentVolumes")
}
t.Spec.Template.Spec.Volumes = append(t.Spec.Template.Spec.Volumes, volumes...)
t.Spec.Template.Spec.Containers[0].VolumeMounts = append(t.Spec.Template.Spec.Containers[0].VolumeMounts, volumeMounts...)
}
}
}
return nil
}
//Ensure the kubernetes objects are in a consistent order
func SortedKeys(komposeObject kobject.KomposeObject) []string { func SortedKeys(komposeObject kobject.KomposeObject) []string {
var sortedKeys []string var sortedKeys []string
for name := range komposeObject.ServiceConfigs { for name := range komposeObject.ServiceConfigs {
@@ -575,7 +526,7 @@ func SortedKeys(komposeObject kobject.KomposeObject) []string {
return sortedKeys return sortedKeys
} }
//converts duration string to *int64 in seconds // DurationStrToSecondsInt converts duration string to *int64 in seconds
func DurationStrToSecondsInt(s string) (*int64, error) { func DurationStrToSecondsInt(s string) (*int64, error) {
if s == "" { if s == "" {
return nil, nil return nil, nil
+95 -36
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -23,8 +23,8 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/testutils" "github.com/kubernetes/kompose/pkg/testutils"
"reflect" "reflect"
@@ -47,7 +47,7 @@ func TestCreateService(t *testing.T) {
Command: []string{"cmd"}, Command: []string{"cmd"},
WorkingDir: "dir", WorkingDir: "dir",
Args: []string{"arg1", "arg2"}, Args: []string{"arg1", "arg2"},
Volumes: []string{"/tmp/volume"}, VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"}, // not supported Network: []string{"network1", "network2"}, // not supported
Labels: nil, Labels: nil,
Annotations: map[string]string{"abc": "def"}, Annotations: map[string]string{"abc": "def"},
@@ -78,30 +78,31 @@ func TestCreateService(t *testing.T) {
} }
/* /*
Test the creation of a service with a memory limit Test the creation of a service with a memory limit and reservation
*/ */
func TestCreateServiceWithMemLimit(t *testing.T) { func TestCreateServiceWithMemLimit(t *testing.T) {
// An example service // An example service
service := kobject.ServiceConfig{ service := kobject.ServiceConfig{
ContainerName: "name", ContainerName: "name",
Image: "image", Image: "image",
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}}, Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: api.ProtocolTCP}}, Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: api.ProtocolTCP}},
Command: []string{"cmd"}, Command: []string{"cmd"},
WorkingDir: "dir", WorkingDir: "dir",
Args: []string{"arg1", "arg2"}, Args: []string{"arg1", "arg2"},
Volumes: []string{"/tmp/volume"}, VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"}, // not supported Network: []string{"network1", "network2"}, // not supported
Labels: nil, Labels: nil,
Annotations: map[string]string{"abc": "def"}, Annotations: map[string]string{"abc": "def"},
CPUQuota: 1, // not supported CPUQuota: 1, // not supported
CapAdd: []string{"cap_add"}, // not supported CapAdd: []string{"cap_add"}, // not supported
CapDrop: []string{"cap_drop"}, // not supported CapDrop: []string{"cap_drop"}, // not supported
Expose: []string{"expose"}, // not supported Expose: []string{"expose"}, // not supported
Privileged: true, Privileged: true,
Restart: "always", Restart: "always",
MemLimit: 1337, MemLimit: 1337,
MemReservation: 1338,
} }
// An example object generated via k8s runtime.Objects() // An example object generated via k8s runtime.Objects()
@@ -114,12 +115,69 @@ func TestCreateServiceWithMemLimit(t *testing.T) {
t.Error(errors.Wrap(err, "k.Transform failed")) t.Error(errors.Wrap(err, "k.Transform failed"))
} }
// Retrieve the deployment object and test that it matches the MemLimit value // Retrieve the deployment object and test that it matches the mem value
for _, obj := range objects { for _, obj := range objects {
if deploy, ok := obj.(*extensions.Deployment); ok { if deploy, ok := obj.(*extensions.Deployment); ok {
memTest, _ := deploy.Spec.Template.Spec.Containers[0].Resources.Limits.Memory().AsInt64() memLimit, _ := deploy.Spec.Template.Spec.Containers[0].Resources.Limits.Memory().AsInt64()
if memTest != 1337 { if memLimit != 1337 {
t.Errorf("Expected 1337 for mem_limit check, got %v", memTest) t.Errorf("Expected 1337 for memory limit check, got %v", memLimit)
}
memReservation, _ := deploy.Spec.Template.Spec.Containers[0].Resources.Requests.Memory().AsInt64()
if memReservation != 1338 {
t.Errorf("Expected 1338 for memory reservation check, got %v", memReservation)
}
}
}
}
/*
Test the creation of a service with a cpu limit and reservation
*/
func TestCreateServiceWithCPULimit(t *testing.T) {
// An example service
service := kobject.ServiceConfig{
ContainerName: "name",
Image: "image",
Environment: []kobject.EnvVar{kobject.EnvVar{Name: "env", Value: "value"}},
Port: []kobject.Ports{kobject.Ports{HostPort: 123, ContainerPort: 456, Protocol: api.ProtocolTCP}},
Command: []string{"cmd"},
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"}, // not supported
Labels: nil,
Annotations: map[string]string{"abc": "def"},
CPUQuota: 1, // not supported
CapAdd: []string{"cap_add"}, // not supported
CapDrop: []string{"cap_drop"}, // not supported
Expose: []string{"expose"}, // not supported
Privileged: true,
Restart: "always",
CPULimit: 10,
CPUReservation: 1,
}
// An example object generated via k8s runtime.Objects()
komposeObject := kobject.KomposeObject{
ServiceConfigs: map[string]kobject.ServiceConfig{"app": service},
}
k := Kubernetes{}
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 cpu value
for _, obj := range objects {
if deploy, ok := obj.(*extensions.Deployment); ok {
cpuLimit, _ := deploy.Spec.Template.Spec.Containers[0].Resources.Limits.Cpu().AsInt64()
if cpuLimit != 10 {
t.Errorf("Expected 10 for cpu limit check, got %v", cpuLimit)
}
cpuReservation, _ := deploy.Spec.Template.Spec.Containers[0].Resources.Requests.Cpu().AsInt64()
if cpuReservation != 1 {
t.Errorf("Expected 1 for cpu reservation check, got %v", cpuReservation)
} }
} }
} }
@@ -140,7 +198,7 @@ func TestCreateServiceWithServiceUser(t *testing.T) {
Command: []string{"cmd"}, Command: []string{"cmd"},
WorkingDir: "dir", WorkingDir: "dir",
Args: []string{"arg1", "arg2"}, Args: []string{"arg1", "arg2"},
Volumes: []string{"/tmp/volume"}, VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"}, // not supported Network: []string{"network1", "network2"}, // not supported
Labels: nil, Labels: nil,
Annotations: map[string]string{"kompose.service.type": "nodeport"}, Annotations: map[string]string{"kompose.service.type": "nodeport"},
@@ -184,7 +242,7 @@ func TestTransformWithPid(t *testing.T) {
Command: []string{"cmd"}, Command: []string{"cmd"},
WorkingDir: "dir", WorkingDir: "dir",
Args: []string{"arg1", "arg2"}, Args: []string{"arg1", "arg2"},
Volumes: []string{"/tmp/volume"}, VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"}, Network: []string{"network1", "network2"},
Restart: "always", Restart: "always",
Pid: "host", Pid: "host",
@@ -203,7 +261,7 @@ func TestTransformWithPid(t *testing.T) {
for _, obj := range objects { for _, obj := range objects {
if deploy, ok := obj.(*extensions.Deployment); ok { if deploy, ok := obj.(*extensions.Deployment); ok {
hostPid := deploy.Spec.Template.Spec.SecurityContext.HostPID hostPid := deploy.Spec.Template.Spec.SecurityContext.HostPID
if hostPid != true { if !hostPid {
t.Errorf("Pid in ServiceConfig is not matching HostPID in PodSpec") t.Errorf("Pid in ServiceConfig is not matching HostPID in PodSpec")
} }
} }
@@ -220,7 +278,7 @@ func TestTransformWithInvaildPid(t *testing.T) {
Command: []string{"cmd"}, Command: []string{"cmd"},
WorkingDir: "dir", WorkingDir: "dir",
Args: []string{"arg1", "arg2"}, Args: []string{"arg1", "arg2"},
Volumes: []string{"/tmp/volume"}, VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"}, Network: []string{"network1", "network2"},
Restart: "always", Restart: "always",
Pid: "badvalue", Pid: "badvalue",
@@ -240,7 +298,7 @@ func TestTransformWithInvaildPid(t *testing.T) {
if deploy, ok := obj.(*extensions.Deployment); ok { if deploy, ok := obj.(*extensions.Deployment); ok {
if deploy.Spec.Template.Spec.SecurityContext != nil { if deploy.Spec.Template.Spec.SecurityContext != nil {
hostPid := deploy.Spec.Template.Spec.SecurityContext.HostPID hostPid := deploy.Spec.Template.Spec.SecurityContext.HostPID
if hostPid != false { if hostPid {
t.Errorf("Pid in ServiceConfig is not matching HostPID in PodSpec") t.Errorf("Pid in ServiceConfig is not matching HostPID in PodSpec")
} }
} }
@@ -272,7 +330,7 @@ func TestIsDir(t *testing.T) {
if err != nil { if err != nil {
t.Error(errors.Wrap(err, "isDir failed")) t.Error(errors.Wrap(err, "isDir failed"))
} }
if output != true { if !output {
t.Errorf("directory %v exists but isDir() returned %v", tempDir, output) t.Errorf("directory %v exists but isDir() returned %v", tempDir, output)
} }
@@ -281,7 +339,7 @@ func TestIsDir(t *testing.T) {
if err != nil { if err != nil {
t.Error(errors.Wrap(err, "isDir failed")) t.Error(errors.Wrap(err, "isDir failed"))
} }
if output != false { if output {
t.Errorf("%v is a file but isDir() returned %v", tempDir, output) t.Errorf("%v is a file but isDir() returned %v", tempDir, output)
} }
@@ -290,7 +348,7 @@ func TestIsDir(t *testing.T) {
if err != nil { if err != nil {
t.Error(errors.Wrap(err, "isDir failed")) t.Error(errors.Wrap(err, "isDir failed"))
} }
if output != false { if output {
t.Errorf("Directory %v does not exist, but isDir() returned %v", tempAbsentDirPath, output) t.Errorf("Directory %v does not exist, but isDir() returned %v", tempAbsentDirPath, output)
} }
@@ -329,7 +387,8 @@ func TestRecreateStrategyWithVolumesPresent(t *testing.T) {
service := kobject.ServiceConfig{ service := kobject.ServiceConfig{
ContainerName: "name", ContainerName: "name",
Image: "image", Image: "image",
Volumes: []string{"/tmp/volume"}, VolList: []string{"/tmp/volume"},
Volumes: []kobject.Volumes{{SvcName: "app", MountPath: "/tmp/volume", PVCName: "app-claim0"}},
} }
komposeObject := kobject.KomposeObject{ komposeObject := kobject.KomposeObject{
+39 -34
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -24,8 +24,8 @@ import (
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
"github.com/fatih/structs" "github.com/fatih/structs"
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/transformer" "github.com/kubernetes/kompose/pkg/transformer"
buildapi "github.com/openshift/origin/pkg/build/api" buildapi "github.com/openshift/origin/pkg/build/api"
deployapi "github.com/openshift/origin/pkg/deploy/api" deployapi "github.com/openshift/origin/pkg/deploy/api"
@@ -49,6 +49,7 @@ import (
"k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/labels"
"sort" "sort"
"strings"
) )
// Kubernetes implements Transformer interface and represents Kubernetes transformer // Kubernetes implements Transformer interface and represents Kubernetes transformer
@@ -61,11 +62,11 @@ type Kubernetes struct {
// used when undeploying resources from kubernetes // used when undeploying resources from kubernetes
const TIMEOUT = 300 const TIMEOUT = 300
//default size of Persistent Volume Claim // PVCRequestSize (Persistent Volume Claim) has default size
const PVCRequestSize = "100Mi" const PVCRequestSize = "100Mi"
// CheckUnsupportedKey checks if given komposeObject contains // CheckUnsupportedKey checks if given komposeObject contains
// keys that are not supported by this tranfomer. // keys that are not supported by this transformer.
// list of all unsupported keys are stored in unsupportedKey variable // list of all unsupported keys are stored in unsupportedKey variable
// returns list of TODO: .... // returns list of TODO: ....
func (k *Kubernetes) CheckUnsupportedKey(komposeObject *kobject.KomposeObject, unsupportedKey map[string]bool) []string { func (k *Kubernetes) CheckUnsupportedKey(komposeObject *kobject.KomposeObject, unsupportedKey map[string]bool) []string {
@@ -138,7 +139,7 @@ func (k *Kubernetes) InitRC(name string, service kobject.ServiceConfig, replicas
return rc return rc
} }
// InitSvc initializes Kubernets Service object // InitSvc initializes Kubernetes Service object
func (k *Kubernetes) InitSvc(name string, service kobject.ServiceConfig) *api.Service { func (k *Kubernetes) InitSvc(name string, service kobject.ServiceConfig) *api.Service {
svc := &api.Service{ svc := &api.Service{
TypeMeta: unversioned.TypeMeta{ TypeMeta: unversioned.TypeMeta{
@@ -376,56 +377,53 @@ func (k *Kubernetes) ConfigVolumes(name string, service kobject.ServiceConfig) (
volumeMounts := []api.VolumeMount{} volumeMounts := []api.VolumeMount{}
volumes := []api.Volume{} volumes := []api.Volume{}
var PVCs []*api.PersistentVolumeClaim var PVCs []*api.PersistentVolumeClaim
var volumeName string
// Set a var based on if the user wants to use emtpy volumes // Set a var based on if the user wants to use empty volumes
// as opposed to persistent volumes and volume claims // as opposed to persistent volumes and volume claims
useEmptyVolumes := k.Opt.EmptyVols useEmptyVolumes := k.Opt.EmptyVols
var count int var count int
//interating over array of `Vols` struct as it contains all necessary information about volumes
for _, volume := range service.Volumes { for _, volume := range service.Volumes {
volumeName, host, container, mode, err := transformer.ParseVolume(volume)
if err != nil {
log.Warningf("Failed to configure container volume: %v", err)
continue
}
log.Debug("Volume name %s", volumeName)
// check if ro/rw mode is defined, default rw // check if ro/rw mode is defined, default rw
readonly := len(mode) > 0 && mode == "ro" readonly := len(volume.Mode) > 0 && volume.Mode == "ro"
if volumeName == "" { if volume.VolumeName == "" {
if useEmptyVolumes { if useEmptyVolumes {
volumeName = fmt.Sprintf("%s-empty%d", name, count) volumeName = strings.Replace(volume.PVCName, "claim", "empty", 1)
} else { } else {
volumeName = fmt.Sprintf("%s-claim%d", name, count) volumeName = volume.PVCName
} }
count++ count++
} else {
volumeName = volume.VolumeName
} }
// create a new volume mount object and append to list
volmount := api.VolumeMount{ volmount := api.VolumeMount{
Name: volumeName, Name: volumeName,
ReadOnly: readonly, ReadOnly: readonly,
MountPath: container, MountPath: volume.Container,
} }
volumeMounts = append(volumeMounts, volmount) volumeMounts = append(volumeMounts, volmount)
// Get a volume source based on the type of volume we are using // Get a volume source based on the type of volume we are using
// For PVC we will also create a PVC object and add to list // For PVC we will also create a PVC object and add to list
var volsource *api.VolumeSource var volsource *api.VolumeSource
if useEmptyVolumes { if useEmptyVolumes {
volsource = k.ConfigEmptyVolumeSource("volume") volsource = k.ConfigEmptyVolumeSource("volume")
} else { } else {
volsource = k.ConfigPVCVolumeSource(volumeName, readonly) volsource = k.ConfigPVCVolumeSource(volumeName, readonly)
if volume.VFrom == "" {
createdPVC, err := k.CreatePVC(volumeName, volume.Mode)
createdPVC, err := k.CreatePVC(volumeName, mode) if err != nil {
if err != nil { return nil, nil, nil, errors.Wrap(err, "k.CreatePVC failed")
return nil, nil, nil, errors.Wrap(err, "k.CreatePVC failed") }
PVCs = append(PVCs, createdPVC)
} }
PVCs = append(PVCs, createdPVC)
} }
// create a new volume object using the volsource and add to list // create a new volume object using the volsource and add to list
@@ -435,10 +433,12 @@ func (k *Kubernetes) ConfigVolumes(name string, service kobject.ServiceConfig) (
} }
volumes = append(volumes, vol) volumes = append(volumes, vol)
if len(host) > 0 { if len(volume.Host) > 0 {
log.Warningf("Volume mount on the host %q isn't supported - ignoring path on the host", host) log.Warningf("Volume mount on the host %q isn't supported - ignoring path on the host", volume.Host)
} }
} }
return volumeMounts, volumes, PVCs, nil return volumeMounts, volumes, PVCs, nil
} }
@@ -489,15 +489,21 @@ func (k *Kubernetes) ConfigEnvs(name string, service kobject.ServiceConfig) []ap
// CreateKubernetesObjects generates a Kubernetes artifact for each input type service // CreateKubernetesObjects generates a Kubernetes artifact for each input type service
func (k *Kubernetes) CreateKubernetesObjects(name string, service kobject.ServiceConfig, opt kobject.ConvertOptions) []runtime.Object { func (k *Kubernetes) CreateKubernetesObjects(name string, service kobject.ServiceConfig, opt kobject.ConvertOptions) []runtime.Object {
var objects []runtime.Object var objects []runtime.Object
var replica int
if opt.IsReplicaSetFlag || service.Replicas == 0 {
replica = opt.Replicas
} else {
replica = service.Replicas
}
if opt.CreateD { if opt.CreateD {
objects = append(objects, k.InitD(name, service, opt.Replicas)) objects = append(objects, k.InitD(name, service, replica))
} }
if opt.CreateDS { if opt.CreateDS {
objects = append(objects, k.InitDS(name, service)) objects = append(objects, k.InitDS(name, service))
} }
if opt.CreateRC { if opt.CreateRC {
objects = append(objects, k.InitRC(name, service, opt.Replicas)) objects = append(objects, k.InitRC(name, service, replica))
} }
return objects return objects
@@ -597,8 +603,7 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
allobjects = append(allobjects, objects...) allobjects = append(allobjects, objects...)
} }
// If docker-compose has a volumes_from directive it will be handled here
k.VolumesFrom(&allobjects, komposeObject)
// sort all object so Services are first // sort all object so Services are first
k.SortServicesFirst(&allobjects) k.SortServicesFirst(&allobjects)
return allobjects, nil return allobjects, nil
+37 -14
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -23,8 +23,8 @@ import (
deployapi "github.com/openshift/origin/pkg/deploy/api" deployapi "github.com/openshift/origin/pkg/deploy/api"
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/transformer" "github.com/kubernetes/kompose/pkg/transformer"
"github.com/pkg/errors" "github.com/pkg/errors"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
@@ -40,7 +40,7 @@ func newServiceConfig() kobject.ServiceConfig {
Command: []string{"cmd"}, Command: []string{"cmd"},
WorkingDir: "dir", WorkingDir: "dir",
Args: []string{"arg1", "arg2"}, Args: []string{"arg1", "arg2"},
Volumes: []string{"/tmp/volume"}, VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"}, // not supported Network: []string{"network1", "network2"}, // not supported
Labels: nil, Labels: nil,
Annotations: map[string]string{"abc": "def"}, Annotations: map[string]string{"abc": "def"},
@@ -53,6 +53,8 @@ func newServiceConfig() kobject.ServiceConfig {
Stdin: true, Stdin: true,
Tty: true, Tty: true,
TmpFs: []string{"/tmp"}, TmpFs: []string{"/tmp"},
Replicas: 2,
Volumes: []kobject.Volumes{{SvcName: "app", MountPath: "/tmp/volume", PVCName: "app-claim0"}},
} }
} }
@@ -67,7 +69,7 @@ func equalStringSlice(s1, s2 []string) bool {
return false return false
} }
for i := range s1 { for i := range s1 {
if s1[i] != s1[i] { if s1[i] != s2[i] {
return false return false
} }
} }
@@ -179,7 +181,7 @@ func checkPodTemplate(config kobject.ServiceConfig, template api.PodTemplateSpec
func privilegedNilOrFalse(template api.PodTemplateSpec) bool { func privilegedNilOrFalse(template api.PodTemplateSpec) bool {
return len(template.Spec.Containers) == 0 || template.Spec.Containers[0].SecurityContext == nil || return len(template.Spec.Containers) == 0 || template.Spec.Containers[0].SecurityContext == nil ||
template.Spec.Containers[0].SecurityContext.Privileged == nil || *template.Spec.Containers[0].SecurityContext.Privileged == false template.Spec.Containers[0].SecurityContext.Privileged == nil || !*template.Spec.Containers[0].SecurityContext.Privileged
} }
func checkService(config kobject.ServiceConfig, svc *api.Service, expectedLabels map[string]string) error { func checkService(config kobject.ServiceConfig, svc *api.Service, expectedLabels map[string]string) error {
@@ -270,11 +272,14 @@ func TestKomposeConvert(t *testing.T) {
expectedNumObjs int expectedNumObjs int
}{ }{
// objects generated are deployment, service and pvc // objects generated are deployment, service and pvc
"Convert to Deployments (D)": {newKomposeObject(), kobject.ConvertOptions{CreateD: true, Replicas: replicas}, 3}, "Convert to Deployments (D)": {newKomposeObject(), kobject.ConvertOptions{CreateD: true, Replicas: replicas, IsReplicaSetFlag: true}, 3},
"Convert to DaemonSets (DS)": {newKomposeObject(), kobject.ConvertOptions{CreateDS: true}, 3}, "Convert to Deployments (D) with v3 replicas": {newKomposeObject(), kobject.ConvertOptions{CreateD: true}, 3},
"Convert to ReplicationController (RC)": {newKomposeObject(), kobject.ConvertOptions{CreateRC: true, Replicas: replicas}, 3}, "Convert to DaemonSets (DS)": {newKomposeObject(), kobject.ConvertOptions{CreateDS: true}, 3},
"Convert to ReplicationController(RC)": {newKomposeObject(), kobject.ConvertOptions{CreateRC: true, Replicas: replicas, IsReplicaSetFlag: true}, 3},
"Convert to ReplicationController(RC) with v3 replicas ": {newKomposeObject(), kobject.ConvertOptions{CreateRC: true}, 3},
// objects generated are deployment, daemonset, ReplicationController, service and pvc // objects generated are deployment, daemonset, ReplicationController, service and pvc
"Convert to D, DS, and RC": {newKomposeObject(), kobject.ConvertOptions{CreateD: true, CreateDS: true, CreateRC: true, Replicas: replicas}, 5}, "Convert to D, DS, and RC": {newKomposeObject(), kobject.ConvertOptions{CreateD: true, CreateDS: true, CreateRC: true, Replicas: replicas, IsReplicaSetFlag: true}, 5},
"Convert to D, DS, and RC with v3 replicas": {newKomposeObject(), kobject.ConvertOptions{CreateD: true, CreateDS: true, CreateRC: true}, 5},
// TODO: add more tests // TODO: add more tests
} }
@@ -313,9 +318,18 @@ func TestKomposeConvert(t *testing.T) {
if err := checkMeta(config, d.ObjectMeta, name, true); err != nil { if err := checkMeta(config, d.ObjectMeta, name, true); err != nil {
t.Errorf("%v", err) t.Errorf("%v", err)
} }
if (int)(d.Spec.Replicas) != replicas { if test.opt.IsReplicaSetFlag {
t.Errorf("Expected %d replicas, got %d", replicas, d.Spec.Replicas) if (int)(d.Spec.Replicas) != replicas {
t.Errorf("Expected %d replicas, got %d", replicas, d.Spec.Replicas)
}
} else {
if (int)(d.Spec.Replicas) != newServiceConfig().Replicas {
t.Errorf("Expected %d replicas, got %d", newServiceConfig().Replicas, d.Spec.Replicas)
}
} }
if d.Spec.Selector != nil && len(d.Spec.Selector.MatchLabels) > 0 { if d.Spec.Selector != nil && len(d.Spec.Selector.MatchLabels) > 0 {
t.Errorf("Expect selector be unset, got: %#v", d.Spec.Selector) t.Errorf("Expect selector be unset, got: %#v", d.Spec.Selector)
} }
@@ -344,9 +358,18 @@ func TestKomposeConvert(t *testing.T) {
if err := checkMeta(config, rc.ObjectMeta, name, true); err != nil { if err := checkMeta(config, rc.ObjectMeta, name, true); err != nil {
t.Errorf("%v", err) t.Errorf("%v", err)
} }
if (int)(rc.Spec.Replicas) != replicas { if test.opt.IsReplicaSetFlag {
t.Errorf("Expected %d replicas, got %d", replicas, rc.Spec.Replicas) if (int)(rc.Spec.Replicas) != replicas {
t.Errorf("Expected %d replicas, got %d", replicas, rc.Spec.Replicas)
}
} else {
if (int)(rc.Spec.Replicas) != newServiceConfig().Replicas {
t.Errorf("Expected %d replicas, got %d", newServiceConfig().Replicas, rc.Spec.Replicas)
}
} }
if len(rc.Spec.Selector) > 0 { if len(rc.Spec.Selector) > 0 {
t.Errorf("Expect selector be unset, got: %#v", rc.Spec.Selector) t.Errorf("Expect selector be unset, got: %#v", rc.Spec.Selector)
} }
+13 -10
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -22,8 +22,8 @@ import (
"os/exec" "os/exec"
"strings" "strings"
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/transformer/kubernetes" "github.com/kubernetes/kompose/pkg/transformer/kubernetes"
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
@@ -39,7 +39,7 @@ import (
"reflect" "reflect"
"github.com/kubernetes-incubator/kompose/pkg/transformer" "github.com/kubernetes/kompose/pkg/transformer"
buildapi "github.com/openshift/origin/pkg/build/api" buildapi "github.com/openshift/origin/pkg/build/api"
buildconfigreaper "github.com/openshift/origin/pkg/build/cmd" buildconfigreaper "github.com/openshift/origin/pkg/build/cmd"
deployapi "github.com/openshift/origin/pkg/deploy/api" deployapi "github.com/openshift/origin/pkg/deploy/api"
@@ -346,7 +346,13 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
for _, name := range sortedKeys { for _, name := range sortedKeys {
service := komposeObject.ServiceConfigs[name] service := komposeObject.ServiceConfigs[name]
var objects []runtime.Object var objects []runtime.Object
//replicas
var replica int
if opt.IsReplicaSetFlag || service.Replicas == 0 {
replica = opt.Replicas
} else {
replica = service.Replicas
}
// Must build the images before conversion (got to add service.Image in case 'image' key isn't provided // Must build the images before conversion (got to add service.Image in case 'image' key isn't provided
// Check to see if there is an InputFile (required!) before we build the container // Check to see if there is an InputFile (required!) before we build the container
// Check that there's actually a Build key // Check that there's actually a Build key
@@ -394,7 +400,7 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
objects = o.CreateKubernetesObjects(name, service, opt) objects = o.CreateKubernetesObjects(name, service, opt)
if opt.CreateDeploymentConfig { if opt.CreateDeploymentConfig {
objects = append(objects, o.initDeploymentConfig(name, service, opt.Replicas)) // OpenShift DeploymentConfigs objects = append(objects, o.initDeploymentConfig(name, service, replica)) // OpenShift DeploymentConfigs
// create ImageStream after deployment (creating IS will trigger new deployment) // create ImageStream after deployment (creating IS will trigger new deployment)
objects = append(objects, o.initImageStream(name, service, opt)) objects = append(objects, o.initImageStream(name, service, opt))
} }
@@ -464,10 +470,7 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
allobjects = append(allobjects, objects...) allobjects = append(allobjects, objects...)
} }
// If docker-compose has a volumes_from directive it will be handled here // sort all object so Services are first
o.VolumesFrom(&allobjects, komposeObject)
// sort all object so all services are first
o.SortServicesFirst(&allobjects) o.SortServicesFirst(&allobjects)
return allobjects, nil return allobjects, nil
+8 -7
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -26,10 +26,10 @@ import (
deployapi "github.com/openshift/origin/pkg/deploy/api" deployapi "github.com/openshift/origin/pkg/deploy/api"
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/testutils" "github.com/kubernetes/kompose/pkg/testutils"
"github.com/kubernetes-incubator/kompose/pkg/transformer" "github.com/kubernetes/kompose/pkg/transformer"
"github.com/kubernetes-incubator/kompose/pkg/transformer/kubernetes" "github.com/kubernetes/kompose/pkg/transformer/kubernetes"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@@ -42,7 +42,7 @@ func newServiceConfig() kobject.ServiceConfig {
Command: []string{"cmd"}, Command: []string{"cmd"},
WorkingDir: "dir", WorkingDir: "dir",
Args: []string{"arg1", "arg2"}, Args: []string{"arg1", "arg2"},
Volumes: []string{"/tmp/volume"}, VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"}, // not supported Network: []string{"network1", "network2"}, // not supported
Labels: nil, Labels: nil,
Annotations: map[string]string{"abc": "def"}, Annotations: map[string]string{"abc": "def"},
@@ -406,7 +406,8 @@ func TestRecreateStrategyWithVolumesPresent(t *testing.T) {
service := kobject.ServiceConfig{ service := kobject.ServiceConfig{
ContainerName: "name", ContainerName: "name",
Image: "image", Image: "image",
Volumes: []string{"/tmp/volume"}, VolList: []string{"/tmp/volume"},
Volumes: []kobject.Volumes{{SvcName: "app", MountPath: "/tmp/volume", PVCName: "app-claim0"}},
} }
komposeObject := kobject.KomposeObject{ komposeObject := kobject.KomposeObject{
ServiceConfigs: map[string]kobject.ServiceConfig{"app": service}, ServiceConfigs: map[string]kobject.ServiceConfig{"app": service},
+2 -2
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@ limitations under the License.
package transformer package transformer
import ( import (
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
) )
+8 -5
View File
@@ -1,5 +1,5 @@
/* /*
Copyright 2016 The Kubernetes Authors All rights reserved. Copyright 2017 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -24,15 +24,16 @@ import (
"strings" "strings"
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/kompose/pkg/kobject" "github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/utils/docker" "github.com/kubernetes/kompose/pkg/utils/docker"
"path/filepath" "path/filepath"
"github.com/pkg/errors" "github.com/pkg/errors"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
) )
// Selector used as labels and selector
const Selector = "io.kompose.service" const Selector = "io.kompose.service"
// CreateOutFile creates the file to write to if --out is specified // CreateOutFile creates the file to write to if --out is specified
@@ -74,7 +75,7 @@ func ParseVolume(volume string) (name, host, container, mode string, err error)
possibleAccessMode := volumeStrings[len(volumeStrings)-1] possibleAccessMode := volumeStrings[len(volumeStrings)-1]
// Check to see if :Z or :z exists. We do not support SELinux relabeling at the moment. // Check to see if :Z or :z exists. We do not support SELinux relabeling at the moment.
// See https://github.com/kubernetes-incubator/kompose/issues/176 // See https://github.com/kubernetes/kompose/issues/176
// Otherwise, check to see if "rw" or "ro" has been passed // Otherwise, check to see if "rw" or "ro" has been passed
if possibleAccessMode == "z" || possibleAccessMode == "Z" { if possibleAccessMode == "z" || possibleAccessMode == "Z" {
log.Warnf("Volume mount \"%s\" will be mounted without labeling support. :z or :Z not supported", volume) log.Warnf("Volume mount \"%s\" will be mounted without labeling support. :z or :Z not supported", volume)
@@ -155,7 +156,7 @@ func formatProviderName(provider string) string {
return provider return provider
} }
// Sort struct // EnvSort struct
type EnvSort []api.EnvVar type EnvSort []api.EnvVar
// returns the number of elements in the collection. // returns the number of elements in the collection.
@@ -189,6 +190,7 @@ func GetComposeFileDir(inputFiles []string) (string, error) {
return filepath.Dir(inputFile), nil return filepath.Dir(inputFile), nil
} }
//BuildDockerImage builds docker image
func BuildDockerImage(service kobject.ServiceConfig, name string, relativePath string) error { func BuildDockerImage(service kobject.ServiceConfig, name string, relativePath string) error {
// First, let's figure out the relative path of the Dockerfile! // First, let's figure out the relative path of the Dockerfile!
@@ -223,6 +225,7 @@ func BuildDockerImage(service kobject.ServiceConfig, name string, relativePath s
return nil return nil
} }
// PushDockerImage pushes docker image
func PushDockerImage(service kobject.ServiceConfig, serviceName string) error { func PushDockerImage(service kobject.ServiceConfig, serviceName string) error {
log.Debugf("Pushing Docker image '%s'", service.Image) log.Debugf("Pushing Docker image '%s'", service.Image)
+3 -2
View File
@@ -20,7 +20,7 @@ import (
"bytes" "bytes"
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
dockerlib "github.com/fsouza/go-dockerclient" dockerlib "github.com/fsouza/go-dockerclient"
"github.com/kubernetes-incubator/kompose/pkg/utils/archive" "github.com/kubernetes/kompose/pkg/utils/archive"
"github.com/pkg/errors" "github.com/pkg/errors"
"io/ioutil" "io/ioutil"
"os" "os"
@@ -28,12 +28,13 @@ import (
"strings" "strings"
) )
// Build will provide methods for interaction with API regarding building images
type Build struct { type Build struct {
Client dockerlib.Client Client dockerlib.Client
} }
/* /*
Build a Docker image via the Docker API. Takes the source directory BuildImage builds a Docker image via the Docker API. Takes the source directory
and image name and then builds the appropriate image. Tarball is utilized and image name and then builds the appropriate image. Tarball is utilized
in order to make building easier. in order to make building easier.
*/ */
+17 -5
View File
@@ -18,16 +18,28 @@ package docker
import ( import (
"github.com/fsouza/go-dockerclient" "github.com/fsouza/go-dockerclient"
"os"
) )
// DockerClient connects to Docker client on host
func DockerClient() (*docker.Client, error) { func DockerClient() (*docker.Client, error) {
// Default end-point, HTTP + TLS support to be added in the future var (
// Eventually functionality to specify end-point added to command-line err error
endpoint := "unix:///var/run/docker.sock" client *docker.Client
)
// Use the unix socker end-point. No support for TLS (yet) dockerHost := os.Getenv("DOCKER_HOST")
client, err := docker.NewClient(endpoint)
if len(dockerHost) > 0 {
// Create client instance from Docker's environment variables:
// DOCKER_HOST, DOCKER_TLS_VERIFY, DOCKER_CERT_PATH
client, err = docker.NewClientFromEnv()
} else {
// Default unix socker end-point
endpoint := "unix:///var/run/docker.sock"
client, err = docker.NewClient(endpoint)
}
if err != nil { if err != nil {
return client, err return client, err
} }
+3 -2
View File
@@ -24,12 +24,13 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// Push will provide methods for interaction with API regarding pushing images
type Push struct { type Push struct {
Client dockerlib.Client Client dockerlib.Client
} }
/* /*
Push a Docker image via the Docker API. Takes the image name, PushImage push a Docker image via the Docker API. Takes the image name,
parses the URL details and then push based on environment authentication parses the URL details and then push based on environment authentication
credentials. credentials.
*/ */
@@ -80,5 +81,5 @@ func (c *Push) PushImage(fullImageName string) error {
} }
} }
return errors.New("Unable to push docker image(s). Check that `docker login` works successfully on the command line.") return errors.New("unable to push docker image(s). Check that `docker login` works successfully on the command line")
} }
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Copyright 2016 The Kubernetes Authors All rights reserved. # Copyright 2017 The Kubernetes Authors All rights reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Copyright 2016 The Kubernetes Authors All rights reserved. # Copyright 2017 The Kubernetes Authors All rights reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
+50 -6
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Copyright 2016 The Kubernetes Authors All rights reserved. # Copyright 2017 The Kubernetes Authors All rights reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@@ -15,9 +15,9 @@
# limitations under the License. # limitations under the License.
# Constants. Enter relevant repo information here. # Constants. Enter relevant repo information here.
UPSTREAM_REPO="kubernetes-incubator" UPSTREAM_REPO="kubernetes"
CLI="kompose" CLI="kompose"
GITPATH="$GOPATH/src/github.com/kubernetes-incubator/kompose" GITPATH="$GOPATH/src/github.com/kubernetes/kompose"
usage() { usage() {
echo "This will prepare $CLI for release!" echo "This will prepare $CLI for release!"
@@ -97,8 +97,11 @@ replaceversion() {
echo "Replaced version in README.md" echo "Replaced version in README.md"
sed -i "s/$1/$2/g" README.md sed -i "s/$1/$2/g" README.md
echo "Replaced version in docs/setup.md" echo "Replaced version in docs/installation.md"
sed -i "s/$1/$2/g" docs/setup.md sed -i "s/$1/$2/g" docs/installation.md
echo "Replaced version in build/VERSION"
sed -i "s/$1/$2/g" build/VERSION
} }
changelog() { changelog() {
@@ -159,6 +162,43 @@ git_tag() {
git tag v$1 git tag v$1
} }
generate_install_guide() {
echo "
# Installation
__Linux and macOS:__
\`\`\`sh
# Linux
curl -L https://github.com/kubernetes/kompose/releases/download/v$1/kompose-linux-amd64 -o kompose
# macOS
curl -L https://github.com/kubernetes/kompose/releases/download/v$1/kompose-darwin-amd64 -o kompose
chmod +x kompose
sudo mv ./kompose /usr/local/bin/kompose
\`\`\`
__Windows:__
Download from [GitHub](https://github.com/kubernetes/kompose/releases/download/v$1/kompose-windows-amd64.exe) and add the binary to your PATH.
__Checksums:__
| Filename | SHA256 Hash |
| ------------- |:-------------:|" > install_guide.txt
for f in bin/*
do
HASH=`sha256sum $f | head -n1 | awk '{print $1;}'`
NAME=`echo $f | sed "s,bin/,,g"`
echo "[$NAME](https://github.com/kubernetes/kompose/releases/download/v$1/$NAME) | $HASH" >> install_guide.txt
done
# Append the file to the file
cat install_guide.txt >> changes.txt
}
push() { push() {
CHANGES=$(cat changes.txt) CHANGES=$(cat changes.txt)
# Release it! # Release it!
@@ -204,7 +244,7 @@ push() {
} }
clean() { clean() {
rm changes.txt rm changes.txt install_guide.txt
} }
main() { main() {
@@ -248,6 +288,7 @@ main() {
"Create tag" "Create tag"
"Build binaries" "Build binaries"
"Create tarballs" "Create tarballs"
"Generate install guide"
"Upload the binaries and push to GitHub release page" "Upload the binaries and push to GitHub release page"
"Clean" "Clean"
"Quit") "Quit")
@@ -282,6 +323,9 @@ main() {
"Create tarballs") "Create tarballs")
create_tarballs create_tarballs
;; ;;
"Generate install guide")
generate_install_guide $VERSION
;;
"Upload the binaries and push to GitHub release page") "Upload the binaries and push to GitHub release page")
push $VERSION push $VERSION
;; ;;
+3 -2
View File
@@ -7,7 +7,7 @@ if [ "$TRAVIS_BRANCH" != "master" ] || [ "$BUILD_DOCS" != "yes" ] || [ "$TRAVIS_
fi fi
DOCS_REPO_NAME="kompose" DOCS_REPO_NAME="kompose"
DOCS_REPO_URL="git@github.com:kubernetes-incubator/kompose.git" DOCS_REPO_URL="git@github.com:kubernetes/kompose.git"
DOCS_KEY="script/deploy_key" DOCS_KEY="script/deploy_key"
DOCS_USER="komposebot" DOCS_USER="komposebot"
DOCS_EMAIL="cdrage+kompose@redhat.com" DOCS_EMAIL="cdrage+kompose@redhat.com"
@@ -65,6 +65,7 @@ for filename in *.md; do
jekyll="--- jekyll="---
layout: default layout: default
permalink: /$name/ permalink: /$name/
redirect_from: \"/docs/$name.md\"
--- ---
" "
echo -e "$jekyll\n$(cat $filename)" > $filename echo -e "$jekyll\n$(cat $filename)" > $filename
@@ -80,7 +81,7 @@ git config user.email "$DOCS_EMAIL"
git add --all git add --all
# Check if anything changed, and if it's the case, push to origin/master. # Check if anything changed, and if it's the case, push to origin/master.
if git commit -m 'Update docs' -m "Commit: https://github.com/kubernetes-incubator/kompose/commit/$TRAVIS_COMMIT" ; then if git commit -m 'Update docs' -m "Commit: https://github.com/kubernetes/kompose/commit/$TRAVIS_COMMIT" ; then
git push git push
fi fi
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Copyright 2016 The Kubernetes Authors All rights reserved. # Copyright 2017 The Kubernetes Authors All rights reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Copyright 2016 The Kubernetes Authors All rights reserved. # Copyright 2017 The Kubernetes Authors All rights reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
+10 -1
View File
@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# Copyright 2016 The Kubernetes Authors All rights reserved. # Copyright 2017 The Kubernetes Authors All rights reserved.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@@ -106,6 +106,12 @@ convert::expect_success_and_warning "kompose -f $KOMPOSE_ROOT/script/test/fixtur
# openshift test # openshift test
convert::expect_success_and_warning "kompose --provider=openshift -f $KOMPOSE_ROOT/script/test/fixtures/volume-mounts/volumes-from/docker-compose.yml convert --stdout -j" "$KOMPOSE_ROOT/script/test/fixtures/volume-mounts/volumes-from/output-os.json" "ignoring path on the host" convert::expect_success_and_warning "kompose --provider=openshift -f $KOMPOSE_ROOT/script/test/fixtures/volume-mounts/volumes-from/docker-compose.yml convert --stdout -j" "$KOMPOSE_ROOT/script/test/fixtures/volume-mounts/volumes-from/output-os.json" "ignoring path on the host"
# Tests related to docker-compose file in /script/test/fixtures/volume-mounts/volumes-from corner cases
# kubernetes test
convert::expect_success "kompose -f $KOMPOSE_ROOT/script/test/fixtures/volume-mounts/volumes-from/docker-compose-case.yml convert --stdout -j" "$KOMPOSE_ROOT/script/test/fixtures/volume-mounts/volumes-from/output-k8s-case.json"
# openshift test
convert::expect_success "kompose --provider=openshift -f $KOMPOSE_ROOT/script/test/fixtures/volume-mounts/volumes-from/docker-compose-case.yml convert --stdout -j" "$KOMPOSE_ROOT/script/test/fixtures/volume-mounts/volumes-from/output-os-case.json"
###### ######
# Tests related to docker-compose file in /script/test/fixtures/envvars-separators # Tests related to docker-compose file in /script/test/fixtures/envvars-separators
@@ -264,6 +270,9 @@ cd $CURRENT_DIR
# Test V3 Support of Docker Compose # Test V3 Support of Docker Compose
# Test support for cpu and memory limits + reservations
convert::expect_success "kompose convert --stdout -j -f $KOMPOSE_ROOT/script/test/fixtures/v3/docker-compose-memcpu.yaml" "$KOMPOSE_ROOT/script/test/fixtures/v3/output-memcpu-k8s.json"
# Test volumes are passed correctly # Test volumes are passed correctly
convert::expect_success "kompose convert --stdout -j -f $KOMPOSE_ROOT/script/test/fixtures/v3/docker-compose-volumes.yaml" "$KOMPOSE_ROOT/script/test/fixtures/v3/output-volumes-k8s.json" convert::expect_success "kompose convert --stdout -j -f $KOMPOSE_ROOT/script/test/fixtures/v3/docker-compose-volumes.yaml" "$KOMPOSE_ROOT/script/test/fixtures/v3/output-volumes-k8s.json"
+10 -10
View File
@@ -95,16 +95,16 @@
"image": "bitnami/mariadb:latest", "image": "bitnami/mariadb:latest",
"env": [ "env": [
{ {
"name": "MARIADB_USER", "name": "ALLOW_EMPTY_PASSWORD",
"value": "bn_wordpress" "value": "yes"
}, },
{ {
"name": "MARIADB_DATABASE", "name": "MARIADB_DATABASE",
"value": "bitnami_wordpress" "value": "bitnami_wordpress"
}, },
{ {
"name": "ALLOW_EMPTY_PASSWORD", "name": "MARIADB_USER",
"value": "yes" "value": "bn_wordpress"
} }
], ],
"resources": {}, "resources": {},
@@ -200,6 +200,10 @@
} }
], ],
"env": [ "env": [
{
"name": "ALLOW_EMPTY_PASSWORD",
"value": "yes"
},
{ {
"name": "MARIADB_HOST", "name": "MARIADB_HOST",
"value": "mariadb" "value": "mariadb"
@@ -208,17 +212,13 @@
"name": "MARIADB_PORT", "name": "MARIADB_PORT",
"value": "3306" "value": "3306"
}, },
{
"name": "WORDPRESS_DATABASE_USER",
"value": "bn_wordpress"
},
{ {
"name": "WORDPRESS_DATABASE_NAME", "name": "WORDPRESS_DATABASE_NAME",
"value": "bitnami_wordpress" "value": "bitnami_wordpress"
}, },
{ {
"name": "ALLOW_EMPTY_PASSWORD", "name": "WORDPRESS_DATABASE_USER",
"value": "yes" "value": "bn_wordpress"
} }
], ],
"resources": {}, "resources": {},
+10 -10
View File
@@ -121,16 +121,16 @@
"image": " ", "image": " ",
"env": [ "env": [
{ {
"name": "MARIADB_USER", "name": "ALLOW_EMPTY_PASSWORD",
"value": "bn_wordpress" "value": "yes"
}, },
{ {
"name": "MARIADB_DATABASE", "name": "MARIADB_DATABASE",
"value": "bitnami_wordpress" "value": "bitnami_wordpress"
}, },
{ {
"name": "ALLOW_EMPTY_PASSWORD", "name": "MARIADB_USER",
"value": "yes" "value": "bn_wordpress"
} }
], ],
"resources": {}, "resources": {},
@@ -277,6 +277,10 @@
} }
], ],
"env": [ "env": [
{
"name": "ALLOW_EMPTY_PASSWORD",
"value": "yes"
},
{ {
"name": "MARIADB_HOST", "name": "MARIADB_HOST",
"value": "mariadb" "value": "mariadb"
@@ -285,17 +289,13 @@
"name": "MARIADB_PORT", "name": "MARIADB_PORT",
"value": "3306" "value": "3306"
}, },
{
"name": "WORDPRESS_DATABASE_USER",
"value": "bn_wordpress"
},
{ {
"name": "WORDPRESS_DATABASE_NAME", "name": "WORDPRESS_DATABASE_NAME",
"value": "bitnami_wordpress" "value": "bitnami_wordpress"
}, },
{ {
"name": "ALLOW_EMPTY_PASSWORD", "name": "WORDPRESS_DATABASE_USER",
"value": "yes" "value": "bn_wordpress"
} }
], ],
"resources": {}, "resources": {},
+1 -1
View File
@@ -39,7 +39,7 @@ services:
cpus: '0.0001' cpus: '0.0001'
memory: 20M memory: 20M
restart_policy: restart_policy:
condition: on_failure condition: on-failure
delay: 5s delay: 5s
max_attempts: 3 max_attempts: 3
window: 120s window: 120s
+13
View File
@@ -0,0 +1,13 @@
version: "3"
services:
foo:
deploy:
resources:
limits:
cpus: '0.01'
memory: 50M
reservations:
cpus: '0.001'
memory: 20M
image: redis
+171 -327
View File
@@ -4,372 +4,216 @@
"metadata": {}, "metadata": {},
"items": [ "items": [
{ {
"kind": "Service", "kind": "Pod",
"apiVersion": "v1", "apiVersion": "v1",
"metadata": { "metadata": {
"name": "foo", "name": "foo",
"creationTimestamp": null, "creationTimestamp": null,
"labels": { "labels": {
"io.kompose.service": "foo" "io.kompose.service": "foo"
},
"annotations": {
"com.example.description": "Accounting webapp",
"com.example.empty-label": "",
"com.example.number": "42"
} }
}, },
"spec": { "spec": {
"ports": [ "volumes": [
{ {
"name": "3000", "name": "foo-claim0",
"port": 3000, "persistentVolumeClaim": {
"targetPort": 3000 "claimName": "foo-claim0"
},
{
"name": "3000",
"port": 3000,
"targetPort": 3000
},
{
"name": "3001",
"port": 3001,
"targetPort": 3001
},
{
"name": "3002",
"port": 3002,
"targetPort": 3002
},
{
"name": "3003",
"port": 3003,
"targetPort": 3003
},
{
"name": "3004",
"port": 3004,
"targetPort": 3004
},
{
"name": "3005",
"port": 3005,
"targetPort": 3005
},
{
"name": "8000",
"port": 8000,
"targetPort": 8000
},
{
"name": "9090",
"port": 9090,
"targetPort": 8080
},
{
"name": "9091",
"port": 9091,
"targetPort": 8081
},
{
"name": "49100",
"port": 49100,
"targetPort": 22
},
{
"name": "8001",
"port": 8001,
"targetPort": 8001
},
{
"name": "5000",
"port": 5000,
"targetPort": 5000
},
{
"name": "5001",
"port": 5001,
"targetPort": 5001
},
{
"name": "5002",
"port": 5002,
"targetPort": 5002
},
{
"name": "5003",
"port": 5003,
"targetPort": 5003
},
{
"name": "5004",
"port": 5004,
"targetPort": 5004
},
{
"name": "5005",
"port": 5005,
"targetPort": 5005
},
{
"name": "5006",
"port": 5006,
"targetPort": 5006
},
{
"name": "5007",
"port": 5007,
"targetPort": 5007
},
{
"name": "5008",
"port": 5008,
"targetPort": 5008
},
{
"name": "5009",
"port": 5009,
"targetPort": 5009
},
{
"name": "5010",
"port": 5010,
"targetPort": 5010
}
],
"selector": {
"io.kompose.service": "foo"
}
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "Deployment",
"apiVersion": "extensions/v1beta1",
"metadata": {
"name": "foo",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo"
},
"annotations": {
"com.example.description": "Accounting webapp",
"com.example.empty-label": "",
"com.example.number": "42"
}
},
"spec": {
"replicas": 1,
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo"
} }
}, },
"spec": { {
"volumes": [ "name": "foo-claim1",
"persistentVolumeClaim": {
"claimName": "foo-claim1"
}
},
{
"name": "foo-claim2",
"persistentVolumeClaim": {
"claimName": "foo-claim2"
}
},
{
"name": "foo-claim3",
"persistentVolumeClaim": {
"claimName": "foo-claim3"
}
},
{
"name": "foo-claim4",
"persistentVolumeClaim": {
"claimName": "foo-claim4",
"readOnly": true
}
},
{
"name": "datavolume",
"persistentVolumeClaim": {
"claimName": "datavolume"
}
},
{
"name": "foo-tmpfs0",
"emptyDir": {
"medium": "Memory"
}
},
{
"name": "foo-tmpfs1",
"emptyDir": {
"medium": "Memory"
}
}
],
"containers": [
{
"name": "my-web-container",
"image": "redis",
"command": [
"/code/entrypoint.sh",
"-p",
"3000"
],
"args": [
"bundle",
"exec",
"thin",
"-p",
"3000"
],
"workingDir": "/code",
"ports": [
{
"containerPort": 3000
},
{
"containerPort": 3000
},
{
"containerPort": 3001
},
{
"containerPort": 3002
},
{
"containerPort": 3003
},
{
"containerPort": 3004
},
{
"containerPort": 3005
},
{
"containerPort": 8000
},
{
"containerPort": 8080
},
{
"containerPort": 8081
},
{
"containerPort": 22
},
{
"containerPort": 8001
},
{
"containerPort": 5000
},
{
"containerPort": 5001
},
{
"containerPort": 5002
},
{
"containerPort": 5003
},
{
"containerPort": 5004
},
{
"containerPort": 5005
},
{
"containerPort": 5006
},
{
"containerPort": 5007
},
{
"containerPort": 5008
},
{
"containerPort": 5009
},
{
"containerPort": 5010
}
],
"resources": {
"limits": {
"cpu": "1",
"memory": "52428800"
},
"requests": {
"memory": "20971520"
}
},
"volumeMounts": [
{ {
"name": "foo-claim0", "name": "foo-claim0",
"persistentVolumeClaim": { "mountPath": "/var/lib/mysql"
"claimName": "foo-claim0"
}
}, },
{ {
"name": "foo-claim1", "name": "foo-claim1",
"persistentVolumeClaim": { "mountPath": "/var/lib/mysql"
"claimName": "foo-claim1"
}
}, },
{ {
"name": "foo-claim2", "name": "foo-claim2",
"persistentVolumeClaim": { "mountPath": "/code"
"claimName": "foo-claim2"
}
}, },
{ {
"name": "foo-claim3", "name": "foo-claim3",
"persistentVolumeClaim": { "mountPath": "/var/www/html"
"claimName": "foo-claim3"
}
}, },
{ {
"name": "foo-claim4", "name": "foo-claim4",
"persistentVolumeClaim": { "readOnly": true,
"claimName": "foo-claim4", "mountPath": "/etc/configs/"
"readOnly": true
}
}, },
{ {
"name": "datavolume", "name": "datavolume",
"persistentVolumeClaim": { "mountPath": "/var/lib/mysql"
"claimName": "datavolume"
}
}, },
{ {
"name": "foo-tmpfs0", "name": "foo-tmpfs0",
"emptyDir": { "mountPath": "/run"
"medium": "Memory"
}
}, },
{ {
"name": "foo-tmpfs1", "name": "foo-tmpfs1",
"emptyDir": { "mountPath": "/tmp"
"medium": "Memory"
}
} }
], ],
"containers": [ "securityContext": {
{ "capabilities": {
"name": "my-web-container", "add": [
"image": "redis", "ALL"
"command": [
"/code/entrypoint.sh",
"-p",
"3000"
], ],
"args": [ "drop": [
"bundle", "NET_ADMIN",
"exec", "SYS_ADMIN"
"thin", ]
"-p", },
"3000" "privileged": true
], },
"workingDir": "/code", "stdin": true,
"ports": [ "tty": true
{
"containerPort": 3000
},
{
"containerPort": 3000
},
{
"containerPort": 3001
},
{
"containerPort": 3002
},
{
"containerPort": 3003
},
{
"containerPort": 3004
},
{
"containerPort": 3005
},
{
"containerPort": 8000
},
{
"containerPort": 8080
},
{
"containerPort": 8081
},
{
"containerPort": 22
},
{
"containerPort": 8001
},
{
"containerPort": 5000
},
{
"containerPort": 5001
},
{
"containerPort": 5002
},
{
"containerPort": 5003
},
{
"containerPort": 5004
},
{
"containerPort": 5005
},
{
"containerPort": 5006
},
{
"containerPort": 5007
},
{
"containerPort": 5008
},
{
"containerPort": 5009
},
{
"containerPort": 5010
}
],
"resources": {
"limits": {
"memory": "52428800"
}
},
"volumeMounts": [
{
"name": "foo-claim0",
"mountPath": "/var/lib/mysql"
},
{
"name": "foo-claim1",
"mountPath": "/var/lib/mysql"
},
{
"name": "foo-claim2",
"mountPath": "/code"
},
{
"name": "foo-claim3",
"mountPath": "/var/www/html"
},
{
"name": "foo-claim4",
"readOnly": true,
"mountPath": "/etc/configs/"
},
{
"name": "datavolume",
"mountPath": "/var/lib/mysql"
},
{
"name": "foo-tmpfs0",
"mountPath": "/run"
},
{
"name": "foo-tmpfs1",
"mountPath": "/tmp"
}
],
"securityContext": {
"capabilities": {
"add": [
"ALL"
],
"drop": [
"NET_ADMIN",
"SYS_ADMIN"
]
},
"privileged": true
},
"stdin": true,
"tty": true
}
],
"restartPolicy": "Always"
} }
}, ],
"strategy": { "restartPolicy": "OnFailure"
"type": "Recreate"
}
}, },
"status": {} "status": {}
}, },
+77
View File
@@ -0,0 +1,77 @@
{
"kind": "List",
"apiVersion": "v1",
"metadata": {},
"items": [
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "foo",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo"
}
},
"spec": {
"ports": [
{
"name": "headless",
"port": 55555,
"targetPort": 0
}
],
"selector": {
"io.kompose.service": "foo"
},
"clusterIP": "None"
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "Deployment",
"apiVersion": "extensions/v1beta1",
"metadata": {
"name": "foo",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo"
}
},
"spec": {
"replicas": 1,
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo"
}
},
"spec": {
"containers": [
{
"name": "foo",
"image": "redis",
"resources": {
"limits": {
"cpu": "10",
"memory": "52428800"
},
"requests": {
"cpu": "1",
"memory": "20971520"
}
}
}
],
"restartPolicy": "Always"
}
},
"strategy": {}
},
"status": {}
}
]
}
+155 -362
View File
@@ -4,426 +4,219 @@
"metadata": {}, "metadata": {},
"items": [ "items": [
{ {
"kind": "Service", "kind": "Pod",
"apiVersion": "v1", "apiVersion": "v1",
"metadata": { "metadata": {
"name": "foo", "name": "foo",
"creationTimestamp": null, "creationTimestamp": null,
"labels": { "labels": {
"io.kompose.service": "foo" "io.kompose.service": "foo"
},
"annotations": {
"com.example.description": "Accounting webapp",
"com.example.empty-label": "",
"com.example.number": "42"
} }
}, },
"spec": { "spec": {
"ports": [ "volumes": [
{ {
"name": "3000", "name": "foo-claim0",
"port": 3000, "persistentVolumeClaim": {
"targetPort": 3000 "claimName": "foo-claim0"
}
}, },
{ {
"name": "3000", "name": "foo-claim1",
"port": 3000, "persistentVolumeClaim": {
"targetPort": 3000 "claimName": "foo-claim1"
}
}, },
{ {
"name": "3001", "name": "foo-claim2",
"port": 3001, "persistentVolumeClaim": {
"targetPort": 3001 "claimName": "foo-claim2"
}
}, },
{ {
"name": "3002", "name": "foo-claim3",
"port": 3002, "persistentVolumeClaim": {
"targetPort": 3002 "claimName": "foo-claim3"
}
}, },
{ {
"name": "3003", "name": "foo-claim4",
"port": 3003, "persistentVolumeClaim": {
"targetPort": 3003 "claimName": "foo-claim4",
"readOnly": true
}
}, },
{ {
"name": "3004", "name": "datavolume",
"port": 3004, "persistentVolumeClaim": {
"targetPort": 3004 "claimName": "datavolume"
}
}, },
{ {
"name": "3005", "name": "foo-tmpfs0",
"port": 3005, "emptyDir": {
"targetPort": 3005 "medium": "Memory"
}
}, },
{ {
"name": "8000", "name": "foo-tmpfs1",
"port": 8000, "emptyDir": {
"targetPort": 8000 "medium": "Memory"
}, }
{
"name": "9090",
"port": 9090,
"targetPort": 8080
},
{
"name": "9091",
"port": 9091,
"targetPort": 8081
},
{
"name": "49100",
"port": 49100,
"targetPort": 22
},
{
"name": "8001",
"port": 8001,
"targetPort": 8001
},
{
"name": "5000",
"port": 5000,
"targetPort": 5000
},
{
"name": "5001",
"port": 5001,
"targetPort": 5001
},
{
"name": "5002",
"port": 5002,
"targetPort": 5002
},
{
"name": "5003",
"port": 5003,
"targetPort": 5003
},
{
"name": "5004",
"port": 5004,
"targetPort": 5004
},
{
"name": "5005",
"port": 5005,
"targetPort": 5005
},
{
"name": "5006",
"port": 5006,
"targetPort": 5006
},
{
"name": "5007",
"port": 5007,
"targetPort": 5007
},
{
"name": "5008",
"port": 5008,
"targetPort": 5008
},
{
"name": "5009",
"port": 5009,
"targetPort": 5009
},
{
"name": "5010",
"port": 5010,
"targetPort": 5010
} }
], ],
"selector": { "containers": [
"io.kompose.service": "foo"
}
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "DeploymentConfig",
"apiVersion": "v1",
"metadata": {
"name": "foo",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo"
},
"annotations": {
"com.example.description": "Accounting webapp",
"com.example.empty-label": "",
"com.example.number": "42"
}
},
"spec": {
"strategy": {
"type": "Recreate",
"resources": {}
},
"triggers": [
{ {
"type": "ConfigChange" "name": "my-web-container",
}, "image": "redis",
{ "command": [
"type": "ImageChange", "/code/entrypoint.sh",
"imageChangeParams": { "-p",
"automatic": true, "3000"
"containerNames": [ ],
"my-web-container" "args": [
], "bundle",
"from": { "exec",
"kind": "ImageStreamTag", "thin",
"name": "foo:latest" "-p",
"3000"
],
"workingDir": "/code",
"ports": [
{
"containerPort": 3000
},
{
"containerPort": 3000
},
{
"containerPort": 3001
},
{
"containerPort": 3002
},
{
"containerPort": 3003
},
{
"containerPort": 3004
},
{
"containerPort": 3005
},
{
"containerPort": 8000
},
{
"containerPort": 8080
},
{
"containerPort": 8081
},
{
"containerPort": 22
},
{
"containerPort": 8001
},
{
"containerPort": 5000
},
{
"containerPort": 5001
},
{
"containerPort": 5002
},
{
"containerPort": 5003
},
{
"containerPort": 5004
},
{
"containerPort": 5005
},
{
"containerPort": 5006
},
{
"containerPort": 5007
},
{
"containerPort": 5008
},
{
"containerPort": 5009
},
{
"containerPort": 5010
} }
} ],
} "resources": {
], "limits": {
"replicas": 1, "cpu": "1",
"test": false, "memory": "52428800"
"selector": { },
"io.kompose.service": "foo" "requests": {
}, "memory": "20971520"
"template": { }
"metadata": { },
"creationTimestamp": null, "volumeMounts": [
"labels": {
"io.kompose.service": "foo"
}
},
"spec": {
"volumes": [
{ {
"name": "foo-claim0", "name": "foo-claim0",
"persistentVolumeClaim": { "mountPath": "/var/lib/mysql"
"claimName": "foo-claim0"
}
}, },
{ {
"name": "foo-claim1", "name": "foo-claim1",
"persistentVolumeClaim": { "mountPath": "/var/lib/mysql"
"claimName": "foo-claim1"
}
}, },
{ {
"name": "foo-claim2", "name": "foo-claim2",
"persistentVolumeClaim": { "mountPath": "/code"
"claimName": "foo-claim2"
}
}, },
{ {
"name": "foo-claim3", "name": "foo-claim3",
"persistentVolumeClaim": { "mountPath": "/var/www/html"
"claimName": "foo-claim3"
}
}, },
{ {
"name": "foo-claim4", "name": "foo-claim4",
"persistentVolumeClaim": { "readOnly": true,
"claimName": "foo-claim4", "mountPath": "/etc/configs/"
"readOnly": true
}
}, },
{ {
"name": "datavolume", "name": "datavolume",
"persistentVolumeClaim": { "mountPath": "/var/lib/mysql"
"claimName": "datavolume"
}
}, },
{ {
"name": "foo-tmpfs0", "name": "foo-tmpfs0",
"emptyDir": { "mountPath": "/run"
"medium": "Memory"
}
}, },
{ {
"name": "foo-tmpfs1", "name": "foo-tmpfs1",
"emptyDir": { "mountPath": "/tmp"
"medium": "Memory"
}
} }
], ],
"containers": [ "securityContext": {
{ "capabilities": {
"name": "my-web-container", "add": [
"image": " ", "ALL"
"command": [
"/code/entrypoint.sh",
"-p",
"3000"
], ],
"args": [ "drop": [
"bundle", "NET_ADMIN",
"exec", "SYS_ADMIN"
"thin", ]
"-p", },
"3000" "privileged": true
], },
"workingDir": "/code", "stdin": true,
"ports": [ "tty": true
{
"containerPort": 3000
},
{
"containerPort": 3000
},
{
"containerPort": 3001
},
{
"containerPort": 3002
},
{
"containerPort": 3003
},
{
"containerPort": 3004
},
{
"containerPort": 3005
},
{
"containerPort": 8000
},
{
"containerPort": 8080
},
{
"containerPort": 8081
},
{
"containerPort": 22
},
{
"containerPort": 8001
},
{
"containerPort": 5000
},
{
"containerPort": 5001
},
{
"containerPort": 5002
},
{
"containerPort": 5003
},
{
"containerPort": 5004
},
{
"containerPort": 5005
},
{
"containerPort": 5006
},
{
"containerPort": 5007
},
{
"containerPort": 5008
},
{
"containerPort": 5009
},
{
"containerPort": 5010
}
],
"resources": {
"limits": {
"memory": "52428800"
}
},
"volumeMounts": [
{
"name": "foo-claim0",
"mountPath": "/var/lib/mysql"
},
{
"name": "foo-claim1",
"mountPath": "/var/lib/mysql"
},
{
"name": "foo-claim2",
"mountPath": "/code"
},
{
"name": "foo-claim3",
"mountPath": "/var/www/html"
},
{
"name": "foo-claim4",
"readOnly": true,
"mountPath": "/etc/configs/"
},
{
"name": "datavolume",
"mountPath": "/var/lib/mysql"
},
{
"name": "foo-tmpfs0",
"mountPath": "/run"
},
{
"name": "foo-tmpfs1",
"mountPath": "/tmp"
}
],
"securityContext": {
"capabilities": {
"add": [
"ALL"
],
"drop": [
"NET_ADMIN",
"SYS_ADMIN"
]
},
"privileged": true
},
"stdin": true,
"tty": true
}
],
"restartPolicy": "Always"
} }
} ],
"restartPolicy": "OnFailure"
}, },
"status": {} "status": {}
}, },
{
"kind": "ImageStream",
"apiVersion": "v1",
"metadata": {
"name": "foo",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo"
}
},
"spec": {
"tags": [
{
"name": "latest",
"annotations": null,
"from": {
"kind": "DockerImage",
"name": "redis"
},
"generation": null,
"importPolicy": {}
}
]
},
"status": {
"dockerImageRepository": ""
}
},
{ {
"kind": "PersistentVolumeClaim", "kind": "PersistentVolumeClaim",
"apiVersion": "v1", "apiVersion": "v1",
@@ -0,0 +1,29 @@
version: '2'
services:
foo:
image: busybox
command: sleep 3600
volumes:
- /foo1
- /foo2
volumes_from:
- cat
bar:
image: busybox
command: sleep 3600
volumes:
- /foo1
- /bar
volumes_from:
- foo
cat:
image: busybox
command: sleep 3600
volumes:
- /cat
@@ -0,0 +1,388 @@
{
"kind": "List",
"apiVersion": "v1",
"metadata": {},
"items": [
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "bar",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "bar"
}
},
"spec": {
"ports": [
{
"name": "headless",
"port": 55555,
"targetPort": 0
}
],
"selector": {
"io.kompose.service": "bar"
},
"clusterIP": "None"
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "cat",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "cat"
}
},
"spec": {
"ports": [
{
"name": "headless",
"port": 55555,
"targetPort": 0
}
],
"selector": {
"io.kompose.service": "cat"
},
"clusterIP": "None"
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "foo",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo"
}
},
"spec": {
"ports": [
{
"name": "headless",
"port": 55555,
"targetPort": 0
}
],
"selector": {
"io.kompose.service": "foo"
},
"clusterIP": "None"
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "Deployment",
"apiVersion": "extensions/v1beta1",
"metadata": {
"name": "bar",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "bar"
}
},
"spec": {
"replicas": 1,
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"io.kompose.service": "bar"
}
},
"spec": {
"volumes": [
{
"name": "bar-claim1",
"persistentVolumeClaim": {
"claimName": "bar-claim1"
}
},
{
"name": "foo-claim0",
"persistentVolumeClaim": {
"claimName": "foo-claim0"
}
},
{
"name": "foo-claim1",
"persistentVolumeClaim": {
"claimName": "foo-claim1"
}
},
{
"name": "cat-claim0",
"persistentVolumeClaim": {
"claimName": "cat-claim0"
}
}
],
"containers": [
{
"name": "bar",
"image": "busybox",
"args": [
"sleep",
"3600"
],
"resources": {},
"volumeMounts": [
{
"name": "bar-claim1",
"mountPath": "/bar"
},
{
"name": "foo-claim0",
"mountPath": "/foo1"
},
{
"name": "foo-claim1",
"mountPath": "/foo2"
},
{
"name": "cat-claim0",
"mountPath": "/cat"
}
]
}
],
"restartPolicy": "Always"
}
},
"strategy": {
"type": "Recreate"
}
},
"status": {}
},
{
"kind": "PersistentVolumeClaim",
"apiVersion": "v1",
"metadata": {
"name": "bar-claim1",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "bar-claim1"
}
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "100Mi"
}
}
},
"status": {}
},
{
"kind": "Deployment",
"apiVersion": "extensions/v1beta1",
"metadata": {
"name": "cat",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "cat"
}
},
"spec": {
"replicas": 1,
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"io.kompose.service": "cat"
}
},
"spec": {
"volumes": [
{
"name": "cat-claim0",
"persistentVolumeClaim": {
"claimName": "cat-claim0"
}
}
],
"containers": [
{
"name": "cat",
"image": "busybox",
"args": [
"sleep",
"3600"
],
"resources": {},
"volumeMounts": [
{
"name": "cat-claim0",
"mountPath": "/cat"
}
]
}
],
"restartPolicy": "Always"
}
},
"strategy": {
"type": "Recreate"
}
},
"status": {}
},
{
"kind": "PersistentVolumeClaim",
"apiVersion": "v1",
"metadata": {
"name": "cat-claim0",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "cat-claim0"
}
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "100Mi"
}
}
},
"status": {}
},
{
"kind": "Deployment",
"apiVersion": "extensions/v1beta1",
"metadata": {
"name": "foo",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo"
}
},
"spec": {
"replicas": 1,
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo"
}
},
"spec": {
"volumes": [
{
"name": "foo-claim0",
"persistentVolumeClaim": {
"claimName": "foo-claim0"
}
},
{
"name": "foo-claim1",
"persistentVolumeClaim": {
"claimName": "foo-claim1"
}
},
{
"name": "cat-claim0",
"persistentVolumeClaim": {
"claimName": "cat-claim0"
}
}
],
"containers": [
{
"name": "foo",
"image": "busybox",
"args": [
"sleep",
"3600"
],
"resources": {},
"volumeMounts": [
{
"name": "foo-claim0",
"mountPath": "/foo1"
},
{
"name": "foo-claim1",
"mountPath": "/foo2"
},
{
"name": "cat-claim0",
"mountPath": "/cat"
}
]
}
],
"restartPolicy": "Always"
}
},
"strategy": {
"type": "Recreate"
}
},
"status": {}
},
{
"kind": "PersistentVolumeClaim",
"apiVersion": "v1",
"metadata": {
"name": "foo-claim0",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo-claim0"
}
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "100Mi"
}
}
},
"status": {}
},
{
"kind": "PersistentVolumeClaim",
"apiVersion": "v1",
"metadata": {
"name": "foo-claim1",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo-claim1"
}
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "100Mi"
}
}
},
"status": {}
}
]
}
@@ -0,0 +1,541 @@
{
"kind": "List",
"apiVersion": "v1",
"metadata": {},
"items": [
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "bar",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "bar"
}
},
"spec": {
"ports": [
{
"name": "headless",
"port": 55555,
"targetPort": 0
}
],
"selector": {
"io.kompose.service": "bar"
},
"clusterIP": "None"
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "cat",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "cat"
}
},
"spec": {
"ports": [
{
"name": "headless",
"port": 55555,
"targetPort": 0
}
],
"selector": {
"io.kompose.service": "cat"
},
"clusterIP": "None"
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "foo",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo"
}
},
"spec": {
"ports": [
{
"name": "headless",
"port": 55555,
"targetPort": 0
}
],
"selector": {
"io.kompose.service": "foo"
},
"clusterIP": "None"
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "DeploymentConfig",
"apiVersion": "v1",
"metadata": {
"name": "bar",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "bar"
}
},
"spec": {
"strategy": {
"type": "Recreate",
"resources": {}
},
"triggers": [
{
"type": "ConfigChange"
},
{
"type": "ImageChange",
"imageChangeParams": {
"automatic": true,
"containerNames": [
"bar"
],
"from": {
"kind": "ImageStreamTag",
"name": "bar:latest"
}
}
}
],
"replicas": 1,
"test": false,
"selector": {
"io.kompose.service": "bar"
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"io.kompose.service": "bar"
}
},
"spec": {
"volumes": [
{
"name": "bar-claim1",
"persistentVolumeClaim": {
"claimName": "bar-claim1"
}
},
{
"name": "foo-claim0",
"persistentVolumeClaim": {
"claimName": "foo-claim0"
}
},
{
"name": "foo-claim1",
"persistentVolumeClaim": {
"claimName": "foo-claim1"
}
},
{
"name": "cat-claim0",
"persistentVolumeClaim": {
"claimName": "cat-claim0"
}
}
],
"containers": [
{
"name": "bar",
"image": " ",
"args": [
"sleep",
"3600"
],
"resources": {},
"volumeMounts": [
{
"name": "bar-claim1",
"mountPath": "/bar"
},
{
"name": "foo-claim0",
"mountPath": "/foo1"
},
{
"name": "foo-claim1",
"mountPath": "/foo2"
},
{
"name": "cat-claim0",
"mountPath": "/cat"
}
]
}
],
"restartPolicy": "Always"
}
}
},
"status": {}
},
{
"kind": "ImageStream",
"apiVersion": "v1",
"metadata": {
"name": "bar",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "bar"
}
},
"spec": {
"tags": [
{
"name": "latest",
"annotations": null,
"from": {
"kind": "DockerImage",
"name": "busybox"
},
"generation": null,
"importPolicy": {}
}
]
},
"status": {
"dockerImageRepository": ""
}
},
{
"kind": "PersistentVolumeClaim",
"apiVersion": "v1",
"metadata": {
"name": "bar-claim1",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "bar-claim1"
}
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "100Mi"
}
}
},
"status": {}
},
{
"kind": "DeploymentConfig",
"apiVersion": "v1",
"metadata": {
"name": "cat",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "cat"
}
},
"spec": {
"strategy": {
"type": "Recreate",
"resources": {}
},
"triggers": [
{
"type": "ConfigChange"
},
{
"type": "ImageChange",
"imageChangeParams": {
"automatic": true,
"containerNames": [
"cat"
],
"from": {
"kind": "ImageStreamTag",
"name": "cat:latest"
}
}
}
],
"replicas": 1,
"test": false,
"selector": {
"io.kompose.service": "cat"
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"io.kompose.service": "cat"
}
},
"spec": {
"volumes": [
{
"name": "cat-claim0",
"persistentVolumeClaim": {
"claimName": "cat-claim0"
}
}
],
"containers": [
{
"name": "cat",
"image": " ",
"args": [
"sleep",
"3600"
],
"resources": {},
"volumeMounts": [
{
"name": "cat-claim0",
"mountPath": "/cat"
}
]
}
],
"restartPolicy": "Always"
}
}
},
"status": {}
},
{
"kind": "ImageStream",
"apiVersion": "v1",
"metadata": {
"name": "cat",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "cat"
}
},
"spec": {
"tags": [
{
"name": "latest",
"annotations": null,
"from": {
"kind": "DockerImage",
"name": "busybox"
},
"generation": null,
"importPolicy": {}
}
]
},
"status": {
"dockerImageRepository": ""
}
},
{
"kind": "PersistentVolumeClaim",
"apiVersion": "v1",
"metadata": {
"name": "cat-claim0",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "cat-claim0"
}
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "100Mi"
}
}
},
"status": {}
},
{
"kind": "DeploymentConfig",
"apiVersion": "v1",
"metadata": {
"name": "foo",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo"
}
},
"spec": {
"strategy": {
"type": "Recreate",
"resources": {}
},
"triggers": [
{
"type": "ConfigChange"
},
{
"type": "ImageChange",
"imageChangeParams": {
"automatic": true,
"containerNames": [
"foo"
],
"from": {
"kind": "ImageStreamTag",
"name": "foo:latest"
}
}
}
],
"replicas": 1,
"test": false,
"selector": {
"io.kompose.service": "foo"
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo"
}
},
"spec": {
"volumes": [
{
"name": "foo-claim0",
"persistentVolumeClaim": {
"claimName": "foo-claim0"
}
},
{
"name": "foo-claim1",
"persistentVolumeClaim": {
"claimName": "foo-claim1"
}
},
{
"name": "cat-claim0",
"persistentVolumeClaim": {
"claimName": "cat-claim0"
}
}
],
"containers": [
{
"name": "foo",
"image": " ",
"args": [
"sleep",
"3600"
],
"resources": {},
"volumeMounts": [
{
"name": "foo-claim0",
"mountPath": "/foo1"
},
{
"name": "foo-claim1",
"mountPath": "/foo2"
},
{
"name": "cat-claim0",
"mountPath": "/cat"
}
]
}
],
"restartPolicy": "Always"
}
}
},
"status": {}
},
{
"kind": "ImageStream",
"apiVersion": "v1",
"metadata": {
"name": "foo",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo"
}
},
"spec": {
"tags": [
{
"name": "latest",
"annotations": null,
"from": {
"kind": "DockerImage",
"name": "busybox"
},
"generation": null,
"importPolicy": {}
}
]
},
"status": {
"dockerImageRepository": ""
}
},
{
"kind": "PersistentVolumeClaim",
"apiVersion": "v1",
"metadata": {
"name": "foo-claim0",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo-claim0"
}
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "100Mi"
}
}
},
"status": {}
},
{
"kind": "PersistentVolumeClaim",
"apiVersion": "v1",
"metadata": {
"name": "foo-claim1",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo-claim1"
}
},
"spec": {
"accessModes": [
"ReadWriteOnce"
],
"resources": {
"requests": {
"storage": "100Mi"
}
}
},
"status": {}
}
]
}
+119
View File
@@ -0,0 +1,119 @@
#!/bin/bash
RED='\033[0;31m'
NOCOLOR='\033[0m'
start_k8s() {
# Note: takes some time for the http server to pop up :)
# MINIMUM 15 seconds
echo "
##########
STARTING KUBERNETES
##########
"
if [ ! -f /usr/bin/kubectl ] && [ ! -f /usr/local/bin/kubectl ]; then
echo "No kubectl bin exists? Please install."
return 1
fi
# Uses https://github.com/kubernetes/minikube/tree/master/deploy/docker
# In which we have to git clone and create the image..
# https://github.com/kubernetes/minikube
# Thus we are using a public docker image
IMAGE=calpicow/localkube-image:v1.5.3
docker run -d \
--volume=/:/rootfs:ro \
--volume=/sys:/sys:rw \
--volume=/var/lib/docker:/var/lib/docker:rw \
--volume=/var/lib/kubelet:/var/lib/kubelet:rw \
--volume=/var/run:/var/run:rw \
--net=host \
--pid=host \
--privileged \
--name=minikube \
$IMAGE \
/localkube start \
--apiserver-insecure-address=0.0.0.0 \
--apiserver-insecure-port=8080 \
--logtostderr=true \
--containerized
until curl 127.0.0.1:8080 &>/dev/null;
do
echo ...
sleep 1
done
# Set the appropriate .kube/config configuration
kubectl config set-cluster dev --server=http://localhost:8080
kubectl config set-context dev --cluster=dev --user=default
kubectl config use-context dev
kubectl config set-credentials default --token=foobar
# Debug info:
# cat ~/.kube/config
# Delay due to CI being a bit too slow when first starting k8s
sleep 5
}
stop_k8s() {
echo "
##########
STOPPING KUBERNETES
##########
"
docker rm -f minikube
# Delete via image name google_containers
# Delete all containers started (names start with k8s_)
# Run twice in-case a container is replicated during that time
for run in {0..2}
do
docker ps -a | grep 'k8s_' | awk '{print $1}' | xargs --no-run-if-empty docker rm -f
docker ps -a | grep 'gcr.io/google_containers/hyperkube-amd64' | awk '{print $1}' | xargs --no-run-if-empty docker rm -f
done
}
wait_k8s() {
echo "Waiting for k8s po/svc/rc to finish terminating..."
kubectl get po,svc,rc
sleep 3 # give kubectl chance to catch up to api call
while [ 1 ]
do
k8s=`kubectl get po,svc,rc | grep Terminating`
if [[ $k8s == "" ]]
then
echo "k8s po/svc/rc terminated!"
break
else
echo "..."
fi
sleep 1
done
}
test_k8s() {
for f in examples/*.yaml
do
echo -e "\n${RED}kompose up -f $f ${NC}\n"
./kompose up -f $f
sleep 2 # Sleep for k8s to catch up to deployment
echo -e "\n${RED}kompose down -f $f ${NC}\n"
./kompose down -f $f
done
}
if [[ $1 == "start" ]]; then
start_k8s
elif [[ $1 == "stop" ]]; then
stop_k8s
elif [[ $1 == "wait" ]]; then
wait_k8s
elif [[ $1 == "test" ]]; then
test_k8s
else
echo $"Usage: kubernetes.sh {answers|start|stop|wait}"
fi
+38
View File
@@ -0,0 +1,38 @@
#!/bin/bash
# These tests will bring up a single-node Kubernetes cluster and test against examples
# WARNING: This will actively create Docker containers on your machine as well as remove them
# do not run this on a production cluster / machine.
# Check requirements!
if ! hash go 2>/dev/null; then
echo "ERROR: go required"
exit 1
fi
if ! hash docker 2>/dev/null; then
echo "ERROR: docker required"
exit 1
fi
if ! hash kubectl 2>/dev/null; then
echo "ERROR: kubectl required"
exit 1
fi
# First off, we have to compile the latest binary
make bin
#####################
# KUBERNETES TESTS ##
#####################
# Now we can start our Kubernetes cluster!
./script/test_ci/kubernetes.sh start
# And we're off! Let's test those example files
./script/test_ci/kubernetes.sh test
# Stop our Kubernetes cluster
./script/test_ci/kubernetes.sh stop
+1 -1
View File
@@ -28,7 +28,7 @@ ENV GOPATH="/opt/go" \
ENV PATH="$PATH:$GOPATH/bin" \ ENV PATH="$PATH:$GOPATH/bin" \
# KOMPOSE_SRC is where kompose source will be copied when container starts (by run.sh script) # KOMPOSE_SRC is where kompose source will be copied when container starts (by run.sh script)
# this is to ensure that we won't write anything to host volume mount # this is to ensure that we won't write anything to host volume mount
KOMPOSE_SRC="$GOPATH/src/github.com/kubernetes-incubator/kompose" KOMPOSE_SRC="$GOPATH/src/github.com/kubernetes/kompose"
RUN go get github.com/Masterminds/glide &&\ RUN go get github.com/Masterminds/glide &&\
go get github.com/sgotti/glide-vc &&\ go get github.com/sgotti/glide-vc &&\
+1 -1
View File
@@ -174,7 +174,7 @@ function convert::oc_cleanup () {
function convert::oc_check_route () { function convert::oc_check_route () {
local route_key=$1 local route_key=$1
if [ $route_key == 'true' ]; then if [ $route_key == 'true' ]; then
route_key='xip.io' route_key='nip.io'
fi fi
if [ $(oc get route | grep ${route_key} | wc -l ) -gt 0 ]; then if [ $(oc get route | grep ${route_key} | wc -l ) -gt 0 ]; then
+10 -3
View File
@@ -1249,13 +1249,20 @@ func (c *Command) persistentFlag(name string) (flag *flag.Flag) {
} }
// ParseFlags parses persistent flag tree and local flags. // ParseFlags parses persistent flag tree and local flags.
func (c *Command) ParseFlags(args []string) (err error) { func (c *Command) ParseFlags(args []string) error {
if c.DisableFlagParsing { if c.DisableFlagParsing {
return nil return nil
} }
beforeErrorBufLen := c.flagErrorBuf.Len()
c.mergePersistentFlags() c.mergePersistentFlags()
err = c.Flags().Parse(args) err := c.Flags().Parse(args)
return // Print warnings if they occurred (e.g. deprecated flag messages).
if c.flagErrorBuf.Len()-beforeErrorBufLen > 0 && err == nil {
c.Print(c.flagErrorBuf.String())
}
return err
} }
// Parent returns a commands parent command. // Parent returns a commands parent command.
+19 -18
View File
@@ -53,7 +53,7 @@ func init() {
type remoteConfigFactory interface { type remoteConfigFactory interface {
Get(rp RemoteProvider) (io.Reader, error) Get(rp RemoteProvider) (io.Reader, error)
Watch(rp RemoteProvider) (io.Reader, error) Watch(rp RemoteProvider) (io.Reader, error)
WatchChannel(rp RemoteProvider)(<-chan *RemoteResponse, chan bool) WatchChannel(rp RemoteProvider) (<-chan *RemoteResponse, chan bool)
} }
// RemoteConfig is optional, see the remote package // RemoteConfig is optional, see the remote package
@@ -597,32 +597,33 @@ func (v *Viper) Get(key string) interface{} {
return nil return nil
} }
valType := val
if v.typeByDefValue { if v.typeByDefValue {
// TODO(bep) this branch isn't covered by a single test. // TODO(bep) this branch isn't covered by a single test.
valType := val
path := strings.Split(lcaseKey, v.keyDelim) path := strings.Split(lcaseKey, v.keyDelim)
defVal := v.searchMap(v.defaults, path) defVal := v.searchMap(v.defaults, path)
if defVal != nil { if defVal != nil {
valType = defVal valType = defVal
} }
switch valType.(type) {
case bool:
return cast.ToBool(val)
case string:
return cast.ToString(val)
case int64, int32, int16, int8, int:
return cast.ToInt(val)
case float64, float32:
return cast.ToFloat64(val)
case time.Time:
return cast.ToTime(val)
case time.Duration:
return cast.ToDuration(val)
case []string:
return cast.ToStringSlice(val)
}
} }
switch valType.(type) {
case bool:
return cast.ToBool(val)
case string:
return cast.ToString(val)
case int64, int32, int16, int8, int:
return cast.ToInt(val)
case float64, float32:
return cast.ToFloat64(val)
case time.Time:
return cast.ToTime(val)
case time.Duration:
return cast.ToDuration(val)
case []string:
return cast.ToStringSlice(val)
}
return val return val
} }