Fix OpenShift tests for build and push

This commit is contained in:
Anush Shetty 2017-08-09 19:14:50 +05:30
commit abdf773908
73 changed files with 3119 additions and 1769 deletions

10
.mention-bot Normal file
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
}

View File

@ -5,7 +5,7 @@ sudo: required
language: go
# make this also work for forks
go_import_path: github.com/kubernetes-incubator/kompose
go_import_path: github.com/kubernetes/kompose
matrix:
include:

File diff suppressed because it is too large Load Diff

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
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).

13
Jenkinsfile vendored Normal file
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"
}
}
}

View File

@ -15,7 +15,7 @@
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)
TEST_IMAGE := kompose/tests:latest
@ -53,7 +53,7 @@ test-unit-cover:
go test -i -race -cover $(PKGS)
# 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
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
@ -110,4 +110,6 @@ test-image:
test-container:
docker run -v `pwd`:/opt/tmp/kompose:ro -it $(TEST_IMAGE)
.PHONE: test-ci
test-ci:
./script/test_ci/test.sh

View File

@ -1,6 +1,6 @@
# 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.
@ -8,10 +8,10 @@
## 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
kompose convert -f docker-compose.yaml
$ kompose convert -f docker-compose.yaml
INFO Kubernetes file "frontend-service.yaml" created
INFO Kubernetes file "redis-master-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.
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:
- [Binary (Prefered method)](README.md)
- [Go](/docs/setup.md#go)
- [CentOS](/docs/setup.md#centos)
- [Fedora](/docs/setup.md#fedora)
- [macOS (Homebrew)](/docs/setup.md#macos)
- [Go](/docs/installation.md#go)
- [CentOS](/docs/installation.md#centos)
- [Fedora](/docs/installation.md#fedora)
- [macOS (Homebrew)](/docs/installation.md#macos)
- [Windows](docs/installation.md#windows)
#### 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
# 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
curl -L https://github.com/kubernetes-incubator/kompose/releases/download/v0.7.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
curl -L https://github.com/kubernetes/kompose/releases/download/v1.0.0/kompose-darwin-amd64 -o kompose
chmod +x 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
@ -101,12 +103,12 @@ $ make cross
## 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:
- [Quick start](docs/quickstart.md)
- [Setup](docs/setup.md)
- [Installation](docs/installation.md)
- [User guide](docs/user-guide.md)
- [Conversion](docs/conversion.md)
- [Architecture](docs/architecture.md)
@ -114,18 +116,13 @@ Here is a list of all available docs:
## 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.
If you find any issues, please [file it](https://github.com/kubernetes-incubator/kompose/issues).
__Issues:__ If you find any issues, please [file it](https://github.com/kubernetes/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).
[@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.
__Chat (Slack):__ We're fairly active on [Slack](http://slack.kubernetes.io#kompose) and you can find us in the #kompose channel.
## 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).
[Build Status]: https://travis-ci.org/kubernetes-incubator/kompose
[Build Status Widget]: https://travis-ci.org/kubernetes-incubator/kompose.svg?branch=master
[GoDoc]: https://godoc.org/github.com/kubernetes-incubator/kompose
[GoDoc Widget]: https://godoc.org/github.com/kubernetes-incubator/kompose?status.svg
[Build Status]: https://travis-ci.org/kubernetes/kompose
[Build Status Widget]: https://travis-ci.org/kubernetes/kompose.svg?branch=master
[GoDoc]: https://godoc.org/github.com/kubernetes/kompose
[GoDoc Widget]: https://godoc.org/github.com/kubernetes/kompose?status.svg
[Slack]: http://slack.kubernetes.io#kompose
[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]: https://coveralls.io/github/kubernetes-incubator/kompose?branch=master
[Coverage Status Widget]: https://coveralls.io/repos/github/kubernetes/kompose/badge.svg?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

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.
### [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] Improved edge-cases for deployment (namespace + insecure-repository parameters added) [#547](https://github.com/kubernetes-incubator/kompose/pull/547)
- [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/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] 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] Args support added to `build` key [#424](https://github.com/kubernetes/kompose/pull/424)
- [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)
- [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] 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] 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/kompose/issues/97) [#521](https://github.com/kubernetes/kompose/pull/521)
### Kompose 0.9.0 (end of July)
- [ ] 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 (???)

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:
```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:

1
build/VERSION Normal file
View File

@ -0,0 +1 @@
1.0.0

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]")
}
shell := args[0]
if shell != "bash" && shell != "zsh" {
}
// Generate bash through cobra if selected
if shell == "bash" {

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");
you may not use this file except in compliance with the License.
@ -20,8 +20,8 @@ import (
"strings"
log "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/kompose/pkg/app"
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/app"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
@ -82,12 +82,13 @@ var convertCmd = &cobra.Command{
IsDeploymentFlag: cmd.Flags().Lookup("deployment").Changed,
IsDaemonSetFlag: cmd.Flags().Lookup("daemon-set").Changed,
IsReplicationControllerFlag: cmd.Flags().Lookup("replication-controller").Changed,
IsReplicaSetFlag: cmd.Flags().Lookup("replicas").Changed,
IsDeploymentConfigFlag: cmd.Flags().Lookup("deployment-config").Changed,
}
// Validate before doing anything else. Use "bundle" if passed in.
app.ValidateFlags(GlobalBundle, args, cmd, &ConvertOpt)
app.ValidateComposeFile(cmd, &ConvertOpt)
app.ValidateComposeFile(&ConvertOpt)
},
Run: func(cmd *cobra.Command, args []string) {

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");
you may not use this file except in compliance with the License.
@ -19,8 +19,8 @@ package cmd
import (
"strings"
"github.com/kubernetes-incubator/kompose/pkg/app"
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/app"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/spf13/cobra"
)
@ -45,7 +45,7 @@ var downCmd = &cobra.Command{
}
// Validate before doing anything else.
app.ValidateComposeFile(cmd, &DownOpt)
app.ValidateComposeFile(&DownOpt)
},
Run: func(cmd *cobra.Command, args []string) {
app.Down(DownOpt)

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");
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().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
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")
}

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");
you may not use this file except in compliance with the License.
@ -20,8 +20,8 @@ import (
log "github.com/Sirupsen/logrus"
"strings"
"github.com/kubernetes-incubator/kompose/pkg/app"
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/app"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/spf13/cobra"
)
@ -60,7 +60,7 @@ var upCmd = &cobra.Command{
}
// Validate before doing anything else.
app.ValidateComposeFile(cmd, &UpOpt)
app.ValidateComposeFile(&UpOpt)
},
Run: func(cmd *cobra.Command, args []string) {
app.Up(UpOpt)

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");
you may not use this file except in compliance with the License.
@ -24,9 +24,9 @@ import (
var (
// 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
// 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
GITCOMMIT = "HEAD"
)

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.
@ -24,7 +24,7 @@ Every loader “implementation” should be placed into `kompose/pkg/loader` (li
## 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
// KomposeObject holds the generic struct of Kompose transformation

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 |
|-------------------|---------|------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|
| SERVICE | | | |
| build | Y | OpenShift: BuildConfig | Converts, but local builds are not yet supported. See issue 97 |
| __Service__ | | | |
| 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 | |
| command | Y | Pod.Spec.Container.Command | |
| cgroup_parent | N | | No compatibility with Kubernetes / OpenShift. Limited use-cases with Docker. |
| container_name | Y | Mapped to both Metadata.Name and Deployment.Spec.Containers.Name | |
| deploy | N | | Upcoming support started |
| devices | N | | Not supported within Kubernetes, see this issue |
| depends_on | N | | |
| dns | N | | |
| dns_search | N | | |
| cgroup_parent | N/A | | Not supported within Kubernetes. See issue https://github.com/kubernetes/kubernetes/issues/11986 |
| container_name | Y | Metadata.Name + Deployment.Spec.Containers.Name | |
| devices | N/A | | Not supported within Kubernetes, See issue https://github.com/kubernetes/kubernetes/issues/5607 |
| depends_on | N/A | | No 1-1 mapping, Kubernetes uses a flat architecture |
| dns | N/A | | Not used within Kubernetes. Kubernetes uses a managed DNS server |
| dns_search | N/A | | See `dns` key |
| 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 |
| env_file | N | | |
| environment | Y | Pod.Spec.Container.Env | |
| expose | Y | Service.Spec.Ports | |
| 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 | | |
| group_add | N | | |
| healthcheck | N | | |
| 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 | |
| links | N | | |
| logging | N | | |
| network_mode | N | | |
| networks | N | | |
| links | N/A | | All containers in the same pod are accessible in Kubernetes |
| logging | N/A | | Kubernetes has built-in logging support at the node-level |
| network_mode | N/A | | Kubernetes uses it's own cluster networking |
| networks | N/A | | See `networks` key |
| pid | Y | Pod.Spec.HostPID | |
| 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_signal | N | | |
| stop_signal | N/A | | Not supported within Kubernetes. See issue https://github.com/kubernetes/kubernetes/issues/30051 |
| sysctls | N | | |
| ulimits | N | | See this issue on the k8s repo |
| userns_mode | N | | |
| ulimits | N/A | | Not supported within Kubernetes. See issue https://github.com/kubernetes/kubernetes/issues/3595 |
| 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 |
| 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) |
| cpu_shares | N | | |
| cpu_quota | N | | |
| cpuset | N | | |
| mem_limit | Y | Containers.Resources.Limits.Memory | |
| memswap_limit | N | | Use mem_limit |
| cpu_shares | Y | | No direct mapping, use `resources` key within Docker Compose Version 3 `deploy` |
| cpu_quota | Y | | No direct mapping, use `resources` key within Docker Compose Version 3 `deploy` |
| cpuset | Y | | No direct mapping, use `resources` key within Docker Compose Version 3 `deploy` |
| mem_limit | Y | Containers.Resources.Limits.Memory | Maps, but recommended to use `resources` key within Version 3 `deploy` |
| memswap_limit | N/A | | Removed in V3+, use mem_limit |
| | | | |
| VOLUME | | | |
| driver | N | | |
| driver_opts | N | | |
| external | N | | |
| __Deploy__ | | | |
| mode | N | | |
| replicas | Y | Deployment.Spec.Replicas / DeploymentConfig.Spec.Replicas | |
| 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 | | |
| | | | |
| NETWORK | | | |
| driver | N | | |
| driver_opts | N | | |
| enable_ipv6 | N | | |
| ipam | N | | |
| internal | N | | |
| labels | N | | |
| external | N | | |
| __Volume__ | N/A | | |
| driver | N/A | | |
| driver_opts | N/A | | |
| external | N/A | | |
| labels | N/A | | |
| | | | |
| __Network__ | N/A | | |
| driver | N/A | | |
| driver_opts | N/A | | |
| enable_ipv6 | N/A | | |
| ipam | N/A | | |
| internal | N/A | | |
| labels | N/A | | |
| external | N/A | | |

View File

@ -2,12 +2,12 @@
## 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
### 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)
### 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.
```console
git clone https://github.com/$YOUR_GITHUB_USERNAME/kompose.git $GOPATH/src/github.com/kubernetes-incubator/kompose
cd $GOPATH/src/github.com/kubernetes-incubator/kompose
git remote add upstream 'https://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/kompose
git remote add upstream 'https://github.com/kubernetes/kompose'
```
### Create a branch and make changes
@ -34,7 +34,7 @@ git fetch upstream
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
git remote set-url --push upstream no_push

View File

@ -4,30 +4,31 @@ We have multiple ways to install Kompose. Our prefered method is downloading the
#### 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
# Linux
curl -L https://github.com/kubernetes-incubator/kompose/releases/download/v0.7.0/kompose-linux-amd64 -o kompose
# Linux
curl -L https://github.com/kubernetes/kompose/releases/download/v1.0.0/kompose-linux-amd64 -o kompose
# macOS
curl -L https://github.com/kubernetes-incubator/kompose/releases/download/v0.7.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
curl -L https://github.com/kubernetes/kompose/releases/download/v1.0.0/kompose-darwin-amd64 -o kompose
chmod +x 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
Installing using `go get` pulls from the master branch with the latest development changes.
```sh
go get -u github.com/kubernetes-incubator/kompose
go get -u github.com/kubernetes/kompose
```
#### 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 have [EPEL](https://fedoraproject.org/wiki/EPEL) enabled in your system, you can install Kompose like any other package.
```bash
sudo yum -y install kompose
```
#### 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
sudo dnf -y install kompose
@ -52,5 +54,11 @@ On macOS you can install latest release via [Homebrew](https://brew.sh):
```bash
brew install kompose
```
#### Windows
Kompose can be installed via [Chocolatey](https://chocolatey.org/packages/kubernetes-kompose)
```console
choco install kubernetes-kompose
```

33
docs/integrations.md Normal file
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)

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).
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.
__1. Take a sample docker-compose.yaml file__
@ -38,7 +36,7 @@ services:
__2. Run `kompose up` in the same directory__
```bash
kompose up
$ kompose up
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.
@ -55,7 +53,7 @@ __Alternatively, you can run `kompose convert` and deploy with `kubectl`__
__2.1. Run `kompose convert` in the same directory__
```bash
kompose convert
$ kompose convert
INFO Kubernetes file "frontend-service.yaml" created
INFO Kubernetes file "redis-master-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!__
```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 "redis-master" 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:
```bash
minikube service frontend
$ minikube service frontend
```
Otherwise, let's look up what IP your service is using!
```sh
kubectl describe svc frontend
$ kubectl describe svc frontend
Name: frontend
Namespace: default
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`.
```sh
curl http://123.45.67.89
$ curl http://123.45.67.89
```

View File

@ -1,48 +1,27 @@
# User Guide
- [Usage](#user-guide)
* [Kompose convert](#kompose-convert)
* [Kompose up](#kompose-up)
* [Kompose down](#kompose-down)
- [Alternate formats](#alternate-formats)
- [Unsupported docker-compose configuration options](#unsupported-docker-compose-configuration-options)
- CLI
- [`kompose convert`](#kompose-convert)
- [`kompose up`](#kompose-up)
- [`kompose down`](#kompose-down)
- Documentation
- [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.
You can choose targeted provider either using global option `--provider`, or by setting environment variable `PROVIDER`.
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.
You can choose a targeted provider using global option `--provider`. If no provider is specified, Kubernetes is set by default.
## 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.
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`.
Kompose supports conversion of V1, V2, and V3 Docker Compose files into Kubernetes and OpenShift objects.
### Kubernetes
```console
$ cd examples/
$ ls
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
```sh
$ kompose --file docker-voting.yml convert
WARN Unsupported key networks - ignoring
WARN Unsupported key build - ignoring
@ -59,12 +38,12 @@ INFO Kubernetes file "db-deployment.yaml" created
$ ls
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:
```console
```sh
$ kompose -f docker-compose.yml -f docker-guestbook.yml convert
INFO Kubernetes file "frontend-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.
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
```console
```sh
$ kompose --provider openshift --file docker-voting.yml convert
WARN [worker] Service cannot be created because of missing port.
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
```
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.
```console
```sh
$ kompose --provider openshift --file buildconfig/docker-compose.yml convert
WARN [foo] Service cannot be created because of missing port.
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 .
## Kompose up
## `kompose up`
Kompose supports a straightforward way to deploy your "composed" application to Kubernetes or OpenShift via `kompose up`.
### Kubernetes
```console
```sh
$ kompose --file ./examples/docker-guestbook.yml up
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.
@ -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.
### OpenShift
```console
$kompose --file ./examples/docker-guestbook.yml --provider openshift up
```sh
$ kompose --file ./examples/docker-guestbook.yml --provider openshift up
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.
@ -221,11 +177,11 @@ is/redis-slave 172.30.12.200:5000/fff/redis-slave v1
Note:
- 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
INFO Successfully deleted service: redis-master
INFO Successfully deleted deployment: redis-master
@ -237,11 +193,58 @@ INFO Successfully deleted deployment: frontend
Note:
- 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.
```console
```sh
$ kompose convert -j
INFO Kubernetes file "redis-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.
```console
```sh
$ kompose convert --replication-controller
INFO Kubernetes file "redis-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`
```console
```sh
$ kompose convert --daemon-set
INFO Kubernetes file "redis-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:
```console
```sh
$ kompose convert -c
INFO Kubernetes file "web-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.
## 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
`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"
```
#### 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 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.

View File

@ -3,4 +3,4 @@ version: "2"
services:
foo:
build: "./build"
image: docker.io/cdrage/foobar
image: docker.io/foo/bar

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"

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

8
glide.lock generated
View File

@ -1,5 +1,5 @@
hash: e33ffcc6bb6fbd6496e430ef69139c47d0b4e79c6255c7184d2ec7307d7a55d1
updated: 2017-06-16T17:40:15.118961307+05:30
updated: 2017-06-20T14:23:11.012556696-04:00
imports:
- name: cloud.google.com/go
version: 3b1ae45394a234c385be014e9a488f2bb6eef821
@ -375,7 +375,7 @@ imports:
- name: github.com/opencontainers/go-digest
version: 279bed98673dd5bef374d3b6e4b09e2af76183bf
- name: github.com/opencontainers/image-spec
version: df6f3c57dafbbf39d98c24fa6ab509183cfa3efc
version: d207df434d113728dc3373cb3a905f00b482a858
subpackages:
- specs-go
- specs-go/v1
@ -456,13 +456,13 @@ imports:
- name: github.com/spf13/cast
version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4
- name: github.com/spf13/cobra
version: b4dbd37a01839e0653eec12aa4bbb2a2ce7b2a37
version: 99b5d838ca16c25cc4944e323684f8415e8b10ba
- name: github.com/spf13/jwalterweatherman
version: 0efa5202c04663c757d84f90f5219c1250baf94f
- name: github.com/spf13/pflag
version: e57e3eeb33f795204c1ca35f56c44f83227c6e66
- name: github.com/spf13/viper
version: a1ecfa6a20bd4ef9e9caded262ee1b1b26847675
version: c1de95864d73a5465492829d7cb2dd422b19ac96
- name: github.com/ugorji/go
version: f4485b318aadd133842532f841dc205a8e339d74
subpackages:

View File

@ -1,5 +1,5 @@
package: github.com/kubernetes-incubator/kompose
homepage: https://github.com/kubernetes-incubator/kompose
package: github.com/kubernetes/kompose
homepage: https://github.com/kubernetes/kompose
licence: Apache-2.0
import:

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");
you may not use this file except in compliance with the License.
@ -16,7 +16,7 @@ limitations under the License.
package main
import "github.com/kubernetes-incubator/kompose/cmd"
import "github.com/kubernetes/kompose/cmd"
func main() {
cmd.Execute()

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");
you may not use this file except in compliance with the License.
@ -34,11 +34,11 @@ import (
"os"
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/loader"
"github.com/kubernetes-incubator/kompose/pkg/transformer"
"github.com/kubernetes-incubator/kompose/pkg/transformer/kubernetes"
"github.com/kubernetes-incubator/kompose/pkg/transformer/openshift"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/loader"
"github.com/kubernetes/kompose/pkg/transformer"
"github.com/kubernetes/kompose/pkg/transformer/kubernetes"
"github.com/kubernetes/kompose/pkg/transformer/openshift"
)
const (
@ -118,7 +118,7 @@ func ValidateFlags(bundle string, args []string, cmd *cobra.Command, opt *kobjec
if len(bundle) > 0 {
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}
}
@ -136,7 +136,7 @@ func ValidateFlags(bundle string, args []string, cmd *cobra.Command, opt *kobjec
}
// 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 {
// Here docker-compose is the input
opt.InputFiles = []string{"docker-compose.yml"}

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");
you may not use this file except in compliance with the License.
@ -53,6 +53,7 @@ type ConvertOptions struct {
IsDeploymentFlag bool
IsDaemonSetFlag bool
IsReplicationControllerFlag bool
IsReplicaSetFlag bool
IsDeploymentConfigFlag bool
IsNamespaceFlag bool
}
@ -60,20 +61,23 @@ type ConvertOptions struct {
// ServiceConfig holds the basic struct of a container
type ServiceConfig struct {
// use tags to mark from what element this value comes
ContainerName string
Image string `compose:"image" bundle:"Image"`
Environment []EnvVar `compose:"environment" bundle:"Env"`
Port []Ports `compose:"ports" bundle:"Ports"`
Command []string `compose:"command" bundle:"Command"`
WorkingDir string `compose:"" bundle:"WorkingDir"`
Args []string `compose:"args" bundle:"Args"`
Volumes []string `compose:"volumes" bundle:"Volumes"`
ContainerName string
Image string `compose:"image" bundle:"Image"`
Environment []EnvVar `compose:"environment" bundle:"Env"`
Port []Ports `compose:"ports" bundle:"Ports"`
Command []string `compose:"command" bundle:"Command"`
WorkingDir string `compose:"" bundle:"WorkingDir"`
Args []string `compose:"args" bundle:"Args"`
// VolList is list of volumes extracted from docker-compose file
VolList []string `compose:"volumes" bundle:"Volumes"`
Network []string `compose:"network" bundle:"Networks"`
Labels map[string]string `compose:"labels" bundle:"Labels"`
Annotations map[string]string `compose:"" bundle:""`
CPUSet string `compose:"cpuset" bundle:""`
CPUShares int64 `compose:"cpu_shares" bundle:""`
CPUQuota int64 `compose:"cpu_quota" bundle:""`
CPULimit int64 `compose:"" bundle:""`
CPUReservation int64 `compose:"" bundle:""`
CapAdd []string `compose:"cap_add" bundle:""`
CapDrop []string `compose:"cap_drop" bundle:""`
Expose []string `compose:"expose" bundle:""`
@ -90,8 +94,12 @@ type ServiceConfig struct {
Stdin bool `compose:"stdin_open" bundle:""`
Tty bool `compose:"tty" bundle:""`
MemLimit yaml.MemStringorInt `compose:"mem_limit" bundle:""`
MemReservation yaml.MemStringorInt `compose:"" bundle:""`
TmpFs []string `compose:"tmpfs" 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
@ -107,3 +115,15 @@ type Ports struct {
HostIP string
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
}

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");
you may not use this file except in compliance with the License.
@ -28,7 +28,7 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/fatih/structs"
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/pkg/errors"
)

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");
you may not use this file except in compliance with the License.

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");
you may not use this file except in compliance with the License.
@ -27,7 +27,7 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/docker/libcompose/project"
"github.com/fatih/structs"
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/pkg/errors"
)

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");
you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@ import (
"strings"
"testing"
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/kobject"
"k8s.io/kubernetes/pkg/api"
"github.com/docker/cli/cli/compose/types"

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");
you may not use this file except in compliance with the License.
@ -21,7 +21,7 @@ import (
"path/filepath"
"strings"
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/pkg/errors"
"k8s.io/kubernetes/pkg/api"
)

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");
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/lookup"
"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"
)
@ -205,7 +206,7 @@ func libComposeToKomposeMapping(composeObject *project.Project) (kobject.Kompose
envs := loadEnvVars(composeServiceConfig.Environment)
serviceConfig.Environment = envs
//Validate dockerfile path
// Validate dockerfile path
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)
}
@ -222,7 +223,7 @@ func libComposeToKomposeMapping(composeObject *project.Project) (kobject.Kompose
if composeServiceConfig.Volumes != nil {
for _, volume := range composeServiceConfig.Volumes.Volumes {
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))
}
}
// This will handle volume at earlier stage itself, it will resolves problems occurred due to `volumes_from` key
handleVolume(&komposeObject)
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 {
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 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{}
}

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");
you may not use this file except in compliance with the License.
@ -17,19 +17,22 @@ limitations under the License.
package compose
import (
libcomposeyaml "github.com/docker/libcompose/yaml"
"io/ioutil"
"strconv"
"strings"
libcomposeyaml "github.com/docker/libcompose/yaml"
"k8s.io/kubernetes/pkg/api"
"github.com/docker/cli/cli/compose/loader"
"github.com/docker/cli/cli/compose/types"
log "github.com/Sirupsen/logrus"
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/pkg/errors"
"os"
log "github.com/Sirupsen/logrus"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/pkg/errors"
)
// converts os.Environ() ([]string) to map[string]string
@ -183,7 +186,6 @@ func dockerComposeToKomposeMapping(composeObject *types.Config) (kobject.Kompose
serviceConfig.CapDrop = composeServiceConfig.CapDrop
serviceConfig.Expose = composeServiceConfig.Expose
serviceConfig.Privileged = composeServiceConfig.Privileged
serviceConfig.Restart = composeServiceConfig.Restart
serviceConfig.User = composeServiceConfig.User
serviceConfig.Stdin = composeServiceConfig.StdinOpen
serviceConfig.Tty = composeServiceConfig.Tty
@ -192,15 +194,46 @@ func dockerComposeToKomposeMapping(composeObject *types.Config) (kobject.Kompose
serviceConfig.Command = composeServiceConfig.Entrypoint
serviceConfig.Args = composeServiceConfig.Command
// This is a bit messy since we use yaml.MemStringorInt
// TODO: Refactor yaml.MemStringorInt in kobject.go to int64
// Since Deploy.Resources.Limits does not initialize, we must check type Resources before continuing
//
// Deploy keys
//
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.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
// serviceConfig.VolumesFrom = composeServiceConfig.VolumesFrom
// restart-policy:
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:
// 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
// Again, in v3, we use the "long syntax" for volumes in terms of parsing
// https://docs.docker.com/compose/compose-file/#long-syntax-2
serviceConfig.Volumes = loadV3Volumes(composeServiceConfig.Volumes)
serviceConfig.VolList = loadV3Volumes(composeServiceConfig.Volumes)
// Label handler
// 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!
komposeObject.ServiceConfigs[normalizeServiceNames(name)] = serviceConfig
}
handleVolume(&komposeObject)
return komposeObject, nil
}

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");
you may not use this file except in compliance with the License.
@ -19,9 +19,9 @@ package loader
import (
"fmt"
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/loader/bundle"
"github.com/kubernetes-incubator/kompose/pkg/loader/compose"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/loader/bundle"
"github.com/kubernetes/kompose/pkg/loader/compose"
)
// Loader interface defines loader that loads files and converts it to kobject representation

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");
you may not use this file except in compliance with the License.
@ -31,8 +31,8 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/ghodss/yaml"
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/transformer"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/transformer"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
@ -343,12 +343,9 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
if len(service.TmpFs) > 0 {
TmpVolumesMount, TmpVolumes := k.ConfigTmpfs(name, service)
for _, volume := range TmpVolumes {
volumes = append(volumes, volume)
}
for _, vMount := range TmpVolumesMount {
volumesMount = append(volumesMount, vMount)
}
volumes = append(volumes, TmpVolumes...)
volumesMount = append(volumesMount, TmpVolumesMount...)
}
@ -392,14 +389,39 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
}
// Configure the resource limits
if service.MemLimit != 0 {
memoryResourceList := api.ResourceList{
api.ResourceMemory: *resource.NewQuantity(
int64(service.MemLimit), "RandomStringForFormat")}
template.Spec.Containers[0].Resources.Limits = memoryResourceList
if service.MemLimit != 0 || service.CPULimit != 0 {
resourceLimit := api.ResourceList{}
if service.MemLimit != 0 {
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{}
//set pid namespace mode
if service.Pid != "" {
if service.Pid == "host" {
@ -411,7 +433,7 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
// Setup security context
securityContext := &api.SecurityContext{}
if service.Privileged == true {
if service.Privileged {
securityContext.Privileged = &service.Privileged
}
if service.User != "" {
@ -441,9 +463,9 @@ func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.Servic
// Configure the container restart policy.
switch service.Restart {
case "", "always":
case "", "always", "any":
template.Spec.RestartPolicy = api.RestartPolicyAlways
case "no":
case "no", "none":
template.Spec.RestartPolicy = api.RestartPolicyNever
case "on-failure":
template.Spec.RestartPolicy = api.RestartPolicyOnFailure
@ -494,78 +516,7 @@ func (k *Kubernetes) SortServicesFirst(objs *[]runtime.Object) {
*objs = ret
}
func (k *Kubernetes) findDependentVolumes(svcname string, komposeObject kobject.KomposeObject) (volumes []api.Volume, volumeMounts []api.VolumeMount, err error) {
// Get all the volumes and volumemounts this particular service is dependent on
for _, dependentSvc := range komposeObject.ServiceConfigs[svcname].VolumesFrom {
vols, volMounts, 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
// SortedKeys Ensure the kubernetes objects are in a consistent order
func SortedKeys(komposeObject kobject.KomposeObject) []string {
var sortedKeys []string
for name := range komposeObject.ServiceConfigs {
@ -575,7 +526,7 @@ func SortedKeys(komposeObject kobject.KomposeObject) []string {
return sortedKeys
}
//converts duration string to *int64 in seconds
// DurationStrToSecondsInt converts duration string to *int64 in seconds
func DurationStrToSecondsInt(s string) (*int64, error) {
if s == "" {
return nil, nil

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");
you may not use this file except in compliance with the License.
@ -23,8 +23,8 @@ import (
"os"
"path/filepath"
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/testutils"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/testutils"
"reflect"
@ -47,7 +47,7 @@ func TestCreateService(t *testing.T) {
Command: []string{"cmd"},
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
Volumes: []string{"/tmp/volume"},
VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"}, // not supported
Labels: nil,
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) {
// 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"},
Volumes: []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",
MemLimit: 1337,
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",
MemLimit: 1337,
MemReservation: 1338,
}
// 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"))
}
// 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 {
if deploy, ok := obj.(*extensions.Deployment); ok {
memTest, _ := deploy.Spec.Template.Spec.Containers[0].Resources.Limits.Memory().AsInt64()
if memTest != 1337 {
t.Errorf("Expected 1337 for mem_limit check, got %v", memTest)
memLimit, _ := deploy.Spec.Template.Spec.Containers[0].Resources.Limits.Memory().AsInt64()
if memLimit != 1337 {
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"},
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
Volumes: []string{"/tmp/volume"},
VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"}, // not supported
Labels: nil,
Annotations: map[string]string{"kompose.service.type": "nodeport"},
@ -184,7 +242,7 @@ func TestTransformWithPid(t *testing.T) {
Command: []string{"cmd"},
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
Volumes: []string{"/tmp/volume"},
VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"},
Restart: "always",
Pid: "host",
@ -203,7 +261,7 @@ func TestTransformWithPid(t *testing.T) {
for _, obj := range objects {
if deploy, ok := obj.(*extensions.Deployment); ok {
hostPid := deploy.Spec.Template.Spec.SecurityContext.HostPID
if hostPid != true {
if !hostPid {
t.Errorf("Pid in ServiceConfig is not matching HostPID in PodSpec")
}
}
@ -220,7 +278,7 @@ func TestTransformWithInvaildPid(t *testing.T) {
Command: []string{"cmd"},
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
Volumes: []string{"/tmp/volume"},
VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"},
Restart: "always",
Pid: "badvalue",
@ -240,7 +298,7 @@ func TestTransformWithInvaildPid(t *testing.T) {
if deploy, ok := obj.(*extensions.Deployment); ok {
if deploy.Spec.Template.Spec.SecurityContext != nil {
hostPid := deploy.Spec.Template.Spec.SecurityContext.HostPID
if hostPid != false {
if hostPid {
t.Errorf("Pid in ServiceConfig is not matching HostPID in PodSpec")
}
}
@ -272,7 +330,7 @@ func TestIsDir(t *testing.T) {
if err != nil {
t.Error(errors.Wrap(err, "isDir failed"))
}
if output != true {
if !output {
t.Errorf("directory %v exists but isDir() returned %v", tempDir, output)
}
@ -281,7 +339,7 @@ func TestIsDir(t *testing.T) {
if err != nil {
t.Error(errors.Wrap(err, "isDir failed"))
}
if output != false {
if 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 {
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)
}
@ -329,7 +387,8 @@ func TestRecreateStrategyWithVolumesPresent(t *testing.T) {
service := kobject.ServiceConfig{
ContainerName: "name",
Image: "image",
Volumes: []string{"/tmp/volume"},
VolList: []string{"/tmp/volume"},
Volumes: []kobject.Volumes{{SvcName: "app", MountPath: "/tmp/volume", PVCName: "app-claim0"}},
}
komposeObject := kobject.KomposeObject{

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");
you may not use this file except in compliance with the License.
@ -24,8 +24,8 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/fatih/structs"
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/transformer"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/transformer"
buildapi "github.com/openshift/origin/pkg/build/api"
deployapi "github.com/openshift/origin/pkg/deploy/api"
@ -49,6 +49,7 @@ import (
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/labels"
"sort"
"strings"
)
// Kubernetes implements Transformer interface and represents Kubernetes transformer
@ -61,11 +62,11 @@ type Kubernetes struct {
// used when undeploying resources from kubernetes
const TIMEOUT = 300
//default size of Persistent Volume Claim
// PVCRequestSize (Persistent Volume Claim) has default size
const PVCRequestSize = "100Mi"
// 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
// returns list of TODO: ....
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
}
// InitSvc initializes Kubernets Service object
// InitSvc initializes Kubernetes Service object
func (k *Kubernetes) InitSvc(name string, service kobject.ServiceConfig) *api.Service {
svc := &api.Service{
TypeMeta: unversioned.TypeMeta{
@ -376,56 +377,53 @@ func (k *Kubernetes) ConfigVolumes(name string, service kobject.ServiceConfig) (
volumeMounts := []api.VolumeMount{}
volumes := []api.Volume{}
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
useEmptyVolumes := k.Opt.EmptyVols
var count int
//interating over array of `Vols` struct as it contains all necessary information about 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
readonly := len(mode) > 0 && mode == "ro"
readonly := len(volume.Mode) > 0 && volume.Mode == "ro"
if volumeName == "" {
if volume.VolumeName == "" {
if useEmptyVolumes {
volumeName = fmt.Sprintf("%s-empty%d", name, count)
volumeName = strings.Replace(volume.PVCName, "claim", "empty", 1)
} else {
volumeName = fmt.Sprintf("%s-claim%d", name, count)
volumeName = volume.PVCName
}
count++
} else {
volumeName = volume.VolumeName
}
// create a new volume mount object and append to list
volmount := api.VolumeMount{
Name: volumeName,
ReadOnly: readonly,
MountPath: container,
MountPath: volume.Container,
}
volumeMounts = append(volumeMounts, volmount)
// 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
var volsource *api.VolumeSource
if useEmptyVolumes {
volsource = k.ConfigEmptyVolumeSource("volume")
} else {
volsource = k.ConfigPVCVolumeSource(volumeName, readonly)
if volume.VFrom == "" {
createdPVC, err := k.CreatePVC(volumeName, volume.Mode)
createdPVC, err := k.CreatePVC(volumeName, mode)
if err != nil {
return nil, nil, nil, errors.Wrap(err, "k.CreatePVC failed")
if err != nil {
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
@ -435,10 +433,12 @@ func (k *Kubernetes) ConfigVolumes(name string, service kobject.ServiceConfig) (
}
volumes = append(volumes, vol)
if len(host) > 0 {
log.Warningf("Volume mount on the host %q isn't supported - ignoring path on the host", host)
if len(volume.Host) > 0 {
log.Warningf("Volume mount on the host %q isn't supported - ignoring path on the host", volume.Host)
}
}
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
func (k *Kubernetes) CreateKubernetesObjects(name string, service kobject.ServiceConfig, opt kobject.ConvertOptions) []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 {
objects = append(objects, k.InitD(name, service, opt.Replicas))
objects = append(objects, k.InitD(name, service, replica))
}
if opt.CreateDS {
objects = append(objects, k.InitDS(name, service))
}
if opt.CreateRC {
objects = append(objects, k.InitRC(name, service, opt.Replicas))
objects = append(objects, k.InitRC(name, service, replica))
}
return objects
@ -597,8 +603,7 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
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
k.SortServicesFirst(&allobjects)
return allobjects, nil

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");
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"
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/transformer"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/transformer"
"github.com/pkg/errors"
"k8s.io/kubernetes/pkg/api"
@ -40,7 +40,7 @@ func newServiceConfig() kobject.ServiceConfig {
Command: []string{"cmd"},
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
Volumes: []string{"/tmp/volume"},
VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"}, // not supported
Labels: nil,
Annotations: map[string]string{"abc": "def"},
@ -53,6 +53,8 @@ func newServiceConfig() kobject.ServiceConfig {
Stdin: true,
Tty: true,
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
}
for i := range s1 {
if s1[i] != s1[i] {
if s1[i] != s2[i] {
return false
}
}
@ -179,7 +181,7 @@ func checkPodTemplate(config kobject.ServiceConfig, template api.PodTemplateSpec
func privilegedNilOrFalse(template api.PodTemplateSpec) bool {
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 {
@ -270,11 +272,14 @@ func TestKomposeConvert(t *testing.T) {
expectedNumObjs int
}{
// objects generated are deployment, service and pvc
"Convert to Deployments (D)": {newKomposeObject(), kobject.ConvertOptions{CreateD: 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}, 3},
"Convert to Deployments (D)": {newKomposeObject(), kobject.ConvertOptions{CreateD: true, Replicas: replicas, IsReplicaSetFlag: true}, 3},
"Convert to Deployments (D) with v3 replicas": {newKomposeObject(), kobject.ConvertOptions{CreateD: true}, 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
"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
}
@ -313,9 +318,18 @@ func TestKomposeConvert(t *testing.T) {
if err := checkMeta(config, d.ObjectMeta, name, true); err != nil {
t.Errorf("%v", err)
}
if (int)(d.Spec.Replicas) != replicas {
t.Errorf("Expected %d replicas, got %d", replicas, d.Spec.Replicas)
if test.opt.IsReplicaSetFlag {
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 {
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 {
t.Errorf("%v", err)
}
if (int)(rc.Spec.Replicas) != replicas {
t.Errorf("Expected %d replicas, got %d", replicas, rc.Spec.Replicas)
if test.opt.IsReplicaSetFlag {
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 {
t.Errorf("Expect selector be unset, got: %#v", rc.Spec.Selector)
}

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");
you may not use this file except in compliance with the License.
@ -22,8 +22,8 @@ import (
"os/exec"
"strings"
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/transformer/kubernetes"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/transformer/kubernetes"
log "github.com/Sirupsen/logrus"
@ -39,7 +39,7 @@ import (
"reflect"
"github.com/kubernetes-incubator/kompose/pkg/transformer"
"github.com/kubernetes/kompose/pkg/transformer"
buildapi "github.com/openshift/origin/pkg/build/api"
buildconfigreaper "github.com/openshift/origin/pkg/build/cmd"
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 {
service := komposeObject.ServiceConfigs[name]
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
// Check to see if there is an InputFile (required!) before we build the container
// 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)
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)
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...)
}
// If docker-compose has a volumes_from directive it will be handled here
o.VolumesFrom(&allobjects, komposeObject)
// sort all object so all services are first
// sort all object so Services are first
o.SortServicesFirst(&allobjects)
return allobjects, nil

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");
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"
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/kubernetes-incubator/kompose/pkg/testutils"
"github.com/kubernetes-incubator/kompose/pkg/transformer"
"github.com/kubernetes-incubator/kompose/pkg/transformer/kubernetes"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/testutils"
"github.com/kubernetes/kompose/pkg/transformer"
"github.com/kubernetes/kompose/pkg/transformer/kubernetes"
"github.com/pkg/errors"
)
@ -42,7 +42,7 @@ func newServiceConfig() kobject.ServiceConfig {
Command: []string{"cmd"},
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
Volumes: []string{"/tmp/volume"},
VolList: []string{"/tmp/volume"},
Network: []string{"network1", "network2"}, // not supported
Labels: nil,
Annotations: map[string]string{"abc": "def"},
@ -406,7 +406,8 @@ func TestRecreateStrategyWithVolumesPresent(t *testing.T) {
service := kobject.ServiceConfig{
ContainerName: "name",
Image: "image",
Volumes: []string{"/tmp/volume"},
VolList: []string{"/tmp/volume"},
Volumes: []kobject.Volumes{{SvcName: "app", MountPath: "/tmp/volume", PVCName: "app-claim0"}},
}
komposeObject := kobject.KomposeObject{
ServiceConfigs: map[string]kobject.ServiceConfig{"app": service},

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");
you may not use this file except in compliance with the License.
@ -17,7 +17,7 @@ limitations under the License.
package transformer
import (
"github.com/kubernetes-incubator/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/kobject"
"k8s.io/kubernetes/pkg/runtime"
)

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");
you may not use this file except in compliance with the License.
@ -24,15 +24,16 @@ import (
"strings"
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"
"github.com/pkg/errors"
"k8s.io/kubernetes/pkg/api"
)
// Selector used as labels and selector
const Selector = "io.kompose.service"
// 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]
// 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
if possibleAccessMode == "z" || possibleAccessMode == "Z" {
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
}
// Sort struct
// EnvSort struct
type EnvSort []api.EnvVar
// returns the number of elements in the collection.
@ -189,6 +190,7 @@ func GetComposeFileDir(inputFiles []string) (string, error) {
return filepath.Dir(inputFile), nil
}
//BuildDockerImage builds docker image
func BuildDockerImage(service kobject.ServiceConfig, name string, relativePath string) error {
// 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
}
// PushDockerImage pushes docker image
func PushDockerImage(service kobject.ServiceConfig, serviceName string) error {
log.Debugf("Pushing Docker image '%s'", service.Image)

View File

@ -20,7 +20,7 @@ import (
"bytes"
log "github.com/Sirupsen/logrus"
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"
"io/ioutil"
"os"
@ -28,12 +28,13 @@ import (
"strings"
)
// Build will provide methods for interaction with API regarding building images
type Build struct {
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
in order to make building easier.
*/

View File

@ -18,16 +18,28 @@ package docker
import (
"github.com/fsouza/go-dockerclient"
"os"
)
// DockerClient connects to Docker client on host
func DockerClient() (*docker.Client, error) {
// Default end-point, HTTP + TLS support to be added in the future
// Eventually functionality to specify end-point added to command-line
endpoint := "unix:///var/run/docker.sock"
var (
err error
client *docker.Client
)
// Use the unix socker end-point. No support for TLS (yet)
client, err := docker.NewClient(endpoint)
dockerHost := os.Getenv("DOCKER_HOST")
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 {
return client, err
}

View File

@ -24,12 +24,13 @@ import (
"github.com/pkg/errors"
)
// Push will provide methods for interaction with API regarding pushing images
type Push struct {
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
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")
}

View File

@ -1,6 +1,6 @@
#!/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");
# you may not use this file except in compliance with the License.

View File

@ -1,6 +1,6 @@
#!/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");
# you may not use this file except in compliance with the License.

View File

@ -1,6 +1,6 @@
#!/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");
# you may not use this file except in compliance with the License.
@ -15,9 +15,9 @@
# limitations under the License.
# Constants. Enter relevant repo information here.
UPSTREAM_REPO="kubernetes-incubator"
UPSTREAM_REPO="kubernetes"
CLI="kompose"
GITPATH="$GOPATH/src/github.com/kubernetes-incubator/kompose"
GITPATH="$GOPATH/src/github.com/kubernetes/kompose"
usage() {
echo "This will prepare $CLI for release!"
@ -97,8 +97,11 @@ replaceversion() {
echo "Replaced version in README.md"
sed -i "s/$1/$2/g" README.md
echo "Replaced version in docs/setup.md"
sed -i "s/$1/$2/g" docs/setup.md
echo "Replaced version in docs/installation.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() {
@ -159,6 +162,43 @@ git_tag() {
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() {
CHANGES=$(cat changes.txt)
# Release it!
@ -204,7 +244,7 @@ push() {
}
clean() {
rm changes.txt
rm changes.txt install_guide.txt
}
main() {
@ -248,6 +288,7 @@ main() {
"Create tag"
"Build binaries"
"Create tarballs"
"Generate install guide"
"Upload the binaries and push to GitHub release page"
"Clean"
"Quit")
@ -282,6 +323,9 @@ main() {
"Create tarballs")
create_tarballs
;;
"Generate install guide")
generate_install_guide $VERSION
;;
"Upload the binaries and push to GitHub release page")
push $VERSION
;;

View File

@ -7,7 +7,7 @@ if [ "$TRAVIS_BRANCH" != "master" ] || [ "$BUILD_DOCS" != "yes" ] || [ "$TRAVIS_
fi
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_USER="komposebot"
DOCS_EMAIL="cdrage+kompose@redhat.com"
@ -65,6 +65,7 @@ for filename in *.md; do
jekyll="---
layout: default
permalink: /$name/
redirect_from: \"/docs/$name.md\"
---
"
echo -e "$jekyll\n$(cat $filename)" > $filename
@ -80,7 +81,7 @@ git config user.email "$DOCS_EMAIL"
git add --all
# 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
fi

View File

@ -1,6 +1,6 @@
#!/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");
# you may not use this file except in compliance with the License.

View File

@ -1,6 +1,6 @@
#!/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");
# you may not use this file except in compliance with the License.

View File

@ -1,6 +1,6 @@
#!/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");
# 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
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
@ -264,6 +270,9 @@ cd $CURRENT_DIR
# 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
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"

View File

@ -95,16 +95,16 @@
"image": "bitnami/mariadb:latest",
"env": [
{
"name": "MARIADB_USER",
"value": "bn_wordpress"
"name": "ALLOW_EMPTY_PASSWORD",
"value": "yes"
},
{
"name": "MARIADB_DATABASE",
"value": "bitnami_wordpress"
},
{
"name": "ALLOW_EMPTY_PASSWORD",
"value": "yes"
"name": "MARIADB_USER",
"value": "bn_wordpress"
}
],
"resources": {},
@ -200,6 +200,10 @@
}
],
"env": [
{
"name": "ALLOW_EMPTY_PASSWORD",
"value": "yes"
},
{
"name": "MARIADB_HOST",
"value": "mariadb"
@ -208,17 +212,13 @@
"name": "MARIADB_PORT",
"value": "3306"
},
{
"name": "WORDPRESS_DATABASE_USER",
"value": "bn_wordpress"
},
{
"name": "WORDPRESS_DATABASE_NAME",
"value": "bitnami_wordpress"
},
{
"name": "ALLOW_EMPTY_PASSWORD",
"value": "yes"
"name": "WORDPRESS_DATABASE_USER",
"value": "bn_wordpress"
}
],
"resources": {},

View File

@ -121,16 +121,16 @@
"image": " ",
"env": [
{
"name": "MARIADB_USER",
"value": "bn_wordpress"
"name": "ALLOW_EMPTY_PASSWORD",
"value": "yes"
},
{
"name": "MARIADB_DATABASE",
"value": "bitnami_wordpress"
},
{
"name": "ALLOW_EMPTY_PASSWORD",
"value": "yes"
"name": "MARIADB_USER",
"value": "bn_wordpress"
}
],
"resources": {},
@ -277,6 +277,10 @@
}
],
"env": [
{
"name": "ALLOW_EMPTY_PASSWORD",
"value": "yes"
},
{
"name": "MARIADB_HOST",
"value": "mariadb"
@ -285,17 +289,13 @@
"name": "MARIADB_PORT",
"value": "3306"
},
{
"name": "WORDPRESS_DATABASE_USER",
"value": "bn_wordpress"
},
{
"name": "WORDPRESS_DATABASE_NAME",
"value": "bitnami_wordpress"
},
{
"name": "ALLOW_EMPTY_PASSWORD",
"value": "yes"
"name": "WORDPRESS_DATABASE_USER",
"value": "bn_wordpress"
}
],
"resources": {},

View File

@ -39,7 +39,7 @@ services:
cpus: '0.0001'
memory: 20M
restart_policy:
condition: on_failure
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s

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

View File

@ -4,372 +4,216 @@
"metadata": {},
"items": [
{
"kind": "Service",
"kind": "Pod",
"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": {
"ports": [
"volumes": [
{
"name": "3000",
"port": 3000,
"targetPort": 3000
},
{
"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"
"name": "foo-claim0",
"persistentVolumeClaim": {
"claimName": "foo-claim0"
}
},
"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",
"persistentVolumeClaim": {
"claimName": "foo-claim0"
}
"mountPath": "/var/lib/mysql"
},
{
"name": "foo-claim1",
"persistentVolumeClaim": {
"claimName": "foo-claim1"
}
"mountPath": "/var/lib/mysql"
},
{
"name": "foo-claim2",
"persistentVolumeClaim": {
"claimName": "foo-claim2"
}
"mountPath": "/code"
},
{
"name": "foo-claim3",
"persistentVolumeClaim": {
"claimName": "foo-claim3"
}
"mountPath": "/var/www/html"
},
{
"name": "foo-claim4",
"persistentVolumeClaim": {
"claimName": "foo-claim4",
"readOnly": true
}
"readOnly": true,
"mountPath": "/etc/configs/"
},
{
"name": "datavolume",
"persistentVolumeClaim": {
"claimName": "datavolume"
}
"mountPath": "/var/lib/mysql"
},
{
"name": "foo-tmpfs0",
"emptyDir": {
"medium": "Memory"
}
"mountPath": "/run"
},
{
"name": "foo-tmpfs1",
"emptyDir": {
"medium": "Memory"
}
"mountPath": "/tmp"
}
],
"containers": [
{
"name": "my-web-container",
"image": "redis",
"command": [
"/code/entrypoint.sh",
"-p",
"3000"
"securityContext": {
"capabilities": {
"add": [
"ALL"
],
"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": {
"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"
"drop": [
"NET_ADMIN",
"SYS_ADMIN"
]
},
"privileged": true
},
"stdin": true,
"tty": true
}
},
"strategy": {
"type": "Recreate"
}
],
"restartPolicy": "OnFailure"
},
"status": {}
},

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": {}
}
]
}

View File

@ -4,426 +4,219 @@
"metadata": {},
"items": [
{
"kind": "Service",
"kind": "Pod",
"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": {
"ports": [
"volumes": [
{
"name": "3000",
"port": 3000,
"targetPort": 3000
"name": "foo-claim0",
"persistentVolumeClaim": {
"claimName": "foo-claim0"
}
},
{
"name": "3000",
"port": 3000,
"targetPort": 3000
"name": "foo-claim1",
"persistentVolumeClaim": {
"claimName": "foo-claim1"
}
},
{
"name": "3001",
"port": 3001,
"targetPort": 3001
"name": "foo-claim2",
"persistentVolumeClaim": {
"claimName": "foo-claim2"
}
},
{
"name": "3002",
"port": 3002,
"targetPort": 3002
"name": "foo-claim3",
"persistentVolumeClaim": {
"claimName": "foo-claim3"
}
},
{
"name": "3003",
"port": 3003,
"targetPort": 3003
"name": "foo-claim4",
"persistentVolumeClaim": {
"claimName": "foo-claim4",
"readOnly": true
}
},
{
"name": "3004",
"port": 3004,
"targetPort": 3004
"name": "datavolume",
"persistentVolumeClaim": {
"claimName": "datavolume"
}
},
{
"name": "3005",
"port": 3005,
"targetPort": 3005
"name": "foo-tmpfs0",
"emptyDir": {
"medium": "Memory"
}
},
{
"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
"name": "foo-tmpfs1",
"emptyDir": {
"medium": "Memory"
}
}
],
"selector": {
"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": [
"containers": [
{
"type": "ConfigChange"
},
{
"type": "ImageChange",
"imageChangeParams": {
"automatic": true,
"containerNames": [
"my-web-container"
],
"from": {
"kind": "ImageStreamTag",
"name": "foo:latest"
"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
}
}
}
],
"replicas": 1,
"test": false,
"selector": {
"io.kompose.service": "foo"
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"io.kompose.service": "foo"
}
},
"spec": {
"volumes": [
],
"resources": {
"limits": {
"cpu": "1",
"memory": "52428800"
},
"requests": {
"memory": "20971520"
}
},
"volumeMounts": [
{
"name": "foo-claim0",
"persistentVolumeClaim": {
"claimName": "foo-claim0"
}
"mountPath": "/var/lib/mysql"
},
{
"name": "foo-claim1",
"persistentVolumeClaim": {
"claimName": "foo-claim1"
}
"mountPath": "/var/lib/mysql"
},
{
"name": "foo-claim2",
"persistentVolumeClaim": {
"claimName": "foo-claim2"
}
"mountPath": "/code"
},
{
"name": "foo-claim3",
"persistentVolumeClaim": {
"claimName": "foo-claim3"
}
"mountPath": "/var/www/html"
},
{
"name": "foo-claim4",
"persistentVolumeClaim": {
"claimName": "foo-claim4",
"readOnly": true
}
"readOnly": true,
"mountPath": "/etc/configs/"
},
{
"name": "datavolume",
"persistentVolumeClaim": {
"claimName": "datavolume"
}
"mountPath": "/var/lib/mysql"
},
{
"name": "foo-tmpfs0",
"emptyDir": {
"medium": "Memory"
}
"mountPath": "/run"
},
{
"name": "foo-tmpfs1",
"emptyDir": {
"medium": "Memory"
}
"mountPath": "/tmp"
}
],
"containers": [
{
"name": "my-web-container",
"image": " ",
"command": [
"/code/entrypoint.sh",
"-p",
"3000"
"securityContext": {
"capabilities": {
"add": [
"ALL"
],
"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": {
"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"
"drop": [
"NET_ADMIN",
"SYS_ADMIN"
]
},
"privileged": true
},
"stdin": true,
"tty": true
}
}
],
"restartPolicy": "OnFailure"
},
"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",
"apiVersion": "v1",

View File

@ -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

View File

@ -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": {}
}
]
}

View File

@ -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
script/test_ci/kubernetes.sh Executable file
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
script/test_ci/test.sh Executable file
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

View File

@ -28,7 +28,7 @@ ENV GOPATH="/opt/go" \
ENV PATH="$PATH:$GOPATH/bin" \
# 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
KOMPOSE_SRC="$GOPATH/src/github.com/kubernetes-incubator/kompose"
KOMPOSE_SRC="$GOPATH/src/github.com/kubernetes/kompose"
RUN go get github.com/Masterminds/glide &&\
go get github.com/sgotti/glide-vc &&\

View File

@ -174,7 +174,7 @@ function convert::oc_cleanup () {
function convert::oc_check_route () {
local route_key=$1
if [ $route_key == 'true' ]; then
route_key='xip.io'
route_key='nip.io'
fi
if [ $(oc get route | grep ${route_key} | wc -l ) -gt 0 ]; then

View File

@ -1249,13 +1249,20 @@ func (c *Command) persistentFlag(name string) (flag *flag.Flag) {
}
// 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 {
return nil
}
beforeErrorBufLen := c.flagErrorBuf.Len()
c.mergePersistentFlags()
err = c.Flags().Parse(args)
return
err := c.Flags().Parse(args)
// 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.

View File

@ -53,7 +53,7 @@ func init() {
type remoteConfigFactory interface {
Get(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
@ -597,32 +597,33 @@ func (v *Viper) Get(key string) interface{} {
return nil
}
valType := val
if v.typeByDefValue {
// TODO(bep) this branch isn't covered by a single test.
valType := val
path := strings.Split(lcaseKey, v.keyDelim)
defVal := v.searchMap(v.defaults, path)
if defVal != nil {
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
}