Add new Kompose site (#1474)
This PR adds the new Kompose site! Go preview it at https://kompose.io Signed-off-by: Charlie Drage <charlie@charliedrage.com>
4
.gitignore
vendored
@ -9,6 +9,10 @@ bin
|
||||
/docker-compose.yml
|
||||
changes.txt
|
||||
|
||||
# Ignore built site
|
||||
site/_site/
|
||||
site/.jekyll-cache/
|
||||
|
||||
#
|
||||
# GO SPECIFIC
|
||||
#
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
---
|
||||
layout: default
|
||||
permalink: /architecture/
|
||||
title: Architecture
|
||||
redirect_from:
|
||||
- /docs/architecture.md/
|
||||
- /docs/architecture/
|
||||
---
|
||||
|
||||
# Architecture and Internal Design
|
||||
|
||||
@ -1,17 +1,41 @@
|
||||
---
|
||||
layout: default
|
||||
title: Conversion
|
||||
permalink: /conversion/
|
||||
redirect_from:
|
||||
- /docs/conversion.md/
|
||||
- /docs/conversion/
|
||||
---
|
||||
|
||||
# Conversion Matrix
|
||||
|
||||
This document outlines all possible conversion details regarding `docker-compose.yaml` values to Kubernetes / OpenShift artifacts. This covers *major* versions of Docker Compose such as 1, 2 and 3.
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
The current table covers all **current** possible Docker Compose keys.
|
||||
This document outlines all possible conversion details regarding `docker-compose.yaml` values to Kubernetes / OpenShift artifacts.
|
||||
|
||||
__Note:__ We don't support anything 3.4 and above at the moment.
|
||||
## Version Table
|
||||
|
||||
| Supported | Compose Version | Docker Engine Version |
|
||||
|------------|-----------------|-----------------------|
|
||||
| N | 3.8 | 19.03.0+ |
|
||||
| N | 3.7 | 18.06.0+ |
|
||||
| N | 3.6 | 18.02.0+ |
|
||||
| N | 3.5 | 17.12.0+ |
|
||||
| N | 3.4 | 17.09.0+ |
|
||||
| Y | 3.3 | 17.06.0+ |
|
||||
| Y | 3.2 | 17.04.0+ |
|
||||
| Y | 3.1 | 1.13.1+ |
|
||||
| Y | 3.0 | 1.13.0+ |
|
||||
| Y | 2.4 | 17.12.0+ |
|
||||
| Y | 2.3 | 17.06.0+ |
|
||||
| Y | 2.2 | 1.13.0+ |
|
||||
| Y | 2.1 | 1.12.0+ |
|
||||
| Y | 2.0 | 1.10.0+ |
|
||||
|
||||
**Note:** We don't support anything 3.4 and above at the moment. It is reccomended to specify `version: "3.3"` in your `docker-compose.yaml` and converting. We use a library called [libcompose](https://github.com/docker/libcompose) that supports up to version `3.3`. If you are interested in adding additional support, please open up a PR!
|
||||
|
||||
## Conversion Table
|
||||
|
||||
__Glossary:__
|
||||
|
||||
@ -20,84 +44,85 @@ __Glossary:__
|
||||
- __n:__ Not yet implemented
|
||||
- __x:__ Not applicable / no 1-1 conversion
|
||||
|
||||
| Keys | V1 | V2 | V3 | Kubernetes / OpenShift | Notes |
|
||||
|------------------------|----|----|----|-------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|
|
||||
| build | ✓ | ✓ | ✓ | | Builds/Pushes to Docker repository. See [user guide on build and push image](https://kompose.io/user-guide/#build-and-push-image) | |
|
||||
| build: context | ✓ | ✓ | ✓ | | |
|
||||
| build: dockerfile | ✓ | ✓ | ✓ | | |
|
||||
| build: args | n | n | n | | |
|
||||
| build: cache_from | - | - | n | | |
|
||||
| cap_add, cap_drop | ✓ | ✓ | ✓ | Pod.Spec.Container.SecurityContext.Capabilities.Add/Drop | |
|
||||
| command | ✓ | ✓ | ✓ | Pod.Spec.Container.Args | |
|
||||
| configs | n | n | ✓ | | |
|
||||
| configs: short-syntax | n | n | ✓ | | Only create configMap |
|
||||
| configs: long-syntax | n | n | ✓ | | If target path is /, ignore this and only create configMap |
|
||||
| cgroup_parent | x | x | x | | Not supported within Kubernetes. See issue https://github.com/kubernetes/kubernetes/issues/11986 |
|
||||
| container_name | ✓ | ✓ | ✓ | Metadata.Name + Deployment.Spec.Containers.Name | |
|
||||
| credential_spec | x | x | x | | Only applicable to Windows containers |
|
||||
| deploy | - | - | ✓ | | |
|
||||
| deploy: mode | - | - | ✓ | | |
|
||||
| deploy: replicas | - | - | ✓ | Deployment.Spec.Replicas / DeploymentConfig.Spec.Replicas | |
|
||||
| deploy: placement | - | - | ✓ | Pod.Spec.Affinity | |
|
||||
| deploy: update_config | - | - | ✓ | Workload.Spec.Strategy | Deployment / DeploymentConfig |
|
||||
| deploy: resources | - | - | ✓ | Containers.Resources.Limits.Memory / Containers.Resources.Limits.CPU | Support for memory as well as cpu |
|
||||
| deploy: restart_policy | - | - | ✓ | Pod generation | This generated a Pod, see the [user guide on restart](http://kompose.io/user-guide/#restart) |
|
||||
| deploy: labels | - | - | ✓ | Workload.Metadata.Labels | Only applied to workload resource | |
|
||||
| devices | x | x | x | | Not supported within Kubernetes, See issue https://github.com/kubernetes/kubernetes/issues/5607 |
|
||||
| depends_on | x | x | x | | |
|
||||
| dns | x | x | x | | Not used within Kubernetes. Kubernetes uses a managed DNS server |
|
||||
| dns_search | x | x | x | | See `dns` key |
|
||||
| domainname | ✓ | ✓ | ✓ | Pod.Spec.SubDomain |
|
||||
| tmpfs | ✓ | ✓ | ✓ | Pod.Spec.Containers.Volumes.EmptyDir | Creates emptyDirvolume with medium set to Memory & mounts given directory inside container |
|
||||
| entrypoint | ✓ | ✓ | ✓ | Pod.Spec.Container.Command | |
|
||||
| env_file | n | n | ✓ | | |
|
||||
| environment | ✓ | ✓ | ✓ | Pod.Spec.Container.Env | |
|
||||
| expose | ✓ | ✓ | ✓ | Service.Spec.Ports
|
||||
| endpoint_mode | n | n | ✓ | | If endpoint_mode=vip, the created Service will be forced to set to NodePort type |
|
||||
| extends | ✓ | ✓ | ✓ | | Extends by utilizing the same image supplied |
|
||||
| external_links | x | x | x | | Kubernetes uses a flat-structure for all containers and thus external_links does not have a 1-1 conversion |
|
||||
| extra_hosts | n | n | n | | |
|
||||
| group_add | ✓ | ✓ | ✓ | | |
|
||||
| healthcheck | - | n | ✓ | | |
|
||||
| hostname | ✓ | ✓ | ✓ | Pod.Spec.HostName | |
|
||||
| image | ✓ | ✓ | ✓ | Deployment.Spec.Containers.Image | |
|
||||
| isolation | x | x | x | | Not applicable as this applies to Windows with HyperV support |
|
||||
| labels | ✓ | ✓ | ✓ | Metadata.Annotations | |
|
||||
| links | x | x | x | | All containers in the same pod are accessible in Kubernetes |
|
||||
| logging | x | x | x | | Kubernetes has built-in logging support at the node-level |
|
||||
| network_mode | x | x | x | | Kubernetes uses its own cluster networking |
|
||||
| networks | ✓ | ✓ | ✓ | | See `networks` key |
|
||||
| networks: aliases | x | x | x | | See `networks` key |
|
||||
| networks: addresses | x | x | x | | See `networks` key |
|
||||
| pid | ✓ | ✓ | ✓ | Pod.Spec.HostPID | |
|
||||
| ports | ✓ | ✓ | ✓ | Service.Spec.Ports | |
|
||||
| ports: short-syntax | ✓ | ✓ | ✓ | Service.Spec.Ports | |
|
||||
| ports: long-syntax | - | - | ✓ | Service.Spec.Ports | |
|
||||
| secrets | - | - | ✓ | Secret | External Secret is not Supported |
|
||||
| secrets: short-syntax | - | - | ✓ | Secret | External Secret is not Supported |
|
||||
| secrets: long-syntax | - | - | ✓ | Secret | External Secret is not Supported |
|
||||
| security_opt | x | x | x | | Kubernetes uses its own container naming scheme |
|
||||
| stop_grace_period | ✓ | ✓ | ✓ | Pod.Spec.TerminationGracePeriodSeconds | |
|
||||
| stop_signal | x | x | x | | Not supported within Kubernetes. See issue https://github.com/kubernetes/kubernetes/issues/30051 |
|
||||
| sysctls | n | n | n | | |
|
||||
| ulimits | x | x | x | | Not supported within Kubernetes. See issue https://github.com/kubernetes/kubernetes/issues/3595 |
|
||||
| userns_mode | x | x | x | | Not supported within Kubernetes and ignored in Docker Compose Version 3 |
|
||||
| volumes | ✓ | ✓ | ✓ | PersistentVolumeClaim | Creates a PersistentVolumeClaim. Can only be created if there is already a PersistentVolume within the cluster |
|
||||
| volumes: short-syntax | ✓ | ✓ | ✓ | PersistentVolumeClaim | Creates a PersistentVolumeClaim. Can only be created if there is already a PersistentVolume within the cluster |
|
||||
| volumes: long-syntax | - | - | ✓ | PersistentVolumeClaim | Creates a PersistentVolumeClaim. Can only be created if there is already a PersistentVolume within the cluster |
|
||||
| restart | ✓ | ✓ | ✓ | | |
|
||||
| | | | | | |
|
||||
| __Volume__ | x | x | x | | |
|
||||
| driver | x | x | x | | |
|
||||
| driver_opts | x | x | x | | |
|
||||
| external | x | x | x | | |
|
||||
| labels | x | x | x | | |
|
||||
| | | | | | |
|
||||
| __Network__ | x | x | x | | |
|
||||
| driver | x | x | x | | |
|
||||
| driver_opts | x | x | x | | |
|
||||
| enable_ipv6 | x | x | x | | |
|
||||
| ipam | x | x | x | | |
|
||||
| internal | x | x | x | | |
|
||||
| labels | x | x | x | | |
|
||||
| external | x | x | x | | |
|
||||
| Keys | V1 | V2 | V3 | Kubernetes / OpenShift | Notes |
|
||||
|------------------------|----|----|----|----------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|
|
||||
| build | ✓ | ✓ | ✓ | | Builds/Pushes to Docker repository. See [user guide on build and push image](https://kompose.io/user-guide/#build-and-push-image) |
|
||||
| build: context | ✓ | ✓ | ✓ | | |
|
||||
| build: dockerfile | ✓ | ✓ | ✓ | | |
|
||||
| build: args | n | n | n | | |
|
||||
| build: cache_from | - | - | n | | |
|
||||
| cap_add | ✓ | ✓ | ✓ | Container.SecurityContext.Capabilities.Add | |
|
||||
| cap_drop | ✓ | ✓ | ✓ | Container.SecurityContext.Capabilities.Drop | |
|
||||
| command | ✓ | ✓ | ✓ | Container.Args | |
|
||||
| configs | n | n | ✓ | | |
|
||||
| configs: short-syntax | n | n | ✓ | | Only create configMap |
|
||||
| configs: long-syntax | n | n | ✓ | | If target path is /, ignore this and only create configMap |
|
||||
| cgroup_parent | x | x | x | | Not supported within Kubernetes. See issue https://github.com/kubernetes/kubernetes/issues/11986 |
|
||||
| container_name | ✓ | ✓ | ✓ | Metadata.Name + Deployment.Spec.Containers.Name | |
|
||||
| credential_spec | x | x | x | | Only applicable to Windows containers |
|
||||
| deploy | - | - | ✓ | | |
|
||||
| deploy: mode | - | - | ✓ | | |
|
||||
| deploy: replicas | - | - | ✓ | Deployment.Spec.Replicas / DeploymentConfig.Spec.Replicas | |
|
||||
| deploy: placement | - | - | ✓ | Affinity | |
|
||||
| deploy: update_config | - | - | ✓ | Workload.Spec.Strategy | Deployment / DeploymentConfig |
|
||||
| deploy: resources | - | - | ✓ | Containers.Resources.Limits.Memory / Containers.Resources.Limits.CPU | Support for memory as well as cpu |
|
||||
| deploy: restart_policy | - | - | ✓ | Pod generation | This generated a Pod, see the [user guide on restart](http://kompose.io/user-guide/#restart) |
|
||||
| deploy: labels | - | - | ✓ | Workload.Metadata.Labels | Only applied to workload resource |
|
||||
| devices | x | x | x | | Not supported within Kubernetes, See issue https://github.com/kubernetes/kubernetes/issues/5607 |
|
||||
| depends_on | x | x | x | | |
|
||||
| dns | x | x | x | | Not used within Kubernetes. Kubernetes uses a managed DNS server |
|
||||
| dns_search | x | x | x | | See `dns` key |
|
||||
| domainname | ✓ | ✓ | ✓ | SubDomain | |
|
||||
| tmpfs | ✓ | ✓ | ✓ | Containers.Volumes.EmptyDir | Creates emptyDirvolume with medium set to Memory & mounts given directory inside container |
|
||||
| entrypoint | ✓ | ✓ | ✓ | Container.Command | |
|
||||
| env_file | n | n | ✓ | | |
|
||||
| environment | ✓ | ✓ | ✓ | Container.Env | |
|
||||
| expose | ✓ | ✓ | ✓ | Service.Spec.Ports | |
|
||||
| endpoint_mode | n | n | ✓ | | If endpoint_mode=vip, the created Service will be forced to set to NodePort type |
|
||||
| extends | ✓ | ✓ | ✓ | | Extends by utilizing the same image supplied |
|
||||
| external_links | x | x | x | | Kubernetes uses a flat-structure for all containers and thus external_links does not have a 1-1 conversion |
|
||||
| extra_hosts | n | n | n | | |
|
||||
| group_add | ✓ | ✓ | ✓ | | |
|
||||
| healthcheck | - | n | ✓ | | |
|
||||
| hostname | ✓ | ✓ | ✓ | HostName | |
|
||||
| image | ✓ | ✓ | ✓ | Deployment.Spec.Containers.Image | |
|
||||
| isolation | x | x | x | | Not applicable as this applies to Windows with HyperV support |
|
||||
| labels | ✓ | ✓ | ✓ | Metadata.Annotations | |
|
||||
| links | x | x | x | | All containers in the same pod are accessible in Kubernetes |
|
||||
| logging | x | x | x | | Kubernetes has built-in logging support at the node-level |
|
||||
| network_mode | x | x | x | | Kubernetes uses its own cluster networking |
|
||||
| networks | ✓ | ✓ | ✓ | | See `networks` key |
|
||||
| networks: aliases | x | x | x | | See `networks` key |
|
||||
| networks: addresses | x | x | x | | See `networks` key |
|
||||
| pid | ✓ | ✓ | ✓ | HostPID | |
|
||||
| ports | ✓ | ✓ | ✓ | Service.Spec.Ports | |
|
||||
| ports: short-syntax | ✓ | ✓ | ✓ | Service.Spec.Ports | |
|
||||
| ports: long-syntax | - | - | ✓ | Service.Spec.Ports | |
|
||||
| secrets | - | - | ✓ | Secret | External Secret is not Supported |
|
||||
| secrets: short-syntax | - | - | ✓ | Secret | External Secret is not Supported |
|
||||
| secrets: long-syntax | - | - | ✓ | Secret | External Secret is not Supported |
|
||||
| security_opt | x | x | x | | Kubernetes uses its own container naming scheme |
|
||||
| stop_grace_period | ✓ | ✓ | ✓ | TerminationGracePeriodSeconds | |
|
||||
| stop_signal | x | x | x | | Not supported within Kubernetes. See issue https://github.com/kubernetes/kubernetes/issues/30051 |
|
||||
| sysctls | n | n | n | | |
|
||||
| ulimits | x | x | x | | Not supported within Kubernetes. See issue https://github.com/kubernetes/kubernetes/issues/3595 |
|
||||
| userns_mode | x | x | x | | Not supported within Kubernetes and ignored in Docker Compose Version 3 |
|
||||
| volumes | ✓ | ✓ | ✓ | PersistentVolumeClaim | Creates a PersistentVolumeClaim. Can only be created if there is already a PersistentVolume within the cluster |
|
||||
| volumes: short-syntax | ✓ | ✓ | ✓ | PersistentVolumeClaim | Creates a PersistentVolumeClaim. Can only be created if there is already a PersistentVolume within the cluster |
|
||||
| volumes: long-syntax | - | - | ✓ | PersistentVolumeClaim | Creates a PersistentVolumeClaim. Can only be created if there is already a PersistentVolume within the cluster |
|
||||
| restart | ✓ | ✓ | ✓ | | |
|
||||
| | | | | | |
|
||||
| __Volume__ | x | x | x | | |
|
||||
| driver | x | x | x | | |
|
||||
| driver_opts | x | x | x | | |
|
||||
| external | x | x | x | | |
|
||||
| labels | x | x | x | | |
|
||||
| | | | | | |
|
||||
| __Network__ | x | x | x | | |
|
||||
| driver | x | x | x | | |
|
||||
| driver_opts | x | x | x | | |
|
||||
| enable_ipv6 | x | x | x | | |
|
||||
| ipam | x | x | x | | |
|
||||
| internal | x | x | x | | |
|
||||
| labels | x | x | x | | |
|
||||
| external | x | x | x | | |
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
---
|
||||
layout: default
|
||||
permalink: /development/
|
||||
title: Development
|
||||
redirect_from:
|
||||
- /docs/development.md/
|
||||
- /docs/development/
|
||||
---
|
||||
|
||||
# Development Guide
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
---
|
||||
layout: default
|
||||
permalink: /getting-started/
|
||||
title: Getting Started
|
||||
redirect_from:
|
||||
- /docs/getting-started.md/
|
||||
- /docs/getting-started/
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
@ -155,8 +157,6 @@ INFO OpenShift file "redis-slave-deploymentconfig.yaml" created
|
||||
INFO OpenShift file "redis-slave-imagestream.yaml" created
|
||||
```
|
||||
|
||||
Alternatively, you can convert and deploy directly to OpenShift with `kompose up --provider=openshift`.
|
||||
|
||||
Then you can use `kubectl apply` to create these resources in OpenShift cluster.
|
||||
|
||||
__Access the newly deployed service:__
|
||||
|
||||
@ -1,15 +1,20 @@
|
||||
---
|
||||
layout: default
|
||||
permalink: /installation/
|
||||
title: Installation
|
||||
redirect_from:
|
||||
- /docs/installation.md/
|
||||
- /docs/installation/
|
||||
---
|
||||
|
||||
# Installation
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
We have multiple ways to install Kompose. Our preferred method is downloading the binary from the latest GitHub release.
|
||||
|
||||
#### GitHub release
|
||||
## GitHub release
|
||||
|
||||
Kompose is released via GitHub on a three-week cycle, you can see all current releases on the [GitHub release page](https://github.com/kubernetes/kompose/releases).
|
||||
|
||||
@ -30,7 +35,7 @@ __Windows:__
|
||||
|
||||
Download from [GitHub](https://github.com/kubernetes/kompose/releases/download/v1.26.1/kompose-windows-amd64.exe) and add the binary to your PATH.
|
||||
|
||||
#### Go
|
||||
## Go
|
||||
|
||||
Installing using `go get` pulls from the master branch with the latest development changes.
|
||||
|
||||
@ -38,7 +43,7 @@ Installing using `go get` pulls from the master branch with the latest developme
|
||||
go get -u github.com/kubernetes/kompose
|
||||
```
|
||||
|
||||
#### CentOS
|
||||
## CentOS
|
||||
|
||||
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`
|
||||
@ -49,14 +54,14 @@ If you have [EPEL](https://fedoraproject.org/wiki/EPEL) enabled in your system,
|
||||
sudo yum -y install kompose
|
||||
```
|
||||
|
||||
#### Fedora
|
||||
## Fedora
|
||||
Kompose is in Fedora 24, 25 and 26 repositories. You can install it just like any other package.
|
||||
|
||||
```bash
|
||||
sudo dnf -y install kompose
|
||||
```
|
||||
|
||||
#### Ubuntu/Debian
|
||||
## Ubuntu/Debian
|
||||
|
||||
A deb package is released for compose. Download latest package in the assets in [github releases](https://github.com/kubernetes/kompose/releases).
|
||||
|
||||
@ -65,7 +70,7 @@ wget https://github.com/kubernetes/kompose/releases/download/v1.26.1/kompose_1.2
|
||||
sudo apt install ./kompose_1.26.1_amd64.deb
|
||||
```
|
||||
|
||||
#### macOS
|
||||
## macOS
|
||||
On macOS you can install latest release via [Homebrew](https://brew.sh) or [MacPorts](https://www.macports.org/).
|
||||
|
||||
```bash
|
||||
@ -76,14 +81,14 @@ brew install kompose
|
||||
port install kompose
|
||||
```
|
||||
|
||||
#### Windows
|
||||
## Windows
|
||||
Kompose can be installed via [Chocolatey](https://chocolatey.org/packages/kubernetes-kompose)
|
||||
|
||||
```console
|
||||
choco install kubernetes-kompose
|
||||
```
|
||||
|
||||
#### openSUSE/SLE
|
||||
## openSUSE/SLE
|
||||
Kompose is available in the official Virtualization:containers repository for openSUSE Tumbleweed, Leap 15, Leap 42.3 and SUSE Linux Enterprise 15.
|
||||
|
||||
Head over to [software.opensuse.org for One-Click Installation](https://software.opensuse.org//download.html?project=Virtualization%3Acontainers&package=kompose) or add the repository manually:
|
||||
@ -106,7 +111,7 @@ sudo zypper refresh
|
||||
sudo zypper install kompose
|
||||
```
|
||||
|
||||
#### NixOS
|
||||
## NixOS
|
||||
|
||||
To install from [Nixpkgs](https://github.com/NixOS/nixpkgs), use [nix-env](https://nixos.org/manual/nix/stable/command-ref/nix-env.html).
|
||||
|
||||
@ -121,7 +126,7 @@ nix-shell -p kompose --run "kompose convert"
|
||||
```
|
||||
|
||||
|
||||
#### Docker
|
||||
## Docker
|
||||
|
||||
You can build an image from the offical repo for [Docker](https://docs.docker.com/engine/reference/commandline/build/) or [Podman](https://docs.podman.io/en/latest/markdown/podman-build.1.html):
|
||||
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
---
|
||||
layout: default
|
||||
permalink: /integrations/
|
||||
title: Integrations
|
||||
redirect_from:
|
||||
- /docs/integrations.md/
|
||||
- /docs/integrations/
|
||||
---
|
||||
|
||||
# Integrations
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
---
|
||||
layout: default
|
||||
permalink: /maven-example/
|
||||
title: Maven Example
|
||||
redirect_from:
|
||||
- /docs/maven-example.md/
|
||||
- /docs/maven-example/
|
||||
---
|
||||
|
||||
# Fabric8 Maven Plugin + Kompose:
|
||||
|
||||
2
docs/user-guide.md
Executable file → Normal file
@ -1,8 +1,10 @@
|
||||
---
|
||||
layout: default
|
||||
permalink: /user-guide/
|
||||
title: User Guide
|
||||
redirect_from:
|
||||
- /docs/user-guide.md/
|
||||
- /docs/user-guide/
|
||||
---
|
||||
|
||||
# User Guide
|
||||
|
||||
@ -99,9 +99,7 @@ replaceversion() {
|
||||
|
||||
echo "Replaced version in docs/installation.md"
|
||||
sed -i "s/$1/$2/g" docs/installation.md || gsed -i "s/$1/$2/g" docs/installation.md
|
||||
|
||||
echo "Replaced version in docs/introduction.md"
|
||||
sed -i "s/$1/$2/g" docs/introduction.md || gsed -i "s/$1/$2/g" docs/introduction.md
|
||||
sed -i "s/$1/$2/g" site/docs/installation.md || gsed -i "s/$1/$2/g" site/docs/installation.md
|
||||
|
||||
echo "Replaced version in build/VERSION"
|
||||
sed -i "s/$1/$2/g" build/VERSION || gsed -i "s/$1/$2/g" build/VERSION
|
||||
|
||||
25
site/404.html
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
permalink: /404.html
|
||||
layout: default
|
||||
---
|
||||
|
||||
<style type="text/css" media="screen">
|
||||
.container {
|
||||
margin: 10px auto;
|
||||
max-width: 600px;
|
||||
text-align: center;
|
||||
}
|
||||
h1 {
|
||||
margin: 30px 0;
|
||||
font-size: 4em;
|
||||
line-height: 1;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container">
|
||||
<h1>404</h1>
|
||||
|
||||
<p><strong>Page not found :(</strong></p>
|
||||
<p>The requested page could not be found.</p>
|
||||
</div>
|
||||
31
site/Gemfile
Normal file
@ -0,0 +1,31 @@
|
||||
source "https://rubygems.org"
|
||||
# Hello! This is where you manage which Jekyll version is used to run.
|
||||
# When you want to use a different version, change it below, save the
|
||||
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
|
||||
#
|
||||
# bundle exec jekyll serve
|
||||
#
|
||||
# This will help ensure the proper Jekyll version is running.
|
||||
# Happy Jekylling!
|
||||
gem "jekyll", "~> 4.0.0"
|
||||
# This is the default theme for new Jekyll sites. You may change this to anything you like.
|
||||
gem "minima", "~> 2.5"
|
||||
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
|
||||
# uncomment the line below. To upgrade, run `bundle update github-pages`.
|
||||
# gem "github-pages", group: :jekyll_plugins
|
||||
# If you have any plugins, put them here!
|
||||
group :jekyll_plugins do
|
||||
gem "jekyll-feed", "~> 0.12"
|
||||
end
|
||||
|
||||
# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||
# and associated library.
|
||||
install_if -> { RUBY_PLATFORM =~ %r!mingw|mswin|java! } do
|
||||
gem "tzinfo", "~> 1.2"
|
||||
gem "tzinfo-data"
|
||||
end
|
||||
|
||||
# Performance-booster for watching directories on Windows
|
||||
gem "wdm", "~> 0.1.1", :install_if => Gem.win_platform?
|
||||
|
||||
gem "jekyll-redirect-from"
|
||||
89
site/Gemfile.lock
Normal file
@ -0,0 +1,89 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
colorator (1.1.0)
|
||||
concurrent-ruby (1.1.9)
|
||||
em-websocket (0.5.3)
|
||||
eventmachine (>= 0.12.9)
|
||||
http_parser.rb (~> 0)
|
||||
eventmachine (1.2.7)
|
||||
ffi (1.15.5)
|
||||
forwardable-extended (2.6.0)
|
||||
http_parser.rb (0.8.0)
|
||||
i18n (1.8.11)
|
||||
concurrent-ruby (~> 1.0)
|
||||
jekyll (4.0.1)
|
||||
addressable (~> 2.4)
|
||||
colorator (~> 1.0)
|
||||
em-websocket (~> 0.5)
|
||||
i18n (>= 0.9.5, < 2)
|
||||
jekyll-sass-converter (~> 2.0)
|
||||
jekyll-watch (~> 2.0)
|
||||
kramdown (~> 2.1)
|
||||
kramdown-parser-gfm (~> 1.0)
|
||||
liquid (~> 4.0)
|
||||
mercenary (~> 0.3.3)
|
||||
pathutil (~> 0.9)
|
||||
rouge (~> 3.0)
|
||||
safe_yaml (~> 1.0)
|
||||
terminal-table (~> 1.8)
|
||||
jekyll-feed (0.16.0)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-redirect-from (0.16.0)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-sass-converter (2.1.0)
|
||||
sassc (> 2.0.1, < 3.0)
|
||||
jekyll-seo-tag (2.7.1)
|
||||
jekyll (>= 3.8, < 5.0)
|
||||
jekyll-watch (2.2.1)
|
||||
listen (~> 3.0)
|
||||
kramdown (2.3.1)
|
||||
rexml
|
||||
kramdown-parser-gfm (1.1.0)
|
||||
kramdown (~> 2.0)
|
||||
liquid (4.0.3)
|
||||
listen (3.7.0)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
mercenary (0.3.6)
|
||||
minima (2.5.1)
|
||||
jekyll (>= 3.5, < 5.0)
|
||||
jekyll-feed (~> 0.9)
|
||||
jekyll-seo-tag (~> 2.1)
|
||||
pathutil (0.16.2)
|
||||
forwardable-extended (~> 2.6)
|
||||
public_suffix (4.0.6)
|
||||
rb-fsevent (0.11.0)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
rexml (3.2.5)
|
||||
rouge (3.27.0)
|
||||
safe_yaml (1.0.5)
|
||||
sassc (2.4.0)
|
||||
ffi (~> 1.9)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
thread_safe (0.3.6)
|
||||
tzinfo (1.2.9)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo-data (1.2021.5)
|
||||
tzinfo (>= 1.0.0)
|
||||
unicode-display_width (1.8.0)
|
||||
wdm (0.1.1)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
jekyll (~> 4.0.0)
|
||||
jekyll-feed (~> 0.12)
|
||||
jekyll-redirect-from
|
||||
minima (~> 2.5)
|
||||
tzinfo (~> 1.2)
|
||||
tzinfo-data
|
||||
wdm (~> 0.1.1)
|
||||
|
||||
BUNDLED WITH
|
||||
2.1.4
|
||||
25
site/LICENSE
Normal file
@ -0,0 +1,25 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2016 GochoMugo <mugo@forfuture.co.ke>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the Software
|
||||
without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to
|
||||
whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall
|
||||
be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
|
||||
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
7
site/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
View the site via:
|
||||
|
||||
```sh
|
||||
bundle exec jekyll serve .
|
||||
```
|
||||
|
||||
And visiting `localhost:4000` on your browser.
|
||||
21
site/_config.yml
Normal file
@ -0,0 +1,21 @@
|
||||
title: Kompose
|
||||
name: Kompose
|
||||
email: foo@gmail.com
|
||||
github_page: https://github.com/kubernetes/kompose
|
||||
slack_page: https://slack.k8s.io
|
||||
description: >- # this means to ignore newlines until "baseurl:"
|
||||
Convert your Docker Compose file to Kubernetes or OpenShift
|
||||
baseurl: "" # the subpath of your site, e.g. /blog
|
||||
url: "" # the base hostname & protocol for your site, e.g. http://example.com
|
||||
year: 2022
|
||||
|
||||
# Google Analytics number (starts with UA?)
|
||||
analytics: 12345
|
||||
|
||||
instagram: https://www.instagram.com
|
||||
facebook: https://www.facebook.com
|
||||
|
||||
# Build settings
|
||||
theme: minima
|
||||
plugins:
|
||||
- jekyll-feed
|
||||
72
site/_data/dates.yml
Normal file
@ -0,0 +1,72 @@
|
||||
- date: "Saturday May 8"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
- date: "Monday May 17"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
- date: "Monday May 31"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
- date: "Monday June 7"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
- date: "Monday June 14"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
- date: "Monday June 21"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
- date: "Monday July 5"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
- date: "Monday July 19"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
- date: "Monday July 26"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
- date: "Monday August 9"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
- date: "Monday August 16"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
- date: "Monday August 23"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
- date: "Monday August 30"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
- date: "Monday September 13"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
- date: "Friday September 24"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
- date: "Monday September 27"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
- date: "Monday October 4"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
- date: "Sunday October 10"
|
||||
green: 20
|
||||
yellow: 20
|
||||
red: 20
|
||||
6
site/_data/menu.yml
Normal file
@ -0,0 +1,6 @@
|
||||
other_links:
|
||||
"Installation": "/installation/"
|
||||
"Getting Started": "/getting-started/"
|
||||
"User Guide": "/user-guide/"
|
||||
"Conversion Matrix": "/conversion/"
|
||||
"Architecture": "/architecture/"
|
||||
2
site/_foobar.yml
Normal file
@ -0,0 +1,2 @@
|
||||
dates:
|
||||
"May 8th 2021"
|
||||
42
site/_includes/footer.html
Normal file
@ -0,0 +1,42 @@
|
||||
<!-- Footer -->
|
||||
<div class="footer">
|
||||
<div class="container text-center">
|
||||
<span class="copyright">
|
||||
We are a Kubernetes incubator graduated project and officially part of the Kubernetes group
|
||||
<br>
|
||||
Apache License 2.0 licensed project
|
||||
<br>
|
||||
© {{ site.year }} Kompose Authors -- All Rights Reserved
|
||||
</span>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row text-center">
|
||||
<div class="col-lg-2 col-md-3 col-sm-12">
|
||||
<div class="footer-logo">
|
||||
<h2>{{ site.name }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6 col-md-6 col-sm-12">
|
||||
<ul class="footer-menu">
|
||||
<!--
|
||||
{% for item in site.data.menu.footer %}
|
||||
<li><a href="{{ item[1] }}">{{ item[0] }}</a></li>
|
||||
{% endfor %}
|
||||
-->
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-lg-4 col-md-3 col-sm-12">
|
||||
<div class="footer-links">
|
||||
<ul>
|
||||
<li><a href="{{ site.slack_page }}" target="_blank"><img class="img-fluid" src="/assets/icons/slack.png" alt="Slack">Slack</a> </li>
|
||||
<li><a href="{{ site.github_page }}" target="_blank"><img class="img-fluid" src="/assets/icons/github.png" alt="GitHub">GitHub</a> </li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Scroll To Top -->
|
||||
<!--<a id="back-top" class="back-to-top js-scroll-trigger" href="#main"></a>-->
|
||||
<!-- Scroll To Top Ends-->
|
||||
</div>
|
||||
</div>
|
||||
46
site/_includes/meta.html
Normal file
@ -0,0 +1,46 @@
|
||||
<!-- Meta -->
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="description" content="{{site.description}}">
|
||||
|
||||
<!-- Cross-site Meta -->
|
||||
<meta name="robots" content="index, follow">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="language" content="English">
|
||||
|
||||
<!-- Metadata loading stuff-->
|
||||
<link href="/assets/css/bootstrap.min.css" rel="stylesheet" type="text/css" media="all" />
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
|
||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:200,300,400,400i,500,600,700%7CMontserrat:300,400,500%7CRoboto" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/assets/css/animate.css"> <!-- Resource style -->
|
||||
<link rel="stylesheet" href="/assets/css/owl.carousel.css">
|
||||
<link rel="stylesheet" href="/assets/css/owl.theme.css">
|
||||
<link rel="stylesheet" href="/assets/css/magnific-popup.css">
|
||||
<link rel="stylesheet" href="/assets/css/ionicons.min.css"> <!-- Resource style -->
|
||||
<link rel="stylesheet" href="/assets/css/style.css">
|
||||
<link rel="stylesheet" href="/assets/css/github-markdown.css">
|
||||
|
||||
|
||||
<!-- Favicons -->
|
||||
<!-- Generate using: https://realfavicongenerator.net/ and put information in /assets/favicons/ folder -->
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/assets/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="/assets/favicons/site.webmanifest">
|
||||
<link rel="mask-icon" href="/assets/favicons/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<link rel="shortcut icon" href="/assets/favicons/favicon.ico">
|
||||
<meta name="msapplication-TileColor" content="#da532c">
|
||||
<meta name="msapplication-config" content="/assets/favicons/browserconfig.xml">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<!-- ANALYTICS -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id={{ site.analytics }}"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', '{{ site.analytics }}');
|
||||
</script>
|
||||
|
||||
18
site/_includes/navbar.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!-- Navbar Section -->
|
||||
<nav class="navbar navbar-expand-md navbar-light bg-light fixed-top">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="/">
|
||||
<img class="navbar-logo" src="/assets/images/logo.png" alt="logo"/>
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav ml-auto navbar-right">
|
||||
{% for item in site.data.menu.other_links %}
|
||||
<li class="nav-item"><a class="nav-link" href="{{ item[1] }}">{{ item[0] }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav><!-- Navbar End -->
|
||||
62
site/_layouts/default.html
Normal file
@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html>
|
||||
<whtml lang="en">
|
||||
<head>
|
||||
|
||||
<!-- Metadata -->
|
||||
<meta charset="utf-8">
|
||||
<title>{{ site.title }} - {{ page.title }}</title>
|
||||
<meta name="title" content="{{ site.title }} - {{ page.title }}">
|
||||
|
||||
{% include meta.html %}
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
|
||||
{% include navbar.html %}
|
||||
|
||||
<div id="main" class="main">
|
||||
<div class="first"><!-- Hero Section-->
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="hero-content wow fadeIn">
|
||||
<div class="hero-content-inner">
|
||||
<div class="style markdown-body">
|
||||
{{ content }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="questions flex-out align-center wow fadeIn">
|
||||
<p>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- Hero End -->
|
||||
</div>
|
||||
|
||||
|
||||
{% include footer.html %}
|
||||
|
||||
</div> <!-- Main -->
|
||||
|
||||
|
||||
<!-- Jquery and Js Plugins -->
|
||||
<script src="/assets/js/jquery-2.1.1.js"></script>
|
||||
<script src="/assets/js/popper.min.js"></script>
|
||||
<script src="/assets/js/jquery.validate.min.js"></script>
|
||||
<script src="/assets/js/bootstrap.min.js"></script>
|
||||
<script src="/assets/js/plugins.js"></script>
|
||||
<script src="/assets/js/menu.js"></script>
|
||||
<script src="/assets/js/custom.js"></script>
|
||||
<script>
|
||||
$('.navbar-nav>li>a').on('click', function(){
|
||||
|
||||
$('.navbar-collapse').collapse('hide');
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
158
site/_layouts/index.html
Normal file
@ -0,0 +1,158 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
||||
<!-- Metadata -->
|
||||
<meta charset="utf-8">
|
||||
<title>{{ site.title }} - {{ site.description }}</title>
|
||||
<meta name="title" content="{{ site.title }} - {{ site.description }}">
|
||||
|
||||
{% include meta.html %}
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
|
||||
{% include navbar.html %}
|
||||
|
||||
<div id="main" class="main">
|
||||
<div class="first home-3"><!-- Hero Section-->
|
||||
<div class="questions flex-out align-center wow fadeIn">
|
||||
<p>
|
||||
An official Kubernetes project, located at <a href="https://github.com/kubernetes/kompose" target="_blank">github.com/kubernetes/kompose</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<div class="hero-content wow fadeIn">
|
||||
<div class="hero-content-inner">
|
||||
<h4>Go from Docker Compose to Kubernetes</h4>
|
||||
<h1>Kompose</h1>
|
||||
<p>
|
||||
Kompose is a conversion tool for Docker Compose to container orchestrators such as Kubernetes (or OpenShift).
|
||||
|
||||
</p>
|
||||
<a class="btn-action" href="/installation">Installation</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-7 markdown-body code-example">
|
||||
{{ content }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div><!-- Hero End -->
|
||||
|
||||
<div id="what" class="what home-3"><!-- Hero Section-->
|
||||
<div class="container">
|
||||
<div class="flex-intro align-center wow fadeIn">
|
||||
<h2>Get started on Kubernetes immediately</h2>
|
||||
<p>
|
||||
So easy your human companion could do it too!
|
||||
</p>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-7">
|
||||
<div class="hero-img loop-video">
|
||||
<video class="embed-responsive drone-video" autoplay loop muted>
|
||||
<source src="assets/video/cat.webm" type="video/webm" />
|
||||
</video>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-5">
|
||||
<div class="hero-content wow fadeIn">
|
||||
<div class="hero-content-inner">
|
||||
<p>
|
||||
Why do cats (and developers) like Kompose?
|
||||
<br>
|
||||
<br>
|
||||
Developers love to simplify their development environment with Docker Compose.
|
||||
<br>
|
||||
<br>
|
||||
With Kompose, you can now push the same file to a production container orchestrator!
|
||||
<br>
|
||||
<br>
|
||||
You only need two commands: <b>kompose convert</b> and <b>kubectl apply</b>
|
||||
</p>
|
||||
<a class="btn-action" href="/getting-started">Getting Started</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div><!-- Hero End -->
|
||||
|
||||
<div id="date" class="home home-3"><!-- Hero Section-->
|
||||
<div class="container">
|
||||
<div class="flex-intro align-center wow fadeIn">
|
||||
<h2>Built for container engineers</h2>
|
||||
<p>
|
||||
Our conversions are not always 1-1 from Docker Compose to Kubernetes, but we will help get you 99% of the way there!
|
||||
</p>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-5">
|
||||
<div class="hero-content wow fadeIn">
|
||||
<div class="hero-content-inner">
|
||||
<h4>The awesome features</h4>
|
||||
<p>
|
||||
• Compatibility with multiple versions of Docker Compose
|
||||
<br>
|
||||
• A <a href="/conversion">conversion matrix</a> that outlines all compatible values and versions
|
||||
<br>
|
||||
• An in-depth <a href="/user-guide">user guide</a> to use advanced features such as LoadBalancer, Service and TLS
|
||||
<br>
|
||||
• <a href="/user-guide#labels">Labels</a> that provide the extra 1% needed to get to 1-1 conversion
|
||||
</p>
|
||||
<a class="btn-action" href="/user-guide">User Guide</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-7">
|
||||
<div class="hero-img loop-video">
|
||||
<video class="embed-responsive drone-video" autoplay loop muted>
|
||||
<source src="assets/video/coding.webm" type="video/webm" />
|
||||
</video>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div><!-- Hero End -->
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{% include footer.html %}
|
||||
|
||||
</div> <!-- Main -->
|
||||
|
||||
|
||||
<!-- Jquery and Js Plugins -->
|
||||
<script src="assets/js/jquery-2.1.1.js"></script>
|
||||
<script src="assets/js/popper.min.js"></script>
|
||||
<script src="assets/js/jquery.validate.min.js"></script>
|
||||
<script src="assets/js/bootstrap.min.js"></script>
|
||||
<script src="assets/js/plugins.js"></script>
|
||||
<script src="assets/js/menu.js"></script>
|
||||
<script src="assets/js/custom.js"></script>
|
||||
<script>
|
||||
$('.navbar-nav>li>a').on('click', function(){
|
||||
|
||||
$('.navbar-collapse').collapse('hide');
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
2742
site/assets/css/animate.css
vendored
Normal file
7
site/assets/css/bootstrap.min.css
vendored
Normal file
1036
site/assets/css/github-markdown.css
Normal file
11
site/assets/css/ionicons.min.css
vendored
Normal file
63
site/assets/css/jquery.accordion.css
Normal file
@ -0,0 +1,63 @@
|
||||
/*!
|
||||
* jQuery Accordion 0.0.1
|
||||
* (c) 2014 Victor Fernandez <victor@vctrfrnndz.com>
|
||||
* MIT Licensed.
|
||||
*/
|
||||
|
||||
/* Requirements */
|
||||
|
||||
[data-accordion] [data-content] {
|
||||
overflow: hidden;
|
||||
max-height: 0;
|
||||
}
|
||||
|
||||
/* Basic Theme */
|
||||
|
||||
[data-accordion-group] {
|
||||
padding: 20px;
|
||||
box-shadow: 0 0px 15px rgba(0,0,0,0.06);
|
||||
}
|
||||
|
||||
[data-control] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
[data-accordion] {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
[data-control],
|
||||
[data-content] > * {
|
||||
border-bottom: 1px solid #EEE;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
[data-content] [data-accordion] {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
[data-accordion] [data-control] {
|
||||
position: relative;
|
||||
padding-right: 40px;
|
||||
}
|
||||
|
||||
[data-accordion] > [data-control]:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 12px;
|
||||
font-size: 25px;
|
||||
font-weight: 200;
|
||||
color: #444;
|
||||
height: 15px;
|
||||
width: 24px;
|
||||
background: url('../images/down.png') center center no-repeat;
|
||||
background-size: 50%;
|
||||
}
|
||||
|
||||
[data-accordion].open > [data-control]:after {
|
||||
-webkit-transform: rotate(-180deg);
|
||||
-ms-transform: rotate(-180deg);
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
351
site/assets/css/magnific-popup.css
Normal file
@ -0,0 +1,351 @@
|
||||
/* Magnific Popup CSS */
|
||||
.mfp-bg {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1042;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
background: #0b0b0b;
|
||||
opacity: 0.8; }
|
||||
|
||||
.mfp-wrap {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1043;
|
||||
position: fixed;
|
||||
outline: none !important;
|
||||
-webkit-backface-visibility: hidden; }
|
||||
|
||||
.mfp-container {
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
padding: 0 8px;
|
||||
box-sizing: border-box; }
|
||||
|
||||
.mfp-container:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
vertical-align: middle; }
|
||||
|
||||
.mfp-align-top .mfp-container:before {
|
||||
display: none; }
|
||||
|
||||
.mfp-content {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin: 0 auto;
|
||||
text-align: left;
|
||||
z-index: 1045; }
|
||||
|
||||
.mfp-inline-holder .mfp-content,
|
||||
.mfp-ajax-holder .mfp-content {
|
||||
width: 100%;
|
||||
cursor: auto; }
|
||||
|
||||
.mfp-ajax-cur {
|
||||
cursor: progress; }
|
||||
|
||||
.mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close {
|
||||
cursor: -moz-zoom-out;
|
||||
cursor: -webkit-zoom-out;
|
||||
cursor: zoom-out; }
|
||||
|
||||
.mfp-zoom {
|
||||
cursor: pointer;
|
||||
cursor: -webkit-zoom-in;
|
||||
cursor: -moz-zoom-in;
|
||||
cursor: zoom-in; }
|
||||
|
||||
.mfp-auto-cursor .mfp-content {
|
||||
cursor: auto; }
|
||||
|
||||
.mfp-close,
|
||||
.mfp-arrow,
|
||||
.mfp-preloader,
|
||||
.mfp-counter {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none; }
|
||||
|
||||
.mfp-loading.mfp-figure {
|
||||
display: none; }
|
||||
|
||||
.mfp-hide {
|
||||
display: none !important; }
|
||||
|
||||
.mfp-preloader {
|
||||
color: #CCC;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: auto;
|
||||
text-align: center;
|
||||
margin-top: -0.8em;
|
||||
left: 8px;
|
||||
right: 8px;
|
||||
z-index: 1044; }
|
||||
.mfp-preloader a {
|
||||
color: #CCC; }
|
||||
.mfp-preloader a:hover {
|
||||
color: #FFF; }
|
||||
|
||||
.mfp-s-ready .mfp-preloader {
|
||||
display: none; }
|
||||
|
||||
.mfp-s-error .mfp-content {
|
||||
display: none; }
|
||||
|
||||
button.mfp-close,
|
||||
button.mfp-arrow {
|
||||
overflow: visible;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
-webkit-appearance: none;
|
||||
display: block;
|
||||
outline: none;
|
||||
padding: 0;
|
||||
z-index: 1046;
|
||||
box-shadow: none;
|
||||
touch-action: manipulation; }
|
||||
|
||||
button::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border: 0; }
|
||||
|
||||
.mfp-close {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
line-height: 44px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
opacity: 0.65;
|
||||
padding: 0 0 18px 10px;
|
||||
color: #FFF;
|
||||
font-style: normal;
|
||||
font-size: 28px;
|
||||
font-family: Arial, Baskerville, monospace; }
|
||||
.mfp-close:hover,
|
||||
.mfp-close:focus {
|
||||
opacity: 1; }
|
||||
.mfp-close:active {
|
||||
top: 1px; }
|
||||
|
||||
.mfp-close-btn-in .mfp-close {
|
||||
color: #333; }
|
||||
|
||||
.mfp-image-holder .mfp-close,
|
||||
.mfp-iframe-holder .mfp-close {
|
||||
color: #FFF;
|
||||
right: -6px;
|
||||
text-align: right;
|
||||
padding-right: 6px;
|
||||
width: 100%; }
|
||||
|
||||
.mfp-counter {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
color: #CCC;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
white-space: nowrap; }
|
||||
|
||||
.mfp-arrow {
|
||||
position: absolute;
|
||||
opacity: 0.65;
|
||||
margin: 0;
|
||||
top: 50%;
|
||||
margin-top: -55px;
|
||||
padding: 0;
|
||||
width: 90px;
|
||||
height: 110px;
|
||||
-webkit-tap-highlight-color: transparent; }
|
||||
.mfp-arrow:active {
|
||||
margin-top: -54px; }
|
||||
.mfp-arrow:hover,
|
||||
.mfp-arrow:focus {
|
||||
opacity: 1; }
|
||||
.mfp-arrow:before,
|
||||
.mfp-arrow:after {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
margin-top: 35px;
|
||||
margin-left: 35px;
|
||||
border: medium inset transparent; }
|
||||
.mfp-arrow:after {
|
||||
border-top-width: 13px;
|
||||
border-bottom-width: 13px;
|
||||
top: 8px; }
|
||||
.mfp-arrow:before {
|
||||
border-top-width: 21px;
|
||||
border-bottom-width: 21px;
|
||||
opacity: 0.7; }
|
||||
|
||||
.mfp-arrow-left {
|
||||
left: 0; }
|
||||
.mfp-arrow-left:after {
|
||||
border-right: 17px solid #FFF;
|
||||
margin-left: 31px; }
|
||||
.mfp-arrow-left:before {
|
||||
margin-left: 25px;
|
||||
border-right: 27px solid #3F3F3F; }
|
||||
|
||||
.mfp-arrow-right {
|
||||
right: 0; }
|
||||
.mfp-arrow-right:after {
|
||||
border-left: 17px solid #FFF;
|
||||
margin-left: 39px; }
|
||||
.mfp-arrow-right:before {
|
||||
border-left: 27px solid #3F3F3F; }
|
||||
|
||||
.mfp-iframe-holder {
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px; }
|
||||
.mfp-iframe-holder .mfp-content {
|
||||
line-height: 0;
|
||||
width: 100%;
|
||||
max-width: 900px; }
|
||||
.mfp-iframe-holder .mfp-close {
|
||||
top: -40px; }
|
||||
|
||||
.mfp-iframe-scaler {
|
||||
width: 100%;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
padding-top: 56.25%; }
|
||||
.mfp-iframe-scaler iframe {
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
|
||||
background: #000; }
|
||||
|
||||
/* Main image in popup */
|
||||
img.mfp-img {
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
line-height: 0;
|
||||
box-sizing: border-box;
|
||||
padding: 40px 0 40px;
|
||||
margin: 0 auto; }
|
||||
|
||||
/* The shadow behind the image */
|
||||
.mfp-figure {
|
||||
line-height: 0; }
|
||||
.mfp-figure:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 40px;
|
||||
bottom: 40px;
|
||||
display: block;
|
||||
right: 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
z-index: -1;
|
||||
box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
|
||||
background: #444; }
|
||||
.mfp-figure small {
|
||||
color: #BDBDBD;
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
line-height: 14px; }
|
||||
.mfp-figure figure {
|
||||
margin: 0; }
|
||||
|
||||
.mfp-bottom-bar {
|
||||
margin-top: -36px;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
cursor: auto; }
|
||||
|
||||
.mfp-title {
|
||||
text-align: left;
|
||||
line-height: 18px;
|
||||
color: #F3F3F3;
|
||||
word-wrap: break-word;
|
||||
padding-right: 36px; }
|
||||
|
||||
.mfp-image-holder .mfp-content {
|
||||
max-width: 100%; }
|
||||
|
||||
.mfp-gallery .mfp-image-holder .mfp-figure {
|
||||
cursor: pointer; }
|
||||
|
||||
@media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) {
|
||||
/**
|
||||
* Remove all paddings around the image on small screen
|
||||
*/
|
||||
.mfp-img-mobile .mfp-image-holder {
|
||||
padding-left: 0;
|
||||
padding-right: 0; }
|
||||
.mfp-img-mobile img.mfp-img {
|
||||
padding: 0; }
|
||||
.mfp-img-mobile .mfp-figure:after {
|
||||
top: 0;
|
||||
bottom: 0; }
|
||||
.mfp-img-mobile .mfp-figure small {
|
||||
display: inline;
|
||||
margin-left: 5px; }
|
||||
.mfp-img-mobile .mfp-bottom-bar {
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
bottom: 0;
|
||||
margin: 0;
|
||||
top: auto;
|
||||
padding: 3px 5px;
|
||||
position: fixed;
|
||||
box-sizing: border-box; }
|
||||
.mfp-img-mobile .mfp-bottom-bar:empty {
|
||||
padding: 0; }
|
||||
.mfp-img-mobile .mfp-counter {
|
||||
right: 5px;
|
||||
top: 3px; }
|
||||
.mfp-img-mobile .mfp-close {
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
position: fixed;
|
||||
text-align: center;
|
||||
padding: 0; } }
|
||||
|
||||
@media all and (max-width: 900px) {
|
||||
.mfp-arrow {
|
||||
-webkit-transform: scale(0.75);
|
||||
transform: scale(0.75); }
|
||||
.mfp-arrow-left {
|
||||
-webkit-transform-origin: 0;
|
||||
transform-origin: 0; }
|
||||
.mfp-arrow-right {
|
||||
-webkit-transform-origin: 100%;
|
||||
transform-origin: 100%; }
|
||||
.mfp-container {
|
||||
padding-left: 6px;
|
||||
padding-right: 6px; } }
|
||||
71
site/assets/css/owl.carousel.css
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Core Owl Carousel CSS File
|
||||
* v1.3.3
|
||||
*/
|
||||
|
||||
/* clearfix */
|
||||
.owl-carousel .owl-wrapper:after {
|
||||
content: ".";
|
||||
display: block;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
line-height: 0;
|
||||
height: 0;
|
||||
}
|
||||
/* display none until init */
|
||||
.owl-carousel{
|
||||
display: none;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
-ms-touch-action: pan-y;
|
||||
}
|
||||
.owl-carousel .owl-wrapper{
|
||||
display: none;
|
||||
position: relative;
|
||||
-webkit-transform: translate3d(0px, 0px, 0px);
|
||||
}
|
||||
.owl-carousel .owl-wrapper-outer{
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
.owl-carousel .owl-wrapper-outer.autoHeight{
|
||||
-webkit-transition: height 500ms ease-in-out;
|
||||
-moz-transition: height 500ms ease-in-out;
|
||||
-ms-transition: height 500ms ease-in-out;
|
||||
-o-transition: height 500ms ease-in-out;
|
||||
transition: height 500ms ease-in-out;
|
||||
}
|
||||
|
||||
.owl-carousel .owl-item{
|
||||
float: left;
|
||||
}
|
||||
.owl-controls .owl-page,
|
||||
.owl-controls .owl-buttons div{
|
||||
cursor: pointer;
|
||||
}
|
||||
.owl-controls {
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* mouse grab icon */
|
||||
.grabbing {
|
||||
cursor:url(grabbing.png) 8 8, move;
|
||||
}
|
||||
|
||||
/* fix */
|
||||
.owl-carousel .owl-wrapper,
|
||||
.owl-carousel .owl-item{
|
||||
-webkit-backface-visibility: hidden;
|
||||
-moz-backface-visibility: hidden;
|
||||
-ms-backface-visibility: hidden;
|
||||
-webkit-transform: translate3d(0,0,0);
|
||||
-moz-transform: translate3d(0,0,0);
|
||||
-ms-transform: translate3d(0,0,0);
|
||||
}
|
||||
|
||||
79
site/assets/css/owl.theme.css
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Owl Carousel Owl Demo Theme
|
||||
* v1.3.3
|
||||
*/
|
||||
|
||||
.owl-theme .owl-controls{
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Styling Next and Prev buttons */
|
||||
|
||||
.owl-theme .owl-controls .owl-buttons div{
|
||||
color: #FFF;
|
||||
display: inline-block;
|
||||
zoom: 1;
|
||||
*display: inline;/*IE7 life-saver */
|
||||
margin: 5px;
|
||||
padding: 3px 10px;
|
||||
font-size: 12px;
|
||||
-webkit-border-radius: 30px;
|
||||
-moz-border-radius: 30px;
|
||||
border-radius: 30px;
|
||||
background: #869791;
|
||||
filter: Alpha(Opacity=50);/*IE7 fix*/
|
||||
opacity: 0.5;
|
||||
}
|
||||
/* Clickable class fix problem with hover on touch devices */
|
||||
/* Use it for non-touch hover action */
|
||||
.owl-theme .owl-controls.clickable .owl-buttons div:hover{
|
||||
filter: Alpha(Opacity=100);/*IE7 fix*/
|
||||
opacity: 1;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Styling Pagination*/
|
||||
|
||||
.owl-theme .owl-controls .owl-page{
|
||||
display: inline-block;
|
||||
zoom: 1;
|
||||
*display: inline;/*IE7 life-saver */
|
||||
}
|
||||
.owl-theme .owl-controls .owl-page span{
|
||||
display: block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin: 5px 7px;
|
||||
filter: Alpha(Opacity=50);/*IE7 fix*/
|
||||
opacity: 0.5;
|
||||
-webkit-border-radius: 20px;
|
||||
-moz-border-radius: 20px;
|
||||
border-radius: 20px;
|
||||
background: #869791;
|
||||
}
|
||||
|
||||
.owl-theme .owl-controls .owl-page.active span,
|
||||
.owl-theme .owl-controls.clickable .owl-page:hover span{
|
||||
filter: Alpha(Opacity=100);/*IE7 fix*/
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* If PaginationNumbers is true */
|
||||
|
||||
.owl-theme .owl-controls .owl-page span.owl-numbers{
|
||||
height: auto;
|
||||
width: auto;
|
||||
color: #FFF;
|
||||
padding: 2px 10px;
|
||||
font-size: 12px;
|
||||
-webkit-border-radius: 30px;
|
||||
-moz-border-radius: 30px;
|
||||
border-radius: 30px;
|
||||
}
|
||||
|
||||
/* preloading images */
|
||||
.owl-item.loading{
|
||||
min-height: 150px;
|
||||
background: url(AjaxLoader.gif) no-repeat center center
|
||||
}
|
||||
3706
site/assets/css/style.css
Normal file
BIN
site/assets/favicons/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
site/assets/favicons/android-chrome-256x256.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
site/assets/favicons/android-chrome-384x384.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
site/assets/favicons/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
9
site/assets/favicons/browserconfig.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/assets/favicons/mstile-150x150.png"/>
|
||||
<TileColor>#da532c</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
BIN
site/assets/favicons/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
site/assets/favicons/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
site/assets/favicons/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
site/assets/favicons/mstile-150x150.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
25
site/assets/favicons/safari-pinned-tab.svg
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="300.000000pt" height="300.000000pt" viewBox="0 0 300.000000 300.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.14, written by Peter Selinger 2001-2017
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,300.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M1450 2910 c-31 -9 -109 -45 -325 -150 -93 -45 -206 -99 -250 -120
|
||||
-44 -21 -147 -70 -230 -110 -82 -40 -177 -85 -210 -100 -96 -45 -130 -88 -150
|
||||
-190 -2 -8 -13 -55 -24 -105 -20 -83 -27 -114 -36 -155 -2 -8 -16 -67 -31
|
||||
-130 -14 -63 -34 -151 -44 -195 -14 -61 -105 -463 -113 -494 0 -3 2 -26 6 -51
|
||||
7 -42 61 -122 165 -245 9 -11 33 -40 52 -65 19 -25 40 -51 48 -58 7 -8 25 -30
|
||||
40 -50 15 -21 29 -39 32 -42 4 -3 33 -39 65 -80 71 -90 70 -88 98 -123 13 -15
|
||||
75 -92 137 -171 122 -153 158 -185 218 -195 20 -4 300 -6 622 -6 584 1 585 1
|
||||
630 23 38 19 99 90 410 478 201 251 373 473 383 493 19 41 18 97 -7 202 -17
|
||||
71 -56 245 -61 269 -2 8 -8 33 -13 55 -6 22 -13 51 -15 65 -3 14 -26 114 -51
|
||||
223 -25 109 -48 208 -50 220 -15 76 -50 205 -61 227 -29 55 -30 55 -530 295
|
||||
-66 31 -167 80 -225 108 -58 28 -107 52 -110 52 -3 1 -63 29 -134 64 -128 62
|
||||
-185 77 -236 61z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
19
site/assets/favicons/site.webmanifest
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "",
|
||||
"short_name": "",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/assets/favicons/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/assets/favicons/android-chrome-256x256.png",
|
||||
"sizes": "256x256",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
||||
BIN
site/assets/fonts/ionicons.eot
Normal file
2230
site/assets/fonts/ionicons.svg
Normal file
|
After Width: | Height: | Size: 326 KiB |
BIN
site/assets/fonts/ionicons.ttf
Normal file
BIN
site/assets/fonts/ionicons.woff
Normal file
BIN
site/assets/fonts/ionicons.woff2
Normal file
BIN
site/assets/icons/c1.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
BIN
site/assets/icons/c2.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
site/assets/icons/c3.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
site/assets/icons/c4.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
site/assets/icons/c5.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
site/assets/icons/fb.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
site/assets/icons/github.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
site/assets/icons/in.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
site/assets/icons/li.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
site/assets/icons/p1.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
site/assets/icons/p3.png
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
BIN
site/assets/icons/p6.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
site/assets/icons/rev.png
Normal file
|
After Width: | Height: | Size: 992 B |
BIN
site/assets/icons/rev2.png
Normal file
|
After Width: | Height: | Size: 992 B |
BIN
site/assets/icons/rev3.png
Normal file
|
After Width: | Height: | Size: 992 B |
BIN
site/assets/icons/slack.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
site/assets/icons/tt.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
site/assets/icons/tw.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
site/assets/icons/up.png
Normal file
|
After Width: | Height: | Size: 179 B |
BIN
site/assets/images/gh_engineer.jpg
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
site/assets/images/logo.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
site/assets/images/placeholder.jpg
Normal file
|
After Width: | Height: | Size: 319 KiB |
7
site/assets/js/bootstrap.min.js
vendored
Normal file
31
site/assets/js/contact.js
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
|
||||
$(function () {
|
||||
"use strict";
|
||||
|
||||
$('#contact-form').validator();
|
||||
|
||||
$('#contact-form').on('submit', function (e) {
|
||||
if (!e.isDefaultPrevented()) {
|
||||
var url = "assets/php/contact.php";
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: url,
|
||||
data: $(this).serialize(),
|
||||
success: function (data)
|
||||
{
|
||||
var messageAlert = 'alert-' + data.type;
|
||||
var messageText = data.message;
|
||||
|
||||
var alertBox = '<div class="alert ' + messageAlert + ' alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' + messageText + '</div>';
|
||||
if (messageAlert && messageText) {
|
||||
$('#contact-form').find('.messages').html(alertBox);
|
||||
$('#contact-form')[0].reset();
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
})
|
||||
});
|
||||
153
site/assets/js/custom.js
Normal file
@ -0,0 +1,153 @@
|
||||
// Custom Scripts for Primal Template //
|
||||
|
||||
jQuery(function($) {
|
||||
"use strict";
|
||||
|
||||
|
||||
// get the value of the bottom of the #main element by adding the offset of that element plus its height, set it as a variable
|
||||
var mainbottom = $('#main').offset().top;
|
||||
|
||||
// on scroll,
|
||||
$(window).on('scroll',function(){
|
||||
|
||||
// we round here to reduce a little workload
|
||||
stop = Math.round($(window).scrollTop());
|
||||
if (stop > mainbottom) {
|
||||
$('.navbar').addClass('past-main');
|
||||
$('.navbar').addClass('effect-main')
|
||||
} else {
|
||||
$('.navbar').removeClass('past-main');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
// Collapse navbar on click
|
||||
|
||||
$(document).on('click.nav','.navbar-collapse.in',function(e) {
|
||||
if( $(e.target).is('a') ) {
|
||||
$(this).removeClass('in').addClass('collapse');
|
||||
}
|
||||
});
|
||||
|
||||
/*-----------------------------------
|
||||
----------- Scroll To Top -----------
|
||||
------------------------------------*/
|
||||
|
||||
$(window).scroll(function () {
|
||||
if ($(this).scrollTop() > 1000) {
|
||||
$('#back-top').fadeIn();
|
||||
} else {
|
||||
$('#back-top').fadeOut();
|
||||
}
|
||||
});
|
||||
// scroll body to 0px on click
|
||||
$('#back-top').on('click', function () {
|
||||
$('#back-top').tooltip('hide');
|
||||
$('body,html').animate({
|
||||
scrollTop: 0
|
||||
}, 1500);
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
/*-------- Owl Carousel ---------- */
|
||||
$(".reviews").owlCarousel({
|
||||
|
||||
slideSpeed : 200,
|
||||
items: 1,
|
||||
singleItem: true,
|
||||
autoPlay : true,
|
||||
pagination : false
|
||||
});
|
||||
|
||||
|
||||
/*-------- Owl Carousel ---------- */
|
||||
$(".review-cards").owlCarousel({
|
||||
|
||||
slideSpeed : 200,
|
||||
items: 1,
|
||||
singleItem: true,
|
||||
autoPlay : true,
|
||||
pagination : false
|
||||
});
|
||||
|
||||
|
||||
/* ------ jQuery for Easing min -- */
|
||||
|
||||
// Smooth scrolling using jQuery easing
|
||||
$('a.js-scroll-trigger[href*="#"]:not([href="#"])').on('click', function () {
|
||||
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
|
||||
var target = $(this.hash);
|
||||
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
|
||||
if (target.length) {
|
||||
$('html, body').animate({
|
||||
scrollTop: (target.offset().top - 54)
|
||||
}, 1000, "easeInOutExpo");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/* --------- Wow Init ------ */
|
||||
|
||||
new WOW().init();
|
||||
|
||||
|
||||
/* ------ Countdown ----- */
|
||||
|
||||
$('#countdown').countdown({
|
||||
date: '12/12/2031 12:00:00',
|
||||
offset: +2,
|
||||
day: 'Day',
|
||||
days: 'Days'
|
||||
}, function () {
|
||||
alert('Done!');
|
||||
});
|
||||
|
||||
|
||||
/*----- Preloader ----- */
|
||||
|
||||
$(window).load(function() {
|
||||
setTimeout(function() {
|
||||
$('#loading').fadeOut('slow', function() {
|
||||
});
|
||||
}, 3000);
|
||||
});
|
||||
|
||||
|
||||
/*----- Subscription Form ----- */
|
||||
|
||||
$(document).ready(function() {
|
||||
// jQuery Validation
|
||||
$("#chimp-form").validate({
|
||||
// if valid, post data via AJAX
|
||||
submitHandler: function(form) {
|
||||
$.post("assets/php/subscribe.php", { email: $("#email").val() }, function(data) {
|
||||
$('#response').html(data);
|
||||
});
|
||||
},
|
||||
// all fields are required
|
||||
rules: {
|
||||
email: {
|
||||
required: true,
|
||||
email: true
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Accordion //
|
||||
|
||||
function toggleChevron(e) {
|
||||
$(e.target)
|
||||
.prev('.panel-heading')
|
||||
.find("span.glyphicon")
|
||||
.toggleClass('glyphicon-chevron-down glyphicon-chevron-right');
|
||||
}
|
||||
$('#accordion').on('hide.bs.collapse show.bs.collapse', toggleChevron);
|
||||
|
||||
|
||||
|
||||
});
|
||||
4
site/assets/js/jquery-2.1.1.js
vendored
Normal file
302
site/assets/js/jquery.accordion.js
Normal file
@ -0,0 +1,302 @@
|
||||
/*!
|
||||
* jQuery Accordion 0.0.1
|
||||
* (c) 2014 Victor Fernandez <victor@vctrfrnndz.com>
|
||||
* MIT Licensed.
|
||||
*/
|
||||
|
||||
;(function ( $, window, document, undefined ) {
|
||||
|
||||
var pluginName = 'accordion',
|
||||
defaults = {
|
||||
transitionSpeed: 300,
|
||||
transitionEasing: 'ease',
|
||||
controlElement: '[data-control]',
|
||||
contentElement: '[data-content]',
|
||||
groupElement: '[data-accordion-group]',
|
||||
singleOpen: true
|
||||
};
|
||||
|
||||
function Accordion(element, options) {
|
||||
this.element = element;
|
||||
this.options = $.extend({}, defaults, options);
|
||||
this._defaults = defaults;
|
||||
this._name = pluginName;
|
||||
this.init();
|
||||
}
|
||||
|
||||
Accordion.prototype.init = function () {
|
||||
var self = this,
|
||||
opts = self.options;
|
||||
|
||||
var $accordion = $(self.element),
|
||||
$controls = $accordion.find('> ' + opts.controlElement),
|
||||
$content = $accordion.find('> ' + opts.contentElement);
|
||||
|
||||
var accordionParentsQty = $accordion.parents('[data-accordion]').length,
|
||||
accordionHasParent = accordionParentsQty > 0;
|
||||
|
||||
var closedCSS = { 'max-height': 0, 'overflow': 'hidden' };
|
||||
|
||||
var CSStransitions = supportsTransitions();
|
||||
|
||||
function debounce(func, threshold, execAsap) {
|
||||
var timeout;
|
||||
|
||||
return function debounced() {
|
||||
var obj = this,
|
||||
args = arguments;
|
||||
|
||||
function delayed() {
|
||||
if (!execAsap) func.apply(obj, args);
|
||||
timeout = null;
|
||||
};
|
||||
|
||||
if (timeout) clearTimeout(timeout);
|
||||
else if (execAsap) func.apply(obj, args);
|
||||
|
||||
timeout = setTimeout(delayed, threshold || 100);
|
||||
};
|
||||
}
|
||||
|
||||
function supportsTransitions() {
|
||||
var b = document.body || document.documentElement,
|
||||
s = b.style,
|
||||
p = 'transition';
|
||||
|
||||
if (typeof s[p] == 'string') {
|
||||
return true;
|
||||
}
|
||||
|
||||
var v = ['Moz', 'webkit', 'Webkit', 'Khtml', 'O', 'ms'];
|
||||
|
||||
p = 'Transition';
|
||||
|
||||
for (var i=0; i<v.length; i++) {
|
||||
if (typeof s[v[i] + p] == 'string') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function requestAnimFrame(cb) {
|
||||
if(window.requestAnimationFrame){
|
||||
requestAnimationFrame(cb);
|
||||
} else if (window.webkitRequestAnimationFrame) {
|
||||
webkitRequestAnimationFrame(cb);
|
||||
} else if (window.mozRequestAnimationFrame) {
|
||||
mozRequestAnimationFrame(cb);
|
||||
} else {
|
||||
setTimeout(cb, 1000 / 60);
|
||||
}
|
||||
}
|
||||
|
||||
function toggleTransition($el, remove) {
|
||||
if(!remove) {
|
||||
$content.css({
|
||||
'-webkit-transition': 'max-height ' + opts.transitionSpeed + 'ms ' + opts.transitionEasing,
|
||||
'transition': 'max-height ' + opts.transitionSpeed + 'ms ' + opts.transitionEasing
|
||||
});
|
||||
} else {
|
||||
$content.css({
|
||||
'-webkit-transition': '',
|
||||
'transition': ''
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function calculateHeight($el) {
|
||||
var height = 0;
|
||||
|
||||
$el.children().each(function() {
|
||||
height = height + $(this).outerHeight(true);
|
||||
});
|
||||
|
||||
$el.data('oHeight', height);
|
||||
}
|
||||
|
||||
function updateParentHeight($parentAccordion, $currentAccordion, qty, operation) {
|
||||
var $content = $parentAccordion.filter('.open').find('> [data-content]'),
|
||||
$childs = $content.find('[data-accordion].open > [data-content]'),
|
||||
$matched;
|
||||
|
||||
if(!opts.singleOpen) {
|
||||
$childs = $childs.not($currentAccordion.siblings('[data-accordion].open').find('> [data-content]'));
|
||||
}
|
||||
|
||||
$matched = $content.add($childs);
|
||||
|
||||
if($parentAccordion.hasClass('open')) {
|
||||
$matched.each(function() {
|
||||
var currentHeight = $(this).data('oHeight');
|
||||
|
||||
switch (operation) {
|
||||
case '+':
|
||||
$(this).data('oHeight', currentHeight + qty);
|
||||
break;
|
||||
case '-':
|
||||
$(this).data('oHeight', currentHeight - qty);
|
||||
break;
|
||||
default:
|
||||
throw 'updateParentHeight method needs an operation';
|
||||
}
|
||||
|
||||
$(this).css('max-height', $(this).data('oHeight'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function refreshHeight($accordion) {
|
||||
if($accordion.hasClass('open')) {
|
||||
var $content = $accordion.find('> [data-content]'),
|
||||
$childs = $content.find('[data-accordion].open > [data-content]'),
|
||||
$matched = $content.add($childs);
|
||||
|
||||
calculateHeight($matched);
|
||||
|
||||
$matched.css('max-height', $matched.data('oHeight'));
|
||||
}
|
||||
}
|
||||
|
||||
function closeAccordion($accordion, $content) {
|
||||
$accordion.trigger('accordion.close');
|
||||
|
||||
if(CSStransitions) {
|
||||
if(accordionHasParent) {
|
||||
var $parentAccordions = $accordion.parents('[data-accordion]');
|
||||
|
||||
updateParentHeight($parentAccordions, $accordion, $content.data('oHeight'), '-');
|
||||
}
|
||||
|
||||
$content.css(closedCSS);
|
||||
|
||||
$accordion.removeClass('open');
|
||||
} else {
|
||||
$content.css('max-height', $content.data('oHeight'));
|
||||
|
||||
$content.animate(closedCSS, opts.transitionSpeed);
|
||||
|
||||
$accordion.removeClass('open');
|
||||
}
|
||||
}
|
||||
|
||||
function openAccordion($accordion, $content) {
|
||||
$accordion.trigger('accordion.open');
|
||||
if(CSStransitions) {
|
||||
toggleTransition($content);
|
||||
|
||||
if(accordionHasParent) {
|
||||
var $parentAccordions = $accordion.parents('[data-accordion]');
|
||||
|
||||
updateParentHeight($parentAccordions, $accordion, $content.data('oHeight'), '+');
|
||||
}
|
||||
|
||||
requestAnimFrame(function() {
|
||||
$content.css('max-height', $content.data('oHeight'));
|
||||
});
|
||||
|
||||
$accordion.addClass('open');
|
||||
} else {
|
||||
$content.animate({
|
||||
'max-height': $content.data('oHeight')
|
||||
}, opts.transitionSpeed, function() {
|
||||
$content.css({'max-height': 'none'});
|
||||
});
|
||||
|
||||
$accordion.addClass('open');
|
||||
}
|
||||
}
|
||||
|
||||
function closeSiblingAccordions($accordion) {
|
||||
var $accordionGroup = $accordion.closest(opts.groupElement);
|
||||
|
||||
var $siblings = $accordion.siblings('[data-accordion]').filter('.open'),
|
||||
$siblingsChildren = $siblings.find('[data-accordion]').filter('.open');
|
||||
|
||||
var $otherAccordions = $siblings.add($siblingsChildren);
|
||||
|
||||
$otherAccordions.each(function() {
|
||||
var $accordion = $(this),
|
||||
$content = $accordion.find(opts.contentElement);
|
||||
|
||||
closeAccordion($accordion, $content);
|
||||
});
|
||||
|
||||
$otherAccordions.removeClass('open');
|
||||
}
|
||||
|
||||
function toggleAccordion() {
|
||||
var isAccordionGroup = (opts.singleOpen) ? $accordion.parents(opts.groupElement).length > 0 : false;
|
||||
|
||||
calculateHeight($content);
|
||||
|
||||
if(isAccordionGroup) {
|
||||
closeSiblingAccordions($accordion);
|
||||
}
|
||||
|
||||
if($accordion.hasClass('open')) {
|
||||
closeAccordion($accordion, $content);
|
||||
} else {
|
||||
openAccordion($accordion, $content);
|
||||
}
|
||||
}
|
||||
|
||||
function addEventListeners() {
|
||||
$controls.on('click', toggleAccordion);
|
||||
|
||||
$controls.on('accordion.toggle', function() {
|
||||
if(opts.singleOpen && $controls.length > 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
toggleAccordion();
|
||||
});
|
||||
|
||||
$controls.on('accordion.refresh', function() {
|
||||
refreshHeight($accordion);
|
||||
});
|
||||
|
||||
$(window).on('resize', debounce(function() {
|
||||
refreshHeight($accordion);
|
||||
}));
|
||||
}
|
||||
|
||||
function setup() {
|
||||
$content.each(function() {
|
||||
var $curr = $(this);
|
||||
|
||||
if($curr.css('max-height') != 0) {
|
||||
if(!$curr.closest('[data-accordion]').hasClass('open')) {
|
||||
$curr.css({ 'max-height': 0, 'overflow': 'hidden' });
|
||||
} else {
|
||||
toggleTransition($curr);
|
||||
calculateHeight($curr);
|
||||
|
||||
$curr.css('max-height', $curr.data('oHeight'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if(!$accordion.attr('data-accordion')) {
|
||||
$accordion.attr('data-accordion', '');
|
||||
$accordion.find(opts.controlElement).attr('data-control', '');
|
||||
$accordion.find(opts.contentElement).attr('data-content', '');
|
||||
}
|
||||
}
|
||||
|
||||
setup();
|
||||
addEventListeners();
|
||||
};
|
||||
|
||||
$.fn[pluginName] = function ( options ) {
|
||||
return this.each(function () {
|
||||
if (!$.data(this, 'plugin_' + pluginName)) {
|
||||
$.data(this, 'plugin_' + pluginName,
|
||||
new Accordion( this, options ));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
})( jQuery, window, document );
|
||||
4
site/assets/js/jquery.validate.min.js
vendored
Normal file
233
site/assets/js/live.js
Normal file
@ -0,0 +1,233 @@
|
||||
/*
|
||||
Live.js - One script closer to Designing in the Browser
|
||||
Written for Handcraft.com by Martin Kool (@mrtnkl).
|
||||
|
||||
Version 4.
|
||||
Recent change: Made stylesheet and mimetype checks case insensitive.
|
||||
|
||||
http://livejs.com
|
||||
http://livejs.com/license (MIT)
|
||||
@livejs
|
||||
|
||||
Include live.js#css to monitor css changes only.
|
||||
Include live.js#js to monitor js changes only.
|
||||
Include live.js#html to monitor html changes only.
|
||||
Mix and match to monitor a preferred combination such as live.js#html,css
|
||||
|
||||
By default, just include live.js to monitor all css, js and html changes.
|
||||
|
||||
Live.js can also be loaded as a bookmarklet. It is best to only use it for CSS then,
|
||||
as a page reload due to a change in html or css would not re-include the bookmarklet.
|
||||
To monitor CSS and be notified that it has loaded, include it as: live.js#css,notify
|
||||
*/
|
||||
(function () {
|
||||
|
||||
var headers = { "Etag": 1, "Last-Modified": 1, "Content-Length": 1, "Content-Type": 1 },
|
||||
resources = {},
|
||||
pendingRequests = {},
|
||||
currentLinkElements = {},
|
||||
oldLinkElements = {},
|
||||
interval = 1000,
|
||||
loaded = false,
|
||||
active = { "html": 1, "css": 1, "js": 1 };
|
||||
|
||||
var Live = {
|
||||
|
||||
// performs a cycle per interval
|
||||
heartbeat: function () {
|
||||
if (document.body) {
|
||||
// make sure all resources are loaded on first activation
|
||||
if (!loaded) Live.loadresources();
|
||||
Live.checkForChanges();
|
||||
}
|
||||
setTimeout(Live.heartbeat, interval);
|
||||
},
|
||||
|
||||
// loads all local css and js resources upon first activation
|
||||
loadresources: function () {
|
||||
|
||||
// helper method to assert if a given url is local
|
||||
function isLocal(url) {
|
||||
var loc = document.location,
|
||||
reg = new RegExp("^\\.|^\/(?!\/)|^[\\w]((?!://).)*$|" + loc.protocol + "//" + loc.host);
|
||||
return url.match(reg);
|
||||
}
|
||||
|
||||
// gather all resources
|
||||
var scripts = document.getElementsByTagName("script"),
|
||||
links = document.getElementsByTagName("link"),
|
||||
uris = [];
|
||||
|
||||
// track local js urls
|
||||
for (var i = 0; i < scripts.length; i++) {
|
||||
var script = scripts[i], src = script.getAttribute("src");
|
||||
if (src && isLocal(src))
|
||||
uris.push(src);
|
||||
if (src && src.match(/\blive.js#/)) {
|
||||
for (var type in active)
|
||||
active[type] = src.match("[#,|]" + type) != null
|
||||
if (src.match("notify"))
|
||||
alert("Live.js is loaded.");
|
||||
}
|
||||
}
|
||||
if (!active.js) uris = [];
|
||||
if (active.html) uris.push(document.location.href);
|
||||
|
||||
// track local css urls
|
||||
for (var i = 0; i < links.length && active.css; i++) {
|
||||
var link = links[i], rel = link.getAttribute("rel"), href = link.getAttribute("href", 2);
|
||||
if (href && rel && rel.match(new RegExp("stylesheet", "i")) && isLocal(href)) {
|
||||
uris.push(href);
|
||||
currentLinkElements[href] = link;
|
||||
}
|
||||
}
|
||||
|
||||
// initialize the resources info
|
||||
for (var i = 0; i < uris.length; i++) {
|
||||
var url = uris[i];
|
||||
Live.getHead(url, function (url, info) {
|
||||
resources[url] = info;
|
||||
});
|
||||
}
|
||||
|
||||
// add rule for morphing between old and new css files
|
||||
var head = document.getElementsByTagName("head")[0],
|
||||
style = document.createElement("style"),
|
||||
rule = "transition: all .3s ease-out;"
|
||||
css = [".livejs-loading * { ", rule, " -webkit-", rule, "-moz-", rule, "-o-", rule, "}"].join('');
|
||||
style.setAttribute("type", "text/css");
|
||||
head.appendChild(style);
|
||||
style.styleSheet ? style.styleSheet.cssText = css : style.appendChild(document.createTextNode(css));
|
||||
|
||||
// yep
|
||||
loaded = true;
|
||||
},
|
||||
|
||||
// check all tracking resources for changes
|
||||
checkForChanges: function () {
|
||||
for (var url in resources) {
|
||||
if (pendingRequests[url])
|
||||
continue;
|
||||
|
||||
Live.getHead(url, function (url, newInfo) {
|
||||
var oldInfo = resources[url],
|
||||
hasChanged = false;
|
||||
resources[url] = newInfo;
|
||||
for (var header in oldInfo) {
|
||||
// do verification based on the header type
|
||||
var oldValue = oldInfo[header],
|
||||
newValue = newInfo[header],
|
||||
contentType = newInfo["Content-Type"];
|
||||
switch (header.toLowerCase()) {
|
||||
case "etag":
|
||||
if (!newValue) break;
|
||||
// fall through to default
|
||||
default:
|
||||
hasChanged = oldValue != newValue;
|
||||
break;
|
||||
}
|
||||
// if changed, act
|
||||
if (hasChanged) {
|
||||
Live.refreshResource(url, contentType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// act upon a changed url of certain content type
|
||||
refreshResource: function (url, type) {
|
||||
switch (type.toLowerCase()) {
|
||||
// css files can be reloaded dynamically by replacing the link element
|
||||
case "text/css":
|
||||
var link = currentLinkElements[url],
|
||||
html = document.body.parentNode,
|
||||
head = link.parentNode,
|
||||
next = link.nextSibling,
|
||||
newLink = document.createElement("link");
|
||||
|
||||
html.className = html.className.replace(/\s*livejs\-loading/gi, '') + ' livejs-loading';
|
||||
newLink.setAttribute("type", "text/css");
|
||||
newLink.setAttribute("rel", "stylesheet");
|
||||
newLink.setAttribute("href", url + "?now=" + new Date() * 1);
|
||||
next ? head.insertBefore(newLink, next) : head.appendChild(newLink);
|
||||
currentLinkElements[url] = newLink;
|
||||
oldLinkElements[url] = link;
|
||||
|
||||
// schedule removal of the old link
|
||||
Live.removeoldLinkElements();
|
||||
break;
|
||||
|
||||
// check if an html resource is our current url, then reload
|
||||
case "text/html":
|
||||
if (url != document.location.href)
|
||||
return;
|
||||
|
||||
// local javascript changes cause a reload as well
|
||||
case "text/javascript":
|
||||
case "application/javascript":
|
||||
case "application/x-javascript":
|
||||
document.location.reload();
|
||||
}
|
||||
},
|
||||
|
||||
// removes the old stylesheet rules only once the new one has finished loading
|
||||
removeoldLinkElements: function () {
|
||||
var pending = 0;
|
||||
for (var url in oldLinkElements) {
|
||||
// if this sheet has any cssRules, delete the old link
|
||||
try {
|
||||
var link = currentLinkElements[url],
|
||||
oldLink = oldLinkElements[url],
|
||||
html = document.body.parentNode,
|
||||
sheet = link.sheet || link.styleSheet,
|
||||
rules = sheet.rules || sheet.cssRules;
|
||||
if (rules.length >= 0) {
|
||||
oldLink.parentNode.removeChild(oldLink);
|
||||
delete oldLinkElements[url];
|
||||
setTimeout(function () {
|
||||
html.className = html.className.replace(/\s*livejs\-loading/gi, '');
|
||||
}, 100);
|
||||
}
|
||||
} catch (e) {
|
||||
pending++;
|
||||
}
|
||||
if (pending) setTimeout(Live.removeoldLinkElements, 50);
|
||||
}
|
||||
},
|
||||
|
||||
// performs a HEAD request and passes the header info to the given callback
|
||||
getHead: function (url, callback) {
|
||||
pendingRequests[url] = true;
|
||||
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XmlHttp");
|
||||
xhr.open("HEAD", url, true);
|
||||
xhr.onreadystatechange = function () {
|
||||
delete pendingRequests[url];
|
||||
if (xhr.readyState == 4 && xhr.status != 304) {
|
||||
xhr.getAllResponseHeaders();
|
||||
var info = {};
|
||||
for (var h in headers) {
|
||||
var value = xhr.getResponseHeader(h);
|
||||
// adjust the simple Etag variant to match on its significant part
|
||||
if (h.toLowerCase() == "etag" && value) value = value.replace(/^W\//, '');
|
||||
if (h.toLowerCase() == "content-type" && value) value = value.replace(/^(.*?);.*?$/i, "$1");
|
||||
info[h] = value;
|
||||
}
|
||||
callback(url, info);
|
||||
}
|
||||
}
|
||||
xhr.send();
|
||||
}
|
||||
};
|
||||
|
||||
// start listening
|
||||
if (document.location.protocol != "file:") {
|
||||
if (!window.liveJsLoaded)
|
||||
Live.heartbeat();
|
||||
|
||||
window.liveJsLoaded = true;
|
||||
}
|
||||
else if (window.console)
|
||||
console.log("Live.js doesn't support the file protocol. It needs http.");
|
||||
})();
|
||||
37
site/assets/js/menu-2.js
Normal file
@ -0,0 +1,37 @@
|
||||
jQuery(document).ready(function($){
|
||||
var $lateral_menu_trigger = $('.nav-trigger'),
|
||||
$content_wrapper = $('.main');
|
||||
|
||||
//open-close lateral menu clicking on the menu icon
|
||||
$lateral_menu_trigger.on('click', function(event){
|
||||
event.preventDefault();
|
||||
|
||||
$lateral_menu_trigger.toggleClass('is-open');
|
||||
$content_wrapper.toggleClass('is-open').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
|
||||
// firefox transitions break when parent overflow is changed, so we need to wait for the end of the trasition to give the body an overflow hidden
|
||||
$('body').toggleClass('overflow-hidden');
|
||||
});
|
||||
$('.menu-inner').toggleClass('is-open');
|
||||
|
||||
//check if transitions are not supported - i.e. in IE9
|
||||
if($('html').hasClass('no-csstransitions')) {
|
||||
$('body').toggleClass('overflow-hidden');
|
||||
}
|
||||
});
|
||||
|
||||
//close lateral menu clicking outside the menu itself
|
||||
$content_wrapper.on('mouseover', function(event){
|
||||
if( !$(event.target).is('.nav-trigger, .nav-trigger span') ) {
|
||||
$lateral_menu_trigger.removeClass('is-open');
|
||||
$content_wrapper.removeClass('is-open').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
|
||||
$('body').removeClass('overflow-hidden');
|
||||
});
|
||||
$('.menu-inner').removeClass('is-open');
|
||||
//check if transitions are not supported
|
||||
if($('html').hasClass('no-csstransitions')) {
|
||||
$('body').removeClass('overflow-hidden');
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
39
site/assets/js/menu.js
Normal file
@ -0,0 +1,39 @@
|
||||
/* ---- Menu Section For Fold Personal Portfolio HTML Template --- */
|
||||
|
||||
jQuery(document).ready(function($){
|
||||
var $lateral_menu_trigger = $('.nav-trigger'),
|
||||
$content_wrapper = $('.main');
|
||||
|
||||
//open-close lateral menu clicking on the menu icon
|
||||
$lateral_menu_trigger.on('click', function(event){
|
||||
event.preventDefault();
|
||||
|
||||
$lateral_menu_trigger.toggleClass('is-active');
|
||||
$content_wrapper.toggleClass('is-active').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
|
||||
// firefox transitions break when parent overflow is changed, so we need to wait for the end of the trasition to give the body an overflow hidden
|
||||
$('body').toggleClass('overflow-hidden');
|
||||
});
|
||||
$('#fld-nav').toggleClass('is-active');
|
||||
|
||||
//check if transitions are not supported - i.e. in IE9
|
||||
if($('html').hasClass('no-csstransitions')) {
|
||||
$('body').toggleClass('overflow-hidden');
|
||||
}
|
||||
});
|
||||
|
||||
//close lateral menu clicking outside the menu itself
|
||||
$content_wrapper.on('mouseover', function(event){
|
||||
if( !$(event.target).is('.nav-trigger, .nav-trigger span') ) {
|
||||
$lateral_menu_trigger.removeClass('is-active');
|
||||
$content_wrapper.removeClass('is-active').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
|
||||
$('body').removeClass('overflow-hidden');
|
||||
});
|
||||
$('#fld-nav').removeClass('is-active');
|
||||
//check if transitions are not supported
|
||||
if($('html').hasClass('no-csstransitions')) {
|
||||
$('body').removeClass('overflow-hidden');
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
985
site/assets/js/plugins.js
Normal file
4
site/assets/js/popper.min.js
vendored
Normal file
362
site/assets/js/validator.js
Normal file
@ -0,0 +1,362 @@
|
||||
|
||||
/* ========================================================================
|
||||
* Bootstrap (plugin): validator.js v0.10.2
|
||||
* ========================================================================
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Cina Saffary.
|
||||
* Made by @1000hz in the style of Bootstrap 3 era @fat
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// VALIDATOR CLASS DEFINITION
|
||||
// ==========================
|
||||
|
||||
function getValue($el) {
|
||||
return $el.is('[type="checkbox"]') ? $el.prop('checked') :
|
||||
$el.is('[type="radio"]') ? !!$('[name="' + $el.attr('name') + '"]:checked').length :
|
||||
$.trim($el.val())
|
||||
}
|
||||
|
||||
var Validator = function (element, options) {
|
||||
this.options = options
|
||||
this.$element = $(element)
|
||||
this.$inputs = this.$element.find(Validator.INPUT_SELECTOR)
|
||||
this.$btn = $('button[type="submit"], input[type="submit"]')
|
||||
.filter('[form="' + this.$element.attr('id') + '"]')
|
||||
.add(this.$element.find('input[type="submit"], button[type="submit"]'))
|
||||
|
||||
options.errors = $.extend({}, Validator.DEFAULTS.errors, options.errors)
|
||||
|
||||
for (var custom in options.custom) {
|
||||
if (!options.errors[custom]) throw new Error('Missing default error message for custom validator: ' + custom)
|
||||
}
|
||||
|
||||
$.extend(Validator.VALIDATORS, options.custom)
|
||||
|
||||
this.$element.attr('novalidate', true) // disable automatic native validation
|
||||
this.toggleSubmit()
|
||||
|
||||
this.$element.on('input.bs.validator change.bs.validator focusout.bs.validator', Validator.INPUT_SELECTOR, $.proxy(this.onInput, this))
|
||||
this.$element.on('submit.bs.validator', $.proxy(this.onSubmit, this))
|
||||
|
||||
this.$element.find('[data-match]').each(function () {
|
||||
var $this = $(this)
|
||||
var target = $this.data('match')
|
||||
|
||||
$(target).on('input.bs.validator', function (e) {
|
||||
getValue($this) && $this.trigger('input.bs.validator')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Validator.INPUT_SELECTOR = ':input:not([type="submit"], button):enabled:visible'
|
||||
|
||||
Validator.FOCUS_OFFSET = 20
|
||||
|
||||
Validator.DEFAULTS = {
|
||||
delay: 500,
|
||||
html: false,
|
||||
disable: true,
|
||||
focus: true,
|
||||
custom: {},
|
||||
errors: {
|
||||
match: 'Does not match',
|
||||
minlength: 'Not long enough'
|
||||
},
|
||||
feedback: {
|
||||
success: 'glyphicon-ok',
|
||||
error: 'glyphicon-remove'
|
||||
}
|
||||
}
|
||||
|
||||
Validator.VALIDATORS = {
|
||||
'native': function ($el) {
|
||||
var el = $el[0]
|
||||
return el.checkValidity ? el.checkValidity() : true
|
||||
},
|
||||
'match': function ($el) {
|
||||
var target = $el.data('match')
|
||||
return !$el.val() || $el.val() === $(target).val()
|
||||
},
|
||||
'minlength': function ($el) {
|
||||
var minlength = $el.data('minlength')
|
||||
return !$el.val() || $el.val().length >= minlength
|
||||
}
|
||||
}
|
||||
|
||||
Validator.prototype.onInput = function (e) {
|
||||
var self = this
|
||||
var $el = $(e.target)
|
||||
var deferErrors = e.type !== 'focusout'
|
||||
this.validateInput($el, deferErrors).done(function () {
|
||||
self.toggleSubmit()
|
||||
})
|
||||
}
|
||||
|
||||
Validator.prototype.validateInput = function ($el, deferErrors) {
|
||||
var value = getValue($el)
|
||||
var prevValue = $el.data('bs.validator.previous')
|
||||
var prevErrors = $el.data('bs.validator.errors')
|
||||
var errors
|
||||
|
||||
if (prevValue === value) return $.Deferred().resolve()
|
||||
else $el.data('bs.validator.previous', value)
|
||||
|
||||
if ($el.is('[type="radio"]')) $el = this.$element.find('input[name="' + $el.attr('name') + '"]')
|
||||
|
||||
var e = $.Event('validate.bs.validator', {relatedTarget: $el[0]})
|
||||
this.$element.trigger(e)
|
||||
if (e.isDefaultPrevented()) return
|
||||
|
||||
var self = this
|
||||
|
||||
return this.runValidators($el).done(function (errors) {
|
||||
$el.data('bs.validator.errors', errors)
|
||||
|
||||
errors.length
|
||||
? deferErrors ? self.defer($el, self.showErrors) : self.showErrors($el)
|
||||
: self.clearErrors($el)
|
||||
|
||||
if (!prevErrors || errors.toString() !== prevErrors.toString()) {
|
||||
e = errors.length
|
||||
? $.Event('invalid.bs.validator', {relatedTarget: $el[0], detail: errors})
|
||||
: $.Event('valid.bs.validator', {relatedTarget: $el[0], detail: prevErrors})
|
||||
|
||||
self.$element.trigger(e)
|
||||
}
|
||||
|
||||
self.toggleSubmit()
|
||||
|
||||
self.$element.trigger($.Event('validated.bs.validator', {relatedTarget: $el[0]}))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Validator.prototype.runValidators = function ($el) {
|
||||
var errors = []
|
||||
var deferred = $.Deferred()
|
||||
var options = this.options
|
||||
|
||||
$el.data('bs.validator.deferred') && $el.data('bs.validator.deferred').reject()
|
||||
$el.data('bs.validator.deferred', deferred)
|
||||
|
||||
function getErrorMessage(key) {
|
||||
return $el.data(key + '-error')
|
||||
|| $el.data('error')
|
||||
|| key == 'native' && $el[0].validationMessage
|
||||
|| options.errors[key]
|
||||
}
|
||||
|
||||
$.each(Validator.VALIDATORS, $.proxy(function (key, validator) {
|
||||
if ((getValue($el) || $el.attr('required')) &&
|
||||
($el.data(key) || key == 'native') &&
|
||||
!validator.call(this, $el)) {
|
||||
var error = getErrorMessage(key)
|
||||
!~errors.indexOf(error) && errors.push(error)
|
||||
}
|
||||
}, this))
|
||||
|
||||
if (!errors.length && getValue($el) && $el.data('remote')) {
|
||||
this.defer($el, function () {
|
||||
var data = {}
|
||||
data[$el.attr('name')] = getValue($el)
|
||||
$.get($el.data('remote'), data)
|
||||
.fail(function (jqXHR, textStatus, error) { errors.push(getErrorMessage('remote') || error) })
|
||||
.always(function () { deferred.resolve(errors)})
|
||||
})
|
||||
} else deferred.resolve(errors)
|
||||
|
||||
return deferred.promise()
|
||||
}
|
||||
|
||||
Validator.prototype.validate = function () {
|
||||
var self = this
|
||||
|
||||
$.when(this.$inputs.map(function (el) {
|
||||
return self.validateInput($(this), false)
|
||||
})).then(function () {
|
||||
self.toggleSubmit()
|
||||
self.focusError()
|
||||
})
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
Validator.prototype.focusError = function () {
|
||||
if (!this.options.focus) return
|
||||
|
||||
var $input = $(".has-error:first :input")
|
||||
if ($input.length === 0) return
|
||||
|
||||
$(document.body).animate({scrollTop: $input.offset().top - Validator.FOCUS_OFFSET}, 250)
|
||||
$input.focus()
|
||||
}
|
||||
|
||||
Validator.prototype.showErrors = function ($el) {
|
||||
var method = this.options.html ? 'html' : 'text'
|
||||
var errors = $el.data('bs.validator.errors')
|
||||
var $group = $el.closest('.form-group')
|
||||
var $block = $group.find('.help-block.with-errors')
|
||||
var $feedback = $group.find('.form-control-feedback')
|
||||
|
||||
if (!errors.length) return
|
||||
|
||||
errors = $('<ul/>')
|
||||
.addClass('list-unstyled')
|
||||
.append($.map(errors, function (error) { return $('<li/>')[method](error) }))
|
||||
|
||||
$block.data('bs.validator.originalContent') === undefined && $block.data('bs.validator.originalContent', $block.html())
|
||||
$block.empty().append(errors)
|
||||
$group.addClass('has-error has-danger')
|
||||
|
||||
$group.hasClass('has-feedback')
|
||||
&& $feedback.removeClass(this.options.feedback.success)
|
||||
&& $feedback.addClass(this.options.feedback.error)
|
||||
&& $group.removeClass('has-success')
|
||||
}
|
||||
|
||||
Validator.prototype.clearErrors = function ($el) {
|
||||
var $group = $el.closest('.form-group')
|
||||
var $block = $group.find('.help-block.with-errors')
|
||||
var $feedback = $group.find('.form-control-feedback')
|
||||
|
||||
$block.html($block.data('bs.validator.originalContent'))
|
||||
$group.removeClass('has-error has-danger')
|
||||
|
||||
$group.hasClass('has-feedback')
|
||||
&& $feedback.removeClass(this.options.feedback.error)
|
||||
&& getValue($el)
|
||||
&& $feedback.addClass(this.options.feedback.success)
|
||||
&& $group.addClass('has-success')
|
||||
}
|
||||
|
||||
Validator.prototype.hasErrors = function () {
|
||||
function fieldErrors() {
|
||||
return !!($(this).data('bs.validator.errors') || []).length
|
||||
}
|
||||
|
||||
return !!this.$inputs.filter(fieldErrors).length
|
||||
}
|
||||
|
||||
Validator.prototype.isIncomplete = function () {
|
||||
function fieldIncomplete() {
|
||||
return !getValue($(this))
|
||||
}
|
||||
|
||||
return !!this.$inputs.filter('[required]').filter(fieldIncomplete).length
|
||||
}
|
||||
|
||||
Validator.prototype.onSubmit = function (e) {
|
||||
this.validate()
|
||||
if (this.isIncomplete() || this.hasErrors()) e.preventDefault()
|
||||
}
|
||||
|
||||
Validator.prototype.toggleSubmit = function () {
|
||||
if (!this.options.disable) return
|
||||
this.$btn.toggleClass('disabled', this.isIncomplete() || this.hasErrors())
|
||||
}
|
||||
|
||||
Validator.prototype.defer = function ($el, callback) {
|
||||
callback = $.proxy(callback, this, $el)
|
||||
if (!this.options.delay) return callback()
|
||||
window.clearTimeout($el.data('bs.validator.timeout'))
|
||||
$el.data('bs.validator.timeout', window.setTimeout(callback, this.options.delay))
|
||||
}
|
||||
|
||||
Validator.prototype.destroy = function () {
|
||||
this.$element
|
||||
.removeAttr('novalidate')
|
||||
.removeData('bs.validator')
|
||||
.off('.bs.validator')
|
||||
.find('.form-control-feedback')
|
||||
.removeClass([this.options.feedback.error, this.options.feedback.success].join(' '))
|
||||
|
||||
this.$inputs
|
||||
.off('.bs.validator')
|
||||
.removeData(['bs.validator.errors', 'bs.validator.deferred', 'bs.validator.previous'])
|
||||
.each(function () {
|
||||
var $this = $(this)
|
||||
var timeout = $this.data('bs.validator.timeout')
|
||||
window.clearTimeout(timeout) && $this.removeData('bs.validator.timeout')
|
||||
})
|
||||
|
||||
this.$element.find('.help-block.with-errors').each(function () {
|
||||
var $this = $(this)
|
||||
var originalContent = $this.data('bs.validator.originalContent')
|
||||
|
||||
$this
|
||||
.removeData('bs.validator.originalContent')
|
||||
.html(originalContent)
|
||||
})
|
||||
|
||||
this.$element.find('input[type="submit"], button[type="submit"]').removeClass('disabled')
|
||||
|
||||
this.$element.find('.has-error, .has-danger').removeClass('has-error has-danger')
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
// VALIDATOR PLUGIN DEFINITION
|
||||
// ===========================
|
||||
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var options = $.extend({}, Validator.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
||||
var data = $this.data('bs.validator')
|
||||
|
||||
if (!data && option == 'destroy') return
|
||||
if (!data) $this.data('bs.validator', (data = new Validator(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.validator
|
||||
|
||||
$.fn.validator = Plugin
|
||||
$.fn.validator.Constructor = Validator
|
||||
|
||||
|
||||
// VALIDATOR NO CONFLICT
|
||||
// =====================
|
||||
|
||||
$.fn.validator.noConflict = function () {
|
||||
$.fn.validator = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// VALIDATOR DATA-API
|
||||
// ==================
|
||||
|
||||
$(window).on('load', function () {
|
||||
$('form[data-toggle="validator"]').each(function () {
|
||||
var $form = $(this)
|
||||
Plugin.call($form, $form.data())
|
||||
})
|
||||
})
|
||||
|
||||
}(jQuery);
|
||||
BIN
site/assets/video/cat.webm
Normal file
BIN
site/assets/video/coding.webm
Normal file
BIN
site/assets/video/placeholder.mp4
Normal file
90
site/docs/architecture.md
Normal file
@ -0,0 +1,90 @@
|
||||
---
|
||||
layout: default
|
||||
permalink: /architecture/
|
||||
title: Architecture
|
||||
redirect_from:
|
||||
- /docs/architecture.md/
|
||||
- /docs/architecture/
|
||||
---
|
||||
|
||||
# Architecture and Internal Design
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
`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.
|
||||
|
||||

|
||||
|
||||
## Loader
|
||||
|
||||
Loader reads input file (now `kompose` supports [Docker Compose](https://docs.docker.com/compose) v1, v2 and converts it to KomposeObject.
|
||||
|
||||
Loader is represented by a Loader interface:
|
||||
|
||||
```go
|
||||
type Loader interface {
|
||||
LoadFile(file string) kobject.KomposeObject
|
||||
}
|
||||
```
|
||||
|
||||
Every loader “implementation” should be placed into `kompose/pkg/loader` (like compose). More input formats will be supported in future. You can take a look for more details at:
|
||||
|
||||
* [kompose/pkg/loader](https://github.com/kubernetes/kompose/tree/master/pkg/loader)
|
||||
* [kompose/pkg/loader/compose](https://github.com/kubernetes/kompose/tree/master/pkg/loader/compose)
|
||||
|
||||
## 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/kompose/blob/master/pkg/kobject/kobject.go)):
|
||||
|
||||
```go
|
||||
// KomposeObject holds the generic struct of Kompose transformation
|
||||
type KomposeObject struct {
|
||||
ServiceConfigs map[string]ServiceConfig
|
||||
}
|
||||
|
||||
// ServiceConfig holds the basic struct of a container
|
||||
type ServiceConfig struct {
|
||||
ContainerName string
|
||||
Image string
|
||||
Environment []EnvVar
|
||||
Port []Ports
|
||||
Command []string
|
||||
WorkingDir string
|
||||
Args []string
|
||||
Volumes []string
|
||||
Network []string
|
||||
Labels map[string]string
|
||||
Annotations map[string]string
|
||||
CPUSet string
|
||||
CPUShares int64
|
||||
CPUQuota int64
|
||||
CapAdd []string
|
||||
CapDrop []string
|
||||
Entrypoint []string
|
||||
Expose []string
|
||||
Privileged bool
|
||||
Restart string
|
||||
User string
|
||||
}
|
||||
```
|
||||
|
||||
## Transformer
|
||||
|
||||
Transformer takes KomposeObject and converts it to target/output format (at this moment, there are sets of kubernetes/openshift objects). Similar to `Loader`, Transformer is represented by a Transformer interface:
|
||||
|
||||
```go
|
||||
type Transformer interface {
|
||||
Transform(kobject.KomposeObject, kobject.ConvertOptions) []runtime.Object
|
||||
}
|
||||
```
|
||||
|
||||
If you wish to add more providers which contain different kind of objects, transformer would be the place to look into. At this moment Kompose supports Kubernetes (by default) and Openshift providers. More details at:
|
||||
|
||||
* [kompose/pkg/transformer](https://github.com/kubernetes/kompose/tree/master/pkg/transformer)
|
||||
* [kompose/pkg/transformer/kubernetes](https://github.com/kubernetes/kompose/tree/master/pkg/transformer/kubernetes)
|
||||
* [kompose/pkg/transformer/openshift](https://github.com/kubernetes/kompose/tree/master/pkg/transformer/openshift)
|
||||
|
||||
## Outputter
|
||||
|
||||
Outputter takes Transformer result and executes given action. For example action can be displaying result to stdout or directly deploying artifacts to Kubernetes/OpenShift.
|
||||
128
site/docs/conversion.md
Normal file
@ -0,0 +1,128 @@
|
||||
---
|
||||
layout: default
|
||||
title: Conversion
|
||||
permalink: /conversion/
|
||||
redirect_from:
|
||||
- /docs/conversion.md/
|
||||
- /docs/conversion/
|
||||
---
|
||||
|
||||
# Conversion Matrix
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
This document outlines all possible conversion details regarding `docker-compose.yaml` values to Kubernetes / OpenShift artifacts.
|
||||
|
||||
## Version Table
|
||||
|
||||
| Supported | Compose Version | Docker Engine Version |
|
||||
|------------|-----------------|-----------------------|
|
||||
| N | 3.8 | 19.03.0+ |
|
||||
| N | 3.7 | 18.06.0+ |
|
||||
| N | 3.6 | 18.02.0+ |
|
||||
| N | 3.5 | 17.12.0+ |
|
||||
| N | 3.4 | 17.09.0+ |
|
||||
| Y | 3.3 | 17.06.0+ |
|
||||
| Y | 3.2 | 17.04.0+ |
|
||||
| Y | 3.1 | 1.13.1+ |
|
||||
| Y | 3.0 | 1.13.0+ |
|
||||
| Y | 2.4 | 17.12.0+ |
|
||||
| Y | 2.3 | 17.06.0+ |
|
||||
| Y | 2.2 | 1.13.0+ |
|
||||
| Y | 2.1 | 1.12.0+ |
|
||||
| Y | 2.0 | 1.10.0+ |
|
||||
|
||||
**Note:** We don't support anything 3.4 and above at the moment. It is reccomended to specify `version: "3.3"` in your `docker-compose.yaml` and converting. We use a library called [libcompose](https://github.com/docker/libcompose) that supports up to version `3.3`. If you are interested in adding additional support, please open up a PR!
|
||||
|
||||
## Conversion Table
|
||||
|
||||
__Glossary:__
|
||||
|
||||
- __✓:__ Converts
|
||||
- __-:__ Not in this Docker Compose Version
|
||||
- __n:__ Not yet implemented
|
||||
- __x:__ Not applicable / no 1-1 conversion
|
||||
|
||||
| Keys | V1 | V2 | V3 | Kubernetes / OpenShift | Notes |
|
||||
|------------------------|----|----|----|----------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|
|
||||
| build | ✓ | ✓ | ✓ | | Builds/Pushes to Docker repository. See [user guide on build and push image](https://kompose.io/user-guide/#build-and-push-image) |
|
||||
| build: context | ✓ | ✓ | ✓ | | |
|
||||
| build: dockerfile | ✓ | ✓ | ✓ | | |
|
||||
| build: args | n | n | n | | |
|
||||
| build: cache_from | - | - | n | | |
|
||||
| cap_add | ✓ | ✓ | ✓ | Container.SecurityContext.Capabilities.Add | |
|
||||
| cap_drop | ✓ | ✓ | ✓ | Container.SecurityContext.Capabilities.Drop | |
|
||||
| command | ✓ | ✓ | ✓ | Container.Args | |
|
||||
| configs | n | n | ✓ | | |
|
||||
| configs: short-syntax | n | n | ✓ | | Only create configMap |
|
||||
| configs: long-syntax | n | n | ✓ | | If target path is /, ignore this and only create configMap |
|
||||
| cgroup_parent | x | x | x | | Not supported within Kubernetes. See issue https://github.com/kubernetes/kubernetes/issues/11986 |
|
||||
| container_name | ✓ | ✓ | ✓ | Metadata.Name + Deployment.Spec.Containers.Name | |
|
||||
| credential_spec | x | x | x | | Only applicable to Windows containers |
|
||||
| deploy | - | - | ✓ | | |
|
||||
| deploy: mode | - | - | ✓ | | |
|
||||
| deploy: replicas | - | - | ✓ | Deployment.Spec.Replicas / DeploymentConfig.Spec.Replicas | |
|
||||
| deploy: placement | - | - | ✓ | Affinity | |
|
||||
| deploy: update_config | - | - | ✓ | Workload.Spec.Strategy | Deployment / DeploymentConfig |
|
||||
| deploy: resources | - | - | ✓ | Containers.Resources.Limits.Memory / Containers.Resources.Limits.CPU | Support for memory as well as cpu |
|
||||
| deploy: restart_policy | - | - | ✓ | Pod generation | This generated a Pod, see the [user guide on restart](http://kompose.io/user-guide/#restart) |
|
||||
| deploy: labels | - | - | ✓ | Workload.Metadata.Labels | Only applied to workload resource |
|
||||
| devices | x | x | x | | Not supported within Kubernetes, See issue https://github.com/kubernetes/kubernetes/issues/5607 |
|
||||
| depends_on | x | x | x | | |
|
||||
| dns | x | x | x | | Not used within Kubernetes. Kubernetes uses a managed DNS server |
|
||||
| dns_search | x | x | x | | See `dns` key |
|
||||
| domainname | ✓ | ✓ | ✓ | SubDomain | |
|
||||
| tmpfs | ✓ | ✓ | ✓ | Containers.Volumes.EmptyDir | Creates emptyDirvolume with medium set to Memory & mounts given directory inside container |
|
||||
| entrypoint | ✓ | ✓ | ✓ | Container.Command | |
|
||||
| env_file | n | n | ✓ | | |
|
||||
| environment | ✓ | ✓ | ✓ | Container.Env | |
|
||||
| expose | ✓ | ✓ | ✓ | Service.Spec.Ports | |
|
||||
| endpoint_mode | n | n | ✓ | | If endpoint_mode=vip, the created Service will be forced to set to NodePort type |
|
||||
| extends | ✓ | ✓ | ✓ | | Extends by utilizing the same image supplied |
|
||||
| external_links | x | x | x | | Kubernetes uses a flat-structure for all containers and thus external_links does not have a 1-1 conversion |
|
||||
| extra_hosts | n | n | n | | |
|
||||
| group_add | ✓ | ✓ | ✓ | | |
|
||||
| healthcheck | - | n | ✓ | | |
|
||||
| hostname | ✓ | ✓ | ✓ | HostName | |
|
||||
| image | ✓ | ✓ | ✓ | Deployment.Spec.Containers.Image | |
|
||||
| isolation | x | x | x | | Not applicable as this applies to Windows with HyperV support |
|
||||
| labels | ✓ | ✓ | ✓ | Metadata.Annotations | |
|
||||
| links | x | x | x | | All containers in the same pod are accessible in Kubernetes |
|
||||
| logging | x | x | x | | Kubernetes has built-in logging support at the node-level |
|
||||
| network_mode | x | x | x | | Kubernetes uses its own cluster networking |
|
||||
| networks | ✓ | ✓ | ✓ | | See `networks` key |
|
||||
| networks: aliases | x | x | x | | See `networks` key |
|
||||
| networks: addresses | x | x | x | | See `networks` key |
|
||||
| pid | ✓ | ✓ | ✓ | HostPID | |
|
||||
| ports | ✓ | ✓ | ✓ | Service.Spec.Ports | |
|
||||
| ports: short-syntax | ✓ | ✓ | ✓ | Service.Spec.Ports | |
|
||||
| ports: long-syntax | - | - | ✓ | Service.Spec.Ports | |
|
||||
| secrets | - | - | ✓ | Secret | External Secret is not Supported |
|
||||
| secrets: short-syntax | - | - | ✓ | Secret | External Secret is not Supported |
|
||||
| secrets: long-syntax | - | - | ✓ | Secret | External Secret is not Supported |
|
||||
| security_opt | x | x | x | | Kubernetes uses its own container naming scheme |
|
||||
| stop_grace_period | ✓ | ✓ | ✓ | TerminationGracePeriodSeconds | |
|
||||
| stop_signal | x | x | x | | Not supported within Kubernetes. See issue https://github.com/kubernetes/kubernetes/issues/30051 |
|
||||
| sysctls | n | n | n | | |
|
||||
| ulimits | x | x | x | | Not supported within Kubernetes. See issue https://github.com/kubernetes/kubernetes/issues/3595 |
|
||||
| userns_mode | x | x | x | | Not supported within Kubernetes and ignored in Docker Compose Version 3 |
|
||||
| volumes | ✓ | ✓ | ✓ | PersistentVolumeClaim | Creates a PersistentVolumeClaim. Can only be created if there is already a PersistentVolume within the cluster |
|
||||
| volumes: short-syntax | ✓ | ✓ | ✓ | PersistentVolumeClaim | Creates a PersistentVolumeClaim. Can only be created if there is already a PersistentVolume within the cluster |
|
||||
| volumes: long-syntax | - | - | ✓ | PersistentVolumeClaim | Creates a PersistentVolumeClaim. Can only be created if there is already a PersistentVolume within the cluster |
|
||||
| restart | ✓ | ✓ | ✓ | | |
|
||||
| | | | | | |
|
||||
| __Volume__ | x | x | x | | |
|
||||
| driver | x | x | x | | |
|
||||
| driver_opts | x | x | x | | |
|
||||
| external | x | x | x | | |
|
||||
| labels | x | x | x | | |
|
||||
| | | | | | |
|
||||
| __Network__ | x | x | x | | |
|
||||
| driver | x | x | x | | |
|
||||
| driver_opts | x | x | x | | |
|
||||
| enable_ipv6 | x | x | x | | |
|
||||
| ipam | x | x | x | | |
|
||||
| internal | x | x | x | | |
|
||||
| labels | x | x | x | | |
|
||||
| external | x | x | x | | |
|
||||
88
site/docs/development.md
Normal file
@ -0,0 +1,88 @@
|
||||
---
|
||||
layout: default
|
||||
permalink: /development/
|
||||
title: Development
|
||||
redirect_from:
|
||||
- /docs/development.md/
|
||||
- /docs/development/
|
||||
---
|
||||
|
||||
# Development Guide
|
||||
|
||||
## Building Kompose
|
||||
|
||||
Read about building kompose [here](https://github.com/kubernetes/kompose#building).
|
||||
|
||||
## Workflow
|
||||
### Fork the main repository
|
||||
|
||||
1. Go to https://github.com/kubernetes/kompose
|
||||
2. Click the "Fork" button (at the top right)
|
||||
|
||||
### Clone your fork
|
||||
|
||||
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/kompose
|
||||
cd $GOPATH/src/github.com/kubernetes/kompose
|
||||
git remote add upstream 'https://github.com/kubernetes/kompose'
|
||||
```
|
||||
|
||||
### Create a branch and make changes
|
||||
|
||||
```console
|
||||
git checkout -b myfeature
|
||||
# Make your code changes
|
||||
```
|
||||
|
||||
### Keeping your development fork in sync
|
||||
|
||||
```console
|
||||
git fetch upstream
|
||||
git rebase upstream/master
|
||||
```
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
### Committing changes to your fork
|
||||
|
||||
```console
|
||||
git commit
|
||||
git push -f origin myfeature
|
||||
```
|
||||
|
||||
### Creating a pull request
|
||||
|
||||
1. Visit https://github.com/$YOUR_GITHUB_USERNAME/kompose.git
|
||||
2. Click the "Compare and pull request" button next to your "myfeature" branch.
|
||||
3. Check out the pull request process for more details
|
||||
|
||||
## Go Modules and dependency management
|
||||
|
||||
Kompose uses [Go Modules](https://github.com/golang/go/wiki/Modules) to manage dependencies.
|
||||
If you want to make changes to dependencies please make sure that `go.mod` and `go.sum` are updated properly.
|
||||
|
||||
##### Updating Kubernetes and OpenShift
|
||||
Kubernetes version depends on what version is OpenShift using.
|
||||
OpenShift is using forked Kubernetes to carry some patches.
|
||||
Currently it is not possible to use different Kubernetes version from version that OpenShift uses.
|
||||
(for more see comments in `go.mod`)
|
||||
|
||||
### Adding CLI tests
|
||||
|
||||
[Kompose CLI tests](https://github.com/kubernetes/kompose/tree/master/script/test/cmd) run `kompose convert` with docker-compose files, and cross-check the k8s and OpenShift artifacts generated with the template files.
|
||||
|
||||
To generate CLI tests, please run `make gen-cmd`.
|
||||
|
||||
### CI
|
||||
|
||||
For Kompose, we use numerous CI's:
|
||||
|
||||
- [TravisCI](https://travis-ci.org/kubernetes/kompose): Unit and CLI tests
|
||||
- [SemaphoreCI](https://semaphoreci.com/cdrage/kompose-2): Integration / cluster tests
|
||||
- [Fabric8CI](http://jenkins.cd.k8s.fabric8.io/): Secondary integration tests / future cluster tests
|
||||
306
site/docs/getting-started.md
Normal file
@ -0,0 +1,306 @@
|
||||
---
|
||||
layout: default
|
||||
permalink: /getting-started/
|
||||
title: Getting Started
|
||||
redirect_from:
|
||||
- /docs/getting-started.md/
|
||||
- /docs/getting-started/
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
This is how you'll get started with Kompose!
|
||||
|
||||
There are three different guides depending on your container orchestrator as well as operating system.
|
||||
|
||||
For beginners and the most compatibility, follow the _Minikube and Kompose_ guide.
|
||||
|
||||
## Minikube and Kompose
|
||||
|
||||
In this guide, we'll deploy a sample `docker-compose.yaml` file to a Kubernetes cluster.
|
||||
|
||||
Requirements:
|
||||
- [minikube](https://github.com/kubernetes/minikube)
|
||||
- [kompose](https://github.com/kubernetes/kompose)
|
||||
|
||||
__Start `minikube`:__
|
||||
|
||||
If you don't already have a Kubernetes cluster running, [minikube](https://github.com/kubernetes/minikube) is the best way to get started.
|
||||
|
||||
```sh
|
||||
$ minikube start
|
||||
Starting local Kubernetes v1.7.5 cluster...
|
||||
Starting VM...
|
||||
Getting VM IP address...
|
||||
Moving files into cluster...
|
||||
Setting up certs...
|
||||
Connecting to cluster...
|
||||
Setting up kubeconfig...
|
||||
Starting cluster components...
|
||||
Kubectl is now configured to use the cluster
|
||||
```
|
||||
|
||||
__Download an [example Docker Compose file](https://raw.githubusercontent.com/kubernetes/kompose/master/examples/docker-compose.yaml), or use your own:__
|
||||
|
||||
```sh
|
||||
wget https://raw.githubusercontent.com/kubernetes/kompose/master/examples/docker-compose.yaml
|
||||
```
|
||||
|
||||
__Convert your Docker Compose file to Kubernetes:__
|
||||
|
||||
Run `kompose convert` in the same directory as your `docker-compose.yaml` file.
|
||||
|
||||
```sh
|
||||
$ 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
|
||||
INFO Kubernetes file "frontend-deployment.yaml" created
|
||||
INFO Kubernetes file "redis-master-deployment.yaml" created
|
||||
INFO Kubernetes file "redis-slave-deployment.yaml" created
|
||||
```
|
||||
|
||||
Then you can use `kubectl apply` to create these resources in kubernetes.
|
||||
|
||||
|
||||
__Access the newly deployed service:__
|
||||
|
||||
Now that your service has been deployed, let's access it.
|
||||
|
||||
If you're using `minikube` you may access it via the `minikube service` command.
|
||||
|
||||
```sh
|
||||
$ minikube service frontend
|
||||
```
|
||||
|
||||
Otherwise, use `kubectl` to see what IP the service is using:
|
||||
|
||||
```sh
|
||||
$ kubectl describe svc frontend
|
||||
Name: frontend
|
||||
Namespace: default
|
||||
Labels: service=frontend
|
||||
Selector: service=frontend
|
||||
Type: LoadBalancer
|
||||
IP: 10.0.0.183
|
||||
LoadBalancer Ingress: 123.45.67.89
|
||||
Port: 80 80/TCP
|
||||
NodePort: 80 31144/TCP
|
||||
Endpoints: 172.17.0.4:80
|
||||
Session Affinity: None
|
||||
No events.
|
||||
|
||||
```
|
||||
|
||||
Note: If you're using a cloud provider, your IP will be listed next to `LoadBalancer Ingress`.
|
||||
|
||||
If you have yet to expose your service (for example, within GCE), use the command:
|
||||
|
||||
```sh
|
||||
kubectl expose deployment frontend --type="LoadBalancer"
|
||||
```
|
||||
|
||||
To check functionality, you may also `curl` the URL.
|
||||
|
||||
```sh
|
||||
$ curl http://123.45.67.89
|
||||
```
|
||||
|
||||
## Minishift and Kompose
|
||||
|
||||
In this guide, we'll deploy a sample `docker-compose.yaml` file to an OpenShift cluster.
|
||||
|
||||
Requirements:
|
||||
- [minishift](https://github.com/minishift/minishift)
|
||||
- [kompose](https://github.com/kubernetes/kompose)
|
||||
- An OpenShift route created
|
||||
|
||||
__Note:__ The service will NOT be accessible until you create an OpenShift route with `oc expose`. You must also have a virtualization environment setup. By default, `minishift` uses KVM.
|
||||
|
||||
__Start `minishift`:__
|
||||
|
||||
[Minishift](https://github.com/minishift/minishift) is a tool that helps run OpenShift locally using a single-node cluster inside of a VM. Similar to [minikube](https://github.com/kubernetes/minikube).
|
||||
|
||||
```sh
|
||||
$ minishift start
|
||||
Starting local OpenShift cluster using 'kvm' hypervisor...
|
||||
-- Checking OpenShift client ... OK
|
||||
-- Checking Docker client ... OK
|
||||
-- Checking Docker version ... OK
|
||||
-- Checking for existing OpenShift container ... OK
|
||||
...
|
||||
```
|
||||
|
||||
__Download an [example Docker Compose file](https://raw.githubusercontent.com/kubernetes/kompose/master/examples/docker-compose.yaml), or use your own:__
|
||||
|
||||
```sh
|
||||
wget https://raw.githubusercontent.com/kubernetes/kompose/master/examples/docker-compose.yaml
|
||||
```
|
||||
|
||||
__Convert your Docker Compose file to OpenShift:__
|
||||
|
||||
Run `kompose convert --provider=openshift` in the same directory as your `docker-compose.yaml` file.
|
||||
|
||||
```sh
|
||||
$ kompose convert --provider=openshift
|
||||
INFO OpenShift file "frontend-service.yaml" created
|
||||
INFO OpenShift file "redis-master-service.yaml" created
|
||||
INFO OpenShift file "redis-slave-service.yaml" created
|
||||
INFO OpenShift file "frontend-deploymentconfig.yaml" created
|
||||
INFO OpenShift file "frontend-imagestream.yaml" created
|
||||
INFO OpenShift file "redis-master-deploymentconfig.yaml" created
|
||||
INFO OpenShift file "redis-master-imagestream.yaml" created
|
||||
INFO OpenShift file "redis-slave-deploymentconfig.yaml" created
|
||||
INFO OpenShift file "redis-slave-imagestream.yaml" created
|
||||
```
|
||||
|
||||
Then you can use `kubectl apply` to create these resources in OpenShift cluster.
|
||||
|
||||
__Access the newly deployed service:__
|
||||
|
||||
After deployment, you must create an OpenShift route in order to access the service.
|
||||
|
||||
If you're using `minishift`, you'll use a combination of `oc` and `minishift` commands to access the service.
|
||||
|
||||
Create a route for the `frontend` service using `oc`:
|
||||
|
||||
```sh
|
||||
$ oc expose service/frontend
|
||||
route "frontend" exposed
|
||||
```
|
||||
|
||||
Access the `frontend` service with `minishift`:
|
||||
|
||||
```sh
|
||||
$ minishift openshift service frontend --namespace=myproject
|
||||
Opening the service myproject/frontend in the default browser...
|
||||
```
|
||||
|
||||
You can also access the GUI interface of OpenShift for an overview of the deployed containers:
|
||||
|
||||
```sh
|
||||
$ minishift console
|
||||
Opening the OpenShift Web console in the default browser...
|
||||
```
|
||||
|
||||
## RHEL and Kompose
|
||||
|
||||
In this guide, we'll deploy a sample `docker-compose.yaml` file using both RHEL (Red Hat Enterprise Linux) and OpenShift.
|
||||
|
||||
Requirements:
|
||||
- Red Hat Enterprise Linux 7.4
|
||||
- [Red Hat Development Suite](https://developers.redhat.com/products/devsuite/overview/)
|
||||
- Which includes:
|
||||
- [minishift](https://github.com/minishift/minishift)
|
||||
- [kompose](https://github.com/kubernetes/kompose)
|
||||
|
||||
__Note:__ A KVM hypervisor must be setup in order to correctly use `minishift` on RHEL. You can set it up via the [CDK Documentation](https://access.redhat.com/documentation/en-us/red_hat_container_development_kit/3.1/html-single/getting_started_guide/index#setup-virtualization) under "Set up your virtualization environment".
|
||||
|
||||
__Install Red Hat Development Suite:__
|
||||
|
||||
Before we are able to use both `minishift` and `kompose`, DevSuite must be installed. A more concise [installation document is available](https://developers.redhat.com/products/cdk/hello-world#fndtn-rhel).
|
||||
|
||||
Change to root.
|
||||
|
||||
```sh
|
||||
$ su -
|
||||
```
|
||||
|
||||
Enable the Red Hat Developer Tools software repository.
|
||||
|
||||
```sh
|
||||
$ subscription-manager repos --enable rhel-7-server-devtools-rpms
|
||||
$ subscription-manager repos --enable rhel-server-rhscl-7-rpms
|
||||
```
|
||||
|
||||
Add the Red Hat Developer Tools key to your system.
|
||||
|
||||
```sh
|
||||
$ cd /etc/pki/rpm-gpg
|
||||
$ wget -O RPM-GPG-KEY-redhat-devel https://www.redhat.com/security/data/a5787476.txt
|
||||
$ rpm --import RPM-GPG-KEY-redhat-devel
|
||||
```
|
||||
|
||||
Install Red Hat Development Suite and Kompose.
|
||||
|
||||
```sh
|
||||
$ yum install rh-devsuite kompose -y
|
||||
```
|
||||
|
||||
__Start `minishift`:__
|
||||
|
||||
Before we begin, we must do a few preliminary steps setting up `minishift`.
|
||||
|
||||
```sh
|
||||
$ su -
|
||||
$ ln -s /var/lib/cdk-minishift-3.0.0/minishift /usr/bin/minishift
|
||||
$ minishift setup-cdk --force --default-vm-driver="kvm"
|
||||
$ ln -s /home/$(whoami)/.minishift/cache/oc/v3.5.5.8/oc /usr/bin/oc
|
||||
```
|
||||
|
||||
Now we may start `minishift`.
|
||||
|
||||
```sh
|
||||
$ minishift start
|
||||
Starting local OpenShift cluster using 'kvm' hypervisor...
|
||||
-- Checking OpenShift client ... OK
|
||||
-- Checking Docker client ... OK
|
||||
-- Checking Docker version ... OK
|
||||
-- Checking for existing OpenShift container ... OK
|
||||
...
|
||||
```
|
||||
|
||||
__Download an [example Docker Compose file](https://raw.githubusercontent.com/kubernetes/kompose/master/examples/docker-compose.yaml), or use your own:__
|
||||
|
||||
```sh
|
||||
wget https://raw.githubusercontent.com/kubernetes/kompose/master/examples/docker-compose.yaml
|
||||
```
|
||||
|
||||
__Convert your Docker Compose file to OpenShift:__
|
||||
|
||||
Run `kompose convert --provider=openshift` in the same directory as your `docker-compose.yaml` file.
|
||||
|
||||
```sh
|
||||
$ kompose convert --provider=openshift
|
||||
INFO OpenShift file "frontend-service.yaml" created
|
||||
INFO OpenShift file "redis-master-service.yaml" created
|
||||
INFO OpenShift file "redis-slave-service.yaml" created
|
||||
INFO OpenShift file "frontend-deploymentconfig.yaml" created
|
||||
INFO OpenShift file "frontend-imagestream.yaml" created
|
||||
INFO OpenShift file "redis-master-deploymentconfig.yaml" created
|
||||
INFO OpenShift file "redis-master-imagestream.yaml" created
|
||||
INFO OpenShift file "redis-slave-deploymentconfig.yaml" created
|
||||
INFO OpenShift file "redis-slave-imagestream.yaml" created
|
||||
```
|
||||
|
||||
Then you can use `kubectl apply` to create these resources in OpenShift.
|
||||
|
||||
__Access the newly deployed service:__
|
||||
|
||||
After deployment, you must create an OpenShift route in order to access the service.
|
||||
|
||||
If you're using `minishift`, you'll use a combination of `oc` and `minishift` commands to access the service.
|
||||
|
||||
Create a route for the `frontend` service using `oc`:
|
||||
|
||||
```sh
|
||||
$ oc expose service/frontend
|
||||
route "frontend" exposed
|
||||
```
|
||||
|
||||
Access the `frontend` service with `minishift`:
|
||||
|
||||
```sh
|
||||
$ minishift openshift service frontend --namespace=myproject
|
||||
Opening the service myproject/frontend in the default browser...
|
||||
```
|
||||
|
||||
You can also access the GUI interface of OpenShift for an overview of the deployed containers:
|
||||
|
||||
```sh
|
||||
$ minishift console
|
||||
Opening the OpenShift Web console in the default browser...
|
||||
```
|
||||
BIN
site/docs/images/design_diagram.png
Normal file
|
After Width: | Height: | Size: 122 KiB |
BIN
site/docs/images/kompose-maven-output-diagram.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
141
site/docs/installation.md
Normal file
@ -0,0 +1,141 @@
|
||||
---
|
||||
layout: default
|
||||
permalink: /installation/
|
||||
title: Installation
|
||||
redirect_from:
|
||||
- /docs/installation.md/
|
||||
- /docs/installation/
|
||||
---
|
||||
|
||||
# Installation
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
We have multiple ways to install Kompose. Our preferred method is downloading the binary from the latest GitHub release.
|
||||
|
||||
## GitHub release
|
||||
|
||||
Kompose is released via GitHub on a three-week cycle, you can see all current releases on the [GitHub release page](https://github.com/kubernetes/kompose/releases).
|
||||
|
||||
__Linux and macOS:__
|
||||
|
||||
```sh
|
||||
# Linux
|
||||
curl -L https://github.com/kubernetes/kompose/releases/download/v1.26.1/kompose-linux-amd64 -o kompose
|
||||
|
||||
# macOS
|
||||
curl -L https://github.com/kubernetes/kompose/releases/download/v1.26.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/v1.26.1/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/kompose
|
||||
```
|
||||
|
||||
## CentOS
|
||||
|
||||
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, 25 and 26 repositories. You can install it just like any other package.
|
||||
|
||||
```bash
|
||||
sudo dnf -y install kompose
|
||||
```
|
||||
|
||||
## Ubuntu/Debian
|
||||
|
||||
A deb package is released for compose. Download latest package in the assets in [github releases](https://github.com/kubernetes/kompose/releases).
|
||||
|
||||
```bash
|
||||
wget https://github.com/kubernetes/kompose/releases/download/v1.26.1/kompose_1.26.1_amd64.deb # Replace 1.26.1 with latest tag
|
||||
sudo apt install ./kompose_1.26.1_amd64.deb
|
||||
```
|
||||
|
||||
## macOS
|
||||
On macOS you can install latest release via [Homebrew](https://brew.sh) or [MacPorts](https://www.macports.org/).
|
||||
|
||||
```bash
|
||||
# Homebrew
|
||||
brew install kompose
|
||||
|
||||
# MacPorts
|
||||
port install kompose
|
||||
```
|
||||
|
||||
## Windows
|
||||
Kompose can be installed via [Chocolatey](https://chocolatey.org/packages/kubernetes-kompose)
|
||||
|
||||
```console
|
||||
choco install kubernetes-kompose
|
||||
```
|
||||
|
||||
## openSUSE/SLE
|
||||
Kompose is available in the official Virtualization:containers repository for openSUSE Tumbleweed, Leap 15, Leap 42.3 and SUSE Linux Enterprise 15.
|
||||
|
||||
Head over to [software.opensuse.org for One-Click Installation](https://software.opensuse.org//download.html?project=Virtualization%3Acontainers&package=kompose) or add the repository manually:
|
||||
```bash
|
||||
#openSUSE Tumbleweed
|
||||
sudo zypper addrepo https://download.opensuse.org/repositories/Virtualization:containers/openSUSE_Tumbleweed/Virtualization:containers.repo
|
||||
|
||||
#openSUSE Leap 42.3
|
||||
sudo zypper addrepo https://download.opensuse.org/repositories/Virtualization:containers/openSUSE_Leap_42.3/Virtualization:containers.repo
|
||||
|
||||
#openSUSE Leap 15
|
||||
sudo zypper addrepo https://download.opensuse.org/repositories/Virtualization:/containers/openSUSE_Leap_15.2/Virtualization:containers.repo
|
||||
|
||||
#SUSE Linux Enterprise 15
|
||||
sudo zypper addrepo https://download.opensuse.org/repositories/Virtualization:/containers/SLE_15_SP1/Virtualization:containers.repo
|
||||
```
|
||||
and install the package:
|
||||
```bash
|
||||
sudo zypper refresh
|
||||
sudo zypper install kompose
|
||||
```
|
||||
|
||||
## NixOS
|
||||
|
||||
To install from [Nixpkgs](https://github.com/NixOS/nixpkgs), use [nix-env](https://nixos.org/manual/nix/stable/command-ref/nix-env.html).
|
||||
|
||||
```bash
|
||||
nix-env --install -A nixpkgs.kompose
|
||||
```
|
||||
|
||||
To run `kompose` without installing it, use [nix-shell](https://nixos.org/manual/nix/stable/command-ref/nix-shell.html).
|
||||
|
||||
```bash
|
||||
nix-shell -p kompose --run "kompose convert"
|
||||
```
|
||||
|
||||
|
||||
## Docker
|
||||
|
||||
You can build an image from the offical repo for [Docker](https://docs.docker.com/engine/reference/commandline/build/) or [Podman](https://docs.podman.io/en/latest/markdown/podman-build.1.html):
|
||||
|
||||
```bash
|
||||
docker build -t kompose https://github.com/kubernetes/kompose.git
|
||||
```
|
||||
|
||||
To run the built image against the current directory, run the following command:
|
||||
|
||||
```bash
|
||||
docker run --rm -it -v $PWD:/opt kompose sh -c "cd /opt && kompose convert"
|
||||
```
|
||||
57
site/docs/integrations.md
Normal file
@ -0,0 +1,57 @@
|
||||
---
|
||||
layout: default
|
||||
permalink: /integrations/
|
||||
title: Integrations
|
||||
redirect_from:
|
||||
- /docs/integrations.md/
|
||||
- /docs/integrations/
|
||||
---
|
||||
|
||||
# Integrations
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
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/cloudfind/kompose-docker)
|
||||
|
||||
### 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 SyGroup 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)
|
||||
|
||||
### Fabric8 Maven Plugin by Red Hat
|
||||
|
||||
__Description:__ "Maven is one of the widely used build tools for Java applications. The Fabric8 Maven Plugin is a maven extension that simplifies the deployment of Java applications to Kubernetes or OpenShift cluster.
|
||||
The main task of this plugin is to build Docker images, generate Kubernetes or OpenShift resource descriptors and run/deploy the application on Kubernetes or OpenShift cluster.
|
||||
Plugin has wide range of configuration options. Docker Compose is one of the option to bring up deployments on Kubernetes or OpenShift cluster.
|
||||
Technically, Fabric8 Maven Plugin processes the external docker-compose.yml file and generates Kubernetes or OpenShift resources via Kompose."
|
||||
|
||||
__Links:__
|
||||
|
||||
* [Quickstart](/docs/maven-example.md)
|
||||
* [Documentation](https://maven.fabric8.io/#docker-compose)
|
||||
98
site/docs/maven-example.md
Normal file
@ -0,0 +1,98 @@
|
||||
---
|
||||
layout: default
|
||||
permalink: /maven-example/
|
||||
title: Maven Example
|
||||
redirect_from:
|
||||
- /docs/maven-example.md/
|
||||
- /docs/maven-example/
|
||||
---
|
||||
|
||||
# Fabric8 Maven Plugin + Kompose:
|
||||
Let's deploy a Springboot Java application with Docker Compose file using Fabric8 Maven Plugin to Kubernetes or OpenShift.
|
||||
|
||||
##### Requirements
|
||||
* Linux or MacOS or Windows
|
||||
* JDK 1.7+ - [JDK Quick Installation Guide](http://openjdk.java.net/install/)
|
||||
* Maven 3.x+ - [Maven Installation Guide](http://www.baeldung.com/install-maven-on-windows-linux-mac)
|
||||
* Kompose - [Kompose Installation Guide](/docs/installation.md)
|
||||
|
||||
__1. Clone the example project from GitHub__
|
||||
```bash
|
||||
$ git clone https://github.com/piyush1594/kompose-maven-example.git
|
||||
```
|
||||
|
||||
Change current directory to `kompose-maven-example` directory.
|
||||
```bash
|
||||
$ cd kompose-maven-example
|
||||
```
|
||||
|
||||
__2. Add Fabric8 Maven Plugin to your project__
|
||||
```bash
|
||||
$ mvn io.fabric8:fabric8-maven-plugin:3.5.28:setup
|
||||
```
|
||||
|
||||
Add the Fabric8 Maven Plugin configuration to `pom.xml` of project. `pom.xml` is manifest or deployment descriptor file of a maven project.
|
||||
|
||||
__3. Install Kompose through Maven__
|
||||
```bash
|
||||
$ mvn fabric8:install
|
||||
```
|
||||
|
||||
This command installs the `kompose` on the host.
|
||||
|
||||
__4. Configure Fabric8 Maven Plugin to use a Docker Compose file__
|
||||
```bash
|
||||
<plugin>
|
||||
<groupId>io.fabric8</groupId>
|
||||
<artifactId>fabric8-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<composeFile>path for docker compose file</composeFile>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>resource</goal>
|
||||
<goal>build</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
```
|
||||
|
||||
Add the `<configuration>` and `<executions>` sections to `pom.xml` as shown in above `pom.xml` snippet. Update the `<composeFile>` to provide the relative path of Docker Compose file from `pom.xml`
|
||||
|
||||
__5. Deploy application on Kubernetes or OpenShift__
|
||||
|
||||
Make sure that Kubernetes/OpenShift cluster or Minikube/minishift is running. In case, if anything of this is not running, you can run minishift to test this application by using following command.
|
||||
```bash
|
||||
$ minishift start
|
||||
```
|
||||
|
||||
Below command deploys this application on Kubernetes or OpenShift.
|
||||
```bash
|
||||
$ mvn fabric8:deploy
|
||||
```
|
||||
|
||||
Now that your service has been deployed, let's access it by querying `pod`, `service` from Kubernetes or OpenShift.
|
||||
```bash
|
||||
$ oc get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
springboot-docker-compose-1-xl0vb 1/1 Running 0 5m
|
||||
springboot-docker-compose-s2i-1-build 0/1 Completed 0 7m
|
||||
```
|
||||
|
||||
```bash
|
||||
$ oc get svc
|
||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
springboot-docker-compose 172.30.205.137 <none> 8080/TCP 6m
|
||||
```
|
||||
|
||||
Let's access the Springboot service.
|
||||
```bash
|
||||
$ minishift openshift service --in-browser springboot-docker-compose
|
||||
Created the new window in existing browser session.
|
||||
```
|
||||
|
||||
It will open your application endpoint in default browser.
|
||||
|
||||

|
||||
474
site/docs/user-guide.md
Normal file
@ -0,0 +1,474 @@
|
||||
---
|
||||
layout: default
|
||||
permalink: /user-guide/
|
||||
title: User Guide
|
||||
redirect_from:
|
||||
- /docs/user-guide.md/
|
||||
- /docs/user-guide/
|
||||
---
|
||||
|
||||
# User Guide
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
Kompose has support for two providers: OpenShift and Kubernetes.
|
||||
You can choose a targeted provider using global option `--provider`. If no provider is specified, Kubernetes is set by default.
|
||||
|
||||
|
||||
## Kompose Convert
|
||||
|
||||
Kompose supports conversion of V1, V2, and V3 Docker Compose files into Kubernetes and OpenShift objects.
|
||||
|
||||
### Kubernetes
|
||||
|
||||
```sh
|
||||
$ kompose --file docker-voting.yml convert
|
||||
WARN Unsupported key networks - ignoring
|
||||
WARN Unsupported key build - ignoring
|
||||
INFO Kubernetes file "worker-svc.yaml" created
|
||||
INFO Kubernetes file "db-svc.yaml" created
|
||||
INFO Kubernetes file "redis-svc.yaml" created
|
||||
INFO Kubernetes file "result-svc.yaml" created
|
||||
INFO Kubernetes file "vote-svc.yaml" created
|
||||
INFO Kubernetes file "redis-deployment.yaml" created
|
||||
INFO Kubernetes file "result-deployment.yaml" created
|
||||
INFO Kubernetes file "vote-deployment.yaml" created
|
||||
INFO Kubernetes file "worker-deployment.yaml" created
|
||||
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-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:
|
||||
|
||||
```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
|
||||
INFO Kubernetes file "mongodb-service.yaml" created
|
||||
INFO Kubernetes file "redis-master-service.yaml" created
|
||||
INFO Kubernetes file "redis-slave-service.yaml" created
|
||||
INFO Kubernetes file "frontend-deployment.yaml" created
|
||||
INFO Kubernetes file "mlbparks-deployment.yaml" created
|
||||
INFO Kubernetes file "mongodb-deployment.yaml" created
|
||||
INFO Kubernetes file "mongodb-claim0-persistentvolumeclaim.yaml" created
|
||||
INFO Kubernetes file "redis-master-deployment.yaml" created
|
||||
INFO Kubernetes file "redis-slave-deployment.yaml" created
|
||||
|
||||
$ ls
|
||||
mlbparks-deployment.yaml mongodb-service.yaml redis-slave-service.jsonmlbparks-service.yaml
|
||||
frontend-deployment.yaml mongodb-claim0-persistentvolumeclaim.yaml redis-master-service.yaml
|
||||
frontend-service.yaml mongodb-deployment.yaml redis-slave-deployment.yaml
|
||||
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.
|
||||
|
||||
### OpenShift
|
||||
|
||||
```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
|
||||
INFO OpenShift file "db-service.yaml" created
|
||||
INFO OpenShift file "redis-service.yaml" created
|
||||
INFO OpenShift file "result-service.yaml" created
|
||||
INFO OpenShift file "vote-deploymentconfig.yaml" created
|
||||
INFO OpenShift file "vote-imagestream.yaml" created
|
||||
INFO OpenShift file "worker-deploymentconfig.yaml" created
|
||||
INFO OpenShift file "worker-imagestream.yaml" created
|
||||
INFO OpenShift file "db-deploymentconfig.yaml" created
|
||||
INFO OpenShift file "db-imagestream.yaml" created
|
||||
INFO OpenShift file "redis-deploymentconfig.yaml" created
|
||||
INFO OpenShift file "redis-imagestream.yaml" created
|
||||
INFO OpenShift file "result-deploymentconfig.yaml" created
|
||||
INFO OpenShift file "result-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.
|
||||
|
||||
```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.
|
||||
INFO OpenShift file "foo-deploymentconfig.yaml" created
|
||||
INFO OpenShift file "foo-imagestream.yaml" created
|
||||
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 .
|
||||
|
||||
## 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, [Daemon Sets](http://kubernetes.io/docs/admin/daemons/), [Statefulset](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/) or [Helm](https://github.com/helm/helm) charts.
|
||||
|
||||
```sh
|
||||
$ kompose convert -j
|
||||
INFO Kubernetes file "redis-svc.json" created
|
||||
INFO Kubernetes file "web-svc.json" created
|
||||
INFO Kubernetes file "redis-deployment.json" created
|
||||
INFO Kubernetes file "web-deployment.json" created
|
||||
```
|
||||
The `*-deployment.json` files contain the Deployment objects.
|
||||
|
||||
```sh
|
||||
$ kompose convert --controller replicationController
|
||||
INFO Kubernetes file "redis-svc.yaml" created
|
||||
INFO Kubernetes file "web-svc.yaml" created
|
||||
INFO Kubernetes file "redis-replicationcontroller.yaml" created
|
||||
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 --controller replicationController --replicas 3`
|
||||
|
||||
```sh
|
||||
$ kompose convert --controller daemonSet
|
||||
INFO Kubernetes file "redis-svc.yaml" created
|
||||
INFO Kubernetes file "web-svc.yaml" created
|
||||
INFO Kubernetes file "redis-daemonset.yaml" created
|
||||
INFO Kubernetes file "web-daemonset.yaml" created
|
||||
```
|
||||
|
||||
The `*-daemonset.yaml` files contain the Daemon Set objects
|
||||
|
||||
```sh
|
||||
$ kompose convert --controller statefulset
|
||||
INFO Kubernetes file "db-service.yaml" created
|
||||
INFO Kubernetes file "wordpress-service.yaml" created
|
||||
INFO Kubernetes file "db-statefulset.yaml" created
|
||||
INFO Kubernetes file "wordpress-statefulset.yaml" created
|
||||
```
|
||||
|
||||
The `*statefulset-.yaml` files contain the Statefulset objects.
|
||||
|
||||
|
||||
If you want to generate a Chart to be used with [Helm](https://github.com/kubernetes/helm) simply do:
|
||||
|
||||
```sh
|
||||
$ kompose convert -c
|
||||
INFO Kubernetes file "web-svc.yaml" created
|
||||
INFO Kubernetes file "redis-svc.yaml" created
|
||||
INFO Kubernetes file "web-deployment.yaml" created
|
||||
INFO Kubernetes file "redis-deployment.yaml" created
|
||||
chart created in "./docker-compose/"
|
||||
|
||||
$ tree docker-compose/
|
||||
docker-compose
|
||||
├── Chart.yaml
|
||||
├── README.md
|
||||
└── templates
|
||||
├── redis-deployment.yaml
|
||||
├── redis-svc.yaml
|
||||
├── web-deployment.yaml
|
||||
└── web-svc.yaml
|
||||
```
|
||||
|
||||
The chart structure is aimed at providing a skeleton for building your Helm charts. It's compatible with both Helm V2 and Helm V3.
|
||||
|
||||
## Labels
|
||||
|
||||
`kompose` supports Kompose-specific labels within the `docker-compose.yml` file to
|
||||
explicitly define the generated resources' behavior upon conversion, like Service, PersistentVolumeClaim...
|
||||
|
||||
The currently supported options are:
|
||||
|
||||
| Key | Value |
|
||||
|----------------------|-------------------------------------|
|
||||
| kompose.service.type | nodeport / clusterip / loadbalancer / headless |
|
||||
| kompose.service.group | name to group the containers contained in a single pod |
|
||||
| kompose.service.expose | true / hostnames (separated by comma) |
|
||||
| kompose.service.nodeport.port | port value (string) |
|
||||
| kompose.service.expose.tls-secret | secret name |
|
||||
| kompose.volume.size | kubernetes supported volume size |
|
||||
| kompose.volume.storage-class-name | kubernetes supported volume storageClassName |
|
||||
| kompose.volume.type | use k8s volume type, eg "configMap", "persistentVolumeClaim", "emptyDir", "hostPath" |
|
||||
| kompose.controller.type | deployment / daemonset / replicationcontroller |
|
||||
| kompose.image-pull-policy | kubernetes pods imagePullPolicy |
|
||||
| kompose.image-pull-secret | kubernetes secret name for imagePullSecrets |
|
||||
| kompose.service.healthcheck.readiness.disable | kubernetes readiness disable |
|
||||
| kompose.service.healthcheck.readiness.test | kubernetes readiness exec command |
|
||||
| kompose.service.healthcheck.readiness.http_get_path | kubernetes readiness httpGet path |
|
||||
| kompose.service.healthcheck.readiness.http_get_port | kubernetes readiness httpGet port |
|
||||
| kompose.service.healthcheck.readiness.tcp_port | kubernetes readiness tcpSocket port |
|
||||
| kompose.service.healthcheck.readiness.interval | kubernetes readiness interval value |
|
||||
| kompose.service.healthcheck.readiness.timeout | kubernetes readiness timeout value |
|
||||
| kompose.service.healthcheck.readiness.retries | kubernetes readiness retries value |
|
||||
| kompose.service.healthcheck.readiness.start_period | kubernetes readiness start_period |
|
||||
| kompose.service.healthcheck.liveness.http_get_path | kubernetes liveness httpGet path |
|
||||
| kompose.service.healthcheck.liveness.http_get_port | kubernetes liveness httpGet port |
|
||||
| kompose.service.healthcheck.liveness.tcp_port | kubernetes liveness tcpSocket port |
|
||||
|
||||
**Note**: `kompose.service.type` label should be defined with `ports` only (except for headless service), otherwise `kompose` will fail.
|
||||
|
||||
|
||||
|
||||
- `kompose.service.type` defines the type of service to be created.
|
||||
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
version: "2"
|
||||
services:
|
||||
nginx:
|
||||
image: nginx
|
||||
dockerfile: foobar
|
||||
build: ./foobar
|
||||
cap_add:
|
||||
- ALL
|
||||
container_name: foobar
|
||||
labels:
|
||||
kompose.service.type: nodeport
|
||||
```
|
||||
|
||||
- `kompose.service.group` defines the group of containers included in a single pod.
|
||||
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
nginx:
|
||||
image: nginx
|
||||
depends_on:
|
||||
- logs
|
||||
labels:
|
||||
- kompose.service.group=sidecar
|
||||
|
||||
logs:
|
||||
image: busybox
|
||||
command: ["tail -f /var/log/nginx/access.log"]
|
||||
labels:
|
||||
- kompose.service.group=sidecar
|
||||
```
|
||||
|
||||
- `kompose.service.expose` defines if the service needs to be made accessible from outside the cluster or not. If the value is set to "true", the provider sets the endpoint automatically, and for any other value, the value is set as the hostname. If multiple ports are defined in a service, the first one is chosen to be the exposed.
|
||||
- For the Kubernetes provider, an ingress resource is created and it is assumed that an ingress controller has already been configured. If the value is set to a comma sepatated list, multiple hostnames are supported.Hostname with path is also supported.
|
||||
- For the OpenShift provider, a route is created.
|
||||
- `kompose.service.nodeport.port` defines the port value when service type is `nodeport`, this label should only be set when the service only contains 1 port. Usually kubernetes define a port range for node port values, kompose will not validate this.
|
||||
- `kompose.service.expose.tls-secret` provides the name of the TLS secret to use with the Kubernetes ingress controller. This requires kompose.service.expose to be set.
|
||||
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
version: "2"
|
||||
services:
|
||||
web:
|
||||
image: tuna/docker-counter23
|
||||
ports:
|
||||
- "5000:5000"
|
||||
links:
|
||||
- redis
|
||||
labels:
|
||||
kompose.service.expose: "counter.example.com,foobar.example.com"
|
||||
kompose.service.expose.tls-secret: "example-secret"
|
||||
redis:
|
||||
image: redis:3.0
|
||||
ports:
|
||||
- "6379"
|
||||
```
|
||||
|
||||
- `kompose.serviceaccount-name` defines the service account name to provide the credential info of the pod.
|
||||
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
version: '3.4'
|
||||
services:
|
||||
app:
|
||||
image: python
|
||||
labels:
|
||||
kompose.serviceaccount-name: "my-service"
|
||||
```
|
||||
|
||||
- `kompose.image-pull-secret` defines a kubernetes secret name for imagePullSecrets podspec field.
|
||||
This secret will be used for pulling private images.
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
version: '2'
|
||||
services:
|
||||
tm-service:
|
||||
image: premium/private-image
|
||||
labels:
|
||||
kompose.image-pull-secret: "example-kubernetes-secret"
|
||||
```
|
||||
|
||||
- `kompose.volume.size` defines the requests storage's size in the PersistentVolumeClaim, or you can use command line parameter `--pvc-request-size`.
|
||||
The priority follow label (kompose.volume.size) > command parameter(--pvc-request-size) > defaultSize (100Mi)
|
||||
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
version: '2'
|
||||
services:
|
||||
db:
|
||||
image: postgres:10.1
|
||||
labels:
|
||||
kompose.volume.size: 1Gi
|
||||
volumes:
|
||||
- db-data:/var/lib/postgresql/data
|
||||
```
|
||||
|
||||
- `kompose.volume.storage-class-name` defines the requests storage's class name in the PersistentVolumeClaim.
|
||||
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
services:
|
||||
db:
|
||||
image: postgres:10.1
|
||||
labels:
|
||||
kompose.volume.storage-class-name: custom-storage-class-name
|
||||
volumes:
|
||||
- db-data:/var/lib/postgresql/data
|
||||
```
|
||||
|
||||
- `kompose.controller.type` defines which controller type should convert for this service
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
web:
|
||||
image: wordpress:4.5
|
||||
ports:
|
||||
- '80'
|
||||
environment:
|
||||
WORDPRESS_AUTH_KEY: changeme
|
||||
WORDPRESS_SECURE_AUTH_KEY: changeme
|
||||
WORDPRESS_LOGGED_IN_KEY: changeme
|
||||
WORDPRESS_NONCE_KEY: changeme
|
||||
WORDPRESS_AUTH_SALT: changeme
|
||||
WORDPRESS_SECURE_AUTH_SALT: changeme
|
||||
WORDPRESS_LOGGED_IN_SALT: changeme
|
||||
WORDPRESS_NONCE_SALT: changeme
|
||||
WORDPRESS_NONCE_AA: changeme
|
||||
restart: always
|
||||
links:
|
||||
- 'db:mysql'
|
||||
db:
|
||||
image: mysql:5.7
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: password
|
||||
restart: always
|
||||
labels:
|
||||
project.logs: /var/log/mysql
|
||||
kompose.controller.type: daemonset
|
||||
```
|
||||
|
||||
Service `web` will be converted to `Deployment` as default, service `db` will be converted to `DaemonSet` because of `kompose.controller.type` label.
|
||||
|
||||
- `kompose.image-pull-policy` defines Kubernetes PodSpec imagePullPolicy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise.
|
||||
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
version: '2'
|
||||
services:
|
||||
example-service:
|
||||
image: example-image
|
||||
labels:
|
||||
kompose.image-pull-policy: "Never"
|
||||
```
|
||||
|
||||
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
version: '2'
|
||||
services:
|
||||
example-service:
|
||||
image: example-image
|
||||
labels:
|
||||
kompose.service.healthcheck.liveness.http_get_path: /health/ping
|
||||
kompose.service.healthcheck.liveness.http_get_port: 8080
|
||||
healthcheck:
|
||||
interval: 10s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 30s
|
||||
```
|
||||
|
||||
- `kompose.service.healthcheck.liveness` defines Kubernetes [liveness HttpRequest](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-a-liveness-http-request), If you use healthcheck without liveness labels, have to define `test` in healcheck it's work to Kubernetes [liveness command](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes)
|
||||
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
version: '2'
|
||||
services:
|
||||
example-service:
|
||||
image: example-image
|
||||
labels:
|
||||
kompose.service.healthcheck.readiness.test: CMD curl -f "http://localhost:8080/health/ping"
|
||||
kompose.service.healthcheck.readiness.interval: 10s
|
||||
kompose.service.healthcheck.readiness.timeout: 10s
|
||||
kompose.service.healthcheck.readiness.retries: 3
|
||||
kompose.service.healthcheck.readiness.start_period: 30s
|
||||
```
|
||||
- `kompose.service.healthcheck.readiness` defines Kubernetes [readiness](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes)
|
||||
|
||||
## Restart
|
||||
|
||||
If you want to create normal pods without controller you can use `restart` construct of docker-compose to define that. Follow table below to see what happens on the `restart` value.
|
||||
|
||||
| `docker-compose` `restart` | object created | Pod `restartPolicy` |
|
||||
|----------------------------|-------------------|---------------------|
|
||||
| `""` | controller object | `Always` |
|
||||
| `always` | controller object | `Always` |
|
||||
| `unless-stopped` | controller object | `Always` |
|
||||
| `on-failure` | Pod | `OnFailure` |
|
||||
| `no` | Pod | `Never` |
|
||||
|
||||
**Note**: controller object could be `deployment` or `replicationcontroller`, etc.
|
||||
|
||||
For e.g. `pival` service will become pod down here. This container calculated value of `pi`.
|
||||
|
||||
```yaml
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
pival:
|
||||
image: perl
|
||||
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
|
||||
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 `_` or `.` in it (eg.`web_service` or `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.
|
||||
|
||||
## Build and push image
|
||||
|
||||
If the Docker Compose file has `build` or `build:context, build:dockerfile` keys, build will run when `--build` specified.
|
||||
|
||||
And Image will push to *docker.io* (default) when `--push-image=true` specified.
|
||||
|
||||
It is possible to push to custom registry by specify `--push-image-registry`, which will override the registry from image name.
|
||||
|
||||
### Authentication on registry
|
||||
|
||||
Kompose uses the docker authentication from file `$DOCKER_CONFIG/config.json`, `$HOME/.docker/config.json`, and `$HOME/.dockercfg` after `docker login`.
|
||||
|
||||
**This only works fine on Linux but macOS would fail when using `"credsStore": "osxkeychain"`.**
|
||||
|
||||
However, there is an approach to push successfully on macOS, by not using `osxkeychain` for `credsStore`. To disable `osxkeychain`:
|
||||
* remove `credsStore` from `config.json` file, and `docker login` again.
|
||||
* for some docker desktop versions, there is a setting `Securely store Docker logins in macOS keychain`, which should be unchecked. Then restart docker desktop if needed, and `docker login` again.
|
||||
|
||||
Now `config.json` should contain base64 encoded passwords, then push image should succeed. Working, but not safe though! Use it at your risk.
|
||||
|
||||
For Windows, there is also `credsStore` which is `wincred`. Technically it will fail on authentication as macOS does, but you can try the approach above like macOS too.
|
||||
|
||||
## 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.
|
||||
BIN
site/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
24
site/feed.xml
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
layout: null
|
||||
---
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>{{ site.title | xml_escape }}</title>
|
||||
<description>{{ site.description | xml_escape }}</description>
|
||||
<link>{{ site.url }}{{ site.baseurl }}/</link>
|
||||
<atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml"/>
|
||||
<pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
|
||||
<lastBuildDate>{{ site.time | date_to_rfc822 }}</lastBuildDate>
|
||||
<generator>Jekyll v{{ jekyll.version }}</generator>
|
||||
{% for doc in site.docs limit:10 %}
|
||||
<item>
|
||||
<title>{{ doc.title | xml_escape }}</title>
|
||||
<description>{{ doc.content | xml_escape }}</description>
|
||||
<pubDate>{{ doc.date | date_to_rfc822 }}</pubDate>
|
||||
<link>{{ doc.url | prepend: site.baseurl | prepend: site.url }}</link>
|
||||
<guid isPermaLink="true">{{ doc.url | prepend: site.baseurl | prepend: site.url }}</guid>
|
||||
</item>
|
||||
{% endfor %}
|
||||
</channel>
|
||||
</rss>
|
||||
17
site/index.md
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
# Feel free to add content and custom Front Matter to this file.
|
||||
# To modify the layout, see https://jekyllrb.com/docs/themes/#overriding-theme-defaults
|
||||
|
||||
layout: index
|
||||
---
|
||||
```sh
|
||||
$ kompose convert -f docker-compose.yaml
|
||||
|
||||
$ kubectl apply -f .
|
||||
|
||||
$ kubectl get po
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
frontend-591253677-5t038 1/1 Running 0 10s
|
||||
redis-master-2410703502-9hshf 1/1 Running 0 10s
|
||||
redis-slave-4049176185-hr1lr 1/1 Running 0 10s
|
||||
```
|
||||
25
site/js/background.js
Normal file
@ -0,0 +1,25 @@
|
||||
$(document).ready(function() {
|
||||
var bgArray = ['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg'];
|
||||
var path = '../img/background/';
|
||||
|
||||
|
||||
secs = 5;
|
||||
bgArray.forEach(function(img){
|
||||
// caches images, avoiding white flash between background replacements
|
||||
new Image().src = path + img;
|
||||
});
|
||||
|
||||
function backgroundSequence() {
|
||||
window.clearTimeout();
|
||||
var k = 0;
|
||||
for (i = 0; i < bgArray.length; i++) {
|
||||
setTimeout(function(){
|
||||
$('#hero').css('background-image', 'url(' + path + bgArray[k] +')');
|
||||
if ((k + 1) === bgArray.length) { setTimeout(function() { backgroundSequence() }, (secs * 1000))} else { k++; }
|
||||
}, (secs * 1000) * i)
|
||||
}
|
||||
}
|
||||
backgroundSequence();
|
||||
});
|
||||
|
||||
|
||||