Merge remote-tracking branch 'origin/master' into feature/add-latest-tag
This commit is contained in:
14
.devcontainer/bin/deploy-test-app
Executable file
14
.devcontainer/bin/deploy-test-app
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
main() {
|
||||
declare APP="${1:-test}"
|
||||
|
||||
if ! dokku apps:exists $APP; then
|
||||
dokku apps:create $APP
|
||||
fi
|
||||
|
||||
dokku builder-herokuish:set $APP allowed true
|
||||
dokku git:sync --build $APP https://github.com/dokku/smoke-test-app.git
|
||||
}
|
||||
|
||||
main "$@"
|
||||
35
.github/dependabot.yml
vendored
35
.github/dependabot.yml
vendored
@@ -141,6 +141,41 @@ updates:
|
||||
open-pull-requests-limit: 2
|
||||
labels:
|
||||
- "type: dependencies"
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/plugins/caddy-vhosts"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- "type: dependencies"
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/plugins/haproxy-vhosts"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- "type: dependencies"
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/plugins/logs"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- "type: dependencies"
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/plugins/openresty-vhosts"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- "type: dependencies"
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/plugins/traefik-vhosts"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- "type: dependencies"
|
||||
- package-ecosystem: bundler
|
||||
directory: "/tests/apps/ruby"
|
||||
schedule:
|
||||
|
||||
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@@ -58,7 +58,7 @@ jobs:
|
||||
PACKER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Get changed files in the docs folder
|
||||
id: changed-files-specific
|
||||
uses: tj-actions/changed-files@v42.0.2
|
||||
uses: tj-actions/changed-files@v42.0.4
|
||||
with:
|
||||
files: contrib/images/digitalocean/**
|
||||
- name: Run `packer validate`
|
||||
|
||||
72
HISTORY.md
72
HISTORY.md
@@ -1,5 +1,77 @@
|
||||
# History
|
||||
|
||||
## 0.33.7
|
||||
|
||||
Install/update via the bootstrap script:
|
||||
|
||||
```shell
|
||||
wget -NP . https://dokku.com/install/v0.33.7/bootstrap.sh
|
||||
sudo DOKKU_TAG=v0.33.7 bash bootstrap.sh
|
||||
```
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- #6608: @josegonzalez Fix issue with setting k3s resource values and lower the initial default values
|
||||
- #6607: @josegonzalez Call sed in unbuffered form to ensure log output is streamed to stdout
|
||||
- #6600: @josegonzalez Use correct label key for worker nodes
|
||||
- #6593: @josegonzalez Remove extra trailing newline to fix govet issue
|
||||
|
||||
### New Features
|
||||
|
||||
- #6595: @josegonzalez Add ability for users to specify alternative kubeconfig and kubecontext
|
||||
|
||||
### Refactors
|
||||
|
||||
- #6594: @josegonzalez Remove all calls to common.NewShellCmd
|
||||
- #6592: @josegonzalez Remove all calls to common.NewShellCmdWithArgs
|
||||
- #6591: @josegonzalez Always capture stdout/stderr when executing subprocesses
|
||||
- #6590: @josegonzalez Remove all direct usage of go-sh outside of plugin trigger setup
|
||||
|
||||
### Dependencies
|
||||
|
||||
- #6609: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.61.1 to 1.62.0 in /tests/apps/gogrpc
|
||||
- #6604: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.9 to 9.5.10 in /docs/_build
|
||||
- #6603: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 42.0.2 to 42.0.4
|
||||
- #6601: @dependabot[bot] chore(deps): bump helm.sh/helm/v3 from 3.13.3 to 3.14.1 in /plugins/scheduler-k3s
|
||||
- #6596: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.61.0 to 1.61.1 in /tests/apps/gogrpc
|
||||
|
||||
## 0.33.6
|
||||
|
||||
Install/update via the bootstrap script:
|
||||
|
||||
```shell
|
||||
wget -NP . https://dokku.com/install/v0.33.6/bootstrap.sh
|
||||
sudo DOKKU_TAG=v0.33.6 bash bootstrap.sh
|
||||
```
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- #6589: @josegonzalez Use image pull secrets instead of registries.yaml to reference private repositories when deploying via k3s
|
||||
- #6581: @josegonzalez Fix issues in tls handling when deploying via k3s
|
||||
- #6582: @josegonzalez Correctly handle extra whitespace in scale file contents
|
||||
- #6390: @renweibo Prefer systemctl over sv when both exist while restarting nginx
|
||||
- #6579: @josegonzalez Ensure k3s can be installed with taints
|
||||
|
||||
### New Features
|
||||
|
||||
- #6585: @josegonzalez Add more context to errors in fetching cron entries
|
||||
- #6583: @josegonzalez Add WithContext functions for all subprocess-related code
|
||||
|
||||
### Refactors
|
||||
|
||||
- #6584: @josegonzalez Use new CallExecCommand when checking to see how help is being called
|
||||
|
||||
### Dependencies
|
||||
|
||||
- #6586: @dependabot[bot] chore(deps): bump mvdan.cc/sh/v3 from 3.7.0 to 3.8.0 in /plugins/cron
|
||||
- #6587: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.8 to 9.5.9 in /docs/_build
|
||||
- #6381: @dependabot[bot] chore(deps): bump actions/upload-artifact from 3 to 4
|
||||
- #6578: @josegonzalez Bump go modules
|
||||
|
||||
### Other
|
||||
|
||||
- #6576: @Tashows Allow creating a detached container with TTY enabled for attaching remote terminal
|
||||
|
||||
## 0.33.5
|
||||
|
||||
Install/update via the bootstrap script:
|
||||
|
||||
@@ -86,8 +86,8 @@ Otherwise, you will need to import the keypair manually after installation using
|
||||
To install the latest stable release, run the following commands as a user who has access to `sudo`:
|
||||
|
||||
```shell
|
||||
wget -NP . https://dokku.com/install/v0.33.5/bootstrap.sh
|
||||
sudo DOKKU_TAG=v0.33.5 bash bootstrap.sh
|
||||
wget -NP . https://dokku.com/install/v0.33.7/bootstrap.sh
|
||||
sudo DOKKU_TAG=v0.33.7 bash bootstrap.sh
|
||||
```
|
||||
|
||||
You can then proceed to configure your server domain (via `dokku domains:set-global`) and user access (via `dokku ssh-keys:add`) to complete the installation.
|
||||
|
||||
2
Vagrantfile
vendored
2
Vagrantfile
vendored
@@ -53,7 +53,7 @@ Vagrant::configure("2") do |config|
|
||||
vb.customize ["modifyvm", :id, "--cableconnected1", "on"]
|
||||
end
|
||||
|
||||
vm.vm.provision :shell, :inline => "export DEBIAN_FRONTEND=noninteractive && apt-get update -qq >/dev/null && apt-get -qq -y --no-install-recommends install git build-essential >/dev/null && cd /root/dokku && #{make_cmd}"
|
||||
vm.vm.provision :shell, :inline => "export DEBIAN_FRONTEND=noninteractive && apt-get update -qq >/dev/null && apt-get -qq -y --no-install-recommends install git build-essential jq >/dev/null && cd /root/dokku && #{make_cmd}"
|
||||
vm.vm.provision :shell do |s|
|
||||
s.inline = <<-EOT
|
||||
echo '"\e[5~": history-search-backward' > /root/.inputrc
|
||||
|
||||
4
debian/control
vendored
4
debian/control
vendored
@@ -1,9 +1,9 @@
|
||||
Package: dokku
|
||||
Version: 0.33.5
|
||||
Version: 0.33.7
|
||||
Section: web
|
||||
Priority: optional
|
||||
Architecture: amd64
|
||||
Depends: apache2-utils, acl, locales, git, cpio, curl, man-db, netcat, sshcommand, docker-engine-cs (>= 17.05.0) | docker-engine (>= 17.05.0) | docker-io (>= 17.05.0) | docker.io (>= 17.05.0) | docker-ce (>= 17.05.0) | docker-ee (>= 17.05.0) | moby-engine, docker-compose-plugin | moby-compose, docker-buildx-plugin | moby-buildx, docker-container-healthchecker, docker-image-labeler, lambda-builder, net-tools, netrc, software-properties-common, parallel, procfile-util, python-software-properties | python3-software-properties, rsync, rsyslog, dos2unix, jq, unzip, util-linux
|
||||
Depends: apache2-utils, locales, git, cpio, curl, man-db, netcat, sshcommand, docker-engine-cs (>= 17.05.0) | docker-engine (>= 17.05.0) | docker-io (>= 17.05.0) | docker.io (>= 17.05.0) | docker-ce (>= 17.05.0) | docker-ee (>= 17.05.0) | moby-engine, docker-compose-plugin | moby-compose, docker-buildx-plugin | moby-buildx, docker-container-healthchecker, docker-image-labeler, lambda-builder, net-tools, netrc, software-properties-common, parallel, procfile-util, python-software-properties | python3-software-properties, rsync, rsyslog, dos2unix, jq, unzip, util-linux
|
||||
Recommends: herokuish, bash-completion, dokku-update, dokku-event-listener
|
||||
Pre-Depends: gliderlabs-sigil, nginx (>= 1.8.0) | openresty, dnsutils, cgroupfs-mount | cgroup-lite, plugn, sudo, python3, debconf
|
||||
Maintainer: Jose Diaz-Gonzalez <dokku@josediazgonzalez.com>
|
||||
|
||||
2
docs/_build/requirements.txt
vendored
2
docs/_build/requirements.txt
vendored
@@ -8,7 +8,7 @@ MarkupSafe==2.1.5
|
||||
mergedeep==1.3.4
|
||||
mkdocs==1.5.3
|
||||
mkdocs-exclude==1.0.2
|
||||
mkdocs-material==9.5.8
|
||||
mkdocs-material==9.5.11
|
||||
mkdocs-material-extensions==1.3.1
|
||||
packaging==23.2
|
||||
Pygments==2.17.2
|
||||
|
||||
@@ -36,35 +36,35 @@ dokku plugin:list
|
||||
|
||||
```
|
||||
plugn: dev
|
||||
00_dokku-standard 0.33.5 enabled dokku core standard plugin
|
||||
20_events 0.33.5 enabled dokku core events logging plugin
|
||||
app-json 0.33.5 enabled dokku core app-json plugin
|
||||
apps 0.33.5 enabled dokku core apps plugin
|
||||
build-env 0.33.5 enabled dokku core build-env plugin
|
||||
buildpacks 0.33.5 enabled dokku core buildpacks plugin
|
||||
certs 0.33.5 enabled dokku core certificate management plugin
|
||||
checks 0.33.5 enabled dokku core checks plugin
|
||||
common 0.33.5 enabled dokku core common plugin
|
||||
config 0.33.5 enabled dokku core config plugin
|
||||
docker-options 0.33.5 enabled dokku core docker-options plugin
|
||||
domains 0.33.5 enabled dokku core domains plugin
|
||||
enter 0.33.5 enabled dokku core enter plugin
|
||||
git 0.33.5 enabled dokku core git plugin
|
||||
logs 0.33.5 enabled dokku core logs plugin
|
||||
network 0.33.5 enabled dokku core network plugin
|
||||
nginx-vhosts 0.33.5 enabled dokku core nginx-vhosts plugin
|
||||
plugin 0.33.5 enabled dokku core plugin plugin
|
||||
proxy 0.33.5 enabled dokku core proxy plugin
|
||||
ps 0.33.5 enabled dokku core ps plugin
|
||||
repo 0.33.5 enabled dokku core repo plugin
|
||||
resource 0.33.5 enabled dokku core resource plugin
|
||||
scheduler-docker-local 0.33.5 enabled dokku core scheduler-docker-local plugin
|
||||
shell 0.33.5 enabled dokku core shell plugin
|
||||
ssh-keys 0.33.5 enabled dokku core ssh-keys plugin
|
||||
storage 0.33.5 enabled dokku core storage plugin
|
||||
tags 0.33.5 enabled dokku core tags plugin
|
||||
tar 0.33.5 enabled dokku core tar plugin
|
||||
trace 0.33.5 enabled dokku core trace plugin
|
||||
00_dokku-standard 0.33.7 enabled dokku core standard plugin
|
||||
20_events 0.33.7 enabled dokku core events logging plugin
|
||||
app-json 0.33.7 enabled dokku core app-json plugin
|
||||
apps 0.33.7 enabled dokku core apps plugin
|
||||
build-env 0.33.7 enabled dokku core build-env plugin
|
||||
buildpacks 0.33.7 enabled dokku core buildpacks plugin
|
||||
certs 0.33.7 enabled dokku core certificate management plugin
|
||||
checks 0.33.7 enabled dokku core checks plugin
|
||||
common 0.33.7 enabled dokku core common plugin
|
||||
config 0.33.7 enabled dokku core config plugin
|
||||
docker-options 0.33.7 enabled dokku core docker-options plugin
|
||||
domains 0.33.7 enabled dokku core domains plugin
|
||||
enter 0.33.7 enabled dokku core enter plugin
|
||||
git 0.33.7 enabled dokku core git plugin
|
||||
logs 0.33.7 enabled dokku core logs plugin
|
||||
network 0.33.7 enabled dokku core network plugin
|
||||
nginx-vhosts 0.33.7 enabled dokku core nginx-vhosts plugin
|
||||
plugin 0.33.7 enabled dokku core plugin plugin
|
||||
proxy 0.33.7 enabled dokku core proxy plugin
|
||||
ps 0.33.7 enabled dokku core ps plugin
|
||||
repo 0.33.7 enabled dokku core repo plugin
|
||||
resource 0.33.7 enabled dokku core resource plugin
|
||||
scheduler-docker-local 0.33.7 enabled dokku core scheduler-docker-local plugin
|
||||
shell 0.33.7 enabled dokku core shell plugin
|
||||
ssh-keys 0.33.7 enabled dokku core ssh-keys plugin
|
||||
storage 0.33.7 enabled dokku core storage plugin
|
||||
tags 0.33.7 enabled dokku core tags plugin
|
||||
tar 0.33.7 enabled dokku core tar plugin
|
||||
trace 0.33.7 enabled dokku core trace plugin
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square70x70logo src="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/mstile-70x70.png"/>
|
||||
<square150x150logo src="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/mstile-150x150.png"/>
|
||||
<square310x310logo src="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/mstile-310x310.png"/>
|
||||
<wide310x150logo src="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/mstile-310x150.png"/>
|
||||
<square70x70logo src="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/mstile-70x70.png"/>
|
||||
<square150x150logo src="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/mstile-150x150.png"/>
|
||||
<square310x310logo src="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/mstile-310x310.png"/>
|
||||
<wide310x150logo src="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/mstile-310x150.png"/>
|
||||
<TileColor>#da532c</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
|
||||
@@ -2,37 +2,37 @@
|
||||
"name": "Dokku",
|
||||
"icons": [
|
||||
{
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.33.5\/docs\/assets\/favicons\/android-chrome-36x36.png",
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.33.7\/docs\/assets\/favicons\/android-chrome-36x36.png",
|
||||
"sizes": "36x36",
|
||||
"type": "image\/png",
|
||||
"density": "0.75"
|
||||
},
|
||||
{
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.33.5\/docs\/assets\/favicons\/android-chrome-48x48.png",
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.33.7\/docs\/assets\/favicons\/android-chrome-48x48.png",
|
||||
"sizes": "48x48",
|
||||
"type": "image\/png",
|
||||
"density": "1.0"
|
||||
},
|
||||
{
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.33.5\/docs\/assets\/favicons\/android-chrome-72x72.png",
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.33.7\/docs\/assets\/favicons\/android-chrome-72x72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image\/png",
|
||||
"density": "1.5"
|
||||
},
|
||||
{
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.33.5\/docs\/assets\/favicons\/android-chrome-96x96.png",
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.33.7\/docs\/assets\/favicons\/android-chrome-96x96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image\/png",
|
||||
"density": "2.0"
|
||||
},
|
||||
{
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.33.5\/docs\/assets\/favicons\/android-chrome-144x144.png",
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.33.7\/docs\/assets\/favicons\/android-chrome-144x144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image\/png",
|
||||
"density": "3.0"
|
||||
},
|
||||
{
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.33.5\/docs\/assets\/favicons\/android-chrome-192x192.png",
|
||||
"src": "https:\/\/cdn.jsdelivr.net\/dokku\/dokku@v0.33.7\/docs\/assets\/favicons\/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image\/png",
|
||||
"density": "4.0"
|
||||
|
||||
@@ -30,6 +30,6 @@
|
||||
"0.30.11",
|
||||
"0.31.5",
|
||||
"0.32.4",
|
||||
"0.33.5"
|
||||
"0.33.7"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ The default value may be set by passing an empty value for the option:
|
||||
dokku scheduler-k3s:set node-js-app image-pull-secrets
|
||||
```
|
||||
|
||||
The `image-pull-secrets` property can also be set globally. The global default is empty string, and k3s will use the local `registries.yaml` for any private registry pulls.
|
||||
The `image-pull-secrets` property can also be set globally. The global default is empty string, and k3s will use Dokku's locally configured `~/.docker/config.json` for any private registry pulls.
|
||||
|
||||
```shell
|
||||
dokku scheduler-k3s:set --global image-pull-secrets 60s
|
||||
@@ -243,7 +243,7 @@ dokku scheduler-k3s:set --global letsencrypt-email-prod automated@dokku.sh
|
||||
dokku scheduler-k3s:set --global letsencrypt-email-stag automated@dokku.sh
|
||||
```
|
||||
|
||||
After enabling and rebuilding, all apps with an `https` port mapping that utilize the related letsencrypt server will be automatically updated to enable ssl. All http requests will then be redirected to https.
|
||||
After enabling and rebuilding, all apps with an `http:80` port mapping will have a corresponding `https:443` added and ssl will be automatically enabled. All http requests will then be redirected to https.
|
||||
|
||||
### Customizing the letsencrypt server
|
||||
|
||||
@@ -320,6 +320,38 @@ By default, Dokku assumes that all it controls all actions on the cluster, and t
|
||||
dokku scheduler-k3s:show-kubeconfig
|
||||
```
|
||||
|
||||
### Interacting with an external Kubernetes cluster
|
||||
|
||||
While the k3s scheduler plugin is designed to work with a Dokku-managed k3s cluster, Dokku can be configured to interact with any Kubernetes cluster by setting the global `kubeconfig-path` to a path to a custom kubeconfig on the Dokku server. This property is only available at a global level.
|
||||
|
||||
```shell
|
||||
dokku scheduler-k3s:set --global kubeconfig-path /path/to/custom/kubeconfig
|
||||
```
|
||||
|
||||
To set the default value, omit the value from the `scheduler-k3s:set` call:
|
||||
|
||||
```shell
|
||||
dokku scheduler-k3s:set --global kubeconfig-path
|
||||
```
|
||||
|
||||
The default value for the `kubeconfig-path` is the k3s kubeconfig located at `/etc/rancher/k3s/k3s.yaml`.
|
||||
|
||||
### Customizing the Kubernetes context
|
||||
|
||||
When interacting with a custom Kubeconfig, the `kube-context` property can be set to specify a specific context within the kubeconfig to use. This property is available only at the global leve.
|
||||
|
||||
```shell
|
||||
dokku scheduler-k3s:set --global kube-context lollipop
|
||||
```
|
||||
|
||||
To set the default value, omit the value from the `scheduler-k3s:set` call:
|
||||
|
||||
```shell
|
||||
dokku scheduler-k3s:set --global kube-context
|
||||
```
|
||||
|
||||
The default value for the `kube-context` is an empty string, and will result in Dokku using the current context within the kubeconfig.
|
||||
|
||||
## Scheduler Interface
|
||||
|
||||
The following sections describe implemented and unimplemented scheduler functionality for the `k3s` scheduler.
|
||||
@@ -361,20 +393,12 @@ App logs for the `logs` command are fetched by Dokku from running containers via
|
||||
|
||||
### Supported Resource Management Properties
|
||||
|
||||
The `k3s` scheduler supports a minimal list of resource _limits_ and _reservations_. The following properties are supported:
|
||||
|
||||
#### Resource Limits
|
||||
|
||||
> [!NOTE]
|
||||
> Cron tasks retrieve resource limits based on the computed cron task ID. If unspecified, the default will be 1 CPU and 512m RAM.
|
||||
The `k3s` scheduler supports a minimal list of resource _limits_ and _reservations_:
|
||||
|
||||
- cpu: is specified in number of CPUs a process can access.
|
||||
- memory: should be specified with a suffix of `b` (bytes), `k` (kilobytes), `m` (megabytes), `g` (gigabytes). Default unit is `m` (megabytes).
|
||||
- memory: should be specified with a suffix of `b` (bytes), `Ki` (kilobytes), `Mi` (megabytes), `Gi` (gigabytes). Default unit is `Mi` (megabytes).
|
||||
|
||||
#### Resource Reservations
|
||||
If unspecified for any task, the default reservation will be `.1` CPU and `128Mi` RAM, with no limit set for either CPU or RAM. This is to avoid issues with overscheduling pods on a cluster. To avoid issues, set more specific values for at least resource reservations. If unbounded utilization is desired, set CPU and Memory to `0m` and `0Mi`, respectively.
|
||||
|
||||
> [!NOTE]
|
||||
> Cron tasks retrieve resource reservations based on the computed cron task ID. If unspecified, the default will be 1 CPU and 512m RAM.
|
||||
|
||||
- cpu: is specified in number of CPUs a process can access.
|
||||
- memory: should be specified with a suffix of `b` (bytes), `k` (kilobytes), `m` (megabytes), `g` (gigabytes). Default unit is `m` (megabytes).
|
||||
> Cron tasks retrieve resource limits based on the computed cron task ID.
|
||||
|
||||
@@ -29,7 +29,7 @@ The workflow looks like this:
|
||||
```shell
|
||||
# having dokku-arch in ../dokku-arch
|
||||
vagrant up build-arch
|
||||
# wait for "==> build-arch: ==> Finished making: dokku 0.33.5-2 (Mon Feb 22 23:20:37 CET 2016)"
|
||||
# wait for "==> build-arch: ==> Finished making: dokku 0.33.7-2 (Mon Feb 22 23:20:37 CET 2016)"
|
||||
cd ../dokku-arch
|
||||
git add PKGBUILD .SRCINFO
|
||||
git commit -m 'Update to dokku 0.9.9'
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Pull the dokku/dokku image:
|
||||
|
||||
```shell
|
||||
docker pull dokku/dokku:0.33.5
|
||||
docker pull dokku/dokku:0.33.7
|
||||
```
|
||||
|
||||
Next, run the image.
|
||||
@@ -19,7 +19,7 @@ docker container run \
|
||||
--publish 8443:443 \
|
||||
--volume /var/lib/dokku:/mnt/dokku \
|
||||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
dokku/dokku:0.33.5
|
||||
dokku/dokku:0.33.7
|
||||
```
|
||||
|
||||
The above command will start a new docker container that is ready when a message similar to `Runit started as PID 12345` appears.
|
||||
@@ -61,7 +61,7 @@ redis: https://github.com/dokku/dokku-redis.git
|
||||
The alternative is to build a custom docker image via a custom Dockerfile. This Dockerfile can run any `plugin:install` command. Note that the version installed at that time will be the one that persists. Below is an example Dockerfile showing this method.
|
||||
|
||||
```Dockerfile
|
||||
FROM dokku/dokku:0.33.5
|
||||
FROM dokku/dokku:0.33.7
|
||||
RUN dokku plugin:install https://github.com/dokku/dokku-postgres.git postgres
|
||||
RUN dokku plugin:install https://github.com/dokku/dokku-redis.git redis
|
||||
```
|
||||
|
||||
@@ -37,8 +37,8 @@ To install the latest stable version of Dokku, you can run the following shell c
|
||||
|
||||
```shell
|
||||
# for debian systems, installs Dokku via apt-get
|
||||
wget -NP . https://dokku.com/install/v0.33.5/bootstrap.sh
|
||||
sudo DOKKU_TAG=v0.33.5 bash bootstrap.sh
|
||||
wget -NP . https://dokku.com/install/v0.33.7/bootstrap.sh
|
||||
sudo DOKKU_TAG=v0.33.7 bash bootstrap.sh
|
||||
```
|
||||
|
||||
The installation process takes about 5-10 minutes, depending upon internet connection speed.
|
||||
|
||||
@@ -10,26 +10,26 @@
|
||||
<meta name="author" content="">
|
||||
<title>Dokku - The smallest PaaS implementation you've ever seen</title>
|
||||
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/android-chrome-192x192.png" sizes="192x192">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/favicon-16x16.png" sizes="16x16">
|
||||
<link rel="manifest" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/manifest.json">
|
||||
<link rel="shortcut icon" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/favicon.ico">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/android-chrome-192x192.png" sizes="192x192">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/favicon-16x16.png" sizes="16x16">
|
||||
<link rel="manifest" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/manifest.json">
|
||||
<link rel="shortcut icon" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/favicon.ico">
|
||||
<meta name="apple-mobile-web-app-title" content="Dokku">
|
||||
<meta name="application-name" content="Dokku">
|
||||
<meta name="msapplication-TileColor" content="#da532c">
|
||||
<meta name="msapplication-TileImage" content="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/mstile-144x144.png">
|
||||
<meta name="msapplication-config" content="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/browserconfig.xml">
|
||||
<meta name="msapplication-TileImage" content="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/mstile-144x144.png">
|
||||
<meta name="msapplication-config" content="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/browserconfig.xml">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
|
||||
@@ -38,7 +38,7 @@
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;700;900&display=swap" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/style.css" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/style.css" rel="stylesheet">
|
||||
<!-- <link href="./assets/style.css" rel="stylesheet"> -->
|
||||
</head>
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
<main class="container px-4 px-lg-5">
|
||||
<div class="row">
|
||||
<div class="col-lg-7">
|
||||
<a class="badge-link" href="https://github.com/dokku/dokku/releases"><span class="badge py-2 d-flex fit-content"><div class="circle align-self-center me-2"></div>Latest release <span id="releaseVersion" class="ms-1">v0.33.5</span></span></a>
|
||||
<a class="badge-link" href="https://github.com/dokku/dokku/releases"><span class="badge py-2 d-flex fit-content"><div class="circle align-self-center me-2"></div>Latest release <span id="releaseVersion" class="ms-1">v0.33.7</span></span></a>
|
||||
<h1 class="text-white hero-heading mt-5">An open source PAAS alternative to Heroku.</h1>
|
||||
<h4 class="text-white mt-5">Dokku helps you build and manage the lifecycle of applications from building to scaling.</h4>
|
||||
<div class="d-flex mt-5">
|
||||
@@ -125,7 +125,7 @@
|
||||
</p>
|
||||
<p class="line">
|
||||
<span class="prompt">$</span>
|
||||
<span class="command">sudo DOKKU_TAG=v0.33.5 bash bootstrap.sh</span>
|
||||
<span class="command">sudo DOKKU_TAG=v0.33.7 bash bootstrap.sh</span>
|
||||
</p>
|
||||
<br>
|
||||
|
||||
@@ -226,8 +226,8 @@
|
||||
</svg>
|
||||
Create</a>
|
||||
<a class="nav-link" id="nav-deploy-tab" data-bs-toggle="tab" href="#nav-deploy" role="tab" aria-controls="nav-deploy" aria-selected="false">
|
||||
<svg width="32" height="32" viewBox="0 0.33.52" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M29.8709 1.40551C29.8591 1.34642 29.8311 1.29205 29.7903 1.24881C29.7495 1.20556 29.6976 1.17524 29.6407 1.16141C25.8466 0.20375 17.082 3.61605 12.3285 8.51812C11.4813 9.38524 10.7088 10.3268 10.0198 11.3321C8.55457 11.1953 7.08939 11.3105 5.84189 11.8721C2.31916 13.4706 1.29423 17.6454 1.00817 19.4376C0.992669 19.5358 0.999288 19.6364 1.02751 19.7315C1.05574 19.8267 1.10481 19.9138 1.17093 19.9862C1.23705 20.0586 1.31844 20.1144 1.40878 20.1491C1.49913 20.1838 1.59601 20.1966 1.69192 20.1865L7.34824 19.5456C7.35215 19.9859 7.37777 20.4257 7.42498 20.8633C7.4545 21.1658 7.58527 21.4482 7.79477 21.6618L9.98487 23.9221C10.1921 24.1384 10.466 24.2734 10.7593 24.3037C11.1808 24.3522 11.6044 24.3786 12.0285 24.3829L11.4082 30.2153C11.3985 30.33.5 11.411 30.414 11.4446 30.507C11.4783 30.6001 11.5323 30.684 11.6023 30.7521C11.6724 30.8202 11.7567 30.8708 11.8487 30.9C11.9408 30.9291 12.0381 30.936 12.1331 30.9202C13.8704 30.6322 17.9241 29.5744 19.4639 25.9396C20.0081 24.6508 20.1198 23.1466 19.9942 21.6417C20.9712 20.9312 21.8861 20.134 22.7285 19.2591C27.4994 14.3627 30.7849 5.51625 29.8709 1.40551ZM18.4878 12.9162C18.0711 12.4862 17.7873 11.9384 17.6723 11.3419C17.5573 10.7455 17.6162 10.1273 17.8417 9.56541C18.0672 9.00356 18.449 8.52333 18.939 8.18546C19.4289 7.84759 20.005 7.66725 20.5942 7.66725C21.1835 7.66725 21.7595 7.84759 22.2494 8.18546C22.7394 8.52333 23.1212 9.00356 23.3467 9.56541C23.5722 10.1273 23.6311 10.7455 23.5161 11.3419C23.4011 11.9384 23.1173 12.4862 22.7006 12.9162C22.4242 13.202 22.0959 13.4288 21.7344 13.5835C21.373 13.7383 20.9855 13.8179 20.5942 13.8179C20.2029 13.8179 19.8154 13.7383 19.454 13.5835C19.0926 13.4288 18.7642 13.202 18.4878 12.9162Z" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<svg width="32" height="32" viewBox="0 0.33.72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M29.8709 1.40551C29.8591 1.34642 29.8311 1.29205 29.7903 1.24881C29.7495 1.20556 29.6976 1.17524 29.6407 1.16141C25.8466 0.20375 17.082 3.61605 12.3285 8.51812C11.4813 9.38524 10.7088 10.3268 10.0198 11.3321C8.55457 11.1953 7.08939 11.3105 5.84189 11.8721C2.31916 13.4706 1.29423 17.6454 1.00817 19.4376C0.992669 19.5358 0.999288 19.6364 1.02751 19.7315C1.05574 19.8267 1.10481 19.9138 1.17093 19.9862C1.23705 20.0586 1.31844 20.1144 1.40878 20.1491C1.49913 20.1838 1.59601 20.1966 1.69192 20.1865L7.34824 19.5456C7.35215 19.9859 7.37777 20.4257 7.42498 20.8633C7.4545 21.1658 7.58527 21.4482 7.79477 21.6618L9.98487 23.9221C10.1921 24.1384 10.466 24.2734 10.7593 24.3037C11.1808 24.3522 11.6044 24.3786 12.0285 24.3829L11.4082 30.2153C11.3985 30.33.7 11.411 30.414 11.4446 30.507C11.4783 30.6001 11.5323 30.684 11.6023 30.7521C11.6724 30.8202 11.7567 30.8708 11.8487 30.9C11.9408 30.9291 12.0381 30.936 12.1331 30.9202C13.8704 30.6322 17.9241 29.5744 19.4639 25.9396C20.0081 24.6508 20.1198 23.1466 19.9942 21.6417C20.9712 20.9312 21.8861 20.134 22.7285 19.2591C27.4994 14.3627 30.7849 5.51625 29.8709 1.40551ZM18.4878 12.9162C18.0711 12.4862 17.7873 11.9384 17.6723 11.3419C17.5573 10.7455 17.6162 10.1273 17.8417 9.56541C18.0672 9.00356 18.449 8.52333 18.939 8.18546C19.4289 7.84759 20.005 7.66725 20.5942 7.66725C21.1835 7.66725 21.7595 7.84759 22.2494 8.18546C22.7394 8.52333 23.1212 9.00356 23.3467 9.56541C23.5722 10.1273 23.6311 10.7455 23.5161 11.3419C23.4011 11.9384 23.1173 12.4862 22.7006 12.9162C22.4242 13.202 22.0959 13.4288 21.7344 13.5835C21.373 13.7383 20.9855 13.8179 20.5942 13.8179C20.2029 13.8179 19.8154 13.7383 19.454 13.5835C19.0926 13.4288 18.7642 13.202 18.4878 12.9162Z" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<path d="M5.29982 22.8765C4.60428 22.9646 3.95721 23.29 3.46136 23.801C2.232 25.074 2.11548 29.7889 2.11548 29.7889C2.11548 29.7889 6.68686 29.6687 7.91692 28.3985C8.41409 27.8876 8.72993 27.2187 8.81347 26.4997" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
||||
Deploy</a>
|
||||
@@ -382,11 +382,11 @@
|
||||
<path d="M349.4,526.666C349.111,527.157,348.412,528.058,348.297,529.367C348.275,529.592,348.093,529.731,348.121,529.384C348.246,528.107,348.805,527.306,349.23,526.61C349.422,526.327,349.513,526.459,349.402,526.667L349.4,526.666Z" fill="#002B64" transform="translate(348.784,528.021) translate(-348.784,-528.021)"/>
|
||||
<path d="M349.112,526.377C348.782,526.842,347.705,527.923,347.479,529.217C347.439,529.438,347.245,529.564,347.302,529.219C347.535,527.956,348.464,526.962,348.943,526.301C349.159,526.035,349.238,526.174,349.111,526.372L349.112,526.377Z" fill="#002B64" transform="translate(348.232,527.793) translate(-348.232,-527.793)"/>
|
||||
<path d="M348.823,526.088C348.43,526.504,347.147,527.879,346.743,529.122C346.671,529.335,346.462,529.431,346.567,529.098C346.974,527.879,348.098,526.568,348.667,525.978C348.918,525.745,348.976,525.894,348.823,526.072L348.823,526.088Z" fill="#002B64" transform="translate(347.723,527.587) translate(-347.723,-527.587)"/>
|
||||
<path d="M336.092,563.3L336.092,570.461L335.188,570.461L335.188,569.233C334.368,570.213,333.434,570.704,332.388,570.704C331.334,570.704,330.444,570.33.529.726,569.584C329.005,568.829,328.647,567.934,328.647,566.899C328.647,565.855,329.012,564.964,329.739,564.237C330.467,563.491,331.341,563.117,332.356,563.117C333.526,563.117,334.474,563.617,335.202,564.615L335.202,563.307L336.106,563.307L336.092,563.3ZM335.257,566.933C335.257,566.114,334.981,565.426,334.433,564.868C333.884,564.301,333.209,564.019,332.409,564.019C331.617,564.019,330.947,564.31,330.398,564.895C329.85,565.472,329.574,566.155,329.574,566.947C329.574,567.739,329.854,568.428,330.412,569.013C330.97,569.589,331.635,569.876,332.409,569.876C333.191,569.876,333.861,569.596,334.419,569.038C334.977,568.48,335.257,567.778,335.257,566.933" fill="#A57242" transform="translate(332.377,566.91) translate(-332.377,-566.91)"/>
|
||||
<path d="M336.092,563.3L336.092,570.461L335.188,570.461L335.188,569.233C334.368,570.213,333.434,570.704,332.388,570.704C331.334,570.704,330.444,570.33.729.726,569.584C329.005,568.829,328.647,567.934,328.647,566.899C328.647,565.855,329.012,564.964,329.739,564.237C330.467,563.491,331.341,563.117,332.356,563.117C333.526,563.117,334.474,563.617,335.202,564.615L335.202,563.307L336.106,563.307L336.092,563.3ZM335.257,566.933C335.257,566.114,334.981,565.426,334.433,564.868C333.884,564.301,333.209,564.019,332.409,564.019C331.617,564.019,330.947,564.31,330.398,564.895C329.85,565.472,329.574,566.155,329.574,566.947C329.574,567.739,329.854,568.428,330.412,569.013C330.97,569.589,331.635,569.876,332.409,569.876C333.191,569.876,333.861,569.596,334.419,569.038C334.977,568.48,335.257,567.778,335.257,566.933" fill="#A57242" transform="translate(332.377,566.91) translate(-332.377,-566.91)"/>
|
||||
<path d="M338.213,570.415L338.213,560.73L340.224,560.73C341.601,560.73,342.611,560.833,343.253,561.04C343.901,561.238,344.458,561.556,344.926,561.997C345.395,562.428,345.755,562.958,346.005,563.59C346.258,564.218,346.384,564.957,346.384,565.802C346.384,566.64,346.186,567.429,345.789,568.166C345.401,568.903,344.871,569.46,344.197,569.839C343.531,570.218,342.569,570.406,341.305,570.406L338.207,570.406L338.213,570.415ZM339.138,569.488L340.258,569.488C341.429,569.488,342.273,569.429,342.806,569.312C343.336,569.195,343.8,568.966,344.197,568.624C344.591,568.273,344.894,567.851,345.101,567.355C345.308,566.859,345.411,566.295,345.411,565.654C345.411,565.016,345.289,564.426,345.046,563.887C344.812,563.348,344.474,562.902,344.034,562.551C343.593,562.2,343.072,561.966,342.468,561.849C341.874,561.723,340.997,561.66,339.829,561.66L339.141,561.66L339.141,569.486" fill="#A57242" transform="translate(342.296,565.572) translate(-342.296,-565.572)"/>
|
||||
<path d="M325.591,561.235C325.591,561.028,325.663,560.847,325.807,560.696C325.96,560.543,326.14,560.466,326.346,560.466C326.562,560.466,326.741,560.543,326.885,560.696C327.038,560.839,327.115,561.019,327.115,561.235C327.115,561.442,327.039,561.623,326.885,561.774C326.742,561.918,326.562,561.99,326.346,561.99C326.139,561.99,325.958,561.914,325.807,561.761C325.663,561.608,325.591,561.433,325.591,561.235L325.591,561.235ZM325.887,563.232L326.819,563.232L326.819,570.392L325.887,570.392L325.887,563.232Z" fill="#A57242" transform="translate(326.353,565.429) translate(-326.353,-565.429)"/>
|
||||
<path d="M300,570.415L301.377,560.73L301.526,560.73L305.473,568.671L309.375,560.73L309.523,560.73L310.914,570.415L309.957,570.415L309.011,563.484L305.592,570.415L305.348,570.415L301.883,563.415L300.937,570.415L300.006,570.415" fill="#A57242" transform="translate(305.457,565.572) translate(-305.457,-565.572)"/>
|
||||
<path d="M319.679,563.3L319.679,570.461L318.775,570.461L318.775,569.233C317.956,570.213,317.022,570.704,315.975,570.704C314.922,570.704,314.031,570.33.513.313,569.584C312.592,568.829,312.234,567.934,312.234,566.899C312.234,565.855,312.599,564.964,313.327,564.237C314.054,563.491,314.929,563.117,315.943,563.117C317.114,563.117,318.061,563.617,318.789,564.615L318.789,563.307L319.693,563.307L319.679,563.3ZM318.844,566.933C318.844,566.114,318.569,565.426,318.02,564.868C317.472,564.301,316.797,564.019,315.996,564.019C315.204,564.019,314.534,564.31,313.985,564.895C313.437,565.472,313.162,566.155,313.162,566.947C313.162,567.739,313.442,568.428,313.999,569.013C314.557,569.589,315.222,569.876,315.996,569.876C316.779,569.876,317.449,569.596,318.006,569.038C318.564,568.48,318.842,567.778,318.844,566.933" fill="#A57242" transform="translate(315.963,566.91) translate(-315.963,-566.91)"/>
|
||||
<path d="M319.679,563.3L319.679,570.461L318.775,570.461L318.775,569.233C317.956,570.213,317.022,570.704,315.975,570.704C314.922,570.704,314.031,570.33.713.313,569.584C312.592,568.829,312.234,567.934,312.234,566.899C312.234,565.855,312.599,564.964,313.327,564.237C314.054,563.491,314.929,563.117,315.943,563.117C317.114,563.117,318.061,563.617,318.789,564.615L318.789,563.307L319.693,563.307L319.679,563.3ZM318.844,566.933C318.844,566.114,318.569,565.426,318.02,564.868C317.472,564.301,316.797,564.019,315.996,564.019C315.204,564.019,314.534,564.31,313.985,564.895C313.437,565.472,313.162,566.155,313.162,566.947C313.162,567.739,313.442,568.428,313.999,569.013C314.557,569.589,315.222,569.876,315.996,569.876C316.779,569.876,317.449,569.596,318.006,569.038C318.564,568.48,318.842,567.778,318.844,566.933" fill="#A57242" transform="translate(315.963,566.91) translate(-315.963,-566.91)"/>
|
||||
<path d="M321.342,563.3L322.287,563.3L322.287,564.34C322.54,563.918,322.783,563.608,323.015,563.408C323.258,563.21,323.522,563.112,323.811,563.112C324.107,563.112,324.406,563.193,324.702,563.355L324.215,564.138C324.08,564.057,323.94,564.017,323.797,564.017C323.517,564.017,323.254,564.161,323.001,564.448C322.758,564.735,322.579,565.109,322.462,565.568C322.345,566.018,322.286,566.842,322.286,568.047L322.286,570.479L321.341,570.479L321.341,563.319" fill="#A57242" transform="translate(323.022,566.795) translate(-323.022,-566.795)"/>
|
||||
<path d="M348.198,560.776L350.114,560.776C351.131,560.776,351.9,560.983,352.432,561.396C352.962,561.799,353.228,562.385,353.228,563.149C353.228,563.571,353.121,563.964,352.905,564.322C352.698,564.673,352.393,564.955,351.987,565.171C352.652,565.387,353.157,565.71,353.497,566.142C353.848,566.573,354.023,567.087,354.023,567.679C354.023,568.48,353.731,569.146,353.146,569.676C352.561,570.197,351.806,570.459,350.878,570.459L348.216,570.459L348.216,560.774L348.198,560.776ZM349.173,561.719L349.173,564.817L349.726,564.817C350.571,564.817,351.202,564.682,351.615,564.413C352.028,564.143,352.235,563.72,352.235,563.144C352.235,562.192,351.588,561.715,350.291,561.715L349.171,561.715L349.173,561.719ZM349.171,565.8L349.171,569.518L350.371,569.518C351.064,569.518,351.571,569.45,351.895,569.315C352.228,569.171,352.499,568.955,352.705,568.668C352.912,568.372,353.015,568.069,353.015,567.764C353.015,567.459,352.956,567.188,352.84,566.954C352.723,566.72,352.548,566.513,352.314,566.334C352.089,566.154,351.814,566.02,351.49,565.93C351.176,565.84,350.581,565.795,349.709,565.795L349.17,565.795" fill="#A57242" transform="translate(351.111,565.617) translate(-351.111,-565.617)"/>
|
||||
</g>
|
||||
@@ -402,7 +402,7 @@
|
||||
<ellipse fill="white" rx="51.2566" ry="51.2566" transform="translate(461.257,119.257)"/>
|
||||
<path d="M475.312,132.542C475.678,129.494,475.568,129.047,477.839,129.541L478.415,129.591C480.161,129.671,482.445,129.311,483.786,128.687C486.675,127.347,488.387,125.109,485.539,125.697C479.043,127.038,478.596,124.838,478.596,124.838C485.456,114.66,488.324,101.74,485.849,98.5769C479.097,89.9505,467.411,94.0298,467.216,94.1357L467.154,94.1472C465.87,93.8808,464.434,93.7217,462.82,93.6956C459.88,93.6473,457.649,94.4663,455.957,95.7498C455.957,95.7498,435.11,87.1609,436.08,106.551C436.286,110.676,441.992,137.763,448.798,129.582C451.285,126.59,453.689,124.06,453.689,124.06C454.883,124.853,456.312,125.258,457.811,125.112L457.927,125.014C457.891,125.385,457.907,125.748,457.973,126.179C456.22,128.138,456.735,128.481,453.23,129.203C449.684,129.934,451.767,131.235,453.127,131.575C454.776,131.988,458.591,132.572,461.17,128.963L461.067,129.375C461.755,129.925,461.708,133.33,461.806,135.762C461.904,138.195,462.066,140.465,462.562,141.803C463.058,143.141,463.643,146.588,468.25,145.601C472.1,144.776,475.044,143.588,475.312,132.542" fill="black" transform="translate(461.523,119.428) translate(-461.523,-119.428)"/>
|
||||
<path d="M475.312,132.542C475.678,129.494,475.568,129.047,477.839,129.541L478.415,129.591C480.161,129.671,482.445,129.311,483.786,128.687C486.675,127.347,488.387,125.109,485.539,125.697C479.043,127.038,478.596,124.838,478.596,124.838C485.456,114.66,488.324,101.74,485.849,98.5769C479.097,89.9505,467.411,94.0298,467.216,94.1357L467.154,94.1472C465.87,93.8808,464.434,93.7217,462.82,93.6956C459.88,93.6473,457.649,94.4663,455.957,95.7498C455.957,95.7498,435.11,87.1609,436.08,106.551C436.286,110.676,441.992,137.763,448.798,129.582C451.285,126.59,453.689,124.06,453.689,124.06C454.883,124.853,456.312,125.258,457.811,125.112L457.927,125.014C457.891,125.385,457.907,125.748,457.973,126.179C456.22,128.138,456.735,128.481,453.23,129.203C449.684,129.934,451.767,131.235,453.127,131.575C454.776,131.988,458.591,132.572,461.17,128.963L461.067,129.375C461.755,129.925,461.708,133.33,461.806,135.762C461.904,138.195,462.066,140.465,462.562,141.803C463.058,143.141,463.643,146.588,468.25,145.601C472.1,144.776,475.044,143.588,475.312,132.542" stroke="black" stroke-width="5.4" transform="translate(461.523,119.428) translate(-461.523,-119.428)"/>
|
||||
<path d="M485.539,125.697C479.042,127.037,478.596,124.838,478.596,124.838C485.455,114.659,488.323,101.738,485.848,98.5761C479.097,89.9502,467.411,94.0297,467.216,94.1356L467.153,94.1469C465.869,93.8804,464.433,93.7217,462.818,93.6953C459.878,93.6471,457.648,94.466,455.956,95.7492C455.956,95.7492,435.109,87.1608,436.078,106.551C436.284,110.676,441.991,137.763,448.797,129.581C451.284,126.59,453.688,124.06,453.688,124.06C454.882,124.853,456.311,125.258,457.809,125.112L457.925,125.014C457.889,125.385,457.906,125.748,457.972,126.178C456.219,128.137,456.734,128.481,453.229,129.203C449.682,129.934,451.766,131.235,453.126,131.575C454.775,131.988,458.59,132.572,461.168,128.963L461.065,129.375C461.752,129.925,462.235,132.954,462.154,135.7C462.073,138.445,462.019,140.33.562.561,141.803C463.102,143.275,463.641,146.588,468.249,145.601C472.099,144.776,474.094,142.638,474.372,139.071C474.569,136.536,475.014,136.911,475.043,134.644L475.4,133.571C475.812,130.133,475.466,129.025,477.838,129.54L478.414,129.591C480.16,129.67,482.445,129.31,483.786,128.687C486.674,127.347,488.386,125.109,485.539,125.697L485.539,125.697Z" fill="#336791" transform="translate(461.522,119.431) translate(-461.522,-119.431)"/>
|
||||
<path d="M485.539,125.697C479.042,127.037,478.596,124.838,478.596,124.838C485.455,114.659,488.323,101.738,485.848,98.5761C479.097,89.9502,467.411,94.0297,467.216,94.1356L467.153,94.1469C465.869,93.8804,464.433,93.7217,462.818,93.6953C459.878,93.6471,457.648,94.466,455.956,95.7492C455.956,95.7492,435.109,87.1608,436.078,106.551C436.284,110.676,441.991,137.763,448.797,129.581C451.284,126.59,453.688,124.06,453.688,124.06C454.882,124.853,456.311,125.258,457.809,125.112L457.925,125.014C457.889,125.385,457.906,125.748,457.972,126.178C456.219,128.137,456.734,128.481,453.229,129.203C449.682,129.934,451.766,131.235,453.126,131.575C454.775,131.988,458.59,132.572,461.168,128.963L461.065,129.375C461.752,129.925,462.235,132.954,462.154,135.7C462.073,138.445,462.019,140.33.762.561,141.803C463.102,143.275,463.641,146.588,468.249,145.601C472.099,144.776,474.094,142.638,474.372,139.071C474.569,136.536,475.014,136.911,475.043,134.644L475.4,133.571C475.812,130.133,475.466,129.025,477.838,129.54L478.414,129.591C480.16,129.67,482.445,129.31,483.786,128.687C486.674,127.347,488.386,125.109,485.539,125.697L485.539,125.697Z" fill="#336791" transform="translate(461.522,119.431) translate(-461.522,-119.431)"/>
|
||||
<path d="M461.448,127.667C461.269,134.063,461.493,140.503,462.119,142.068C462.745,143.633,464.085,146.677,468.693,145.69C472.543,144.865,473.944,143.268,474.551,139.742C474.999,137.149,475.862,129.945,475.973,128.469" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="translate(468.681,136.775) translate(-468.681,-136.775)"/>
|
||||
<path d="M455.925,95.6064C455.925,95.6064,435.063,87.0798,436.033,106.47C436.239,110.595,441.946,137.683,448.752,129.501C451.239,126.509,453.488,124.162,453.488,124.162" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="translate(445.963,112.386) translate(-445.963,-112.386)"/>
|
||||
<path d="M467.194,94.0502C466.472,94.2766,478.799,89.5439,485.804,98.4954C488.279,101.658,485.411,114.578,478.551,124.757" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="translate(476.923,108.879) translate(-476.923,-108.879)"/>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
```
|
||||
run [-e|--env KEY=VALUE] [--no-tty] <app> <cmd> # Run a command in a new container using the current app image
|
||||
run:detached [-e|-env KEY=VALUE] [--no-tty] <app> <cmd> # Run a command in a new detached container using the current app image
|
||||
run:detached [-e|-env KEY=VALUE] [--force-tty] <app> <cmd> # Run a command in a new detached container using the current app image
|
||||
run:list [--format json|stdout] [<app>] # List all run containers for an app
|
||||
run:logs <app|--container CONTAINER> [-h] [-t] [-n num] [-q] # Display recent log output for run containers
|
||||
run:stop <app|--container CONTAINER> # Stops all run containers for an app or a specified run container
|
||||
@@ -73,6 +73,12 @@ dokku run:detached node-js-app ls -lah
|
||||
# returns the ID of the new container
|
||||
```
|
||||
|
||||
To start a detached container with a tty, specify the `--force-tty` flag. Containers will still exit upon command termination, but can be attached to as long as they are running.
|
||||
|
||||
```shell
|
||||
dokku run:detached --force-tty node-js-app bash
|
||||
```
|
||||
|
||||
### Displaying one-off container logs
|
||||
|
||||
You can easily get logs of all one-off containers for an app using the `logs` command:
|
||||
|
||||
@@ -9,26 +9,26 @@
|
||||
<meta name="author" content="">
|
||||
<title>Dokku - {{DOC_TITLE}}</title>
|
||||
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/apple-touch-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/android-chrome-192x192.png" sizes="192x192">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/favicon-16x16.png" sizes="16x16">
|
||||
<link rel="manifest" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/manifest.json">
|
||||
<link rel="shortcut icon" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/favicon.ico">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/apple-touch-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/favicon-32x32.png" sizes="32x32">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/android-chrome-192x192.png" sizes="192x192">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/favicon-96x96.png" sizes="96x96">
|
||||
<link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/favicon-16x16.png" sizes="16x16">
|
||||
<link rel="manifest" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/manifest.json">
|
||||
<link rel="shortcut icon" href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/favicon.ico">
|
||||
<meta name="apple-mobile-web-app-title" content="Dokku">
|
||||
<meta name="application-name" content="Dokku">
|
||||
<meta name="msapplication-TileColor" content="#da532c">
|
||||
<meta name="msapplication-TileImage" content="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/mstile-144x144.png">
|
||||
<meta name="msapplication-config" content="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/favicons/browserconfig.xml">
|
||||
<meta name="msapplication-TileImage" content="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/mstile-144x144.png">
|
||||
<meta name="msapplication-config" content="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/favicons/browserconfig.xml">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<script>
|
||||
@@ -48,7 +48,7 @@
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;700;900&display=swap" rel="stylesheet">
|
||||
|
||||
<link href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.5/docs/assets/style.css" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/gh/dokku/dokku@v0.33.7/docs/assets/style.css" rel="stylesheet">
|
||||
<!-- <link href="./assets/style.css" rel="stylesheet"> -->
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core standard plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core events logging plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package appjson
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
@@ -332,13 +331,16 @@ func executeScript(appName string, image string, imageTag string, phase string)
|
||||
fmt.Sprintf("LABEL com.dokku.%s-phase=true", phase),
|
||||
}...)
|
||||
commitArgs = append(commitArgs, containerID, image)
|
||||
containerCommitCmd := common.NewShellCmdWithArgs(
|
||||
common.DockerBin(),
|
||||
commitArgs...,
|
||||
)
|
||||
containerCommitCmd.ShowOutput = false
|
||||
containerCommitCmd.Command.Stderr = os.Stderr
|
||||
if !containerCommitCmd.Execute() {
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: common.DockerBin(),
|
||||
Args: commitArgs,
|
||||
StreamStderr: true,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Commiting of '%s' to image failed: %w", phase, err)
|
||||
}
|
||||
|
||||
if result.ExitCode != 0 {
|
||||
return fmt.Errorf("Commiting of '%s' to image failed: %s", phase, command)
|
||||
}
|
||||
|
||||
@@ -390,34 +392,11 @@ func getCommandFromImage(image string) (string, error) {
|
||||
}
|
||||
|
||||
func waitForExecution(containerID string) bool {
|
||||
containerStartCmd := common.NewShellCmdWithArgs(
|
||||
common.DockerBin(),
|
||||
"container",
|
||||
"start",
|
||||
containerID,
|
||||
)
|
||||
containerStartCmd.ShowOutput = false
|
||||
containerStartCmd.Command.Stderr = os.Stderr
|
||||
if !containerStartCmd.Execute() {
|
||||
if !common.ContainerStart(containerID) {
|
||||
return false
|
||||
}
|
||||
|
||||
containerWaitCmd := common.NewShellCmdWithArgs(
|
||||
common.DockerBin(),
|
||||
"container",
|
||||
"wait",
|
||||
containerID,
|
||||
)
|
||||
|
||||
containerWaitCmd.ShowOutput = false
|
||||
containerWaitCmd.Command.Stderr = os.Stderr
|
||||
b, err := containerWaitCmd.Output()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
containerExitCode := strings.TrimSpace(string(b[:]))
|
||||
return containerExitCode == "0"
|
||||
return common.ContainerWait(containerID)
|
||||
}
|
||||
|
||||
func createdContainerID(appName string, dockerArgs []string, image string, command []string, phase string) (string, error) {
|
||||
@@ -440,21 +419,19 @@ func createdContainerID(appName string, dockerArgs []string, image string, comma
|
||||
return "", err
|
||||
}
|
||||
|
||||
containerCreateCmd := common.NewShellCmdWithArgs(
|
||||
common.DockerBin(),
|
||||
arguments...,
|
||||
)
|
||||
var stderr bytes.Buffer
|
||||
containerCreateCmd.Env = env
|
||||
containerCreateCmd.ShowOutput = false
|
||||
containerCreateCmd.Command.Stderr = &stderr
|
||||
|
||||
b, err = containerCreateCmd.Output()
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: common.DockerBin(),
|
||||
Args: arguments,
|
||||
Env: env,
|
||||
})
|
||||
if err != nil {
|
||||
return "", errors.New(stderr.String())
|
||||
return "", err
|
||||
}
|
||||
if result.ExitCode != 0 {
|
||||
return "", errors.New(result.StderrContents())
|
||||
}
|
||||
|
||||
containerID := strings.TrimSpace(string(b))
|
||||
containerID := result.StdoutContents()
|
||||
err = common.PlugnTrigger("post-container-create", []string{"app", containerID, appName, phase}...)
|
||||
return containerID, err
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core app-json plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -19,8 +19,7 @@ Additional commands:`
|
||||
|
||||
helpContent = `
|
||||
app-json:report [<app>] [<flag>], Displays a app-json report for one or more apps
|
||||
app-json:set <app> <property> (<value>), Set or clear a app-json property for an app
|
||||
`
|
||||
app-json:set <app> <property> (<value>), Set or clear a app-json property for an app`
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -33,10 +32,8 @@ func main() {
|
||||
usage()
|
||||
case "help":
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
CaptureOutput: true,
|
||||
StreamStdio: false,
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
})
|
||||
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
|
||||
fmt.Println(helpContent)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core apps plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -28,8 +28,7 @@ Additional commands:`
|
||||
apps:locked <app>, Checks if an app is locked for deployment
|
||||
apps:rename <old-app> <new-app>, Rename an app
|
||||
apps:report [<app>] [<flag>], Display report about an app
|
||||
apps:unlock <app>, Unlocks an app for deployment
|
||||
`
|
||||
apps:unlock <app>, Unlocks an app for deployment`
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -50,10 +49,8 @@ func main() {
|
||||
usage()
|
||||
case "help":
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
CaptureOutput: true,
|
||||
StreamStdio: false,
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
})
|
||||
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
|
||||
fmt.Println(helpContent)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core builder-dockerfile plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -36,27 +36,24 @@ trigger-builder-herokuish-builder-build() {
|
||||
local CID TAR_CID
|
||||
|
||||
pushd "$SOURCECODE_WORK_DIR" &>/dev/null
|
||||
if [[ -f "$SOURCECODE_WORK_DIR/.dockerignore" ]]; then
|
||||
rm -f "$SOURCECODE_WORK_DIR/.dockerignore"
|
||||
fi
|
||||
|
||||
eval "$(config_export app "$APP")"
|
||||
plugn trigger builder-create-dokku-image "$BUILDER_TYPE" "$APP" "$SOURCECODE_WORK_DIR" "$DOKKU_IMAGE"
|
||||
NEW_DOKKU_IMAGE=$(plugn trigger builder-dokku-image "$BUILDER_TYPE" "$APP" "$SOURCECODE_WORK_DIR" "$DOKKU_IMAGE")
|
||||
[[ -n "$NEW_DOKKU_IMAGE" ]] && DOKKU_IMAGE="$NEW_DOKKU_IMAGE"
|
||||
|
||||
if ! TAR_CID=$(tar -c . | "$DOCKER_BIN" container run "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -i -a stdin "$DOKKU_IMAGE" /bin/bash -c "mkdir -p /app && tar -xC /app"); then
|
||||
local DOCKER_BUILD_LABEL_ARGS="--label=org.label-schema.schema-version=1.0 --label=org.label-schema.vendor=dokku --label=com.dokku.app-name=$APP"
|
||||
DOKKU_APP_USER=$(config_get "$APP" DOKKU_APP_USER || true)
|
||||
DOKKU_APP_USER=${DOKKU_APP_USER:="herokuishuser"}
|
||||
if ! suppress_output "$DOCKER_BIN" image build "${DOCKER_BUILD_LABEL_ARGS[@]}" $DOKKU_GLOBAL_BUILD_ARGS -f "$PLUGIN_AVAILABLE_PATH/builder-herokuish/dockerfiles/copy-source.Dockerfile" --build-arg APP_IMAGE="$DOKKU_IMAGE" --build-arg DOKKU_APP_USER=$DOKKU_APP_USER -t $IMAGE "$SOURCECODE_WORK_DIR"; then
|
||||
DOKKU_SKIP_IMAGE_CLEANUP_REGISTRATION=1 plugn trigger scheduler-register-retired "$APP" "$TAR_CID"
|
||||
dokku_log_warn "Failure extracting app code"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if test "$("$DOCKER_BIN" container wait "$TAR_CID")" -ne 0; then
|
||||
DOKKU_SKIP_IMAGE_CLEANUP_REGISTRATION=1 plugn trigger scheduler-register-retired "$APP" "$TAR_CID"
|
||||
dokku_log_warn "Failure extracting app code"
|
||||
return 1
|
||||
fi
|
||||
|
||||
"$DOCKER_BIN" container commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "$TAR_CID" "$IMAGE" >/dev/null
|
||||
DOKKU_SKIP_IMAGE_CLEANUP_REGISTRATION=1 plugn trigger scheduler-register-retired "$APP" "$TAR_CID"
|
||||
|
||||
if fn-plugn-trigger-exists "pre-build-buildpack"; then
|
||||
dokku_log_warn "Deprecated: please upgrade plugin to use 'pre-build' plugin trigger instead of pre-build-buildpack"
|
||||
plugn trigger pre-build-buildpack "$APP" "$SOURCECODE_WORK_DIR"
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
ARG APP_IMAGE
|
||||
FROM $APP_IMAGE
|
||||
|
||||
ARG DOKKU_APP_USER herokuishuser
|
||||
RUN USER=$DOKKU_APP_USER /exec true
|
||||
COPY --chown=$DOKKU_APP_USER . /app
|
||||
WORKDIR /app
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core builder-herokuish plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core builder-lambda plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core builder-nixpacks plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core builder-null plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core builder-pack plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
@@ -11,25 +10,18 @@ import (
|
||||
)
|
||||
|
||||
func listImagesByImageRepo(imageRepo string) ([]string, error) {
|
||||
command := []string{
|
||||
common.DockerBin(),
|
||||
"image",
|
||||
"ls",
|
||||
"--quiet",
|
||||
imageRepo,
|
||||
}
|
||||
|
||||
var stderr bytes.Buffer
|
||||
listCmd := common.NewShellCmd(strings.Join(command, " "))
|
||||
listCmd.ShowOutput = false
|
||||
listCmd.Command.Stderr = &stderr
|
||||
b, err := listCmd.Output()
|
||||
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: common.DockerBin(),
|
||||
Args: []string{"image", "ls", "--quiet", imageRepo},
|
||||
})
|
||||
if err != nil {
|
||||
return []string{}, errors.New(strings.TrimSpace(stderr.String()))
|
||||
return []string{}, fmt.Errorf("Unable to list images: %w", err)
|
||||
}
|
||||
if result.ExitCode != 0 {
|
||||
return []string{}, fmt.Errorf("Unable to list images: %s", result.StderrContents())
|
||||
}
|
||||
|
||||
output := strings.Split(strings.TrimSpace(string(b[:])), "\n")
|
||||
output := strings.Split(result.StdoutContents(), "\n")
|
||||
return output, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core builder plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -19,8 +19,7 @@ Additional commands:`
|
||||
|
||||
helpContent = `
|
||||
builder:report [<app>] [<flag>], Displays a builder report for one or more apps
|
||||
builder:set <app> <property> (<value>), Set or clear a builder property for an app
|
||||
`
|
||||
builder:set <app> <property> (<value>), Set or clear a builder property for an app`
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -33,10 +32,8 @@ func main() {
|
||||
usage()
|
||||
case "help":
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
CaptureOutput: true,
|
||||
StreamStdio: false,
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
})
|
||||
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
|
||||
fmt.Println(helpContent)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core buildpacks plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -24,8 +24,7 @@ Additional commands:`
|
||||
buildpacks:remove <app> <buildpack>, Remove a buildpack set on the app
|
||||
buildpacks:report [<app>] [<flag>], Displays a buildpack report for one or more apps
|
||||
buildpacks:set [--index 1] <app> <buildpack>, Set new app buildpack at a given position defaulting to the first buildpack if no index is specified
|
||||
buildpacks:set-property [--global|<app>] <key> <value>, Set or clear a buildpacks property for an app
|
||||
`
|
||||
buildpacks:set-property [--global|<app>] <key> <value>, Set or clear a buildpacks property for an app`
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -38,10 +37,8 @@ func main() {
|
||||
usage()
|
||||
case "help":
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
CaptureOutput: true,
|
||||
StreamStdio: false,
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
})
|
||||
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
|
||||
fmt.Println(helpContent)
|
||||
|
||||
1
plugins/caddy-vhosts/Dockerfile
Normal file
1
plugins/caddy-vhosts/Dockerfile
Normal file
@@ -0,0 +1 @@
|
||||
FROM lucaslorentz/caddy-docker-proxy:2.8
|
||||
@@ -46,7 +46,7 @@ fn-caddy-template-compose-file() {
|
||||
}
|
||||
|
||||
fn-caddy-image() {
|
||||
fn-plugin-property-get-default "caddy" "--global" "image" "lucaslorentz/caddy-docker-proxy:2.8"
|
||||
fn-plugin-property-get-default "caddy" "--global" "image" "$(grep "FROM" "$PLUGIN_AVAILABLE_PATH/caddy-vhosts/Dockerfile" | awk '{print $2}')"
|
||||
}
|
||||
|
||||
fn-caddy-letsencrypt-email() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core caddy-vhosts plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core certificate management plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core checks plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/codeskyblue/go-sh"
|
||||
)
|
||||
|
||||
// ContainerIsRunning checks to see if a container is running
|
||||
@@ -21,40 +17,54 @@ func ContainerIsRunning(containerID string) bool {
|
||||
}
|
||||
|
||||
// ContainerStart runs 'docker container start' against an existing container
|
||||
// whether that container is running or not
|
||||
func ContainerStart(containerID string) bool {
|
||||
cmd := sh.Command(DockerBin(), "container", "start", containerID)
|
||||
cmd.Stdout = nil
|
||||
cmd.Stderr = nil
|
||||
if err := cmd.Run(); err != nil {
|
||||
result, err := CallExecCommand(ExecCommandInput{
|
||||
Command: DockerBin(),
|
||||
Args: []string{"container", "start", containerID},
|
||||
StreamStderr: true,
|
||||
})
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
return result.ExitCode == 0
|
||||
}
|
||||
|
||||
// ContainerRemove runs 'docker container remove' against an existing container
|
||||
func ContainerRemove(containerID string) bool {
|
||||
cmd := sh.Command(DockerBin(), "container", "remove", "-f", containerID)
|
||||
cmd.Stdout = nil
|
||||
cmd.Stderr = nil
|
||||
if err := cmd.Run(); err != nil {
|
||||
result, err := CallExecCommand(ExecCommandInput{
|
||||
Command: DockerBin(),
|
||||
Args: []string{"container", "remove", "-f", containerID},
|
||||
StreamStderr: true,
|
||||
})
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
return result.ExitCode == 0
|
||||
}
|
||||
|
||||
// ContainerExists checks to see if a container exists
|
||||
func ContainerExists(containerID string) bool {
|
||||
cmd := sh.Command(DockerBin(), "container", "inspect", containerID)
|
||||
cmd.Stdout = nil
|
||||
cmd.Stderr = nil
|
||||
if err := cmd.Run(); err != nil {
|
||||
result, err := CallExecCommand(ExecCommandInput{
|
||||
Command: DockerBin(),
|
||||
Args: []string{"container", "inspect", containerID},
|
||||
})
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return result.ExitCode == 0
|
||||
}
|
||||
|
||||
return true
|
||||
// ContainerWait runs 'docker container wait' against an existing container
|
||||
func ContainerWait(containerID string) bool {
|
||||
result, err := CallExecCommand(ExecCommandInput{
|
||||
Command: DockerBin(),
|
||||
Args: []string{"container", "wait", containerID},
|
||||
StreamStderr: true,
|
||||
})
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return result.ExitCode == 0
|
||||
}
|
||||
|
||||
// ContainerWaitTilReady will wait timeout seconds and then check if a container is running
|
||||
@@ -96,32 +106,20 @@ func CopyFromImage(appName string, image string, source string, destination stri
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to create temporary container: %v", err)
|
||||
}
|
||||
defer ContainerRemove(containerID)
|
||||
|
||||
// docker cp exits with status 1 when run as non-root user when it tries to chown the file
|
||||
// after successfully copying the file. Thus, we suppress stderr.
|
||||
// ref: https://github.com/dotcloud/docker/issues/3986
|
||||
containerCopyCmd := NewShellCmd(strings.Join([]string{
|
||||
DockerBin(),
|
||||
"container",
|
||||
"cp",
|
||||
fmt.Sprintf("%s:%s", containerID, source),
|
||||
tmpFile.Name(),
|
||||
}, " "))
|
||||
containerCopyCmd.ShowOutput = false
|
||||
fileCopied := containerCopyCmd.Execute()
|
||||
|
||||
containerRemoveCmd := NewShellCmd(strings.Join([]string{
|
||||
DockerBin(),
|
||||
"container",
|
||||
"rm",
|
||||
"--force",
|
||||
containerID,
|
||||
}, " "))
|
||||
containerRemoveCmd.ShowOutput = false
|
||||
containerRemoveCmd.Execute()
|
||||
|
||||
if !fileCopied {
|
||||
return fmt.Errorf("Unable to copy file %s from image", source)
|
||||
result, err := CallExecCommand(ExecCommandInput{
|
||||
Command: DockerBin(),
|
||||
Args: []string{"container", "cp", fmt.Sprintf("%s:%s", containerID, source), tmpFile.Name()},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to copy file %s from image: %w", source, err)
|
||||
}
|
||||
if result.ExitCode != 0 {
|
||||
return fmt.Errorf("Unable to copy file %s from image: %v", source, result.StderrContents())
|
||||
}
|
||||
|
||||
fi, err := os.Stat(tmpFile.Name())
|
||||
@@ -134,19 +132,21 @@ func CopyFromImage(appName string, image string, source string, destination stri
|
||||
}
|
||||
|
||||
// workaround when owner is root. seems to only happen when running inside docker
|
||||
dos2unixCmd := NewShellCmd(strings.Join([]string{
|
||||
"dos2unix",
|
||||
"-l",
|
||||
"-n",
|
||||
tmpFile.Name(),
|
||||
destination,
|
||||
}, " "))
|
||||
dos2unixCmd.ShowOutput = false
|
||||
dos2unixCmd.Execute()
|
||||
CallExecCommand(ExecCommandInput{
|
||||
Command: "dos2unix",
|
||||
Args: []string{"-l", "-n", tmpFile.Name(), destination},
|
||||
}) // nolint: errcheck
|
||||
|
||||
// add trailing newline for certain places where file parsing depends on it
|
||||
b, err := sh.Command("tail", "-c1", destination).Output()
|
||||
if string(b) != "" {
|
||||
result, err = CallExecCommand(ExecCommandInput{
|
||||
Command: "tail",
|
||||
Args: []string{"-c1", destination},
|
||||
})
|
||||
if err != nil || result.ExitCode != 0 {
|
||||
return fmt.Errorf("Unable to append trailing newline to copied file: %v", result.Stderr)
|
||||
}
|
||||
|
||||
if result.Stdout != "" {
|
||||
f, err := os.OpenFile(destination, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -225,34 +225,39 @@ func DockerCleanup(appName string, forceCleanup bool) error {
|
||||
|
||||
// DockerContainerCreate creates a new container and returns the container ID
|
||||
func DockerContainerCreate(image string, containerCreateArgs []string) (string, error) {
|
||||
cmd := []string{
|
||||
DockerBin(),
|
||||
args := []string{
|
||||
"container",
|
||||
"create",
|
||||
}
|
||||
|
||||
cmd = append(cmd, containerCreateArgs...)
|
||||
cmd = append(cmd, image)
|
||||
args = append(args, containerCreateArgs...)
|
||||
args = append(args, image)
|
||||
|
||||
var stderr bytes.Buffer
|
||||
containerCreateCmd := NewShellCmd(strings.Join(cmd, " "))
|
||||
containerCreateCmd.ShowOutput = false
|
||||
containerCreateCmd.Command.Stderr = &stderr
|
||||
b, err := containerCreateCmd.Output()
|
||||
result, err := CallExecCommand(ExecCommandInput{
|
||||
Command: DockerBin(),
|
||||
Args: args,
|
||||
})
|
||||
if err != nil {
|
||||
return "", errors.New(strings.TrimSpace(stderr.String()))
|
||||
return "", fmt.Errorf("Unable to create container: %w", err)
|
||||
}
|
||||
if result.ExitCode != 0 {
|
||||
return "", fmt.Errorf("Unable to create container: %s", result.StderrContents())
|
||||
}
|
||||
|
||||
return strings.TrimSpace(string(b[:])), nil
|
||||
return result.StdoutContents(), nil
|
||||
}
|
||||
|
||||
// DockerInspect runs an inspect command with a given format against a container or image ID
|
||||
func DockerInspect(containerOrImageID, format string) (output string, err error) {
|
||||
b, err := sh.Command(DockerBin(), "inspect", "--format", format, containerOrImageID).Output()
|
||||
result, err := CallExecCommand(ExecCommandInput{
|
||||
Command: DockerBin(),
|
||||
Args: []string{"inspect", "--format", format, containerOrImageID},
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
output = strings.TrimSpace(string(b[:]))
|
||||
|
||||
output = result.StdoutContents()
|
||||
if strings.HasPrefix(output, "'") && strings.HasSuffix(output, "'") {
|
||||
output = strings.TrimSuffix(strings.TrimPrefix(output, "'"), "'")
|
||||
}
|
||||
@@ -273,9 +278,8 @@ func GetWorkingDir(appName string, image string) string {
|
||||
|
||||
func IsComposeInstalled() bool {
|
||||
result, err := CallExecCommand(ExecCommandInput{
|
||||
Command: DockerBin(),
|
||||
Args: []string{"info", "--format", "{{range .ClientInfo.Plugins}}{{if eq .Name \"compose\"}}true{{end}}{{end}}')"},
|
||||
CaptureOutput: true,
|
||||
Command: DockerBin(),
|
||||
Args: []string{"info", "--format", "{{range .ClientInfo.Plugins}}{{if eq .Name \"compose\"}}true{{end}}{{end}}')"},
|
||||
})
|
||||
return err == nil && result.ExitCode == 0
|
||||
}
|
||||
@@ -337,21 +341,22 @@ func RemoveImages(imageIDs []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
command := []string{
|
||||
DockerBin(),
|
||||
args := []string{
|
||||
"image",
|
||||
"rm",
|
||||
}
|
||||
|
||||
command = append(command, imageIDs...)
|
||||
args = append(args, imageIDs...)
|
||||
|
||||
var stderr bytes.Buffer
|
||||
rmCmd := NewShellCmd(strings.Join(command, " "))
|
||||
rmCmd.ShowOutput = false
|
||||
rmCmd.Command.Stderr = &stderr
|
||||
rmCmd.Execute()
|
||||
if _, err := rmCmd.Output(); err != nil {
|
||||
return errors.New(strings.TrimSpace(stderr.String()))
|
||||
result, err := CallExecCommand(ExecCommandInput{
|
||||
Command: DockerBin(),
|
||||
Args: args,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to remove images: %w", err)
|
||||
}
|
||||
if result.ExitCode != 0 {
|
||||
return fmt.Errorf("Unable to remove images: %s", result.StderrContents())
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -359,15 +364,16 @@ func RemoveImages(imageIDs []string) error {
|
||||
|
||||
// VerifyImage returns true if docker image exists in local repo
|
||||
func VerifyImage(image string) bool {
|
||||
imageCmd := NewShellCmd(strings.Join([]string{DockerBin(), "image", "inspect", image}, " "))
|
||||
imageCmd.ShowOutput = false
|
||||
return imageCmd.Execute()
|
||||
result, err := CallExecCommand(ExecCommandInput{
|
||||
Command: DockerBin(),
|
||||
Args: []string{"image", "inspect", image},
|
||||
})
|
||||
return err == nil && result.ExitCode == 0
|
||||
}
|
||||
|
||||
// DockerFilterContainers returns a slice of container IDs based on the passed in filters
|
||||
func DockerFilterContainers(filters []string) ([]string, error) {
|
||||
command := []string{
|
||||
DockerBin(),
|
||||
args := []string{
|
||||
"container",
|
||||
"ls",
|
||||
"--quiet",
|
||||
@@ -375,27 +381,27 @@ func DockerFilterContainers(filters []string) ([]string, error) {
|
||||
}
|
||||
|
||||
for _, filter := range filters {
|
||||
command = append(command, "--filter", filter)
|
||||
args = append(args, "--filter", filter)
|
||||
}
|
||||
|
||||
var stderr bytes.Buffer
|
||||
listCmd := NewShellCmd(strings.Join(command, " "))
|
||||
listCmd.ShowOutput = false
|
||||
listCmd.Command.Stderr = &stderr
|
||||
b, err := listCmd.Output()
|
||||
|
||||
result, err := CallExecCommand(ExecCommandInput{
|
||||
Command: DockerBin(),
|
||||
Args: args,
|
||||
})
|
||||
if err != nil {
|
||||
return []string{}, errors.New(strings.TrimSpace(stderr.String()))
|
||||
return []string{}, fmt.Errorf("Unable to filter containers: %w", err)
|
||||
}
|
||||
if result.ExitCode != 0 {
|
||||
return []string{}, fmt.Errorf("Unable to filter containers: %s", result.StderrContents())
|
||||
}
|
||||
|
||||
output := strings.Split(strings.TrimSpace(string(b[:])), "\n")
|
||||
output := strings.Split(result.StdoutContents(), "\n")
|
||||
return output, nil
|
||||
}
|
||||
|
||||
// DockerFilterImages returns a slice of image IDs based on the passed in filters
|
||||
func DockerFilterImages(filters []string) ([]string, error) {
|
||||
command := []string{
|
||||
DockerBin(),
|
||||
args := []string{
|
||||
"image",
|
||||
"ls",
|
||||
"--quiet",
|
||||
@@ -403,20 +409,21 @@ func DockerFilterImages(filters []string) ([]string, error) {
|
||||
}
|
||||
|
||||
for _, filter := range filters {
|
||||
command = append(command, "--filter", filter)
|
||||
args = append(args, "--filter", filter)
|
||||
}
|
||||
|
||||
var stderr bytes.Buffer
|
||||
listCmd := NewShellCmd(strings.Join(command, " "))
|
||||
listCmd.ShowOutput = false
|
||||
listCmd.Command.Stderr = &stderr
|
||||
b, err := listCmd.Output()
|
||||
|
||||
result, err := CallExecCommand(ExecCommandInput{
|
||||
Command: DockerBin(),
|
||||
Args: args,
|
||||
})
|
||||
if err != nil {
|
||||
return []string{}, errors.New(strings.TrimSpace(stderr.String()))
|
||||
return []string{}, fmt.Errorf("Unable to filter images: %w", err)
|
||||
}
|
||||
if result.ExitCode != 0 {
|
||||
return []string{}, fmt.Errorf("Unable to filter images: %s", result.StderrContents())
|
||||
}
|
||||
|
||||
output := strings.Split(strings.TrimSpace(string(b[:])), "\n")
|
||||
output := strings.Split(result.StdoutContents(), "\n")
|
||||
return output, nil
|
||||
}
|
||||
|
||||
@@ -433,8 +440,7 @@ func listContainers(status string, appName string) ([]string, error) {
|
||||
}
|
||||
|
||||
func pruneUnusedImages(appName string) {
|
||||
command := []string{
|
||||
DockerBin(),
|
||||
args := []string{
|
||||
"image",
|
||||
"prune",
|
||||
"--all",
|
||||
@@ -443,26 +449,23 @@ func pruneUnusedImages(appName string) {
|
||||
fmt.Sprintf("label=com.dokku.app-name=%v", appName),
|
||||
}
|
||||
|
||||
var stderr bytes.Buffer
|
||||
pruneCmd := NewShellCmd(strings.Join(command, " "))
|
||||
pruneCmd.ShowOutput = false
|
||||
pruneCmd.Command.Stderr = &stderr
|
||||
pruneCmd.Execute()
|
||||
CallExecCommand(ExecCommandInput{
|
||||
Command: DockerBin(),
|
||||
Args: args,
|
||||
}) // nolint: errcheck
|
||||
}
|
||||
|
||||
// DockerRemoveContainers will call `docker container rm` on the specified containers
|
||||
func DockerRemoveContainers(containerIDs []string) {
|
||||
command := []string{
|
||||
DockerBin(),
|
||||
args := []string{
|
||||
"container",
|
||||
"rm",
|
||||
}
|
||||
|
||||
command = append(command, containerIDs...)
|
||||
args = append(args, containerIDs...)
|
||||
|
||||
var stderr bytes.Buffer
|
||||
rmCmd := NewShellCmd(strings.Join(command, " "))
|
||||
rmCmd.ShowOutput = false
|
||||
rmCmd.Command.Stderr = &stderr
|
||||
rmCmd.Execute()
|
||||
CallExecCommand(ExecCommandInput{
|
||||
Command: DockerBin(),
|
||||
Args: args,
|
||||
}) // nolint: errcheck
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ type ExecCommandInput struct {
|
||||
// Args are the arguments to pass to the command
|
||||
Args []string
|
||||
|
||||
// CaptureOutput determines whether to capture the output of the command
|
||||
CaptureOutput bool
|
||||
// DisableStdioBuffer disables the stdio buffer
|
||||
DisableStdioBuffer bool
|
||||
|
||||
// Env is the environment variables to pass to the command
|
||||
Env map[string]string
|
||||
@@ -42,6 +42,12 @@ type ExecCommandInput struct {
|
||||
// StreamStderr prints stderr directly to os.Stderr as the command runs.
|
||||
StreamStderr bool
|
||||
|
||||
// StdoutWriter is the writer to write stdout to
|
||||
StdoutWriter io.Writer
|
||||
|
||||
// StderrWriter is the writer to write stderr to
|
||||
StderrWriter io.Writer
|
||||
|
||||
// Sudo runs the command with sudo -n -u root
|
||||
Sudo bool
|
||||
}
|
||||
@@ -95,7 +101,7 @@ func CallExecCommandWithContext(ctx context.Context, input ExecCommandInput) (Ex
|
||||
// being captured, then color output can be forced.
|
||||
isatty := !color.NoColor
|
||||
env := os.Environ()
|
||||
if isatty && !input.CaptureOutput {
|
||||
if isatty && input.DisableStdioBuffer {
|
||||
env = append(env, "FORCE_TTY=1")
|
||||
}
|
||||
if input.Env != nil {
|
||||
@@ -115,11 +121,15 @@ func CallExecCommandWithContext(ctx context.Context, input ExecCommandInput) (Ex
|
||||
Command: command,
|
||||
Args: commandArgs,
|
||||
Env: env,
|
||||
DisableStdioBuffer: !input.CaptureOutput,
|
||||
DisableStdioBuffer: input.DisableStdioBuffer,
|
||||
}
|
||||
|
||||
if os.Getenv("DOKKU_TRACE") == "1" {
|
||||
cmd.PrintCommand = true
|
||||
argsSt := ""
|
||||
if len(cmd.Args) > 0 {
|
||||
argsSt = strings.Join(cmd.Args, " ")
|
||||
}
|
||||
LogWarn(fmt.Sprintf("exec: %s %s", cmd.Command, argsSt))
|
||||
}
|
||||
|
||||
if input.Stdin != nil {
|
||||
@@ -137,6 +147,12 @@ func CallExecCommandWithContext(ctx context.Context, input ExecCommandInput) (Ex
|
||||
if input.StreamStderr {
|
||||
cmd.StdErrWriter = os.Stderr
|
||||
}
|
||||
if input.StdoutWriter != nil {
|
||||
cmd.StdOutWriter = input.StdoutWriter
|
||||
}
|
||||
if input.StderrWriter != nil {
|
||||
cmd.StdErrWriter = input.StderrWriter
|
||||
}
|
||||
|
||||
res, err := cmd.Execute(ctx)
|
||||
if err != nil {
|
||||
|
||||
@@ -38,15 +38,16 @@ func Copy(src, dst string) error {
|
||||
}
|
||||
|
||||
// ensure file has the correct line endings
|
||||
dos2unixCmd := NewShellCmd(strings.Join([]string{
|
||||
"dos2unix",
|
||||
"-l",
|
||||
"-n",
|
||||
src,
|
||||
dst,
|
||||
}, " "))
|
||||
dos2unixCmd.ShowOutput = false
|
||||
dos2unixCmd.Execute()
|
||||
result, err := CallExecCommand(ExecCommandInput{
|
||||
Command: "dos2unix",
|
||||
Args: []string{"-l", "-n", src, dst},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error running dos2unix: %s", err)
|
||||
}
|
||||
if result.ExitCode != 0 {
|
||||
return fmt.Errorf("Error running dos2unix: %s", result.StderrContents())
|
||||
}
|
||||
|
||||
// ensure file permissions are correct
|
||||
b, err := os.ReadFile(dst)
|
||||
|
||||
@@ -174,22 +174,27 @@ func LogVerboseQuietContainerLogsTail(containerID string, lines int, tail bool)
|
||||
args = append(args, "--follow")
|
||||
}
|
||||
|
||||
sc := NewShellCmdWithArgs(DockerBin(), args...)
|
||||
var mu sync.Mutex
|
||||
sc.Command.Stdout = &writer{
|
||||
mu: &mu,
|
||||
source: "stdout",
|
||||
}
|
||||
sc.Command.Stderr = &writer{
|
||||
mu: &mu,
|
||||
source: "stderr",
|
||||
}
|
||||
result, err := CallExecCommand(ExecCommandInput{
|
||||
Command: DockerBin(),
|
||||
Args: args,
|
||||
DisableStdioBuffer: true,
|
||||
StdoutWriter: &writer{
|
||||
mu: &mu,
|
||||
source: "stdout",
|
||||
},
|
||||
StderrWriter: &writer{
|
||||
mu: &mu,
|
||||
source: "stderr",
|
||||
},
|
||||
})
|
||||
|
||||
if err := sc.Command.Start(); err != nil {
|
||||
if err != nil {
|
||||
LogExclaim(fmt.Sprintf("Failed to fetch container logs: %s", containerID))
|
||||
return
|
||||
}
|
||||
|
||||
if err := sc.Command.Wait(); err != nil {
|
||||
if !tail && result.ExitCode != 0 {
|
||||
LogExclaim(fmt.Sprintf("Failed to fetch container logs: %s", containerID))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core common plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -2,7 +2,10 @@ package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// PlugnTriggerInput is the input for CallPlugnTrigger
|
||||
@@ -10,8 +13,8 @@ type PlugnTriggerInput struct {
|
||||
// Args are the arguments to pass to the trigger
|
||||
Args []string
|
||||
|
||||
// CaptureOutput determines whether to capture the output of the trigger
|
||||
CaptureOutput bool
|
||||
// DisableStdioBuffer disables the stdio buffer
|
||||
DisableStdioBuffer bool
|
||||
|
||||
// Env is the environment variables to pass to the trigger
|
||||
Env map[string]string
|
||||
@@ -41,14 +44,25 @@ func CallPlugnTrigger(input PlugnTriggerInput) (ExecCommandResponse, error) {
|
||||
func CallPlugnTriggerWithContext(ctx context.Context, input PlugnTriggerInput) (ExecCommandResponse, error) {
|
||||
args := []string{"trigger", input.Trigger}
|
||||
args = append(args, input.Args...)
|
||||
return CallExecCommandWithContext(ctx, ExecCommandInput{
|
||||
Command: "plugn",
|
||||
Args: args,
|
||||
CaptureOutput: input.CaptureOutput,
|
||||
Env: input.Env,
|
||||
Stdin: input.Stdin,
|
||||
StreamStdio: input.StreamStdio,
|
||||
StreamStdout: input.StreamStdout,
|
||||
StreamStderr: input.StreamStderr,
|
||||
result, err := CallExecCommandWithContext(ctx, ExecCommandInput{
|
||||
Command: "plugn",
|
||||
Args: args,
|
||||
DisableStdioBuffer: input.DisableStdioBuffer,
|
||||
Env: input.Env,
|
||||
Stdin: input.Stdin,
|
||||
StreamStdio: input.StreamStdio,
|
||||
StreamStdout: input.StreamStdout,
|
||||
StreamStderr: input.StreamStderr,
|
||||
})
|
||||
|
||||
if os.Getenv("DOKKU_TRACE") == "1" {
|
||||
for _, line := range strings.Split(result.Stderr, "\n") {
|
||||
LogDebug(fmt.Sprintf("plugn trigger %s stderr: %s", input.Trigger, line))
|
||||
}
|
||||
for _, line := range strings.Split(result.Stdout, "\n") {
|
||||
LogDebug(fmt.Sprintf("plugn trigger %s stdout: %s", input.Trigger, line))
|
||||
}
|
||||
}
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ type SshCommandInput struct {
|
||||
// Args are the arguments to pass to the command.
|
||||
Args []string
|
||||
|
||||
// CaptureOutput saves any output from in the TaskResult
|
||||
CaptureOutput bool
|
||||
// DisableStdioBuffer disables the stdio buffer
|
||||
DisableStdioBuffer bool
|
||||
|
||||
// Env is a list of environment variables to add to the current environment
|
||||
Env map[string]string
|
||||
@@ -137,7 +137,7 @@ func CallSshCommandWithContext(ctx context.Context, input SshCommandInput) (SshR
|
||||
Command: input.Command,
|
||||
Args: input.Args,
|
||||
Env: env,
|
||||
DisableStdioBuffer: !input.CaptureOutput,
|
||||
DisableStdioBuffer: input.DisableStdioBuffer,
|
||||
AllowUknownHosts: input.AllowUknownHosts,
|
||||
Hostname: u.Hostname(),
|
||||
Port: uint(port),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core config plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -27,8 +27,7 @@ Additional commands:`
|
||||
config:keys [--merged] (<app>|--global), Show keys set in environment
|
||||
config:show [--merged] (<app>|--global), Show keys set in environment
|
||||
config:set [--encoded] [--no-restart] (<app>|--global) KEY1=VALUE1 [KEY2=VALUE2 ...], Set one or more config vars
|
||||
config:unset [--no-restart] (<app>|--global) KEY1 [KEY2 ...], Unset one or more config vars
|
||||
`
|
||||
config:unset [--no-restart] (<app>|--global) KEY1 [KEY2 ...], Unset one or more config vars`
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -54,10 +53,8 @@ func main() {
|
||||
usage()
|
||||
case "help":
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
CaptureOutput: true,
|
||||
StreamStdio: false,
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
})
|
||||
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
|
||||
fmt.Println(helpContent)
|
||||
|
||||
@@ -9,7 +9,7 @@ require (
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/ryanuber/columnize v2.1.2+incompatible
|
||||
github.com/spf13/pflag v1.0.5
|
||||
mvdan.cc/sh/v3 v3.7.0
|
||||
mvdan.cc/sh/v3 v3.8.0
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@@ -8,8 +8,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/frankban/quicktest v1.14.5 h1:dfYrrRyLtiqT9GyKXgdh+k4inNeTvmGbuSgZ3lx3GhA=
|
||||
github.com/frankban/quicktest v1.14.5/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
@@ -47,8 +47,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/go-internal v1.10.1-0.20230524175051-ec119421bb97 h1:3RPlVWzZ/PDqmVuf/FKHARG5EMid/tl7cv54Sw/QRVY=
|
||||
github.com/rogpeppe/go-internal v1.10.1-0.20230524175051-ec119421bb97/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/ryanuber/columnize v2.1.2+incompatible h1:C89EOx/XBWwIXl8wm8OPJBd7kPF25UfsK2X7Ph/zCAk=
|
||||
github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
@@ -107,5 +107,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
mvdan.cc/sh/v3 v3.7.0 h1:lSTjdP/1xsddtaKfGg7Myu7DnlHItd3/M2tomOcNNBg=
|
||||
mvdan.cc/sh/v3 v3.7.0/go.mod h1:K2gwkaesF/D7av7Kxl0HbF5kGOd2ArupNTX3X44+8l8=
|
||||
mvdan.cc/sh/v3 v3.8.0 h1:ZxuJipLZwr/HLbASonmXtcvvC9HXY9d2lXZHnKGjFc8=
|
||||
mvdan.cc/sh/v3 v3.8.0/go.mod h1:w04623xkgBVo7/IUK89E0g8hBykgEpN0vgOj3RJr6MY=
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core cron plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -20,8 +20,7 @@ Additional commands:`
|
||||
helpContent = `
|
||||
cron:list <app> [--format json|stdout], List scheduled cron tasks for an app
|
||||
cron:report [<app>] [<flag>], Display report about an app
|
||||
cron:run <app> <cron_id> [--detach], Run a cron task on the fly
|
||||
`
|
||||
cron:run <app> <cron_id> [--detach], Run a cron task on the fly`
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -34,10 +33,8 @@ func main() {
|
||||
usage()
|
||||
case "help":
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
CaptureOutput: true,
|
||||
StreamStdio: false,
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
})
|
||||
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
|
||||
fmt.Println(helpContent)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core docker-options plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core domains plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core enter plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core git plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
1
plugins/haproxy-vhosts/Dockerfile
Normal file
1
plugins/haproxy-vhosts/Dockerfile
Normal file
@@ -0,0 +1 @@
|
||||
FROM byjg/easy-haproxy:4.4.0
|
||||
@@ -44,7 +44,7 @@ fn-haproxy-template-compose-file() {
|
||||
}
|
||||
|
||||
fn-haproxy-image() {
|
||||
fn-plugin-property-get-default "haproxy" "--global" "image" "byjg/easy-haproxy:4.3.0"
|
||||
fn-plugin-property-get-default "haproxy" "--global" "image" "$(grep "FROM" "$PLUGIN_AVAILABLE_PATH/haproxy-vhosts/Dockerfile" | awk '{print $2}')"
|
||||
}
|
||||
|
||||
fn-haproxy-log-level() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core haproxy-vhosts plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
1
plugins/logs/Dockerfile
Normal file
1
plugins/logs/Dockerfile
Normal file
@@ -0,0 +1 @@
|
||||
FROM timberio/vector:0.36.X-debian
|
||||
@@ -38,8 +38,7 @@ const vectorOldContainerName = "vector"
|
||||
|
||||
func getComposeFile() ([]byte, error) {
|
||||
result, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
|
||||
Trigger: "vector-template-source",
|
||||
CaptureOutput: true,
|
||||
Trigger: "vector-template-source",
|
||||
})
|
||||
if err == nil && result.ExitCode == 0 && strings.TrimSpace(result.Stdout) != "" {
|
||||
contents, err := os.ReadFile(strings.TrimSpace(result.Stdout))
|
||||
@@ -122,6 +121,17 @@ func startVectorContainer(vectorImage string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getComputedVectorImage() string {
|
||||
return common.PropertyGetDefault("logs", "--global", "vector-image", getDefaultVectorImage())
|
||||
}
|
||||
|
||||
// getDefaultVectorImage returns the default image used for the vector container
|
||||
func getDefaultVectorImage() string {
|
||||
contents := strings.TrimSpace(VectorDockerfile)
|
||||
parts := strings.SplitN(contents, " ", 2)
|
||||
return parts[1]
|
||||
}
|
||||
|
||||
func stopVectorContainer() error {
|
||||
if !common.IsComposeInstalled() {
|
||||
return errors.New("Required docker compose plugin is not installed")
|
||||
@@ -160,7 +170,7 @@ func stopVectorContainer() error {
|
||||
data := vectorTemplateData{
|
||||
DokkuLibRoot: dokkuLibRoot,
|
||||
DokkuLogsDir: dokkuLogsDir,
|
||||
VectorImage: VectorImage,
|
||||
VectorImage: getComputedVectorImage(),
|
||||
}
|
||||
|
||||
if err := tmpl.Execute(tmpFile, data); err != nil {
|
||||
|
||||
@@ -3,7 +3,6 @@ module github.com/dokku/dokku/plugins/logs
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27
|
||||
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
|
||||
github.com/dokku/dokku/plugins/docker-options v0.0.0-00010101000000-000000000000
|
||||
github.com/joncalhoun/qson v0.0.0-20200422171543-84433dcd3da0
|
||||
@@ -13,6 +12,7 @@ require (
|
||||
require (
|
||||
github.com/alexellis/go-execute/v2 v2.2.1 // indirect
|
||||
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
|
||||
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
|
||||
@@ -25,8 +25,11 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
// VectorImage contains the default vector image to run
|
||||
const VectorImage = "timberio/vector:0.35.X-debian"
|
||||
// VectorDockerfile is the contents of the default Dockerfile
|
||||
// containing the version of vector Dokku uses
|
||||
//
|
||||
//go:embed Dockerfile
|
||||
var VectorDockerfile string
|
||||
|
||||
// VectorDefaultSink contains the default sink in use for vector log shipping
|
||||
const VectorDefaultSink = "blackhole://?print_interval_secs=1"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core logs plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -44,7 +44,7 @@ func reportGlobalMaxSize(appName string) string {
|
||||
}
|
||||
|
||||
func reportVectorGlobalImage(appName string) string {
|
||||
return common.PropertyGetDefault("logs", "--global", "vector-image", VectorImage)
|
||||
return getComputedVectorImage()
|
||||
}
|
||||
|
||||
func reportGlobalVectorSink(appName string) string {
|
||||
|
||||
@@ -28,8 +28,7 @@ Additional commands:`
|
||||
logs:set [--global|<app>] <key> <value>, Set or clear a logs property for an app
|
||||
logs:vector-logs [--num num] [--tail], Display vector log output
|
||||
logs:vector-start, Start the vector logging container
|
||||
logs:vector-stop, Stop the vector logging container
|
||||
`
|
||||
logs:vector-stop, Stop the vector logging container`
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -60,10 +59,8 @@ func main() {
|
||||
usage()
|
||||
case "help":
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
CaptureOutput: true,
|
||||
StreamStdio: false,
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
})
|
||||
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
|
||||
fmt.Println(helpContent)
|
||||
|
||||
@@ -104,7 +104,7 @@ func CommandVectorStart(vectorImage string) error {
|
||||
}
|
||||
|
||||
if vectorImage == "" {
|
||||
vectorImage = common.PropertyGetDefault("logs", "--global", "vector-image", VectorImage)
|
||||
vectorImage = common.PropertyGetDefault("logs", "--global", "vector-image", getComputedVectorImage())
|
||||
}
|
||||
|
||||
common.LogVerbose("Starting vector container")
|
||||
|
||||
@@ -10,8 +10,6 @@ import (
|
||||
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
dockeroptions "github.com/dokku/dokku/plugins/docker-options"
|
||||
|
||||
sh "github.com/codeskyblue/go-sh"
|
||||
)
|
||||
|
||||
// TriggerDockerArgsProcessDeploy outputs the logs plugin docker options for an app
|
||||
@@ -47,9 +45,12 @@ func TriggerDockerArgsProcessDeploy(appName string) error {
|
||||
}
|
||||
|
||||
if !hasDriverOpt {
|
||||
b, _ := sh.Command(common.DockerBin(), "system", "info", "--format", "{{ .LoggingDriver }}").Output()
|
||||
output := strings.TrimSpace(string(b[:]))
|
||||
if !allowedDrivers[output] {
|
||||
result, _ := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: common.DockerBin(),
|
||||
Args: []string{"system", "info", "--format", "{{ .LoggingDriver }}"},
|
||||
})
|
||||
|
||||
if !allowedDrivers[result.StdoutContents()] {
|
||||
ignoreMaxSize = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
|
||||
sh "github.com/codeskyblue/go-sh"
|
||||
)
|
||||
|
||||
// attachAppToNetwork attaches a container to a network
|
||||
@@ -18,7 +15,6 @@ func attachAppToNetwork(containerID string, networkName string, appName string,
|
||||
}
|
||||
|
||||
cmdParts := []string{
|
||||
common.DockerBin(),
|
||||
"network",
|
||||
"connect",
|
||||
}
|
||||
@@ -45,14 +41,16 @@ func attachAppToNetwork(containerID string, networkName string, appName string,
|
||||
|
||||
cmdParts = append(cmdParts, networkName)
|
||||
cmdParts = append(cmdParts, containerID)
|
||||
attachCmd := common.NewShellCmd(strings.Join(cmdParts, " "))
|
||||
var stderr bytes.Buffer
|
||||
attachCmd.ShowOutput = false
|
||||
attachCmd.Command.Stderr = &stderr
|
||||
_, err := attachCmd.Output()
|
||||
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: common.DockerBin(),
|
||||
Args: cmdParts,
|
||||
})
|
||||
if err != nil {
|
||||
err = errors.New(strings.TrimSpace(stderr.String()))
|
||||
return fmt.Errorf("Unable to attach container to network: %v", err.Error())
|
||||
return fmt.Errorf("Unable to attach container to network: %w", err)
|
||||
}
|
||||
if result.ExitCode != 0 {
|
||||
return fmt.Errorf("Unable to attach container to network: %s", result.StderrContents())
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -60,20 +58,21 @@ func attachAppToNetwork(containerID string, networkName string, appName string,
|
||||
|
||||
// isContainerInNetwork returns true if the container is already attached to the specified network
|
||||
func isContainerInNetwork(containerID string, networkName string) bool {
|
||||
b, err := sh.Command(
|
||||
common.DockerBin(),
|
||||
"container",
|
||||
"inspect",
|
||||
"--format",
|
||||
"{{range $net, $v := .NetworkSettings.Networks}}{{println $net}}{{end}}",
|
||||
containerID,
|
||||
).Output()
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: common.DockerBin(),
|
||||
Args: []string{"container", "inspect", "--format", "{{range $net, $v := .NetworkSettings.Networks}}{{println $net}}{{end}}", containerID},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
common.LogVerboseQuiet(fmt.Sprintf("Error checking container networking status:%v", err.Error()))
|
||||
common.LogVerboseQuiet(fmt.Sprintf("Error checking container networking status: %v", err.Error()))
|
||||
return false
|
||||
}
|
||||
if result.ExitCode != 0 {
|
||||
common.LogVerboseQuiet(fmt.Sprintf("Error checking container networking status: %v", result.StderrContents()))
|
||||
return false
|
||||
}
|
||||
|
||||
for _, line := range strings.Split(strings.TrimSpace(string(b[:])), "\n") {
|
||||
for _, line := range strings.Split(result.StdoutContents(), "\n") {
|
||||
network := strings.TrimSpace(line)
|
||||
if network == "" {
|
||||
continue
|
||||
@@ -128,15 +127,19 @@ func networkExists(networkName string) (bool, error) {
|
||||
|
||||
// listNetworks returns a list of docker networks
|
||||
func listNetworks() ([]string, error) {
|
||||
b, err := sh.Command(common.DockerBin(), "network", "ls", "--format", "{{ .Name }}").Output()
|
||||
output := strings.TrimSpace(string(b[:]))
|
||||
|
||||
networks := []string{}
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: common.DockerBin(),
|
||||
Args: []string{"network", "ls", "--format", "{{ .Name }}"},
|
||||
})
|
||||
if err != nil {
|
||||
common.LogVerboseQuiet(output)
|
||||
return networks, err
|
||||
common.LogVerboseQuiet(result.StderrContents())
|
||||
return []string{}, err
|
||||
}
|
||||
if result.ExitCode != 0 {
|
||||
common.LogVerboseQuiet(result.StderrContents())
|
||||
return []string{}, fmt.Errorf("Unable to list networks")
|
||||
}
|
||||
|
||||
networks = strings.Split(output, "\n")
|
||||
networks := strings.Split(result.StdoutContents(), "\n")
|
||||
return networks, nil
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ module github.com/dokku/dokku/plugins/network
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27
|
||||
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
|
||||
github.com/spf13/pflag v1.0.5
|
||||
)
|
||||
@@ -11,6 +10,7 @@ require (
|
||||
require (
|
||||
github.com/alexellis/go-execute/v2 v2.2.1 // indirect
|
||||
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
|
||||
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core network plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -26,8 +26,7 @@ Additional commands:`
|
||||
network:rebuild <app>, Rebuilds network settings for an app
|
||||
network:rebuildall, Rebuild network settings for all apps
|
||||
network:report [<app>] [<flag>], Displays a network report for one or more apps
|
||||
network:set <app> <property> (<value>...), Set or clear a network property for an app
|
||||
`
|
||||
network:set <app> <property> (<value>...), Set or clear a network property for an app`
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -40,10 +39,8 @@ func main() {
|
||||
usage()
|
||||
case "help":
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
CaptureOutput: true,
|
||||
StreamStdio: false,
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
})
|
||||
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
|
||||
fmt.Println(helpContent)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
@@ -13,22 +12,15 @@ import (
|
||||
// CommandCreate is an alias for "docker network create"
|
||||
func CommandCreate(networkName string) error {
|
||||
common.LogInfo1Quiet(fmt.Sprintf("Creating network %v", networkName))
|
||||
createCmd := common.NewShellCmd(strings.Join([]string{
|
||||
common.DockerBin(),
|
||||
"network",
|
||||
"create",
|
||||
"--attachable",
|
||||
"--label",
|
||||
fmt.Sprintf("com.dokku.network-name=%v", networkName),
|
||||
networkName,
|
||||
}, " "))
|
||||
var stderr bytes.Buffer
|
||||
createCmd.ShowOutput = false
|
||||
createCmd.Command.Stderr = &stderr
|
||||
_, err := createCmd.Output()
|
||||
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: common.DockerBin(),
|
||||
Args: []string{"network", "create", "--attachable", "--label", fmt.Sprintf("com.dokku.network-name=%v", networkName), networkName},
|
||||
})
|
||||
if err != nil {
|
||||
err = errors.New(strings.TrimSpace(stderr.String()))
|
||||
return fmt.Errorf("Unable to create network: %w", err)
|
||||
}
|
||||
if result.ExitCode != 0 {
|
||||
return fmt.Errorf("Unable to create network: %s", result.StderrContents())
|
||||
}
|
||||
|
||||
return err
|
||||
@@ -47,22 +39,18 @@ func CommandDestroy(networkName string, forceDestroy bool) error {
|
||||
}
|
||||
|
||||
common.LogInfo1Quiet(fmt.Sprintf("Destroying network %v", networkName))
|
||||
destroyCmd := common.NewShellCmd(strings.Join([]string{
|
||||
common.DockerBin(),
|
||||
"network",
|
||||
"rm",
|
||||
networkName,
|
||||
}, " "))
|
||||
var stderr bytes.Buffer
|
||||
destroyCmd.ShowOutput = false
|
||||
destroyCmd.Command.Stderr = &stderr
|
||||
_, err := destroyCmd.Output()
|
||||
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: common.DockerBin(),
|
||||
Args: []string{"network", "rm", networkName},
|
||||
})
|
||||
if err != nil {
|
||||
err = errors.New(strings.TrimSpace(stderr.String()))
|
||||
return fmt.Errorf("Unable to destroy network: %w", err)
|
||||
}
|
||||
if result.ExitCode != 0 {
|
||||
return fmt.Errorf("Unable to destroy network: %s", result.StderrContents())
|
||||
}
|
||||
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
||||
// CommandExists checks if a network exists
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core nginx-vhosts plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
1
plugins/openresty-vhosts/Dockerfile
Normal file
1
plugins/openresty-vhosts/Dockerfile
Normal file
@@ -0,0 +1 @@
|
||||
FROM dokku/openresty-docker-proxy:0.6.0
|
||||
@@ -112,7 +112,7 @@ fn-openresty-hsts-is-enabled() {
|
||||
}
|
||||
|
||||
fn-openresty-image() {
|
||||
fn-plugin-property-get-default "openresty" "--global" "image" "dokku/openresty-docker-proxy:0.6.0"
|
||||
fn-plugin-property-get-default "openresty" "--global" "image" "$(grep "FROM" "$PLUGIN_AVAILABLE_PATH/openresty-vhosts/Dockerfile" | awk '{print $2}')"
|
||||
}
|
||||
|
||||
fn-openresty-letsencrypt-email() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core openresty-vhosts plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core plugin plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/ryanuber/columnize"
|
||||
)
|
||||
|
||||
// addPortMaps adds port mappings to an app
|
||||
func addPortMaps(appName string, portMaps []PortMap) error {
|
||||
allPortMaps := getPortMaps(appName)
|
||||
allPortMaps = append(allPortMaps, portMaps...)
|
||||
@@ -21,6 +22,7 @@ func addPortMaps(appName string, portMaps []PortMap) error {
|
||||
return setPortMaps(appName, allPortMaps)
|
||||
}
|
||||
|
||||
// clearPorts clears all port mappings for an app
|
||||
func clearPorts(appName string) error {
|
||||
if err := common.PropertyDelete("ports", appName, "map"); err != nil {
|
||||
return err
|
||||
@@ -29,6 +31,7 @@ func clearPorts(appName string) error {
|
||||
return common.PropertyDelete("ports", appName, "map-detected")
|
||||
}
|
||||
|
||||
// doesCertExist checks if a cert exists for an app
|
||||
func doesCertExist(appName string) bool {
|
||||
certsExists, _ := common.PlugnTriggerOutputAsString("certs-exists", []string{appName}...)
|
||||
if certsExists == "true" {
|
||||
@@ -39,6 +42,7 @@ func doesCertExist(appName string) bool {
|
||||
return certsForce == "true"
|
||||
}
|
||||
|
||||
// filterAppPortMaps filters the port mappings for an app
|
||||
func filterAppPortMaps(appName string, scheme string, hostPort int) []PortMap {
|
||||
var filteredPortMaps []PortMap
|
||||
for _, portMap := range getPortMaps(appName) {
|
||||
@@ -50,6 +54,7 @@ func filterAppPortMaps(appName string, scheme string, hostPort int) []PortMap {
|
||||
return filteredPortMaps
|
||||
}
|
||||
|
||||
// getAvailablePort gets an available port
|
||||
func getAvailablePort() int {
|
||||
addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
|
||||
if err != nil {
|
||||
@@ -70,6 +75,7 @@ func getAvailablePort() int {
|
||||
}
|
||||
}
|
||||
|
||||
// getComputedProxyPort gets the computed proxy port for an app
|
||||
func getComputedProxyPort(appName string) int {
|
||||
port := getProxyPort(appName)
|
||||
if port == 0 {
|
||||
@@ -79,6 +85,7 @@ func getComputedProxyPort(appName string) int {
|
||||
return port
|
||||
}
|
||||
|
||||
// getComputedProxySSLPort gets the computed proxy ssl port for an app
|
||||
func getComputedProxySSLPort(appName string) int {
|
||||
port := getProxySSLPort(appName)
|
||||
if port == 0 {
|
||||
@@ -88,6 +95,7 @@ func getComputedProxySSLPort(appName string) int {
|
||||
return port
|
||||
}
|
||||
|
||||
// getDetectedPortMaps gets the detected port mappings for an app
|
||||
func getDetectedPortMaps(appName string) []PortMap {
|
||||
basePort := getComputedProxyPort(appName)
|
||||
if basePort == 0 {
|
||||
@@ -145,6 +153,7 @@ func getDetectedPortMaps(appName string) []PortMap {
|
||||
return portMaps
|
||||
}
|
||||
|
||||
// getGlobalProxyPort gets the global proxy port
|
||||
func getGlobalProxyPort() int {
|
||||
port := 0
|
||||
b, _ := common.PlugnTriggerOutput("config-get-global", []string{"DOKKU_PROXY_PORT"}...)
|
||||
@@ -155,6 +164,7 @@ func getGlobalProxyPort() int {
|
||||
return port
|
||||
}
|
||||
|
||||
// getGlobalProxySSLPort gets the global proxy ssl port
|
||||
func getGlobalProxySSLPort() int {
|
||||
port := 0
|
||||
b, _ := common.PlugnTriggerOutput("config-get-global", []string{"DOKKU_PROXY_SSL_PORT"}...)
|
||||
@@ -165,6 +175,7 @@ func getGlobalProxySSLPort() int {
|
||||
return port
|
||||
}
|
||||
|
||||
// getPortMaps gets the port mappings for an app
|
||||
func getPortMaps(appName string) []PortMap {
|
||||
value, err := common.PropertyListGet("ports", appName, "map")
|
||||
if err != nil {
|
||||
@@ -175,6 +186,7 @@ func getPortMaps(appName string) []PortMap {
|
||||
return portMaps
|
||||
}
|
||||
|
||||
// getProxyPort gets the proxy port for an app
|
||||
func getProxyPort(appName string) int {
|
||||
port := 0
|
||||
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_PROXY_PORT"}...)
|
||||
@@ -185,6 +197,7 @@ func getProxyPort(appName string) int {
|
||||
return port
|
||||
}
|
||||
|
||||
// getProxySSLPort gets the proxy ssl port for an app
|
||||
func getProxySSLPort(appName string) int {
|
||||
port := 0
|
||||
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_PROXY_SSL_PORT"}...)
|
||||
@@ -195,6 +208,7 @@ func getProxySSLPort(appName string) int {
|
||||
return port
|
||||
}
|
||||
|
||||
// initializeProxyPort initializes the proxy port for an app
|
||||
func initializeProxyPort(appName string) error {
|
||||
port := getProxyPort(appName)
|
||||
if port != 0 {
|
||||
@@ -219,6 +233,7 @@ func initializeProxyPort(appName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// initializeProxySSLPort initializes the proxy ssl port for an app
|
||||
func initializeProxySSLPort(appName string) error {
|
||||
port := getProxySSLPort(appName)
|
||||
if port != 0 {
|
||||
@@ -246,10 +261,12 @@ func initializeProxySSLPort(appName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// inRange checks if a value is within a range
|
||||
func inRange(value int, min int, max int) bool {
|
||||
return min < value && value < max
|
||||
}
|
||||
|
||||
// isAppVhostEnabled checks if the app vhost is enabled
|
||||
func isAppVhostEnabled(appName string) bool {
|
||||
if err := common.PlugnTrigger("domains-vhost-enabled", []string{appName}...); err != nil {
|
||||
return false
|
||||
@@ -257,6 +274,7 @@ func isAppVhostEnabled(appName string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// listAppPortMaps lists the port mappings for an app
|
||||
func listAppPortMaps(appName string) error {
|
||||
portMaps := getPortMaps(appName)
|
||||
|
||||
@@ -283,6 +301,7 @@ func listAppPortMaps(appName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// parsePortMapString parses a port map string into a slice of PortMap structs
|
||||
func parsePortMapString(stringPortMap string) ([]PortMap, error) {
|
||||
var portMaps []PortMap
|
||||
|
||||
@@ -334,9 +353,10 @@ func parsePortMapString(stringPortMap string) ([]PortMap, error) {
|
||||
})
|
||||
}
|
||||
|
||||
return uniquePortMaps(portMaps), nil
|
||||
return portMaps, nil
|
||||
}
|
||||
|
||||
// removePortMaps removes specific port mappings from an app
|
||||
func removePortMaps(appName string, portMaps []PortMap) error {
|
||||
toRemove := map[string]bool{}
|
||||
toRemoveByPort := map[int]bool{}
|
||||
@@ -369,9 +389,29 @@ func removePortMaps(appName string, portMaps []PortMap) error {
|
||||
return setPortMaps(appName, toSet)
|
||||
}
|
||||
|
||||
// reusesSchemeHostPort returns true if the port maps reuse the same scheme:host-port
|
||||
func reusesSchemeHostPort(portMaps []PortMap) error {
|
||||
found := map[string]bool{}
|
||||
|
||||
for _, portMap := range portMaps {
|
||||
key := fmt.Sprintf("%s:%d", portMap.Scheme, portMap.HostPort)
|
||||
if found[key] {
|
||||
return fmt.Errorf("The same scheme:host-port is being reused: %s", key)
|
||||
}
|
||||
found[key] = true
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// setPortMaps sets the port maps for an app
|
||||
func setPortMaps(appName string, portMaps []PortMap) error {
|
||||
if err := reusesSchemeHostPort(portMaps); err != nil {
|
||||
return fmt.Errorf("Error validating port mappings: %s", err)
|
||||
}
|
||||
|
||||
var value []string
|
||||
for _, portMap := range uniquePortMaps(portMaps) {
|
||||
for _, portMap := range portMaps {
|
||||
if portMap.AllowsPersistence() {
|
||||
continue
|
||||
}
|
||||
@@ -383,6 +423,7 @@ func setPortMaps(appName string, portMaps []PortMap) error {
|
||||
return common.PropertyListWrite("ports", appName, "map", value)
|
||||
}
|
||||
|
||||
// setProxyPort sets the proxy port for an app
|
||||
func setProxyPort(appName string, port int) error {
|
||||
return common.EnvWrap(func() error {
|
||||
entries := map[string]string{
|
||||
@@ -392,6 +433,7 @@ func setProxyPort(appName string, port int) error {
|
||||
}, map[string]string{"DOKKU_QUIET_OUTPUT": "1"})
|
||||
}
|
||||
|
||||
// setProxySSLPort sets the proxy ssl port for an app
|
||||
func setProxySSLPort(appName string, port int) error {
|
||||
return common.EnvWrap(func() error {
|
||||
entries := map[string]string{
|
||||
@@ -401,18 +443,20 @@ func setProxySSLPort(appName string, port int) error {
|
||||
}, map[string]string{"DOKKU_QUIET_OUTPUT": "1"})
|
||||
}
|
||||
|
||||
// uniquePortMaps returns a unique set of port maps
|
||||
func uniquePortMaps(portMaps []PortMap) []PortMap {
|
||||
var unique []PortMap
|
||||
existingPortMaps := map[string]bool{}
|
||||
uniquePortMaps := []PortMap{}
|
||||
found := map[string]bool{}
|
||||
|
||||
for _, portMap := range portMaps {
|
||||
if existingPortMaps[portMap.String()] {
|
||||
key := fmt.Sprintf("%s:%d", portMap.Scheme, portMap.HostPort)
|
||||
if found[key] {
|
||||
continue
|
||||
}
|
||||
|
||||
existingPortMaps[portMap.String()] = true
|
||||
unique = append(unique, portMap)
|
||||
found[key] = true
|
||||
uniquePortMaps = append(uniquePortMaps, portMap)
|
||||
}
|
||||
|
||||
return unique
|
||||
return uniquePortMaps
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core ports plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -6,9 +6,14 @@ import (
|
||||
|
||||
// PortMap is a struct that contains a scheme:host-port:container-port mapping
|
||||
type PortMap struct {
|
||||
ContainerPort int `json:"container_port"`
|
||||
HostPort int `json:"host_port"`
|
||||
Scheme string `json:"scheme"`
|
||||
// ContainerPort is the port on the container
|
||||
ContainerPort int `json:"container_port"`
|
||||
|
||||
// HostPort is the port on the host
|
||||
HostPort int `json:"host_port"`
|
||||
|
||||
// Scheme is the scheme of the port mapping
|
||||
Scheme string `json:"scheme"`
|
||||
}
|
||||
|
||||
func (p PortMap) String() string {
|
||||
|
||||
@@ -23,8 +23,7 @@ Additional commands:`
|
||||
ports:clear <app>, Clear all port mappings for an app
|
||||
ports:remove <app> [<host-port>|<scheme>:<host-port>:<container-port>...], Remove specific port mappings from an app
|
||||
ports:set <app> [<scheme>:<host-port>:<container-port>...], Set port mappings for an app
|
||||
ports:report [<app>] [<flag>], Displays a ports report for one or more apps
|
||||
`
|
||||
ports:report [<app>] [<flag>], Displays a ports report for one or more apps`
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -37,10 +36,8 @@ func main() {
|
||||
usage()
|
||||
case "help":
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
CaptureOutput: true,
|
||||
StreamStdio: false,
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
})
|
||||
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
|
||||
fmt.Println(helpContent)
|
||||
|
||||
@@ -2,6 +2,7 @@ package ports
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
@@ -31,6 +32,16 @@ func CommandAdd(appName string, portMapStrings []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := reusesSchemeHostPort(portMaps); err != nil {
|
||||
return fmt.Errorf("Error validating new port mappings: %s", err)
|
||||
}
|
||||
|
||||
existingPortMaps := getPortMaps(appName)
|
||||
allPortMaps := append(existingPortMaps, portMaps...)
|
||||
if err := reusesSchemeHostPort(allPortMaps); err != nil {
|
||||
return fmt.Errorf("Error validating all port mappings: %s", err)
|
||||
}
|
||||
|
||||
if err := addPortMaps(appName, portMaps); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -88,6 +99,10 @@ func CommandSet(appName string, portMapStrings []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := reusesSchemeHostPort(portMaps); err != nil {
|
||||
return fmt.Errorf("Error validating port mappings: %s", err)
|
||||
}
|
||||
|
||||
if err := setPortMaps(appName, portMaps); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -87,6 +87,8 @@ func TriggerPortsGet(appName string, format string) error {
|
||||
persisted = append(persisted, portMap)
|
||||
}
|
||||
|
||||
persisted = uniquePortMaps(persisted)
|
||||
|
||||
if format == "json" {
|
||||
b, err := json.Marshal(persisted)
|
||||
if err != nil {
|
||||
@@ -207,6 +209,8 @@ func TriggerPostCertsUpdate(appName string) error {
|
||||
}
|
||||
}
|
||||
|
||||
http80Ports = uniquePortMaps(http80Ports)
|
||||
|
||||
if len(http80Ports) > 0 {
|
||||
var https443Ports []PortMap
|
||||
for _, portMap := range portMaps {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core proxy plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -23,8 +23,7 @@ Additional commands:`
|
||||
proxy:disable <app>, Disable proxy for app
|
||||
proxy:enable <app>, Enable proxy for app
|
||||
proxy:report [<app>] [<flag>], Displays a proxy report for one or more apps
|
||||
proxy:set <app> <proxy-type>, Set proxy type for app
|
||||
`
|
||||
proxy:set <app> <proxy-type>, Set proxy type for app`
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -37,10 +36,8 @@ func main() {
|
||||
usage()
|
||||
case "help":
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
CaptureOutput: true,
|
||||
StreamStdio: false,
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
})
|
||||
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
|
||||
fmt.Println(helpContent)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package ps
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
@@ -24,26 +23,18 @@ func getProcfileCommand(procfilePath string, processType string, port int) (stri
|
||||
return "", errors.New("No procfile found")
|
||||
}
|
||||
|
||||
shellCmd := common.NewShellCmd(strings.Join([]string{
|
||||
"procfile-util",
|
||||
"show",
|
||||
"--procfile",
|
||||
procfilePath,
|
||||
"--process-type",
|
||||
processType,
|
||||
"--default-port",
|
||||
strconv.Itoa(port),
|
||||
}, " "))
|
||||
var stderr bytes.Buffer
|
||||
shellCmd.ShowOutput = false
|
||||
shellCmd.Command.Stderr = &stderr
|
||||
b, err := shellCmd.Output()
|
||||
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: "procfile-util",
|
||||
Args: []string{"show", "--procfile", procfilePath, "--process-type", processType, "--default-port", strconv.Itoa(port)},
|
||||
})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf(strings.TrimSpace(stderr.String()))
|
||||
return "", fmt.Errorf("Error running procfile-util: %s", err)
|
||||
}
|
||||
if result.ExitCode != 0 {
|
||||
return "", fmt.Errorf("Error running procfile-util: %s", result.StderrContents())
|
||||
}
|
||||
|
||||
return strings.TrimSpace(string(b[:])), nil
|
||||
return result.StdoutContents(), nil
|
||||
}
|
||||
|
||||
func getProcfilePath(appName string) string {
|
||||
@@ -154,22 +145,18 @@ func parseProcessTuples(processTuples []string) (FormationSlice, error) {
|
||||
func processesInProcfile(procfilePath string) (map[string]bool, error) {
|
||||
processes := map[string]bool{}
|
||||
|
||||
shellCmd := common.NewShellCmd(strings.Join([]string{
|
||||
"procfile-util",
|
||||
"list",
|
||||
"--procfile",
|
||||
procfilePath,
|
||||
}, " "))
|
||||
var stderr bytes.Buffer
|
||||
shellCmd.ShowOutput = false
|
||||
shellCmd.Command.Stderr = &stderr
|
||||
b, err := shellCmd.Output()
|
||||
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: "procfile-util",
|
||||
Args: []string{"list", "--procfile", procfilePath},
|
||||
})
|
||||
if err != nil {
|
||||
return processes, fmt.Errorf(strings.TrimSpace(stderr.String()))
|
||||
return processes, fmt.Errorf("Error listing processes: %s", err)
|
||||
}
|
||||
if result.ExitCode != 0 {
|
||||
return processes, fmt.Errorf("Error listing processes: %s", result.StderrContents())
|
||||
}
|
||||
|
||||
for _, s := range strings.Split(strings.TrimSpace(string(b[:])), "\n") {
|
||||
for _, s := range strings.Split(result.StdoutContents(), "\n") {
|
||||
processes[s] = true
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ module github.com/dokku/dokku/plugins/ps
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27
|
||||
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
|
||||
github.com/dokku/dokku/plugins/config v0.0.0-00010101000000-000000000000
|
||||
github.com/dokku/dokku/plugins/docker-options v0.0.0-00010101000000-000000000000
|
||||
@@ -14,6 +13,7 @@ require (
|
||||
require (
|
||||
github.com/alexellis/go-execute/v2 v2.2.1 // indirect
|
||||
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
|
||||
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core ps plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -40,10 +40,8 @@ func main() {
|
||||
usage()
|
||||
case "help":
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
CaptureOutput: true,
|
||||
StreamStdio: false,
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
})
|
||||
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
|
||||
fmt.Println(helpContent)
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
sh "github.com/codeskyblue/go-sh"
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
"github.com/dokku/dokku/plugins/config"
|
||||
dockeroptions "github.com/dokku/dokku/plugins/docker-options"
|
||||
@@ -103,8 +102,15 @@ func TriggerCorePostExtract(appName string, sourceWorkDir string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if b, err := sh.Command("procfile-util", "check", "-P", processSpecificProcfile).CombinedOutput(); err != nil {
|
||||
return fmt.Errorf(strings.TrimSpace(string(b[:])))
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: "procfile-util",
|
||||
Args: []string{"check", "-P", processSpecificProcfile},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf(result.StderrContents())
|
||||
}
|
||||
if result.ExitCode != 0 {
|
||||
return fmt.Errorf("Invalid Procfile: %s", result.StderrContents())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -4,12 +4,10 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/codeskyblue/go-sh"
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
)
|
||||
|
||||
@@ -152,25 +150,21 @@ func pushToRegistry(appName string, tag int, imageID string, imageRepo string) e
|
||||
}
|
||||
|
||||
func dockerTag(imageID string, imageTag string) bool {
|
||||
cmd := sh.Command(common.DockerBin(), "image", "tag", imageID, imageTag)
|
||||
cmd.Stdout = nil
|
||||
cmd.Stderr = nil
|
||||
if err := cmd.Run(); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: common.DockerBin(),
|
||||
Args: []string{"image", "tag", imageID, imageTag},
|
||||
StreamStdio: true,
|
||||
})
|
||||
return err == nil && result.ExitCode == 0
|
||||
}
|
||||
|
||||
func dockerPush(imageTag string) bool {
|
||||
cmd := sh.Command(common.DockerBin(), "image", "push", imageTag)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: common.DockerBin(),
|
||||
Args: []string{"image", "push", imageTag},
|
||||
StreamStdio: true,
|
||||
})
|
||||
return err == nil && result.ExitCode == 0
|
||||
}
|
||||
|
||||
func imageCleanup(appName string, imageRepo string, imageTag string, tag int) {
|
||||
|
||||
@@ -3,7 +3,6 @@ module github.com/dokku/dokku/plugins/registry
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27
|
||||
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
|
||||
github.com/spf13/pflag v1.0.5
|
||||
)
|
||||
@@ -11,6 +10,7 @@ require (
|
||||
require (
|
||||
github.com/alexellis/go-execute/v2 v2.2.1 // indirect
|
||||
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
|
||||
github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core registry plugin"
|
||||
version = "0.33.5"
|
||||
version = "0.33.7"
|
||||
[plugin.config]
|
||||
|
||||
@@ -20,8 +20,7 @@ Additional commands:`
|
||||
helpContent = `
|
||||
registry:login [--password-stdin] <server> <username> [<password>], Login to a docker registry
|
||||
registry:report [<app>] [<flag>], Displays a registry report for one or more apps
|
||||
registry:set <app> <property> (<value>), Set or clear a registry property for an app
|
||||
`
|
||||
registry:set <app> <property> (<value>), Set or clear a registry property for an app`
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -34,10 +33,8 @@ func main() {
|
||||
usage()
|
||||
case "help":
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
CaptureOutput: true,
|
||||
StreamStdio: false,
|
||||
Command: "ps",
|
||||
Args: []string{"-o", "command=", strconv.Itoa(os.Getppid())},
|
||||
})
|
||||
if err == nil && strings.Contains(result.StdoutContents(), "--all") {
|
||||
fmt.Println(helpContent)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user