Merge branch 'master' into cn
* master: (427 commits) chore(deps): bump gunicorn from 25.0.2 to 25.1.0 in /tests/apps/multi chore(deps): bump flask from 3.1.2 to 3.1.3 in /tests/apps/multi chore(deps): bump python in /docs/_build chore(deps): bump google.golang.org/grpc in /tests/apps/gogrpc chore(deps): bump qs from 6.14.1 to 6.14.2 in /tests/apps/checks-root chore(deps): bump rack from 3.2.4 to 3.2.5 in /tests/apps/ruby fix: call correct function for limiting letsencrypt to certain domains chore(deps): bump gunicorn in /tests/apps/python-flask chore(deps): bump whitenoise in /tests/apps/dockerfile-release chore(deps): bump phusion/baseimage from noble-1.0.2 to noble-1.0.3 chore(deps): bump actions/upload-artifact from 6 to 7 chore(deps): bump actions/download-artifact from 7 to 8 chore(deps): bump github.com/traefik/traefik/v2 chore(deps): bump gunicorn in /tests/apps/dockerfile-release chore(deps): bump flask from 3.1.2 to 3.1.3 in /tests/apps/python-flask chore(deps): bump traefik from 3.6.7 to 3.6.9 in /plugins/traefik-vhosts chore(deps): bump mkdocs-material from 9.7.1 to 9.7.3 in /docs/_build chore(deps): bump byjg/easy-haproxy in /plugins/haproxy-vhosts chore(deps): bump dj-database-url in /tests/apps/dockerfile-release chore(deps): bump werkzeug in /tests/apps/python-flask ... # Conflicts: # common.mk # contrib/dependencies.json
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core standard plugin"
|
||||
version = "0.36.8"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core events logging plugin"
|
||||
version = "0.36.8"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
"github.com/tailscale/hujson"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
||||
@@ -25,8 +26,8 @@ var (
|
||||
|
||||
// AppJSON is a struct that represents an app.json file as understood by Dokku
|
||||
type AppJSON struct {
|
||||
// Cron is a list of cron commands to execute
|
||||
Cron []CronCommand `json:"cron"`
|
||||
// Cron is a list of cron tasks to execute
|
||||
Cron []CronTask `json:"cron"`
|
||||
|
||||
// Formation is a map of process types to scale
|
||||
Formation map[string]Formation `json:"formation"`
|
||||
@@ -50,13 +51,19 @@ type AppJSON struct {
|
||||
} `json:"scripts"`
|
||||
}
|
||||
|
||||
// CronCommand is a struct that represents a single cron command from an app.json file
|
||||
type CronCommand struct {
|
||||
// CronTask is a struct that represents a single cron task from an app.json file
|
||||
type CronTask struct {
|
||||
// Command is the command to execute
|
||||
Command string `json:"command"`
|
||||
|
||||
// Maintenance is whether or not the cron task is in maintenance mode
|
||||
Maintenance bool `json:"maintenance"`
|
||||
|
||||
// Schedule is the cron schedule to execute the command on
|
||||
Schedule string `json:"schedule"`
|
||||
|
||||
// ConcurrencyPolicy is the concurrency policy for the cron command
|
||||
ConcurrencyPolicy string `json:"concurrency_policy"`
|
||||
}
|
||||
|
||||
// Formation is a struct that represents the scale for a process from an app.json file
|
||||
@@ -69,6 +76,16 @@ type Formation struct {
|
||||
|
||||
// MaxParallel is the maximum number of processes to start in parallel
|
||||
MaxParallel *int `json:"max_parallel"`
|
||||
|
||||
// Service is a struct that represents how to expose the process to the network
|
||||
// This only applies to non-web processes
|
||||
Service *FormationService `json:"service"`
|
||||
}
|
||||
|
||||
// FormationService is a struct that represents how to expose a process to the network
|
||||
type FormationService struct {
|
||||
// Exposed is whether or not the process is exposed as a service
|
||||
Exposed bool `json:"exposed"`
|
||||
}
|
||||
|
||||
// FormationAutoscaling is a struct that represents the autoscaling configuration for a process from an app.json file
|
||||
@@ -256,8 +273,14 @@ func ReadAppJSON(path string) (AppJSON, error) {
|
||||
return AppJSON{}, nil
|
||||
}
|
||||
|
||||
ast, err := hujson.Parse(b)
|
||||
if err != nil {
|
||||
return AppJSON{}, fmt.Errorf("Cannot parse app.json as jsonc: %v", err)
|
||||
}
|
||||
ast.Standardize()
|
||||
|
||||
var appJSON AppJSON
|
||||
if err = json.Unmarshal(b, &appJSON); err != nil {
|
||||
if err = json.Unmarshal(ast.Pack(), &appJSON); err != nil {
|
||||
return AppJSON{}, fmt.Errorf("Cannot parse app.json: %v", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -133,11 +133,7 @@ func cleanupDeploymentContainer(containerID string, phase string) error {
|
||||
}
|
||||
|
||||
func executeScript(appName string, image string, imageTag string, phase string) error {
|
||||
phaseName := phase
|
||||
if phase == "heroku.postdeploy" {
|
||||
phaseName = "first deploy postdeploy"
|
||||
}
|
||||
common.LogInfo1(fmt.Sprintf("Checking for %s task", phaseName))
|
||||
common.LogInfo1(fmt.Sprintf("Checking for %s task", phase))
|
||||
command := ""
|
||||
phaseSource := ""
|
||||
if phase == "release" {
|
||||
@@ -152,14 +148,14 @@ func executeScript(appName string, image string, imageTag string, phase string)
|
||||
}
|
||||
|
||||
if command == "" {
|
||||
common.LogVerbose(fmt.Sprintf("No %s task found, skipping", phaseName))
|
||||
common.LogVerbose(fmt.Sprintf("No %s task found, skipping", phase))
|
||||
return nil
|
||||
}
|
||||
|
||||
if phase == "predeploy" {
|
||||
common.LogVerbose(fmt.Sprintf("Executing %s task from %s: %s", phaseName, phaseSource, command))
|
||||
common.LogVerbose(fmt.Sprintf("Executing %s task from %s: %s", phase, phaseSource, command))
|
||||
} else {
|
||||
common.LogVerbose(fmt.Sprintf("Executing %s task from %s in ephemeral container: %s", phaseName, phaseSource, command))
|
||||
common.LogVerbose(fmt.Sprintf("Executing %s task from %s in ephemeral container: %s", phase, phaseSource, command))
|
||||
}
|
||||
|
||||
isHerokuishImage := common.IsImageHerokuishBased(image, appName)
|
||||
@@ -271,15 +267,15 @@ func executeScript(appName string, image string, imageTag string, phase string)
|
||||
defer cleanupDeploymentContainer(containerID, phase)
|
||||
|
||||
if !waitForExecution(containerID) {
|
||||
common.LogInfo2Quiet(fmt.Sprintf("Start of %s %s task (%s) output", appName, phaseName, containerID[0:9]))
|
||||
common.LogInfo2Quiet(fmt.Sprintf("Start of %s %s task (%s) output", appName, phase, containerID[0:9]))
|
||||
common.LogVerboseQuietContainerLogs(containerID)
|
||||
common.LogInfo2Quiet(fmt.Sprintf("End of %s %s task (%s) output", appName, phaseName, containerID[0:9]))
|
||||
return fmt.Errorf("Execution of %s task failed: %s", phaseName, command)
|
||||
common.LogInfo2Quiet(fmt.Sprintf("End of %s %s task (%s) output", appName, phase, containerID[0:9]))
|
||||
return fmt.Errorf("Execution of %s task failed: %s", phase, command)
|
||||
}
|
||||
|
||||
common.LogInfo2Quiet(fmt.Sprintf("Start of %s %s task (%s) output", appName, phaseName, containerID[0:9]))
|
||||
common.LogInfo2Quiet(fmt.Sprintf("Start of %s %s task (%s) output", appName, phase, containerID[0:9]))
|
||||
common.LogVerboseQuietContainerLogs(containerID)
|
||||
common.LogInfo2Quiet(fmt.Sprintf("End of %s %s task (%s) output", appName, phaseName, containerID[0:9]))
|
||||
common.LogInfo2Quiet(fmt.Sprintf("End of %s %s task (%s) output", appName, phase, containerID[0:9]))
|
||||
|
||||
if phase != "predeploy" {
|
||||
return nil
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
module github.com/dokku/dokku/plugins/app-json
|
||||
|
||||
go 1.25.1
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
|
||||
github.com/spf13/pflag v1.0.10
|
||||
github.com/tailscale/hujson v0.0.0-20250605163823-992244df8c5a
|
||||
k8s.io/utils v0.0.0-20240102154912-e7106e64919e
|
||||
)
|
||||
|
||||
@@ -23,9 +24,10 @@ require (
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pkg/sftp v1.13.5 // indirect
|
||||
github.com/ryanuber/columnize v2.1.2+incompatible // indirect
|
||||
golang.org/x/crypto v0.43.0 // indirect
|
||||
golang.org/x/sync v0.17.0 // indirect
|
||||
golang.org/x/sys v0.37.0 // indirect
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
golang.org/x/crypto v0.46.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/dokku/dokku/plugins/common => ../common
|
||||
|
||||
@@ -22,8 +22,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/melbahja/goph v1.4.0 h1:z0PgDbBFe66lRYl3v5dGb9aFgPy0kotuQ37QOwSQFqs=
|
||||
github.com/melbahja/goph v1.4.0/go.mod h1:uG+VfK2Dlhk+O32zFrRlc3kYKTlV6+BtvPWd/kK7U68=
|
||||
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
|
||||
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
|
||||
github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q=
|
||||
github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4=
|
||||
github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8=
|
||||
github.com/otiai10/copy v1.14.1/go.mod h1:oQwrEDDOci3IM8dJF0d8+jnbfPDllW6vUjNc3DoZm9I=
|
||||
github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
|
||||
@@ -39,8 +39,11 @@ github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFo
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/tailscale/hujson v0.0.0-20250605163823-992244df8c5a h1:a6TNDN9CgG+cYjaeN8l2mc4kSz2iMiCDQxPEyltUV/I=
|
||||
github.com/tailscale/hujson v0.0.0-20250605163823-992244df8c5a/go.mod h1:EbW0wDK/qEUYI0A5bqq0C2kF8JTQwWONmGDBbzsxxHo=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
@@ -48,20 +51,20 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
||||
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.45.0 h1:RLBg5JKixCy82FtLJpeNlVM0nrSqpCRYzVU1n8kj0tM=
|
||||
golang.org/x/net v0.45.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -72,20 +75,20 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
||||
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
|
||||
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
|
||||
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
|
||||
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
||||
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core app-json plugin"
|
||||
version = "0.36.8"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package appjson
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
@@ -42,18 +42,17 @@ func TriggerAppJSONGetContent(appName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
b, err := os.ReadFile(getProcessSpecificAppJSONPath(appName))
|
||||
appJSON, err := ReadAppJSON(getProcessSpecificAppJSONPath(appName))
|
||||
if err != nil {
|
||||
return fmt.Errorf("Cannot read app.json file: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
content := strings.TrimSpace(string(b))
|
||||
if content == "" {
|
||||
fmt.Print("{}")
|
||||
return nil
|
||||
content, err := json.Marshal(appJSON)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Print(content)
|
||||
fmt.Print(string(content))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/dokku/dokku/plugins/apps
|
||||
|
||||
go 1.25.1
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
|
||||
@@ -21,9 +21,9 @@ require (
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pkg/sftp v1.13.5 // indirect
|
||||
github.com/ryanuber/columnize v2.1.2+incompatible // indirect
|
||||
golang.org/x/crypto v0.43.0 // indirect
|
||||
golang.org/x/sync v0.17.0 // indirect
|
||||
golang.org/x/sys v0.37.0 // indirect
|
||||
golang.org/x/crypto v0.46.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/dokku/dokku/plugins/common => ../common
|
||||
|
||||
@@ -19,8 +19,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/melbahja/goph v1.4.0 h1:z0PgDbBFe66lRYl3v5dGb9aFgPy0kotuQ37QOwSQFqs=
|
||||
github.com/melbahja/goph v1.4.0/go.mod h1:uG+VfK2Dlhk+O32zFrRlc3kYKTlV6+BtvPWd/kK7U68=
|
||||
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
|
||||
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
|
||||
github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q=
|
||||
github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4=
|
||||
github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8=
|
||||
github.com/otiai10/copy v1.14.1/go.mod h1:oQwrEDDOci3IM8dJF0d8+jnbfPDllW6vUjNc3DoZm9I=
|
||||
github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
|
||||
@@ -45,20 +45,20 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
||||
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.45.0 h1:RLBg5JKixCy82FtLJpeNlVM0nrSqpCRYzVU1n8kj0tM=
|
||||
golang.org/x/net v0.45.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -69,20 +69,20 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
||||
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
|
||||
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
|
||||
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
|
||||
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
||||
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core apps plugin"
|
||||
version = "0.36.8"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package apps
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
@@ -48,7 +49,7 @@ func TriggerInstall() error {
|
||||
}
|
||||
|
||||
apps, err := common.UnfilteredDokkuApps()
|
||||
if err != nil {
|
||||
if err != nil && !errors.Is(err, common.NoAppsExist) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,7 @@ trigger-builder-dockerfile-builder-build() {
|
||||
dokku_log_info1 "Building $APP from Dockerfile"
|
||||
|
||||
local IMAGE=$(get_app_image_name "$APP")
|
||||
local DOKKU_DOCKERFILE_CACHE_BUILD=$(config_get "$APP" "DOKKU_DOCKERFILE_CACHE_BUILD")
|
||||
local DOKKU_DOCKER_BUILD_OPTS=$(config_get "$APP" "DOKKU_DOCKER_BUILD_OPTS")
|
||||
local DOCKER_BUILD_LABEL_ARGS=("--label=dokku" "--label=org.label-schema.schema-version=1.0" "--label=org.label-schema.vendor=dokku" "--label=com.dokku.image-stage=build" "--label=com.dokku.builder-type=dockerfile" "--label=com.dokku.app-name=$APP")
|
||||
local DOCKER_BUILD_LABEL_ARGS=("--label=org.label-schema.schema-version=1.0" "--label=org.label-schema.vendor=dokku" "--label=com.dokku.image-stage=build" "--label=com.dokku.builder-type=dockerfile" "--label=com.dokku.app-name=$APP" "--label=dokku")
|
||||
|
||||
pushd "$SOURCECODE_WORK_DIR" &>/dev/null
|
||||
|
||||
@@ -34,17 +32,224 @@ trigger-builder-dockerfile-builder-build() {
|
||||
fi
|
||||
plugn trigger pre-build "$BUILDER_TYPE" "$APP" "$SOURCECODE_WORK_DIR"
|
||||
|
||||
[[ "$DOKKU_DOCKERFILE_CACHE_BUILD" == "false" ]] && DOKKU_DOCKER_BUILD_OPTS="$DOKKU_DOCKER_BUILD_OPTS --no-cache"
|
||||
local DOCKER_ARGS=$(: | plugn trigger docker-args-build "$APP" "$BUILDER_TYPE")
|
||||
DOCKER_ARGS+=$(: | plugn trigger docker-args-process-build "$APP" "$BUILDER_TYPE")
|
||||
DOCKER_ARGS+=" $DOKKU_GLOBAL_BUILD_ARGS"
|
||||
|
||||
# strip --link, --volume and -v args from DOCKER_ARGS
|
||||
local DOCKER_ARGS=$(sed -e "s/^--link=[[:graph:]]\+[[:blank:]]\?//g" -e "s/^--link[[:blank:]]\?[[:graph:]]\+[[:blank:]]\?//g" -e "s/^--volume=[[:graph:]]\+[[:blank:]]\?//g" -e "s/^--volume[[:blank:]]\?[[:graph:]]\+[[:blank:]]\?//g" -e "s/^-v[[:blank:]]\?[[:graph:]]\+[[:blank:]]\?//g" <<<"$DOCKER_ARGS")
|
||||
declare -a ARG_ARRAY
|
||||
eval "ARG_ARRAY=($DOCKER_ARGS)"
|
||||
DOCKER_ARGS=" $DOCKER_ARGS "
|
||||
eval set -- "$DOCKER_ARGS"
|
||||
|
||||
declare -a DOCKERFILE_ARGS
|
||||
while true; do
|
||||
case "$1" in
|
||||
--add-host)
|
||||
DOCKERFILE_ARGS+=("--add-host")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--add-host=*)
|
||||
DOCKERFILE_ARGS+=("--add-host" "${1#--add-host=}")
|
||||
shift 1
|
||||
;;
|
||||
--allow)
|
||||
DOCKERFILE_ARGS+=("--allow")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--allow=*)
|
||||
DOCKERFILE_ARGS+=("--allow" "${1#--allow=}")
|
||||
shift 1
|
||||
;;
|
||||
--annotation)
|
||||
DOCKERFILE_ARGS+=("--annotation")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--annotation=*)
|
||||
DOCKERFILE_ARGS+=("--annotation" "${1#--annotation=}")
|
||||
shift 1
|
||||
;;
|
||||
--attest)
|
||||
DOCKERFILE_ARGS+=("--attest")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--attest=*)
|
||||
DOCKERFILE_ARGS+=("--attest" "${1#--attest=}")
|
||||
shift 1
|
||||
;;
|
||||
--build-arg)
|
||||
DOCKERFILE_ARGS+=("--build-arg")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--build-arg=*)
|
||||
DOCKERFILE_ARGS+=("--build-arg" "${1#--build-arg=}")
|
||||
shift 1
|
||||
;;
|
||||
--builder)
|
||||
DOCKERFILE_ARGS+=("--builder")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--builder=*)
|
||||
DOCKERFILE_ARGS+=("--builder" "${1#--builder=}")
|
||||
shift 1
|
||||
;;
|
||||
--cache-from)
|
||||
DOCKERFILE_ARGS+=("--cache-from")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--cache-from=*)
|
||||
DOCKERFILE_ARGS+=("--cache-from" "${1#--cache-from=}")
|
||||
shift 1
|
||||
;;
|
||||
--cache-to)
|
||||
DOCKERFILE_ARGS+=("--cache-to")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--cache-to=*)
|
||||
DOCKERFILE_ARGS+=("--cache-to" "${1#--cache-to=}")
|
||||
shift 1
|
||||
;;
|
||||
--call)
|
||||
DOCKERFILE_ARGS+=("--call")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--call=*)
|
||||
DOCKERFILE_ARGS+=("--call" "${1#--call=}")
|
||||
shift 1
|
||||
;;
|
||||
--cgroup-parent)
|
||||
DOCKERFILE_ARGS+=("--cgroup-parent")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--cgroup-parent=*)
|
||||
DOCKERFILE_ARGS+=("--cgroup-parent" "${1#--cgroup-parent=}")
|
||||
shift 1
|
||||
;;
|
||||
--label)
|
||||
DOCKERFILE_ARGS+=("--label")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--label=*)
|
||||
DOCKERFILE_ARGS+=("--label" "${1#--label=}")
|
||||
shift 1
|
||||
;;
|
||||
--network)
|
||||
DOCKERFILE_ARGS+=("--network")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--network=*)
|
||||
DOCKERFILE_ARGS+=("--network" "${1#--network=}")
|
||||
shift 1
|
||||
;;
|
||||
--platform)
|
||||
DOCKERFILE_ARGS+=("--platform")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--platform=*)
|
||||
DOCKERFILE_ARGS+=("--platform" "${1#--platform=}")
|
||||
shift 1
|
||||
;;
|
||||
--progress)
|
||||
DOCKERFILE_ARGS+=("--progress")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--progress=*)
|
||||
DOCKERFILE_ARGS+=("--progress" "${1#--progress=}")
|
||||
shift 1
|
||||
;;
|
||||
--provenance)
|
||||
DOCKERFILE_ARGS+=("--provenance")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--provenance=*)
|
||||
DOCKERFILE_ARGS+=("--provenance" "${1#--provenance=}")
|
||||
shift 1
|
||||
;;
|
||||
--sbom)
|
||||
DOCKERFILE_ARGS+=("--sbom")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--sbom=*)
|
||||
DOCKERFILE_ARGS+=("--sbom" "${1#--sbom=}")
|
||||
shift 1
|
||||
;;
|
||||
--secret)
|
||||
DOCKERFILE_ARGS+=("--secret")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--secret=*)
|
||||
DOCKERFILE_ARGS+=("--secret" "${1#--secret=}")
|
||||
shift 1
|
||||
;;
|
||||
--shm-size)
|
||||
DOCKERFILE_ARGS+=("--shm-size")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--shm-size=*)
|
||||
DOCKERFILE_ARGS+=("--shm-size" "${1#--shm-size=}")
|
||||
shift 1
|
||||
;;
|
||||
--ssh)
|
||||
DOCKERFILE_ARGS+=("--platform")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--ssh=*)
|
||||
DOCKERFILE_ARGS+=("--ssh" "${1#--ssh=}")
|
||||
shift 1
|
||||
;;
|
||||
--target)
|
||||
DOCKERFILE_ARGS+=("--target")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--target=*)
|
||||
DOCKERFILE_ARGS+=("--target" "${1#--target=}")
|
||||
shift 1
|
||||
;;
|
||||
--ulimit)
|
||||
DOCKERFILE_ARGS+=("--tag")
|
||||
DOCKERFILE_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--tag=*)
|
||||
DOCKERFILE_ARGS+=("--tag" "${1#--tag=}")
|
||||
shift 1
|
||||
;;
|
||||
--check | -D | --debug | --no-cache)
|
||||
DOCKERFILE_ARGS+=("$1")
|
||||
shift 1
|
||||
;;
|
||||
*)
|
||||
if [[ -n "$1" ]]; then
|
||||
shift
|
||||
continue
|
||||
fi
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
eval "$(config_export app "$APP")"
|
||||
"$DOCKER_BIN" image build "${DOCKER_BUILD_LABEL_ARGS[@]}" $DOKKU_GLOBAL_BUILD_ARGS "${ARG_ARRAY[@]}" ${DOKKU_DOCKER_BUILD_OPTS} -t $IMAGE .
|
||||
local DOCKER_CONFIG
|
||||
DOCKER_CONFIG="$(fn-registry-docker-config-dir "$APP")"
|
||||
[[ -n "$DOCKER_CONFIG" ]] && export DOCKER_CONFIG
|
||||
"$DOCKER_BIN" image build "${DOCKER_BUILD_LABEL_ARGS[@]}" "${DOCKERFILE_ARGS[@]}" --tag $IMAGE .
|
||||
|
||||
plugn trigger ports-set-detected "$APP" "$(fn-builder-dockerfile-get-detect-port-map "$APP" "$IMAGE" "$SOURCECODE_WORK_DIR/Dockerfile")"
|
||||
if fn-plugn-trigger-exists "post-build-dockerfile"; then
|
||||
|
||||
@@ -29,6 +29,9 @@ trigger-builder-dockerfile-builder-release() {
|
||||
DOCKER_BUILD_ARGS+=("--platform=linux/amd64")
|
||||
fi
|
||||
|
||||
local DOCKER_CONFIG
|
||||
DOCKER_CONFIG="$(fn-registry-docker-config-dir "$APP")"
|
||||
[[ -n "$DOCKER_CONFIG" ]] && export DOCKER_CONFIG
|
||||
if ! suppress_output "$DOCKER_BIN" image build "${DOCKER_BUILD_ARGS[@]}" $DOKKU_GLOBAL_BUILD_ARGS -f "$PLUGIN_AVAILABLE_PATH/builder-dockerfile/dockerfiles/builder-release.Dockerfile" --build-arg APP_IMAGE="$IMAGE" -t "$IMAGE" "$TMP_WORK_DIR"; then
|
||||
dokku_log_warn "Failure injecting docker labels on image"
|
||||
return 1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core builder-dockerfile plugin"
|
||||
version = "0.36.8"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/config/functions"
|
||||
|
||||
fn-builder-herokuish-ensure-cache() {
|
||||
@@ -45,7 +46,10 @@ trigger-builder-herokuish-builder-build() {
|
||||
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"
|
||||
|
||||
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"
|
||||
local DOCKER_BUILD_LABEL_ARGS=("--label=org.label-schema.schema-version=1.0" "--label=org.label-schema.vendor=dokku" "--label=com.dokku.image-stage=build" "--label=com.dokku.builder-type=herokuish" "--label=com.dokku.app-name=$APP" "--label=dokku")
|
||||
local DOCKER_CONFIG
|
||||
DOCKER_CONFIG="$(fn-registry-docker-config-dir "$APP")"
|
||||
[[ -n "$DOCKER_CONFIG" ]] && export DOCKER_CONFIG
|
||||
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" --build-arg "TRACE=$DOKKU_TRACE" -t $IMAGE "$SOURCECODE_WORK_DIR"; then
|
||||
@@ -61,7 +65,10 @@ trigger-builder-herokuish-builder-build() {
|
||||
plugn trigger pre-build "$BUILDER_TYPE" "$APP" "$SOURCECODE_WORK_DIR"
|
||||
|
||||
local DOCKER_ARGS=$(: | plugn trigger docker-args-build "$APP" "$BUILDER_TYPE")
|
||||
[[ "$DOKKU_TRACE" ]] && DOCKER_ARGS+=" --env=TRACE=true "
|
||||
if [[ -n "$DOKKU_TRACE" ]]; then
|
||||
DOCKER_ARGS+=" --env=TRACE=true "
|
||||
DOCKER_ARGS+=" --env=BUILDPACK_XTRACE=1 "
|
||||
fi
|
||||
DOCKER_ARGS+=$(: | plugn trigger docker-args-process-build "$APP" "$BUILDER_TYPE")
|
||||
|
||||
declare -a ARG_ARRAY
|
||||
|
||||
@@ -30,6 +30,10 @@ trigger-builder-herokuish-builder-release() {
|
||||
DOKKU_APP_USER=$(config_get "$APP" DOKKU_APP_USER || true)
|
||||
DOKKU_APP_USER=${DOKKU_APP_USER:="herokuishuser"}
|
||||
|
||||
local DOCKER_CONFIG
|
||||
DOCKER_CONFIG="$(fn-registry-docker-config-dir "$APP")"
|
||||
[[ -n "$DOCKER_CONFIG" ]] && export DOCKER_CONFIG
|
||||
|
||||
if ! suppress_output "$DOCKER_BIN" image build "${DOCKER_BUILD_ARGS[@]}" $DOKKU_GLOBAL_BUILD_ARGS -f "$PLUGIN_AVAILABLE_PATH/builder-herokuish/dockerfiles/builder-pre-release.Dockerfile" --build-arg APP_IMAGE="$IMAGE" --build-arg "DOKKU_APP_USER=$DOKKU_APP_USER" -t "$IMAGE" "$TMP_WORK_DIR"; then
|
||||
dokku_log_warn "Failure injecting environment variables"
|
||||
return 1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core builder-herokuish plugin"
|
||||
version = "0.36.8"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
|
||||
@@ -14,7 +14,7 @@ trigger-builder-herokuish-pre-build-buildpack() {
|
||||
return
|
||||
fi
|
||||
|
||||
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"
|
||||
local DOCKER_BUILD_LABEL_ARGS=("--label=org.label-schema.schema-version=1.0" "--label=org.label-schema.vendor=dokku" "--label=com.dokku.image-stage=build" "--label=com.dokku.builder-type=herokuish" "--label=com.dokku.app-name=$APP" "--label=dokku")
|
||||
|
||||
IMAGE=$(get_app_image_name "$APP")
|
||||
|
||||
@@ -41,6 +41,9 @@ trigger-builder-herokuish-pre-build-buildpack() {
|
||||
|
||||
DOKKU_APP_USER=$(config_get "$APP" DOKKU_APP_USER || true)
|
||||
DOKKU_APP_USER=${DOKKU_APP_USER:="herokuishuser"}
|
||||
local DOCKER_CONFIG
|
||||
DOCKER_CONFIG="$(fn-registry-docker-config-dir "$APP")"
|
||||
[[ -n "$DOCKER_CONFIG" ]] && export DOCKER_CONFIG
|
||||
if ! suppress_output "$DOCKER_BIN" image build "${DOCKER_BUILD_LABEL_ARGS[@]}" $DOKKU_GLOBAL_BUILD_ARGS -f "$PLUGIN_AVAILABLE_PATH/builder-herokuish/dockerfiles/pre-build.Dockerfile" --build-arg APP_IMAGE="$IMAGE" --build-arg "DOKKU_APP_USER=$DOKKU_APP_USER" -t $IMAGE "$TMP_WORK_DIR"; then
|
||||
dokku_log_warn "Failure injecting BUILD_ENV into build environment"
|
||||
return 1
|
||||
|
||||
@@ -24,6 +24,9 @@ trigger-builder-lambda-builder-build() {
|
||||
fi
|
||||
plugn trigger pre-build "$BUILDER_TYPE" "$APP" "$SOURCECODE_WORK_DIR"
|
||||
|
||||
local DOCKER_CONFIG
|
||||
DOCKER_CONFIG="$(fn-registry-docker-config-dir "$APP")"
|
||||
[[ -n "$DOCKER_CONFIG" ]] && export DOCKER_CONFIG
|
||||
lambda-builder build --generate-image --write-procfile --image-env=DOCKER_LAMBDA_STAY_OPEN=1 --label=org.label-schema.schema-version=1.0 --label=org.label-schema.vendor=dokku --label=com.dokku.image-stage=build --label=com.dokku.builder-type=lambda "--label=com.dokku.app-name=$APP" $DOKKU_GLOBAL_BUILD_ARGS --port 5000 --tag "$IMAGE" --working-directory "$SOURCECODE_WORK_DIR"
|
||||
if [[ ! -f "$SOURCECODE_WORK_DIR/lambda.zip" ]]; then
|
||||
dokku_log_warn "Compressed lambda.zip not detected, failed to build lambda function"
|
||||
|
||||
@@ -22,7 +22,10 @@ trigger-builder-lambda-builder-release() {
|
||||
TMP_WORK_DIR="$(mktemp -d "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")"
|
||||
trap "rm -rf '$TMP_WORK_DIR' >/dev/null" RETURN INT TERM EXIT
|
||||
|
||||
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 --label=com.dokku.image-stage=release --label=dokku"
|
||||
local DOCKER_BUILD_LABEL_ARGS=("--label=org.label-schema.schema-version=1.0" "--label=org.label-schema.vendor=dokku" "--label=com.dokku.image-stage=release" "--label=com.dokku.builder-type=lambda" "--label=com.dokku.app-name=$APP" "--label=dokku")
|
||||
local DOCKER_CONFIG
|
||||
DOCKER_CONFIG="$(fn-registry-docker-config-dir "$APP")"
|
||||
[[ -n "$DOCKER_CONFIG" ]] && export DOCKER_CONFIG
|
||||
if ! suppress_output "$DOCKER_BIN" image build "${DOCKER_BUILD_LABEL_ARGS[@]}" $DOKKU_GLOBAL_BUILD_ARGS -f "$PLUGIN_AVAILABLE_PATH/builder-lambda/dockerfiles/builder-release.Dockerfile" --build-arg APP_IMAGE="$IMAGE" -t "$IMAGE" "$TMP_WORK_DIR"; then
|
||||
dokku_log_warn "Failure injecting docker labels on image"
|
||||
return 1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core builder-lambda plugin"
|
||||
version = "0.36.8"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
|
||||
@@ -21,36 +21,233 @@ trigger-builder-nixpacks-builder-build() {
|
||||
fi
|
||||
|
||||
local IMAGE=$(get_app_image_name "$APP")
|
||||
local DOCKER_BUILD_LABEL_ARGS=("--label=dokku" "--label=org.label-schema.schema-version=1.0" "--label=org.label-schema.vendor=dokku" "--label=com.dokku.image-stage=build" "--label=com.dokku.builder-type=nixpacks" "--label=com.dokku.app-name=$APP")
|
||||
local DOCKER_BUILD_LABEL_ARGS=("--label=org.label-schema.schema-version=1.0" "--label=org.label-schema.vendor=dokku" "--label=com.dokku.image-stage=build" "--label=com.dokku.builder-type=nixpacks" "--label=com.dokku.app-name=$APP" "--label=dokku")
|
||||
|
||||
pushd "$SOURCECODE_WORK_DIR" &>/dev/null
|
||||
|
||||
plugn trigger pre-build "$BUILDER_TYPE" "$APP" "$SOURCECODE_WORK_DIR"
|
||||
|
||||
no_cache="$(fn-builder-nixpacks-computed-no-cache "$APP")"
|
||||
NIXPACKS_ARGS=""
|
||||
if [[ "$no_cache" == "true" ]]; then
|
||||
NIXPACKS_ARGS="$NIXPACKS_ARGS --no-cache"
|
||||
fi
|
||||
|
||||
local DOCKER_ARGS=$(: | plugn trigger docker-args-build "$APP" "$BUILDER_TYPE")
|
||||
DOCKER_ARGS+=$(: | plugn trigger docker-args-process-build "$APP" "$BUILDER_TYPE")
|
||||
|
||||
# strip --link, --volume and -v args from DOCKER_ARGS
|
||||
local DOCKER_ARGS=$(sed -e "s/^--link=[[:graph:]]\+[[:blank:]]\?//g" -e "s/^--link[[:blank:]]\?[[:graph:]]\+[[:blank:]]\?//g" -e "s/^--volume=[[:graph:]]\+[[:blank:]]\?//g" -e "s/^--volume[[:blank:]]\?[[:graph:]]\+[[:blank:]]\?//g" -e "s/^-v[[:blank:]]\?[[:graph:]]\+[[:blank:]]\?//g" <<<"$DOCKER_ARGS")
|
||||
declare -a ARG_ARRAY
|
||||
eval "ARG_ARRAY=($DOCKER_ARGS)"
|
||||
|
||||
eval "$(config_export app "$APP" --merged)"
|
||||
|
||||
if [[ -f "$SOURCECODE_WORK_DIR/Procfile" ]]; then
|
||||
if procfile-util exists --process-type release; then
|
||||
procfile-util delete --process-type release
|
||||
fi
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
if ! nixpacks build "${DOCKER_BUILD_LABEL_ARGS[@]}" $DOKKU_GLOBAL_BUILD_ARGS "${ARG_ARRAY[@]}" $NIXPACKS_ARGS --name "$IMAGE" "$SOURCECODE_WORK_DIR"; then
|
||||
local DOCKER_ARGS=$(: | plugn trigger docker-args-build "$APP" "$BUILDER_TYPE")
|
||||
DOCKER_ARGS+=$(: | plugn trigger docker-args-process-build "$APP" "$BUILDER_TYPE")
|
||||
DOCKER_ARGS+=" $DOKKU_GLOBAL_BUILD_ARGS"
|
||||
|
||||
DOCKER_ARGS=" $DOCKER_ARGS "
|
||||
eval set -- "$DOCKER_ARGS"
|
||||
|
||||
declare -a NIXPACKS_ARGS
|
||||
while true; do
|
||||
case "$1" in
|
||||
-t | --tag)
|
||||
NIXPACKS_ARGS+=("--tag")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
-t=* | --tag=*)
|
||||
if [[ "$1" == "--tag=*" ]]; then
|
||||
NIXPACKS_ARGS+=("--tag" "${1#--tag=}")
|
||||
elif [[ "$1" == "-t=*" ]]; then
|
||||
NIXPACKS_ARGS+=("--tag" "${1#-t=}")
|
||||
fi
|
||||
shift 1
|
||||
;;
|
||||
-i | --install-cmd)
|
||||
NIXPACKS_ARGS+=("--install-cmd")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
-i=* | --install-cmd=*)
|
||||
if [[ "$1" == "--install-cmd=*" ]]; then
|
||||
NIXPACKS_ARGS+=("--install-cmd" "${1#--install-cmd=}")
|
||||
elif [[ "$1" == "-i=*" ]]; then
|
||||
NIXPACKS_ARGS+=("--install-cmd" "${1#-i=}")
|
||||
fi
|
||||
shift 1
|
||||
;;
|
||||
-l | --label)
|
||||
NIXPACKS_ARGS+=("--label")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
-l=* | --label=*)
|
||||
if [[ "$1" == "--label=*" ]]; then
|
||||
NIXPACKS_ARGS+=("--label" "${1#--label=}")
|
||||
elif [[ "$1" == "-l=*" ]]; then
|
||||
NIXPACKS_ARGS+=("--label" "${1#-l=}")
|
||||
fi
|
||||
shift 1
|
||||
;;
|
||||
-b | --build-cmd)
|
||||
NIXPACKS_ARGS+=("--build-cmd")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
-b=* | --build-cmd=*)
|
||||
if [[ "$1" == "--build-cmd=*" ]]; then
|
||||
NIXPACKS_ARGS+=("--build-cmd" "${1#--build-cmd=}")
|
||||
elif [[ "$1" == "-b=*" ]]; then
|
||||
NIXPACKS_ARGS+=("--build-cmd" "${1#-b=}")
|
||||
fi
|
||||
shift 1
|
||||
;;
|
||||
-s | --start-cmd)
|
||||
NIXPACKS_ARGS+=("--start-cmd")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
-s=* | --start-cmd=*)
|
||||
if [[ "$1" == "--start-cmd=*" ]]; then
|
||||
NIXPACKS_ARGS+=("--start-cmd" "${1#--start-cmd=}")
|
||||
elif [[ "$1" == "-s=*" ]]; then
|
||||
NIXPACKS_ARGS+=("--start-cmd" "${1#-s=}")
|
||||
fi
|
||||
shift 1
|
||||
;;
|
||||
-p | --pkgs)
|
||||
NIXPACKS_ARGS+=("--pkgs")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
-p=* | --pkgs=*)
|
||||
if [[ "$1" == "--pkgs=*" ]]; then
|
||||
NIXPACKS_ARGS+=("--pkgs" "${1#--pkgs=}")
|
||||
elif [[ "$1" == "-p=*" ]]; then
|
||||
NIXPACKS_ARGS+=("--pkgs" "${1#-p=}")
|
||||
fi
|
||||
shift 1
|
||||
;;
|
||||
-a | --apt)
|
||||
NIXPACKS_ARGS+=("--apt")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
-a=* | --apt=*)
|
||||
if [[ "$1" == "--apt=*" ]]; then
|
||||
NIXPACKS_ARGS+=("--apt" "${1#--apt=}")
|
||||
elif [[ "$1" == "-a=*" ]]; then
|
||||
NIXPACKS_ARGS+=("--apt" "${1#-a=}")
|
||||
fi
|
||||
shift 1
|
||||
;;
|
||||
-e | --env)
|
||||
NIXPACKS_ARGS+=("--env")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
-e=* | --env=*)
|
||||
if [[ "$1" == "--env=*" ]]; then
|
||||
NIXPACKS_ARGS+=("--env" "${1#--env=}")
|
||||
elif [[ "$1" == "-e=*" ]]; then
|
||||
NIXPACKS_ARGS+=("--env" "${1#-e=}")
|
||||
fi
|
||||
shift 1
|
||||
;;
|
||||
--platform)
|
||||
NIXPACKS_ARGS+=("$1")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--platform=*)
|
||||
NIXPACKS_ARGS+=("$1")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--cache-key)
|
||||
NIXPACKS_ARGS+=("$1")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--cache-key=*)
|
||||
NIXPACKS_ARGS+=("$1")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--incremental-cache-image)
|
||||
NIXPACKS_ARGS+=("$1")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--incremental-cache-image=*)
|
||||
NIXPACKS_ARGS+=("$1")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--libs)
|
||||
NIXPACKS_ARGS+=("$1")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--libs=*)
|
||||
NIXPACKS_ARGS+=("$1")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--cache-from)
|
||||
NIXPACKS_ARGS+=("$1")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--cache-from=*)
|
||||
NIXPACKS_ARGS+=("$1")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--docker-host)
|
||||
NIXPACKS_ARGS+=("$1")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--docker-host=*)
|
||||
NIXPACKS_ARGS+=("$1")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--add-host)
|
||||
NIXPACKS_ARGS+=("$1")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--add-host=*)
|
||||
NIXPACKS_ARGS+=("$1")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--docker-tls-verify)
|
||||
NIXPACKS_ARGS+=("$1")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--docker-tls-verify=*)
|
||||
NIXPACKS_ARGS+=("$1")
|
||||
NIXPACKS_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--no-cache | --inline-cache | --no-error-without-start)
|
||||
NIXPACKS_ARGS+=("$1")
|
||||
shift 1
|
||||
;;
|
||||
*)
|
||||
if [[ -n "$1" ]]; then
|
||||
shift
|
||||
continue
|
||||
fi
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
eval "$(config_export app "$APP" --merged)"
|
||||
|
||||
local DOCKER_CONFIG
|
||||
DOCKER_CONFIG="$(fn-registry-docker-config-dir "$APP")"
|
||||
[[ -n "$DOCKER_CONFIG" ]] && export DOCKER_CONFIG
|
||||
|
||||
if ! nixpacks build "${DOCKER_BUILD_LABEL_ARGS[@]}" "${NIXPACKS_ARGS[@]}" --name "$IMAGE" "$SOURCECODE_WORK_DIR"; then
|
||||
dokku_log_warn "Failure building image"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -18,7 +18,10 @@ trigger-builder-nixpacks-builder-release() {
|
||||
TMP_WORK_DIR="$(mktemp -d "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")"
|
||||
trap "rm -rf '$TMP_WORK_DIR' >/dev/null" RETURN INT TERM EXIT
|
||||
|
||||
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 --label=com.dokku.image-stage=release --label=dokku"
|
||||
local DOCKER_BUILD_LABEL_ARGS=("--label=org.label-schema.schema-version=1.0" "--label=org.label-schema.vendor=dokku" "--label=com.dokku.image-stage=release" "--label=com.dokku.builder-type=nixpacks" "--label=com.dokku.app-name=$APP" "--label=dokku")
|
||||
local DOCKER_CONFIG
|
||||
DOCKER_CONFIG="$(fn-registry-docker-config-dir "$APP")"
|
||||
[[ -n "$DOCKER_CONFIG" ]] && export DOCKER_CONFIG
|
||||
if ! suppress_output "$DOCKER_BIN" image build "${DOCKER_BUILD_LABEL_ARGS[@]}" $DOKKU_GLOBAL_BUILD_ARGS -f "$PLUGIN_AVAILABLE_PATH/builder-nixpacks/dockerfiles/builder-release.Dockerfile" --build-arg APP_IMAGE="$IMAGE" -t "$IMAGE" "$TMP_WORK_DIR"; then
|
||||
dokku_log_warn "Failure injecting docker labels on image"
|
||||
return 1
|
||||
|
||||
@@ -38,9 +38,6 @@ cmd-builder-nixpacks-report-single() {
|
||||
"--builder-nixpacks-computed-nixpackstoml-path: $(fn-builder-nixpacks-computed-nixpackstoml-path "$APP")"
|
||||
"--builder-nixpacks-global-nixpackstoml-path: $(fn-builder-nixpacks-global-nixpackstoml-path "$APP")"
|
||||
"--builder-nixpacks-nixpackstoml-path: $(fn-builder-nixpacks-nixpackstoml-path "$APP")"
|
||||
"--builder-nixpacks-computed-no-cache: $(fn-builder-nixpacks-computed-no-cache "$APP")"
|
||||
"--builder-nixpacks-global-no-cache: $(fn-builder-nixpacks-global-no-cache "$APP")"
|
||||
"--builder-nixpacks-no-cache: $(fn-builder-nixpacks-no-cache "$APP")"
|
||||
)
|
||||
|
||||
if [[ -z "$INFO_FLAG" ]]; then
|
||||
@@ -91,26 +88,3 @@ fn-builder-nixpacks-nixpackstoml-path() {
|
||||
|
||||
fn-plugin-property-get "builder-nixpacks" "$APP" "nixpackstoml-path" ""
|
||||
}
|
||||
|
||||
fn-builder-nixpacks-computed-no-cache() {
|
||||
declare APP="$1"
|
||||
|
||||
file="$(fn-builder-nixpacks-no-cache "$APP")"
|
||||
if [[ "$file" == "" ]]; then
|
||||
file="$(fn-builder-nixpacks-global-no-cache "$APP")"
|
||||
fi
|
||||
|
||||
echo "$file"
|
||||
}
|
||||
|
||||
fn-builder-nixpacks-global-no-cache() {
|
||||
declare APP="$1"
|
||||
|
||||
fn-plugin-property-get "builder-nixpacks" "--global" "no-cache" "false"
|
||||
}
|
||||
|
||||
fn-builder-nixpacks-no-cache() {
|
||||
declare APP="$1"
|
||||
|
||||
fn-plugin-property-get "builder-nixpacks" "$APP" "no-cache" ""
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core builder-nixpacks plugin"
|
||||
version = "0.36.8"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
|
||||
@@ -9,13 +9,13 @@ cmd-builder-nixpacks-set() {
|
||||
declare cmd="builder-nixpacks:set"
|
||||
[[ "$1" == "$cmd" ]] && shift 1
|
||||
declare APP="$1" KEY="$2" VALUE="$3"
|
||||
local VALID_KEYS=("nixpackstoml-path" "no-cache")
|
||||
local VALID_KEYS=("nixpackstoml-path")
|
||||
[[ "$APP" == "--global" ]] || verify_app_name "$APP"
|
||||
|
||||
[[ -z "$KEY" ]] && dokku_log_fail "No key specified"
|
||||
|
||||
if ! fn-in-array "$KEY" "${VALID_KEYS[@]}"; then
|
||||
dokku_log_fail "Invalid key specified, valid keys include: nixpackstoml-path, no-cache"
|
||||
dokku_log_fail "Invalid key specified, valid keys include: nixpackstoml-path"
|
||||
fi
|
||||
|
||||
if [[ -n "$VALUE" ]]; then
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core builder-null plugin"
|
||||
version = "0.36.8"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
|
||||
@@ -38,33 +38,264 @@ trigger-builder-pack-builder-build() {
|
||||
plugn trigger pre-build "$BUILDER_TYPE" "$APP" "$SOURCECODE_WORK_DIR"
|
||||
|
||||
local DOCKER_ARGS=$(: | plugn trigger docker-args-build "$APP" "$BUILDER_TYPE")
|
||||
[[ "$DOKKU_TRACE" ]] && DOCKER_ARGS+=" --env=TRACE=true "
|
||||
DOCKER_ARGS+=$(: | plugn trigger docker-args-process-build "$APP" "$BUILDER_TYPE")
|
||||
[[ "$DOKKU_TRACE" ]] && DOCKER_ARGS+=" --env=TRACE=true "
|
||||
|
||||
DOCKER_ARGS=" $DOCKER_ARGS "
|
||||
declare -a ARG_ARRAY
|
||||
eval "ARG_ARRAY=($DOCKER_ARGS)"
|
||||
|
||||
eval set -- "$DOCKER_ARGS"
|
||||
|
||||
declare -a PACK_ARGS
|
||||
while true; do
|
||||
case "$1" in
|
||||
--volume=* | -v=*)
|
||||
PACK_ARGS+=("$1")
|
||||
shift
|
||||
-b | --buildpack)
|
||||
PACK_ARGS+=("--buildpack")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
-b=* | --buildpack=*)
|
||||
if [[ "$1" == "--buildpack=*" ]]; then
|
||||
PACK_ARGS+=("--buildpack" "${1#--buildpack=}")
|
||||
elif [[ "$1" == "-b=*" ]]; then
|
||||
PACK_ARGS+=("--buildpack" "${1#-b=}")
|
||||
fi
|
||||
shift 1
|
||||
;;
|
||||
-r | --buildpack-registry)
|
||||
PACK_ARGS+=("--buildpack-registry")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
-r=* | --buildpack-registry=*)
|
||||
if [[ "$1" == "--buildpack-registry=*" ]]; then
|
||||
PACK_ARGS+=("--buildpack-registry" "${1#--buildpack-registry=}")
|
||||
elif [[ "$1" == "-r=*" ]]; then
|
||||
PACK_ARGS+=("--buildpack-registry" "${1#-r=}")
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
-e | --env)
|
||||
PACK_ARGS+=("--env")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
-e=* | --env=*)
|
||||
if [[ "$1" == "--env=*" ]]; then
|
||||
PACK_ARGS+=("--env" "${1#--env=}")
|
||||
elif [[ "$1" == "-e=*" ]]; then
|
||||
PACK_ARGS+=("--env" "${1#-e=}")
|
||||
fi
|
||||
shift 1
|
||||
;;
|
||||
-t | --tag)
|
||||
PACK_ARGS+=("--tag")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
-t=* | --tag=*)
|
||||
if [[ "$1" == "--tag=*" ]]; then
|
||||
PACK_ARGS+=("--tag" "${1#--tag=}")
|
||||
elif [[ "$1" == "-t=*" ]]; then
|
||||
PACK_ARGS+=("--tag" "${1#-t=}")
|
||||
fi
|
||||
shift 1
|
||||
;;
|
||||
--volume | -v)
|
||||
PACK_ARGS+=("--volume")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--volume=* | -v=*)
|
||||
if [[ "$1" == "--volume=*" ]]; then
|
||||
PACK_ARGS+=("--volume" "${1#--volume=}")
|
||||
elif [[ "$1" == "-v=*" ]]; then
|
||||
PACK_ARGS+=("--volume" "${1#-v=}")
|
||||
fi
|
||||
shift 1
|
||||
;;
|
||||
--cache)
|
||||
PACK_ARGS+=("--cache")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--cache=*)
|
||||
PACK_ARGS+=("--cache" "${1#--cache=}")
|
||||
shift 1
|
||||
;;
|
||||
--cache-image)
|
||||
PACK_ARGS+=("--cache-image")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--cache-image=*)
|
||||
PACK_ARGS+=("--cache-image" "${1#--cache-image=}")
|
||||
shift 1
|
||||
;;
|
||||
--creation-time)
|
||||
PACK_ARGS+=("--creation-time")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--creation-time=*)
|
||||
PACK_ARGS+=("--creation-time" "${1#--creation-time=}")
|
||||
shift 1
|
||||
;;
|
||||
--env-file)
|
||||
PACK_ARGS+=("--env-file")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--env-file=*)
|
||||
PACK_ARGS+=("--env-file" "${1#--env-file=}")
|
||||
shift 1
|
||||
;;
|
||||
--extension)
|
||||
PACK_ARGS+=("--extension")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--extension=*)
|
||||
PACK_ARGS+=("--extension" "${1#--extension=}")
|
||||
shift 1
|
||||
;;
|
||||
--gid)
|
||||
PACK_ARGS+=("--gid")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--gid=*)
|
||||
PACK_ARGS+=("--gid" "${1#--gid=}")
|
||||
shift 1
|
||||
;;
|
||||
--insecure-registry)
|
||||
PACK_ARGS+=("--insecure-registry")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--insecure-registry=*)
|
||||
PACK_ARGS+=("--insecure-registry" "${1#--insecure-registry=}")
|
||||
shift 1
|
||||
;;
|
||||
--lifecycle-image)
|
||||
PACK_ARGS+=("--lifecycle-image")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--lifecycle-image=*)
|
||||
PACK_ARGS+=("--lifecycle-image" "${1#--lifecycle-image=}")
|
||||
shift 1
|
||||
;;
|
||||
--network)
|
||||
PACK_ARGS+=("--network")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--network=*)
|
||||
PACK_ARGS+=("--network" "${1#--network=}")
|
||||
shift 1
|
||||
;;
|
||||
--platform)
|
||||
PACK_ARGS+=("--platform")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--platform=*)
|
||||
PACK_ARGS+=("--platform" "${1#--platform=}")
|
||||
shift 1
|
||||
;;
|
||||
--post-buildpack)
|
||||
PACK_ARGS+=("--post-buildpack")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--post-buildpack=*)
|
||||
PACK_ARGS+=("--post-buildpack" "${1#--post-buildpack=}")
|
||||
shift 1
|
||||
;;
|
||||
--pre-buildpack)
|
||||
PACK_ARGS+=("--pre-buildpack")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--pre-buildpack=*)
|
||||
PACK_ARGS+=("--pre-buildpack" "${1#--pre-buildpack=}")
|
||||
shift 1
|
||||
;;
|
||||
--previous-image)
|
||||
PACK_ARGS+=("--previous-image")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--previous-image=*)
|
||||
PACK_ARGS+=("--previous-image" "${1#--previous-image=}")
|
||||
shift 1
|
||||
;;
|
||||
--pull-policy)
|
||||
PACK_ARGS+=("--pull-policy")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--pull-policy=*)
|
||||
PACK_ARGS+=("--pull-policy" "${1#--pull-policy=}")
|
||||
shift 1
|
||||
;;
|
||||
--run-image)
|
||||
PACK_ARGS+=("--run-image")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--run-image=*)
|
||||
PACK_ARGS+=("--run-image" "${1#--run-image=}")
|
||||
shift 1
|
||||
;;
|
||||
--uid)
|
||||
PACK_ARGS+=("--uid")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--uid=*)
|
||||
PACK_ARGS+=("--uid" "${1#--uid=}")
|
||||
shift 1
|
||||
;;
|
||||
--workspace)
|
||||
PACK_ARGS+=("--workspace")
|
||||
PACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--workspace=*)
|
||||
PACK_ARGS+=("--workspace" "${1#--workspace=}")
|
||||
shift 1
|
||||
;;
|
||||
--clear-cache | --disable-system-buildpacks | --publish | --trust-builder | --trust-extra-buildpacks | --userns-host)
|
||||
PACK_ARGS+=("$1")
|
||||
shift 1
|
||||
;;
|
||||
*)
|
||||
if [[ -n "$1" ]]; then
|
||||
shift
|
||||
continue
|
||||
fi
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -n "$BUILDPACK_URL" ]; then
|
||||
PACK_ARGS+=("--builder")
|
||||
PACK_ARGS+=("$BUILDPACK_URL")
|
||||
elif [ -f "$SOURCECODE_WORK_DIR/.buildpacks" ]; then
|
||||
while read -r buildpack; do
|
||||
if [ -z "$buildpack" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
PACK_ARGS+=("--builder")
|
||||
PACK_ARGS+=("$buildpack")
|
||||
done <"$SOURCECODE_WORK_DIR/.buildpacks"
|
||||
fi
|
||||
|
||||
local DOCKER_CONFIG
|
||||
DOCKER_CONFIG="$(fn-registry-docker-config-dir "$APP")"
|
||||
[[ -n "$DOCKER_CONFIG" ]] && export DOCKER_CONFIG
|
||||
pack build "$IMAGE" --builder "$DOKKU_CNB_BUILDER" --path "$SOURCECODE_WORK_DIR" --default-process web "${PACK_ARGS[@]}" "${ENV_ARGS[@]}"
|
||||
docker-image-labeler relabel --label=dokku --label=org.label-schema.schema-version=1.0 --label=org.label-schema.vendor=dokku --label=com.dokku.image-stage=build --label=com.dokku.builder-type=pack --label=com.dokku.app-name=$APP "$IMAGE"
|
||||
|
||||
|
||||
@@ -12,11 +12,6 @@ trigger-builder-pack-builder-detect() {
|
||||
echo "pack"
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ "$(config_get "$APP" DOKKU_CNB_EXPERIMENTAL || true)" == "1" ]]; then
|
||||
echo "pack"
|
||||
return
|
||||
fi
|
||||
}
|
||||
|
||||
trigger-builder-pack-builder-detect "$@"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core builder-pack plugin"
|
||||
version = "0.36.8"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
|
||||
149
plugins/builder-railpack/builder-build
Executable file
149
plugins/builder-railpack/builder-build
Executable file
@@ -0,0 +1,149 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/builder-railpack/internal-functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/config/functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
trigger-builder-railpack-builder-build() {
|
||||
declare desc="builder-railpack builder-build plugin trigger"
|
||||
declare trigger="builder-build"
|
||||
declare BUILDER_TYPE="$1" APP="$2" SOURCECODE_WORK_DIR="$3"
|
||||
|
||||
if [[ "$BUILDER_TYPE" != "railpack" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
dokku_log_info1 "Building $APP from railpack"
|
||||
|
||||
if ! command -v "railpack" &>/dev/null; then
|
||||
dokku_log_fail "Missing railpack, install it"
|
||||
fi
|
||||
|
||||
local IMAGE=$(get_app_image_name "$APP")
|
||||
local DOCKER_BUILD_LABEL_ARGS=("--label=org.label-schema.schema-version=1.0" "--label=org.label-schema.vendor=dokku" "--label=com.dokku.image-stage=build" "--label=com.dokku.builder-type=railpack" "--label=com.dokku.app-name=$APP" "--label=dokku")
|
||||
|
||||
pushd "$SOURCECODE_WORK_DIR" &>/dev/null
|
||||
|
||||
plugn trigger pre-build "$BUILDER_TYPE" "$APP" "$SOURCECODE_WORK_DIR"
|
||||
|
||||
if [[ -f "$SOURCECODE_WORK_DIR/Procfile" ]]; then
|
||||
if procfile-util exists --process-type release; then
|
||||
procfile-util delete --process-type release
|
||||
fi
|
||||
fi
|
||||
|
||||
local DOCKER_ARGS=$(: | plugn trigger docker-args-build "$APP" "$BUILDER_TYPE")
|
||||
DOCKER_ARGS+=$(: | plugn trigger docker-args-process-build "$APP" "$BUILDER_TYPE")
|
||||
|
||||
DOCKER_ARGS=" $DOCKER_ARGS "
|
||||
eval set -- "$DOCKER_ARGS"
|
||||
|
||||
declare -a RAILPACK_ARGS
|
||||
while true; do
|
||||
case "$1" in
|
||||
--platform)
|
||||
RAILPACK_ARGS+=("--platform")
|
||||
RAILPACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--platform=*)
|
||||
RAILPACK_ARGS+=("--platform" "${1#--platform=}")
|
||||
shift 1
|
||||
;;
|
||||
--progress)
|
||||
RAILPACK_ARGS+=("--progress")
|
||||
RAILPACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--progress=*)
|
||||
RAILPACK_ARGS+=("--progress" "${1#--progress=}")
|
||||
shift 1
|
||||
;;
|
||||
--cache-key)
|
||||
RAILPACK_ARGS+=("--cache-key")
|
||||
RAILPACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--cache-key=*)
|
||||
RAILPACK_ARGS+=("--cache-key" "${1#--cache-key=}")
|
||||
shift 1
|
||||
;;
|
||||
-e | --env)
|
||||
RAILPACK_ARGS+=("--env")
|
||||
RAILPACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
-e=* | --env=*)
|
||||
if [[ "$1" == "--env=*" ]]; then
|
||||
RAILPACK_ARGS+=("--env" "${1#--env=}")
|
||||
elif [[ "$1" == "--e=*" ]]; then
|
||||
RAILPACK_ARGS+=("--env" "${1#-e=}")
|
||||
fi
|
||||
shift 1
|
||||
;;
|
||||
--previous)
|
||||
RAILPACK_ARGS+=("--previous")
|
||||
RAILPACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--previous=*)
|
||||
RAILPACK_ARGS+=("--previous" "${1#--previous=}")
|
||||
shift 1
|
||||
;;
|
||||
--build-cmd)
|
||||
RAILPACK_ARGS+=("--build-cmd")
|
||||
RAILPACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--build-cmd=*)
|
||||
RAILPACK_ARGS+=("--build-cmd" "${1#--build-cmd=}")
|
||||
shift 1
|
||||
;;
|
||||
--start-cmd)
|
||||
RAILPACK_ARGS+=("--start-cmd")
|
||||
RAILPACK_ARGS+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--start-cmd=*)
|
||||
RAILPACK_ARGS+=("--start-cmd" "${1#--start-cmd=}")
|
||||
shift 1
|
||||
;;
|
||||
---show-plan | --error-missing-start)
|
||||
RAILPACK_ARGS+=("$1")
|
||||
shift 1
|
||||
;;
|
||||
*)
|
||||
if [[ -n "$1" ]]; then
|
||||
shift
|
||||
continue
|
||||
fi
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
eval "$(config_export app "$APP" --merged)"
|
||||
|
||||
local DOCKER_CONFIG
|
||||
DOCKER_CONFIG="$(fn-registry-docker-config-dir "$APP")"
|
||||
[[ -n "$DOCKER_CONFIG" ]] && export DOCKER_CONFIG
|
||||
|
||||
if ! railpack build "${RAILPACK_ARGS[@]}" --name "$IMAGE-build" "$SOURCECODE_WORK_DIR"; then
|
||||
dokku_log_warn "Failure building image"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! suppress_output "$DOCKER_BIN" image build -f "$PLUGIN_AVAILABLE_PATH/builder-railpack/dockerfiles/builder-build.Dockerfile" --build-arg APP_IMAGE="$IMAGE-build" "${DOCKER_BUILD_LABEL_ARGS[@]}" $DOKKU_GLOBAL_BUILD_ARGS -t "$IMAGE" "$SOURCECODE_WORK_DIR"; then
|
||||
"$DOCKER_BIN" image remove "$IMAGE-build"
|
||||
dokku_log_warn "Failure injecting docker labels and custom entrypoint on image"
|
||||
return 1
|
||||
fi
|
||||
|
||||
"$DOCKER_BIN" image remove "$IMAGE-build"
|
||||
|
||||
plugn trigger post-build "$BUILDER_TYPE" "$APP" "$SOURCECODE_WORK_DIR"
|
||||
popd &>/dev/null || pushd "/tmp" >/dev/null
|
||||
}
|
||||
|
||||
trigger-builder-railpack-builder-build "$@"
|
||||
17
plugins/builder-railpack/builder-detect
Executable file
17
plugins/builder-railpack/builder-detect
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_AVAILABLE_PATH/config/functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
trigger-builder-railpack-builder-detect() {
|
||||
declare desc="builder-railpack builder-detect plugin trigger"
|
||||
declare trigger="builder-detect"
|
||||
declare APP="$1" SOURCECODE_WORK_DIR="$2"
|
||||
|
||||
if [[ -f "$SOURCECODE_WORK_DIR/railpack.json" ]]; then
|
||||
echo "railpack"
|
||||
return
|
||||
fi
|
||||
}
|
||||
|
||||
trigger-builder-railpack-builder-detect "$@"
|
||||
33
plugins/builder-railpack/builder-release
Executable file
33
plugins/builder-railpack/builder-release
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
trigger-builder-railpack-builder-release() {
|
||||
declare desc="builder-railpack builder-release plugin trigger"
|
||||
declare trigger="builder-release"
|
||||
declare BUILDER_TYPE="$1" APP="$2" IMAGE_TAG="$3"
|
||||
|
||||
if [[ "$BUILDER_TYPE" != "railpack" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG")
|
||||
plugn trigger pre-release-builder "$BUILDER_TYPE" "$APP" "$IMAGE"
|
||||
|
||||
TMP_WORK_DIR="$(mktemp -d "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")"
|
||||
trap "rm -rf '$TMP_WORK_DIR' >/dev/null" RETURN INT TERM EXIT
|
||||
|
||||
local DOCKER_BUILD_LABEL_ARGS=("--label=org.label-schema.schema-version=1.0" "--label=org.label-schema.vendor=dokku" "--label=com.dokku.image-stage=release" "--label=com.dokku.builder-type=railpack" "--label=com.dokku.app-name=$APP" "--label=dokku")
|
||||
local DOCKER_CONFIG
|
||||
DOCKER_CONFIG="$(fn-registry-docker-config-dir "$APP")"
|
||||
[[ -n "$DOCKER_CONFIG" ]] && export DOCKER_CONFIG
|
||||
if ! suppress_output "$DOCKER_BIN" image build "${DOCKER_BUILD_LABEL_ARGS[@]}" $DOKKU_GLOBAL_BUILD_ARGS -f "$PLUGIN_AVAILABLE_PATH/builder-railpack/dockerfiles/builder-release.Dockerfile" --build-arg APP_IMAGE="$IMAGE" -t "$IMAGE" "$TMP_WORK_DIR"; then
|
||||
dokku_log_warn "Failure injecting docker labels on image"
|
||||
return 1
|
||||
fi
|
||||
|
||||
plugn trigger post-release-builder "$BUILDER_TYPE" "$APP" "$IMAGE"
|
||||
}
|
||||
|
||||
trigger-builder-railpack-builder-release "$@"
|
||||
15
plugins/builder-railpack/commands
Executable file
15
plugins/builder-railpack/commands
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_AVAILABLE_PATH/builder-railpack/help-functions"
|
||||
|
||||
case "$1" in
|
||||
help | builder-railpack:help)
|
||||
cmd-builder-railpack-help "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
|
||||
;;
|
||||
|
||||
esac
|
||||
30
plugins/builder-railpack/core-post-extract
Executable file
30
plugins/builder-railpack/core-post-extract
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/builder-railpack/internal-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
trigger-builder-railpack-core-post-extract() {
|
||||
declare desc="builder-railpack post-extract plugin trigger"
|
||||
declare trigger="post-extract"
|
||||
declare APP="$1" SOURCECODE_WORK_DIR="$2"
|
||||
local NEW_RAILPACK_JSON="$(fn-builder-railpack-computed-railpackjson-path "$APP")"
|
||||
|
||||
pushd "$TMP_WORK_DIR" >/dev/null
|
||||
|
||||
if [[ -z "$NEW_RAILPACK_JSON" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ ! -f "$NEW_RAILPACK_JSON" ]]; then
|
||||
rm -f railpack.json
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ "$NEW_RAILPACK_JSON" != "railpack.json" ]]; then
|
||||
mv "$NEW_RAILPACK_JSON" railpack.json
|
||||
fi
|
||||
popd &>/dev/null || pushd "/tmp" >/dev/null
|
||||
}
|
||||
|
||||
trigger-builder-railpack-core-post-extract "$@"
|
||||
@@ -0,0 +1,4 @@
|
||||
ARG APP_IMAGE
|
||||
FROM $APP_IMAGE
|
||||
|
||||
ENTRYPOINT []
|
||||
@@ -0,0 +1,2 @@
|
||||
ARG APP_IMAGE
|
||||
FROM $APP_IMAGE
|
||||
@@ -2,11 +2,11 @@
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-storage-help() {
|
||||
cmd-builder-railpack-help() {
|
||||
declare desc="help command"
|
||||
declare CMD="$1"
|
||||
local plugin_name="storage"
|
||||
local plugin_description="Manage mounted volumes"
|
||||
local plugin_name="builder-railpack"
|
||||
local plugin_description="Manage the railpack builder integration for an app"
|
||||
|
||||
if [[ "$CMD" == "${plugin_name}:help" ]]; then
|
||||
echo -e "Usage: dokku ${plugin_name}[:COMMAND]"
|
||||
@@ -27,10 +27,7 @@ help_desc
|
||||
fn-help-content() {
|
||||
declare desc="return help content"
|
||||
cat <<help_content
|
||||
storage:ensure-directory [--chown option] <directory>, Creates a persistent storage directory in the recommended storage path
|
||||
storage:list <app> [--format text|json], List bind mounts for app's container(s) (host:container)
|
||||
storage:mount <app> <host-dir:container-dir>, Create a new bind mount
|
||||
storage:report [<app>] [<flag>], Displays a checks report for one or more apps
|
||||
storage:unmount <app> <host-dir:container-dir>, Remove an existing bind mount
|
||||
builder-railpack:report [<app>] [<flag>], Displays a builder-railpack report for one or more apps
|
||||
builder-railpack:set <app> <property> (<value>), Set or clear a builder-railpack property for an app
|
||||
help_content
|
||||
}
|
||||
16
plugins/builder-railpack/install
Executable file
16
plugins/builder-railpack/install
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
trigger-builder-railpack-install() {
|
||||
declare desc="installs the builder-railpack plugin"
|
||||
declare trigger="install"
|
||||
|
||||
fn-plugin-property-setup "builder-railpack"
|
||||
|
||||
mkdir -p "${DOKKU_LIB_ROOT}/data/builder-railpack"
|
||||
chown -R "${DOKKU_SYSTEM_USER}:${DOKKU_SYSTEM_GROUP}" "${DOKKU_LIB_ROOT}/data/builder-railpack"
|
||||
}
|
||||
|
||||
trigger-builder-railpack-install "$@"
|
||||
90
plugins/builder-railpack/internal-functions
Executable file
90
plugins/builder-railpack/internal-functions
Executable file
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-builder-railpack-report() {
|
||||
declare desc="displays a builder-railpack report for one or more apps"
|
||||
declare cmd="builder-railpack:report"
|
||||
[[ "$1" == "$cmd" ]] && shift 1
|
||||
declare APP="$1" INFO_FLAG="$2"
|
||||
|
||||
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
|
||||
INFO_FLAG="$APP"
|
||||
APP=""
|
||||
fi
|
||||
|
||||
if [[ -z "$APP" ]] && [[ -z "$INFO_FLAG" ]]; then
|
||||
INFO_FLAG="true"
|
||||
fi
|
||||
|
||||
if [[ -z "$APP" ]]; then
|
||||
for app in $(dokku_apps); do
|
||||
cmd-builder-railpack-report-single "$app" "$INFO_FLAG" | tee || true
|
||||
done
|
||||
else
|
||||
cmd-builder-railpack-report-single "$APP" "$INFO_FLAG"
|
||||
fi
|
||||
}
|
||||
|
||||
cmd-builder-railpack-report-single() {
|
||||
declare APP="$1" INFO_FLAG="$2"
|
||||
if [[ "$INFO_FLAG" == "true" ]]; then
|
||||
INFO_FLAG=""
|
||||
fi
|
||||
verify_app_name "$APP"
|
||||
local flag_map=(
|
||||
"--builder-railpack-computed-railpackjson-path: $(fn-builder-railpack-computed-railpackjson-path "$APP")"
|
||||
"--builder-railpack-global-railpackjson-path: $(fn-builder-railpack-global-railpackjson-path "$APP")"
|
||||
"--builder-railpack-railpackjson-path: $(fn-builder-railpack-railpackjson-path "$APP")"
|
||||
)
|
||||
|
||||
if [[ -z "$INFO_FLAG" ]]; then
|
||||
dokku_log_info2_quiet "${APP} builder-railpack information"
|
||||
for flag in "${flag_map[@]}"; do
|
||||
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
|
||||
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"
|
||||
done
|
||||
else
|
||||
local match=false
|
||||
local value_exists=false
|
||||
for flag in "${flag_map[@]}"; do
|
||||
valid_flags="${valid_flags} $(echo "$flag" | cut -d':' -f1)"
|
||||
if [[ "$flag" == "${INFO_FLAG}:"* ]]; then
|
||||
value=${flag#*: }
|
||||
size="${#value}"
|
||||
if [[ "$size" -ne 0 ]]; then
|
||||
echo "$value" && match=true && value_exists=true
|
||||
else
|
||||
match=true
|
||||
fi
|
||||
fi
|
||||
done
|
||||
[[ "$match" == "true" ]] || dokku_log_fail "Invalid flag passed, valid flags:${valid_flags}"
|
||||
[[ "$value_exists" == "true" ]] || dokku_log_fail "not deployed"
|
||||
fi
|
||||
}
|
||||
|
||||
fn-builder-railpack-computed-railpackjson-path() {
|
||||
declare APP="$1"
|
||||
|
||||
file="$(fn-builder-railpack-railpackjson-path "$APP")"
|
||||
if [[ "$file" == "" ]]; then
|
||||
file="$(fn-builder-railpack-global-railpackjson-path "$APP")"
|
||||
fi
|
||||
|
||||
echo "$file"
|
||||
}
|
||||
|
||||
fn-builder-railpack-global-railpackjson-path() {
|
||||
declare APP="$1"
|
||||
|
||||
fn-plugin-property-get "builder-railpack" "--global" "railpackjson-path" "railpack.json"
|
||||
}
|
||||
|
||||
fn-builder-railpack-railpackjson-path() {
|
||||
declare APP="$1"
|
||||
|
||||
fn-plugin-property-get "builder-railpack" "$APP" "railpackjson-path" ""
|
||||
}
|
||||
4
plugins/builder-railpack/plugin.toml
Normal file
4
plugins/builder-railpack/plugin.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core builder-railpack plugin"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
14
plugins/builder-railpack/post-app-clone-setup
Executable file
14
plugins/builder-railpack/post-app-clone-setup
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
trigger-builder-railpack-post-app-clone-setup() {
|
||||
declare desc="sets up properties for new app"
|
||||
declare trigger="post-app-clone-setup"
|
||||
declare OLD_APP="$1" NEW_APP="$2"
|
||||
|
||||
fn-plugin-property-clone "builder-railpack" "$OLD_APP" "$NEW_APP"
|
||||
}
|
||||
|
||||
trigger-builder-railpack-post-app-clone-setup "$@"
|
||||
15
plugins/builder-railpack/post-app-rename-setup
Executable file
15
plugins/builder-railpack/post-app-rename-setup
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
trigger-builder-railpack-post-app-rename-setup() {
|
||||
declare desc="updates settings for new app"
|
||||
declare trigger="post-app-rename-setup"
|
||||
declare OLD_APP="$1" NEW_APP="$2"
|
||||
|
||||
fn-plugin-property-clone "builder-railpack" "$OLD_APP" "$NEW_APP"
|
||||
fn-plugin-property-destroy "builder-railpack" "$OLD_APP"
|
||||
}
|
||||
|
||||
trigger-builder-railpack-post-app-rename-setup "$@"
|
||||
15
plugins/builder-railpack/post-delete
Executable file
15
plugins/builder-railpack/post-delete
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
trigger-builder-railpack-post-delete() {
|
||||
declare desc="destroys the builder-railpack properties for a given app"
|
||||
declare trigger="post-delete"
|
||||
declare APP="$1"
|
||||
|
||||
fn-plugin-property-destroy "builder-railpack" "$APP"
|
||||
rm -rf "${DOKKU_LIB_ROOT}/data/builder-railpack/$APP"
|
||||
}
|
||||
|
||||
trigger-builder-railpack-post-delete "$@"
|
||||
6
plugins/builder-railpack/report
Executable file
6
plugins/builder-railpack/report
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_AVAILABLE_PATH/builder-railpack/internal-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-builder-railpack-report-single "$@"
|
||||
6
plugins/builder-railpack/subcommands/default
Executable file
6
plugins/builder-railpack/subcommands/default
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_AVAILABLE_PATH/builder-railpack/help-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-builder-railpack-help "builder-railpack:help"
|
||||
6
plugins/builder-railpack/subcommands/report
Executable file
6
plugins/builder-railpack/subcommands/report
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_AVAILABLE_PATH/builder-railpack/internal-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-builder-railpack-report "$@"
|
||||
30
plugins/builder-railpack/subcommands/set
Executable file
30
plugins/builder-railpack/subcommands/set
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-builder-railpack-set() {
|
||||
declare desc="set or clear a builder-railpack property for an app"
|
||||
declare cmd="builder-railpack:set"
|
||||
[[ "$1" == "$cmd" ]] && shift 1
|
||||
declare APP="$1" KEY="$2" VALUE="$3"
|
||||
local VALID_KEYS=("railpackjson-path")
|
||||
[[ "$APP" == "--global" ]] || verify_app_name "$APP"
|
||||
|
||||
[[ -z "$KEY" ]] && dokku_log_fail "No key specified"
|
||||
|
||||
if ! fn-in-array "$KEY" "${VALID_KEYS[@]}"; then
|
||||
dokku_log_fail "Invalid key specified, valid keys include: railpackjson-path"
|
||||
fi
|
||||
|
||||
if [[ -n "$VALUE" ]]; then
|
||||
dokku_log_info2_quiet "Setting ${KEY} to ${VALUE}"
|
||||
fn-plugin-property-write "builder-railpack" "$APP" "$KEY" "$VALUE"
|
||||
else
|
||||
dokku_log_info2_quiet "Unsetting ${KEY}"
|
||||
fn-plugin-property-delete "builder-railpack" "$APP" "$KEY"
|
||||
fi
|
||||
}
|
||||
|
||||
cmd-builder-railpack-set "$@"
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/dokku/dokku/plugins/builder
|
||||
|
||||
go 1.25.1
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
|
||||
@@ -21,9 +21,9 @@ require (
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pkg/sftp v1.13.5 // indirect
|
||||
github.com/ryanuber/columnize v2.1.2+incompatible // indirect
|
||||
golang.org/x/crypto v0.43.0 // indirect
|
||||
golang.org/x/sync v0.17.0 // indirect
|
||||
golang.org/x/sys v0.37.0 // indirect
|
||||
golang.org/x/crypto v0.46.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/dokku/dokku/plugins/common => ../common
|
||||
|
||||
@@ -19,8 +19,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/melbahja/goph v1.4.0 h1:z0PgDbBFe66lRYl3v5dGb9aFgPy0kotuQ37QOwSQFqs=
|
||||
github.com/melbahja/goph v1.4.0/go.mod h1:uG+VfK2Dlhk+O32zFrRlc3kYKTlV6+BtvPWd/kK7U68=
|
||||
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
|
||||
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
|
||||
github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q=
|
||||
github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4=
|
||||
github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8=
|
||||
github.com/otiai10/copy v1.14.1/go.mod h1:oQwrEDDOci3IM8dJF0d8+jnbfPDllW6vUjNc3DoZm9I=
|
||||
github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
|
||||
@@ -45,20 +45,20 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
||||
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.45.0 h1:RLBg5JKixCy82FtLJpeNlVM0nrSqpCRYzVU1n8kj0tM=
|
||||
golang.org/x/net v0.45.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -69,20 +69,20 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
||||
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
|
||||
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
|
||||
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
|
||||
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
||||
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core builder plugin"
|
||||
version = "0.36.8"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
|
||||
@@ -109,7 +109,7 @@ func TriggerInstall() error {
|
||||
}
|
||||
|
||||
apps, err := common.UnfilteredDokkuApps()
|
||||
if err != nil {
|
||||
if err != nil && !errors.Is(err, common.NoAppsExist) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
SUBCOMMANDS = subcommands/add subcommands/clear subcommands/list subcommands/remove subcommands/report subcommands/set subcommands/set-property
|
||||
SUBCOMMANDS = subcommands/add subcommands/clear subcommands/detect subcommands/list subcommands/remove subcommands/report subcommands/set subcommands/set-property
|
||||
TRIGGERS = triggers/buildpack-stack-name triggers/install triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-delete triggers/post-extract triggers/report
|
||||
BUILD = commands subcommands triggers
|
||||
PLUGIN_NAME = buildpacks
|
||||
|
||||
@@ -63,3 +63,32 @@ func validBuildpackURL(buildpack string) (string, error) {
|
||||
|
||||
return buildpack, fmt.Errorf("Invalid buildpack specified: %v", buildpack)
|
||||
}
|
||||
|
||||
func checkoutBareGitRepo(sourceWorkDir string, branch string) (string, error) {
|
||||
tmpdir, err := os.MkdirTemp("", "bare-git-checkout")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Unable to create temporary directory: %s", err.Error())
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"--git-dir=" + sourceWorkDir,
|
||||
"--work-tree=" + tmpdir,
|
||||
"checkout", "-f",
|
||||
}
|
||||
|
||||
if branch != "" {
|
||||
args = append(args, branch)
|
||||
}
|
||||
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: "git",
|
||||
Args: args,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
os.RemoveAll(tmpdir)
|
||||
return "", fmt.Errorf("Unable to checkout bare git repository: %s", result.StderrContents())
|
||||
}
|
||||
|
||||
return tmpdir, nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/dokku/dokku/plugins/buildpacks
|
||||
|
||||
go 1.25.1
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
|
||||
@@ -21,9 +21,9 @@ require (
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pkg/sftp v1.13.5 // indirect
|
||||
github.com/ryanuber/columnize v2.1.2+incompatible // indirect
|
||||
golang.org/x/crypto v0.43.0 // indirect
|
||||
golang.org/x/sync v0.17.0 // indirect
|
||||
golang.org/x/sys v0.37.0 // indirect
|
||||
golang.org/x/crypto v0.46.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/dokku/dokku/plugins/common => ../common
|
||||
|
||||
@@ -19,8 +19,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/melbahja/goph v1.4.0 h1:z0PgDbBFe66lRYl3v5dGb9aFgPy0kotuQ37QOwSQFqs=
|
||||
github.com/melbahja/goph v1.4.0/go.mod h1:uG+VfK2Dlhk+O32zFrRlc3kYKTlV6+BtvPWd/kK7U68=
|
||||
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
|
||||
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
|
||||
github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q=
|
||||
github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4=
|
||||
github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8=
|
||||
github.com/otiai10/copy v1.14.1/go.mod h1:oQwrEDDOci3IM8dJF0d8+jnbfPDllW6vUjNc3DoZm9I=
|
||||
github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
|
||||
@@ -45,20 +45,20 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
||||
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.45.0 h1:RLBg5JKixCy82FtLJpeNlVM0nrSqpCRYzVU1n8kj0tM=
|
||||
golang.org/x/net v0.45.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -69,20 +69,20 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
||||
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
|
||||
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
|
||||
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
|
||||
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
||||
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core buildpacks plugin"
|
||||
version = "0.36.8"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
|
||||
@@ -20,6 +20,7 @@ Additional commands:`
|
||||
helpContent = `
|
||||
buildpacks:add [--index 1] <app> <buildpack>, Add new app buildpack while inserting into list of buildpacks if necessary
|
||||
buildpacks:clear <app>, Clear all buildpacks set on the app
|
||||
buildpacks:detect <app> [--branch <branch-name>], Detect the buildpack for an app (if not specified, the branch flag defaults to the deploy branch)
|
||||
buildpacks:list <app>, List all buildpacks for an app
|
||||
buildpacks:remove <app> <buildpack>, Remove a buildpack set on the app
|
||||
buildpacks:report [<app>] [<flag>], Displays a buildpack report for one or more apps
|
||||
|
||||
@@ -30,6 +30,15 @@ func main() {
|
||||
args.Parse(os.Args[2:])
|
||||
appName := args.Arg(0)
|
||||
err = buildpacks.CommandClear(appName)
|
||||
case "detect":
|
||||
args := flag.NewFlagSet("buildpacks:detect", flag.ExitOnError)
|
||||
branch := args.String("branch", "", "--branch: the branch to detect against (defaults to the deploy branch)")
|
||||
args.Parse(os.Args[2:])
|
||||
appName := args.Arg(0)
|
||||
if *branch == "" {
|
||||
*branch = common.PropertyGet("git", appName, "deploy-branch")
|
||||
}
|
||||
err = buildpacks.CommandDetect(appName, *branch)
|
||||
case "list":
|
||||
args := flag.NewFlagSet("buildpacks:list", flag.ExitOnError)
|
||||
args.Parse(os.Args[2:])
|
||||
|
||||
@@ -3,6 +3,7 @@ package buildpacks
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/dokku/dokku/plugins/common"
|
||||
)
|
||||
@@ -30,6 +31,41 @@ func CommandClear(appName string) error {
|
||||
return common.PropertyDelete("buildpacks", appName, "buildpacks")
|
||||
}
|
||||
|
||||
// CommandDetect implements buildpacks:detect
|
||||
func CommandDetect(appName string, branch string) (err error) {
|
||||
if err := common.VerifyAppName(appName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
workDir := common.AppRoot(appName)
|
||||
checkedOutDir, err := checkoutBareGitRepo(workDir, branch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := os.RemoveAll(checkedOutDir); err != nil {
|
||||
common.LogWarn(fmt.Sprintf("Failed to remove temporary directory %s: %v", checkedOutDir, err))
|
||||
}
|
||||
}()
|
||||
|
||||
dockerArgs := []string{
|
||||
"run", "--rm",
|
||||
"-v", fmt.Sprintf("%s:/tmp/app", checkedOutDir),
|
||||
"gliderlabs/herokuish", "/bin/herokuish", "buildpack", "detect", "/tmp/app",
|
||||
}
|
||||
|
||||
result, err := common.CallExecCommand(common.ExecCommandInput{
|
||||
Command: common.DockerBin(),
|
||||
Args: dockerArgs,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Buildpack detection failed: %s", result.StderrContents())
|
||||
}
|
||||
|
||||
common.LogVerbose(result.StdoutContents())
|
||||
return nil
|
||||
}
|
||||
|
||||
// CommandList implements buildpacks:list
|
||||
func CommandList(appName string) (err error) {
|
||||
if err := common.VerifyAppName(appName); err != nil {
|
||||
|
||||
@@ -1,9 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/proxy/command-functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/caddy-vhosts/internal-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
cmd-caddy-labels-add() {
|
||||
declare desc="adds container label to app for specified proxy"
|
||||
declare cmd="caddy:labels:add"
|
||||
[[ "$1" == "$cmd" ]] && shift 1
|
||||
|
||||
cmd-proxy-labels-add "proxy:labels:add" "caddy" "$@"
|
||||
}
|
||||
|
||||
cmd-caddy-labels-remove() {
|
||||
declare desc="removes container label from app for specified proxy"
|
||||
declare cmd="caddy:labels:remove"
|
||||
[[ "$1" == "$cmd" ]] && shift 1
|
||||
|
||||
cmd-proxy-labels-remove "proxy:labels:remove" "caddy" "$@"
|
||||
}
|
||||
|
||||
cmd-caddy-labels-show() {
|
||||
declare desc="shows container labels for app for specified proxy"
|
||||
declare cmd="caddy:labels:show"
|
||||
[[ "$1" == "$cmd" ]] && shift 1
|
||||
|
||||
cmd-proxy-labels-show "proxy:labels:show" "caddy" "$@"
|
||||
}
|
||||
|
||||
cmd-caddy-report() {
|
||||
declare desc="displays a caddy report for one or more apps"
|
||||
declare cmd="caddy:report"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
[[ " caddy:help help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
|
||||
[[ " caddy:help caddy:labels:add caddy:labels:remove caddy:labels:show help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
|
||||
source "$PLUGIN_AVAILABLE_PATH/caddy-vhosts/help-functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/caddy-vhosts/command-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
@@ -9,6 +10,18 @@ case "$1" in
|
||||
cmd-caddy-help "$@"
|
||||
;;
|
||||
|
||||
caddy:labels:add)
|
||||
cmd-caddy-labels-add "$@"
|
||||
;;
|
||||
|
||||
caddy:labels:remove)
|
||||
cmd-caddy-labels-remove "$@"
|
||||
;;
|
||||
|
||||
caddy:labels:show)
|
||||
cmd-caddy-labels-show "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
|
||||
;;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/caddy-vhosts/internal-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
@@ -8,7 +9,7 @@ trigger-caddy-vhosts-docker-args-process-deploy() {
|
||||
declare desc="nginx-vhosts core-post-deploy plugin trigger"
|
||||
declare trigger="docker-args-process-deploy"
|
||||
declare APP="$1" IMAGE_SOURCE_TYPE="$2" IMAGE_TAG="$3" PROC_TYPE="$4" CONTAINER_INDEX="$5"
|
||||
local app_domains caddy_domains is_app_listening letsencrypt_email output proxy_container_port proxy_host_port port_map proxy_scheme proxy_schemes scheme tls_internal label_key
|
||||
local app_domains caddy_domains is_app_listening letsencrypt_email output proxy_container_port proxy_host_port port_map proxy_scheme proxy_schemes scheme tls_internal
|
||||
local proxy_container_http_port proxy_container_http_port_candidate proxy_host_http_port_candidate
|
||||
local proxy_container_https_port proxy_container_https_port_candidate proxy_host_https_port_candidate
|
||||
local STDIN=$(cat)
|
||||
@@ -88,14 +89,13 @@ trigger-caddy-vhosts-docker-args-process-deploy() {
|
||||
if [[ -n "$is_app_listening" ]] && [[ -n "$caddy_domains" ]]; then
|
||||
has_443_mapping=false
|
||||
tls_internal="$(fn-caddy-tls-internal)"
|
||||
label_key="$(fn-caddy-label-key "$APP")"
|
||||
if [[ -n "$proxy_container_https_port" ]] || [[ -n "$proxy_container_https_port_candidate" ]]; then
|
||||
has_443_mapping=true
|
||||
fi
|
||||
|
||||
ssl_warning_mapping="https:443"
|
||||
if [[ "$tls_internal" == "true" ]]; then
|
||||
output="--label ${label_key}.tls=internal"
|
||||
output="--label caddy.tls=internal"
|
||||
if [[ "$has_443_mapping" == "false" ]]; then
|
||||
ssl_warning_mapping="http:80"
|
||||
proxy_host_https_port_candidate="$proxy_host_http_port_candidate"
|
||||
@@ -106,7 +106,7 @@ trigger-caddy-vhosts-docker-args-process-deploy() {
|
||||
|
||||
scheme="http"
|
||||
if [[ -n "$letsencrypt_email" ]] && [[ "$has_443_mapping" == "true" ]]; then
|
||||
output="--label '${label_key}=${caddy_domains}'"
|
||||
output="--label 'caddy=${caddy_domains}'"
|
||||
scheme="https"
|
||||
if [[ -z "$proxy_container_https_port" ]]; then
|
||||
warning_scheme="$(awk -F ':' '{ print $1 }' <<<"$ssl_warning_mapping")"
|
||||
@@ -115,20 +115,28 @@ trigger-caddy-vhosts-docker-args-process-deploy() {
|
||||
proxy_container_https_port="$proxy_container_https_port_candidate"
|
||||
fi
|
||||
|
||||
output="$output --label \"${label_key}.reverse_proxy={{ upstreams $proxy_container_https_port }}\""
|
||||
output="$output --label \"caddy.reverse_proxy={{ upstreams $proxy_container_https_port }}\""
|
||||
elif [[ -n "$proxy_container_http_port" ]] || [[ -n "$proxy_container_http_port_candidate" ]]; then
|
||||
caddy_domains="${caddy_domains//, /:80, }"
|
||||
output="--label '${label_key}=${caddy_domains}:80'"
|
||||
output="--label 'caddy=${caddy_domains}:80'"
|
||||
if [[ -z "$proxy_container_http_port" ]]; then
|
||||
dokku_log_warn "Warning: http:80 port mapping not found"
|
||||
dokku_log_warn "Utilizing first http port mapping, http:$proxy_host_http_port_candidate:$proxy_container_http_port_candidate"
|
||||
proxy_container_http_port="$proxy_container_http_port_candidate"
|
||||
fi
|
||||
|
||||
output="$output --label \"${label_key}.reverse_proxy={{ upstreams $proxy_container_http_port }}\""
|
||||
output="$output --label \"caddy.reverse_proxy={{ upstreams $proxy_container_http_port }}\""
|
||||
fi
|
||||
fi
|
||||
|
||||
local proxy_labels_file_path=$(fn-proxy-get-labels-file-path "caddy" "$APP")
|
||||
if [[ -f "$proxy_labels_file_path" ]]; then
|
||||
while read -r line; do
|
||||
[[ -z "$line" ]] && continue
|
||||
output="$output --label '$line'"
|
||||
done <"$proxy_labels_file_path"
|
||||
fi
|
||||
|
||||
echo -n "$STDIN$output"
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@ fn-help-content() {
|
||||
caddy:report [<app>] [<flag>], Displays an caddy report for one or more apps
|
||||
caddy:set <app> <property> (<value>), Set or clear an caddy property for an app
|
||||
caddy:show-config <app>, Display caddy compose config
|
||||
caddy:labels:add <app> <label> <value>, Add a label to an caddy app
|
||||
caddy:labels:remove <app> <label>, Remove a label from an caddy app
|
||||
caddy:labels:show <app> [<label>], Show labels for an caddy app
|
||||
caddy:start, Starts the caddy server
|
||||
caddy:stop, Stops the caddy server
|
||||
help_content
|
||||
|
||||
@@ -71,8 +71,3 @@ fn-caddy-tls-internal() {
|
||||
declare APP="$1"
|
||||
fn-plugin-property-get-default "caddy" "$APP" "tls-internal" "false"
|
||||
}
|
||||
|
||||
fn-caddy-label-key() {
|
||||
declare APP="$1"
|
||||
fn-plugin-property-get-default "caddy" "$APP" "label-key" "caddy"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core caddy-vhosts plugin"
|
||||
version = "0.36.8"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
|
||||
14
plugins/caddy-vhosts/post-create
Executable file
14
plugins/caddy-vhosts/post-create
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
trigger-caddy-vhosts-post-create() {
|
||||
declare desc="caddy-vhosts post-create trigger"
|
||||
declare trigger="post-create"
|
||||
declare APP="$1"
|
||||
|
||||
fn-plugin-property-setup-app "caddy" "$APP"
|
||||
}
|
||||
|
||||
trigger-caddy-vhosts-post-create "$@"
|
||||
@@ -9,13 +9,13 @@ cmd-caddy-set() {
|
||||
declare cmd="caddy:set"
|
||||
[[ "$1" == "$cmd" ]] && shift 1
|
||||
declare APP="$1" KEY="$2" VALUE="$3"
|
||||
local VALID_KEYS=("image" "letsencrypt-email" "letsencrypt-server" "log-level" "polling-interval" "label-key" "tls-internal")
|
||||
local VALID_KEYS=("image" "letsencrypt-email" "letsencrypt-server" "log-level" "polling-interval" "tls-internal")
|
||||
local GLOBAL_KEYS=("image" "letsencrypt-email" "letsencrypt-server" "log-level" "polling-interval")
|
||||
|
||||
[[ -z "$KEY" ]] && dokku_log_fail "No key specified"
|
||||
|
||||
if ! fn-in-array "$KEY" "${VALID_KEYS[@]}"; then
|
||||
dokku_log_fail "Invalid key specified, valid keys include: image letsencrypt-email letsencrypt-server log-level polling-interval label-key tls-internal"
|
||||
dokku_log_fail "Invalid key specified, valid keys include: image letsencrypt-email letsencrypt-server log-level polling-interval tls-internal"
|
||||
fi
|
||||
|
||||
if ! fn-in-array "$KEY" "${GLOBAL_KEYS[@]}"; then
|
||||
|
||||
24
plugins/certs/certs-get
Executable file
24
plugins/certs/certs-get
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
source "$PLUGIN_AVAILABLE_PATH/certs/functions"
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
|
||||
trigger-certs-certs-get() {
|
||||
declare desc="returns certificate or key content"
|
||||
declare trigger="certs-get"
|
||||
declare APP="$1" KEY_TYPE="$2"
|
||||
|
||||
local APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
|
||||
|
||||
if [[ "$KEY_TYPE" != "key" ]] && [[ "$KEY_TYPE" != "crt" ]]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! is_ssl_enabled "$APP"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
cat "$APP_SSL_PATH/server.$KEY_TYPE"
|
||||
}
|
||||
|
||||
trigger-certs-certs-get "$@"
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core certificate management plugin"
|
||||
version = "0.36.8"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core checks plugin"
|
||||
version = "0.36.8"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
|
||||
@@ -123,6 +123,19 @@ func CorePostDeploy(input CorePostDeployInput) error {
|
||||
return fmt.Errorf("Missing required Destination in CorePostDeploy for plugin %v", input.PluginName)
|
||||
}
|
||||
|
||||
if !DirectoryExists(input.Destination) {
|
||||
if err := os.MkdirAll(input.Destination, 0755); err != nil {
|
||||
return fmt.Errorf("Unable to create destination directory %v: %s", input.Destination, err.Error())
|
||||
}
|
||||
|
||||
if err := SetPermissions(SetPermissionInput{
|
||||
Filename: input.Destination,
|
||||
Mode: 0755,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("Unable to set destination directory permissions %v: %s", input.Destination, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
for i, extractedPath := range input.ExtractedPaths {
|
||||
if extractedPath.Path == "" {
|
||||
return fmt.Errorf("Missing required Name in CorePostDeploy for index %v for plugin %v", i, input.PluginName)
|
||||
@@ -250,6 +263,19 @@ func CorePostExtract(input CorePostExtractInput) error {
|
||||
})
|
||||
sourceImage := results.StdoutContents()
|
||||
|
||||
if !DirectoryExists(input.Destination) {
|
||||
if err := os.MkdirAll(input.Destination, 0755); err != nil {
|
||||
return fmt.Errorf("Unable to create destination directory %v: %s", input.Destination, err.Error())
|
||||
}
|
||||
|
||||
if err := SetPermissions(SetPermissionInput{
|
||||
Filename: input.Destination,
|
||||
Mode: 0755,
|
||||
}); err != nil {
|
||||
return fmt.Errorf("Unable to set destination directory permissions %v: %s", input.Destination, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
for i, toExtract := range input.ToExtract {
|
||||
if toExtract.Name == "" {
|
||||
return fmt.Errorf("Name is required for index %v in CorePostExtract for plugin %v", i, input.PluginName)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -78,7 +79,7 @@ func SetupAppData(pluginName string) error {
|
||||
}
|
||||
|
||||
apps, err := UnfilteredDokkuApps()
|
||||
if err != nil {
|
||||
if err != nil && !errors.Is(err, NoAppsExist) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@ type ExecCommandInput struct {
|
||||
// Env is the environment variables to pass to the command
|
||||
Env map[string]string
|
||||
|
||||
// PrintCommand prints the command before executing
|
||||
PrintCommand bool
|
||||
|
||||
// Stdin is the stdin of the command
|
||||
Stdin io.Reader
|
||||
|
||||
@@ -141,7 +144,7 @@ func CallExecCommandWithContext(ctx context.Context, input ExecCommandInput) (Ex
|
||||
cmd.Cwd = input.WorkingDirectory
|
||||
}
|
||||
|
||||
if os.Getenv("DOKKU_TRACE") == "1" {
|
||||
if input.PrintCommand || os.Getenv("DOKKU_TRACE") == "1" {
|
||||
argsSt := ""
|
||||
if len(cmd.Args) > 0 {
|
||||
argsSt = strings.Join(cmd.Args, " ")
|
||||
|
||||
@@ -665,11 +665,6 @@ dokku_receive() {
|
||||
|
||||
docker_cleanup "$APP"
|
||||
|
||||
local DOKKU_CNB_EXPERIMENTAL="$(config_get "$APP" DOKKU_CNB_EXPERIMENTAL || true)"
|
||||
if [[ "$DOKKU_CNB_EXPERIMENTAL" == "1" ]]; then
|
||||
IMAGE_SOURCE_TYPE="pack"
|
||||
fi
|
||||
|
||||
plugn trigger builder-set-property "$APP" "detected" "$IMAGE_SOURCE_TYPE"
|
||||
if ! dokku_build "$APP" "$IMAGE_SOURCE_TYPE" "$TMP_WORK_DIR"; then
|
||||
return 1
|
||||
@@ -952,3 +947,14 @@ fn-migrate-config-to-property() {
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
fn-registry-docker-config-dir() {
|
||||
declare desc="returns docker config file path if per-app registry credentials exist"
|
||||
declare APP="$1"
|
||||
local config_dir="/var/lib/dokku/config/registry/$APP"
|
||||
local config_file="$config_dir/config.json"
|
||||
|
||||
if [[ -f "$config_file" ]] && [[ "$(jq -r '.auths | length' "$config_file" 2>/dev/null)" != "0" ]]; then
|
||||
echo "$config_dir"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
module github.com/dokku/dokku/plugins/common
|
||||
|
||||
go 1.25.1
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/alexellis/go-execute/v2 v2.2.1
|
||||
github.com/fatih/color v1.18.0
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/melbahja/goph v1.4.0
|
||||
github.com/onsi/gomega v1.38.2
|
||||
github.com/onsi/gomega v1.39.0
|
||||
github.com/otiai10/copy v1.14.1
|
||||
github.com/ryanuber/columnize v2.1.2+incompatible
|
||||
github.com/spf13/pflag v1.0.10
|
||||
golang.org/x/crypto v0.43.0
|
||||
golang.org/x/sync v0.17.0
|
||||
golang.org/x/crypto v0.46.0
|
||||
golang.org/x/sync v0.19.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -25,8 +25,8 @@ require (
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pkg/sftp v1.13.5 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/net v0.45.0 // indirect
|
||||
golang.org/x/sys v0.37.0 // indirect
|
||||
golang.org/x/text v0.30.0 // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
golang.org/x/text v0.32.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -27,10 +27,10 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/melbahja/goph v1.4.0 h1:z0PgDbBFe66lRYl3v5dGb9aFgPy0kotuQ37QOwSQFqs=
|
||||
github.com/melbahja/goph v1.4.0/go.mod h1:uG+VfK2Dlhk+O32zFrRlc3kYKTlV6+BtvPWd/kK7U68=
|
||||
github.com/onsi/ginkgo/v2 v2.25.1 h1:Fwp6crTREKM+oA6Cz4MsO8RhKQzs2/gOIVOUscMAfZY=
|
||||
github.com/onsi/ginkgo/v2 v2.25.1/go.mod h1:ppTWQ1dh9KM/F1XgpeRqelR+zHVwV81DGRSDnFxK7Sk=
|
||||
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
|
||||
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
|
||||
github.com/onsi/ginkgo/v2 v2.25.3 h1:Ty8+Yi/ayDAGtk4XxmmfUy4GabvM+MegeB4cDLRi6nw=
|
||||
github.com/onsi/ginkgo/v2 v2.25.3/go.mod h1:43uiyQC4Ed2tkOzLsEYm7hnrb7UJTWHYNsuy3bG/snE=
|
||||
github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q=
|
||||
github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4=
|
||||
github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8=
|
||||
github.com/otiai10/copy v1.14.1/go.mod h1:oQwrEDDOci3IM8dJF0d8+jnbfPDllW6vUjNc3DoZm9I=
|
||||
github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
|
||||
@@ -57,20 +57,20 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
||||
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.45.0 h1:RLBg5JKixCy82FtLJpeNlVM0nrSqpCRYzVU1n8kj0tM=
|
||||
golang.org/x/net v0.45.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -81,25 +81,25 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
||||
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
|
||||
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
|
||||
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
|
||||
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
||||
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
|
||||
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
|
||||
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
|
||||
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -90,7 +90,9 @@ func LogFailWithError(err error) {
|
||||
fmt.Fprintf(os.Stderr, " ! %s\n", e.Error())
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, " ! %s\n", err.Error())
|
||||
if err.Error() != "" {
|
||||
fmt.Fprintf(os.Stderr, " ! %s\n", err.Error())
|
||||
}
|
||||
}
|
||||
if errExit, ok := err.(ErrWithExitCode); ok {
|
||||
os.Exit(errExit.ExitCode())
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core common plugin"
|
||||
version = "0.36.8"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
|
||||
@@ -19,6 +19,9 @@ type PlugnTriggerInput struct {
|
||||
// Env is the environment variables to pass to the trigger
|
||||
Env map[string]string
|
||||
|
||||
// PrintCommand prints the command before executing
|
||||
PrintCommand bool
|
||||
|
||||
// Stdin is the stdin of the command
|
||||
Stdin io.Reader
|
||||
|
||||
@@ -55,7 +58,7 @@ func CallPlugnTriggerWithContext(ctx context.Context, input PlugnTriggerInput) (
|
||||
StreamStderr: input.StreamStderr,
|
||||
})
|
||||
|
||||
if os.Getenv("DOKKU_TRACE") == "1" {
|
||||
if input.PrintCommand || os.Getenv("DOKKU_TRACE") == "1" {
|
||||
for _, line := range strings.Split(result.Stderr, "\n") {
|
||||
LogDebug(fmt.Sprintf("plugn trigger %s stderr: %s", input.Trigger, line))
|
||||
}
|
||||
|
||||
@@ -12,27 +12,27 @@ import (
|
||||
)
|
||||
|
||||
// CommandPropertySet is a generic function that will set a property for a given plugin/app combination
|
||||
func CommandPropertySet(pluginName, appName, property, value string, properties map[string]string, globalProperties map[string]bool) {
|
||||
func CommandPropertySet(pluginName, appName, property, value string, validProperties map[string]string, validGlobalProperties map[string]bool) {
|
||||
if appName != "--global" {
|
||||
if err := VerifyAppName(appName); err != nil {
|
||||
LogFailWithError(err)
|
||||
}
|
||||
}
|
||||
if appName == "--global" && !globalProperties[property] {
|
||||
if appName == "--global" && !validGlobalProperties[property] {
|
||||
LogFail("Property cannot be specified globally")
|
||||
}
|
||||
if property == "" {
|
||||
LogFail("No property specified")
|
||||
}
|
||||
|
||||
for k := range globalProperties {
|
||||
if _, ok := properties[k]; !ok {
|
||||
properties[k] = ""
|
||||
for k := range validGlobalProperties {
|
||||
if _, ok := validProperties[k]; !ok {
|
||||
validProperties[k] = ""
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := properties[property]; !ok {
|
||||
properties := reflect.ValueOf(properties).MapKeys()
|
||||
if _, ok := validProperties[property]; !ok {
|
||||
properties := reflect.ValueOf(validProperties).MapKeys()
|
||||
validPropertyList := make([]string, len(properties))
|
||||
for i := 0; i < len(properties); i++ {
|
||||
validPropertyList[i] = properties[i].String()
|
||||
@@ -540,6 +540,14 @@ func PropertySetup(pluginName string) error {
|
||||
})
|
||||
}
|
||||
|
||||
func PropertySetupApp(pluginName string, appName string) error {
|
||||
if err := makePluginAppPropertyPath(pluginName, appName); err != nil {
|
||||
return fmt.Errorf("Unable to create %s config directory for %s: %s", pluginName, appName, err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getPropertyPath(pluginName string, appName string, property string) string {
|
||||
pluginAppConfigRoot := getPluginAppPropertyPath(pluginName, appName)
|
||||
return filepath.Join(pluginAppConfigRoot, property)
|
||||
|
||||
@@ -39,6 +39,12 @@ fn-plugin-property-get-all() {
|
||||
"$PLUGIN_CORE_AVAILABLE_PATH/common/prop" "get-all" "$PLUGIN" "$APP"
|
||||
}
|
||||
|
||||
fn-plugin-property-get-all-by-prefix() {
|
||||
declare desc="returns a map of all properties for a given app with a specified prefix"
|
||||
declare PLUGIN="$1" APP="$2" PREFIX="$3"
|
||||
"$PLUGIN_CORE_AVAILABLE_PATH/common/prop" "get-all-by-prefix" "$PLUGIN" "$APP" "$PREFIX"
|
||||
}
|
||||
|
||||
fn-plugin-property-get-default() {
|
||||
declare desc="returns the value for a given property with a specified default value"
|
||||
declare PLUGIN="$1" APP="$2" KEY="$3" DEFAULT="$4"
|
||||
@@ -104,3 +110,9 @@ fn-plugin-property-setup() {
|
||||
declare PLUGIN="$1"
|
||||
"$PLUGIN_CORE_AVAILABLE_PATH/common/prop" "setup" "$PLUGIN"
|
||||
}
|
||||
|
||||
fn-plugin-property-setup-app() {
|
||||
declare desc="setup the properties for an app"
|
||||
declare PLUGIN="$1" APP="$2"
|
||||
"$PLUGIN_CORE_AVAILABLE_PATH/common/prop" "setup-app" "$PLUGIN" "$APP"
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ func (task SftpCopyTask) Execute(ctx context.Context) (SftpCopyResult, error) {
|
||||
}, ctx.Err()
|
||||
}
|
||||
|
||||
if task.PrintCommand {
|
||||
if task.PrintCommand || os.Getenv("DOKKU_TRACE") == "1" {
|
||||
LogDebug(fmt.Sprintf("ssh %s@%s cp %s %v", task.Username, task.Hostname, task.SourcePath, task.DestinationPath))
|
||||
}
|
||||
|
||||
|
||||
@@ -78,6 +78,19 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
for key, value := range values {
|
||||
fmt.Println(fmt.Sprintf("%s %s", key, strings.TrimSuffix(value, "\n")))
|
||||
}
|
||||
|
||||
case "get-all-by-prefix":
|
||||
appName := flag.Arg(2)
|
||||
prefix := flag.Arg(3)
|
||||
values, err := common.PropertyGetAllByPrefix(pluginName, appName, prefix)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
for key, value := range values {
|
||||
fmt.Println(fmt.Sprintf("%s %s", key, strings.TrimSuffix(value, "\n")))
|
||||
}
|
||||
@@ -194,5 +207,12 @@ func main() {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
case "setup-app":
|
||||
appName := flag.Arg(2)
|
||||
err := common.PropertySetupApp(pluginName, appName)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,6 +203,7 @@ type SshTask struct {
|
||||
|
||||
// PrintCommand prints the command before executing
|
||||
PrintCommand bool
|
||||
|
||||
// StreamStdio prints stdout and stderr directly to os.Stdout/err as
|
||||
// the command runs.
|
||||
StreamStdio bool
|
||||
@@ -334,7 +335,7 @@ func (task SshTask) Execute(ctx context.Context) (SshResult, error) {
|
||||
command = "sudo"
|
||||
}
|
||||
|
||||
if task.PrintCommand {
|
||||
if task.PrintCommand || os.Getenv("DOKKU_TRACE") == "1" {
|
||||
LogDebug(fmt.Sprintf("ssh %s@%s %s %v", task.Username, task.Hostname, command, commandArgs))
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
@@ -34,7 +35,7 @@ func TriggerInstall() error {
|
||||
}
|
||||
|
||||
apps, err := UnfilteredDokkuApps()
|
||||
if err != nil {
|
||||
if err != nil && !errors.Is(err, NoAppsExist) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GOARCH ?= amd64
|
||||
SUBCOMMANDS = subcommands/bundle subcommands/clear subcommands/export subcommands/get subcommands/keys subcommands/show subcommands/set subcommands/unset
|
||||
SUBCOMMANDS = subcommands/bundle subcommands/clear subcommands/export subcommands/get subcommands/import subcommands/keys subcommands/show subcommands/set subcommands/unset
|
||||
TRIGGERS = triggers/config-export triggers/config-get triggers/config-get-global triggers/config-unset triggers/post-app-clone-setup triggers/post-app-rename-setup
|
||||
BUILD = commands config_sub subcommands triggers
|
||||
PLUGIN_NAME = config
|
||||
|
||||
@@ -30,7 +30,7 @@ func GetWithDefault(appName string, key string, defaultValue string) (value stri
|
||||
}
|
||||
|
||||
// SetMany variables in the environment. If appName is empty the global config is used. If restart is true the app is restarted.
|
||||
func SetMany(appName string, entries map[string]string, restart bool) (err error) {
|
||||
func SetMany(appName string, entries map[string]string, replace bool, restart bool) (err error) {
|
||||
global := appName == "" || appName == "--global"
|
||||
env, err := loadAppOrGlobalEnv(appName)
|
||||
if err != nil {
|
||||
@@ -42,6 +42,10 @@ func SetMany(appName string, entries map[string]string, restart bool) (err error
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if replace {
|
||||
env.Clear()
|
||||
}
|
||||
for k, v := range entries {
|
||||
env.Set(k, v)
|
||||
keys = append(keys, k)
|
||||
@@ -128,6 +132,10 @@ func UnsetAll(appName string, restart bool) (err error) {
|
||||
}
|
||||
|
||||
func triggerRestart(appName string) {
|
||||
if !common.IsDeployed(appName) {
|
||||
return
|
||||
}
|
||||
|
||||
common.LogInfo1(fmt.Sprintf("Restarting app %s", appName))
|
||||
_, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
|
||||
Trigger: "release-and-deploy",
|
||||
|
||||
@@ -128,6 +128,82 @@ func TestConfigUnsetMany(t *testing.T) {
|
||||
Expect(CommandUnset(testAppName+"does-not-exist", keys, false, true)).ToNot(Succeed())
|
||||
}
|
||||
|
||||
func TestConfigImport(t *testing.T) {
|
||||
RegisterTestingT(t)
|
||||
Expect(setupTests()).To(Succeed())
|
||||
Expect(setupTestApp()).To(Succeed())
|
||||
defer teardownTestApp()
|
||||
|
||||
tempFile, err := os.CreateTemp("", "test-config-import-*.env")
|
||||
Expect(err).To(Succeed())
|
||||
defer os.Remove(tempFile.Name())
|
||||
content := `
|
||||
testKey=TESTING-updated1
|
||||
testKey2=TESTING-updated2
|
||||
`
|
||||
_, err = tempFile.WriteString(content)
|
||||
Expect(err).To(Succeed())
|
||||
tempFile.Close()
|
||||
|
||||
Expect(CommandImport(testAppName, false, false, true, "envfile", tempFile.Name())).To(Succeed())
|
||||
expectValue(testAppName, "testKey", "TESTING-updated1")
|
||||
expectValue(testAppName, "testKey2", "TESTING-updated2")
|
||||
|
||||
env, err := LoadAppEnv(testAppName)
|
||||
Expect(err).To(Succeed())
|
||||
env.Set("testKey", "TESTING-original1")
|
||||
env.Set("testKey2", "TESTING-original2")
|
||||
env.Set("testKey3", "TESTING-original3")
|
||||
env.Write()
|
||||
|
||||
Expect(CommandImport(testAppName, false, false, true, "envfile", tempFile.Name())).To(Succeed())
|
||||
expectValue(testAppName, "testKey", "TESTING-updated1")
|
||||
expectValue(testAppName, "testKey2", "TESTING-updated2")
|
||||
expectValue(testAppName, "testKey3", "TESTING-original3")
|
||||
|
||||
Expect(CommandImport(testAppName, false, true, true, "envfile", tempFile.Name())).To(Succeed())
|
||||
expectValue(testAppName, "testKey", "TESTING-updated1")
|
||||
expectValue(testAppName, "testKey2", "TESTING-updated2")
|
||||
expectNoValue(testAppName, "testKey3")
|
||||
}
|
||||
|
||||
func TestConfigImportJSON(t *testing.T) {
|
||||
RegisterTestingT(t)
|
||||
Expect(setupTests()).To(Succeed())
|
||||
Expect(setupTestApp()).To(Succeed())
|
||||
defer teardownTestApp()
|
||||
|
||||
tempFile, err := os.CreateTemp("", "test-config-import-*.json")
|
||||
Expect(err).To(Succeed())
|
||||
defer os.Remove(tempFile.Name())
|
||||
|
||||
content := `{"testKey": "TESTING-updated1", "testKey2": "TESTING-updated2"}`
|
||||
_, err = tempFile.WriteString(content)
|
||||
Expect(err).To(Succeed())
|
||||
tempFile.Close()
|
||||
|
||||
Expect(CommandImport(testAppName, false, false, true, "json", tempFile.Name())).To(Succeed())
|
||||
expectValue(testAppName, "testKey", "TESTING-updated1")
|
||||
expectValue(testAppName, "testKey2", "TESTING-updated2")
|
||||
|
||||
env, err := LoadAppEnv(testAppName)
|
||||
Expect(err).To(Succeed())
|
||||
env.Set("testKey", "TESTING-original1")
|
||||
env.Set("testKey2", "TESTING-original2")
|
||||
env.Set("testKey3", "TESTING-original3")
|
||||
env.Write()
|
||||
|
||||
Expect(CommandImport(testAppName, false, false, true, "json", tempFile.Name())).To(Succeed())
|
||||
expectValue(testAppName, "testKey", "TESTING-updated1")
|
||||
expectValue(testAppName, "testKey2", "TESTING-updated2")
|
||||
expectValue(testAppName, "testKey3", "TESTING-original3")
|
||||
|
||||
Expect(CommandImport(testAppName, false, true, true, "json", tempFile.Name())).To(Succeed())
|
||||
expectValue(testAppName, "testKey", "TESTING-updated1")
|
||||
expectValue(testAppName, "testKey2", "TESTING-updated2")
|
||||
expectNoValue(testAppName, "testKey3")
|
||||
}
|
||||
|
||||
func TestEnvironmentLoading(t *testing.T) {
|
||||
RegisterTestingT(t)
|
||||
Expect(setupTests()).To(Succeed())
|
||||
@@ -161,12 +237,13 @@ func TestInvalidKeys(t *testing.T) {
|
||||
|
||||
invalidKeys := []string{"0invalidKey", "invalid:key", "invalid=Key", "!invalidKey"}
|
||||
for _, key := range invalidKeys {
|
||||
Expect(SetMany(testAppName, map[string]string{key: "value"}, false)).NotTo(Succeed())
|
||||
Expect(SetMany(testAppName, map[string]string{key: "value"}, false, false)).NotTo(Succeed())
|
||||
Expect(UnsetMany(testAppName, []string{key}, false)).NotTo(Succeed())
|
||||
value, ok := Get(testAppName, key)
|
||||
Expect(ok).To(Equal(false))
|
||||
value = GetWithDefault(testAppName, key, "default")
|
||||
Expect(value).To(Equal("default"))
|
||||
Expect(value).To(Equal(""))
|
||||
value2 := GetWithDefault(testAppName, key, "default")
|
||||
Expect(value2).To(Equal("default"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -88,6 +88,11 @@ func LoadGlobalEnv() (*Env, error) {
|
||||
return loadFromFile("<global>", getGlobalFile())
|
||||
}
|
||||
|
||||
// Clear clears the environment
|
||||
func (e *Env) Clear() {
|
||||
e.env = make(map[string]string)
|
||||
}
|
||||
|
||||
// Filename returns the full path on disk to the file holding the env vars
|
||||
func (e *Env) Filename() string {
|
||||
return e.filename
|
||||
@@ -326,8 +331,17 @@ func prettyPrintEnvEntries(prefix string, entries map[string]string) string {
|
||||
|
||||
func loadFromFile(name string, filename string) (env *Env, err error) {
|
||||
envMap := make(map[string]string)
|
||||
if filename == "-" {
|
||||
envMap, err = godotenv.Parse(os.Stdin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if _, err := os.Stat(filename); err == nil {
|
||||
envMap, err = godotenv.Read(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
dirty := false
|
||||
@@ -352,6 +366,31 @@ func loadFromFile(name string, filename string) (env *Env, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func loadFromFileJSON(name string, filename string) (env *Env, err error) {
|
||||
envMap := make(map[string]string)
|
||||
if filename == "-" {
|
||||
err = json.NewDecoder(os.Stdin).Decode(&envMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
err = json.NewDecoder(file).Decode(&envMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &Env{
|
||||
name: name,
|
||||
filename: "",
|
||||
env: envMap,
|
||||
}, nil
|
||||
}
|
||||
func getAppFile(appName string) (string, error) {
|
||||
return filepath.Join(common.MustGetEnv("DOKKU_ROOT"), appName, "ENV"), nil
|
||||
}
|
||||
|
||||
@@ -82,6 +82,44 @@ func SubGet(appName string, keys []string, quoted bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SubImport imports environment variables from a file
|
||||
func SubImport(appName string, replace bool, noRestart bool, format string, filename string) error {
|
||||
if filename == "-" {
|
||||
common.LogInfo1Quiet("Reading config vars from stdin")
|
||||
}
|
||||
|
||||
if format == "" {
|
||||
format = "envfile"
|
||||
}
|
||||
|
||||
var env *Env
|
||||
var err error
|
||||
switch format {
|
||||
case "envfile":
|
||||
env, err = loadFromFile(appName, filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case "json":
|
||||
env, err = loadFromFileJSON(appName, filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("Unknown format: %s", format)
|
||||
}
|
||||
|
||||
if len(env.Map()) == 0 {
|
||||
return errors.New("No config vars to set")
|
||||
}
|
||||
|
||||
for k, v := range env.Map() {
|
||||
common.LogInfo1Quiet(fmt.Sprintf("Setting config var %s=%s", k, v))
|
||||
}
|
||||
|
||||
return SetMany(appName, env.Map(), replace, !noRestart)
|
||||
}
|
||||
|
||||
// SubKeys implements the logic for config:keys without app name validation
|
||||
func SubKeys(appName string, merged bool) error {
|
||||
env := getEnvironment(appName, merged)
|
||||
@@ -115,7 +153,7 @@ func SubSet(appName string, pairs []string, noRestart bool, encoded bool) error
|
||||
updated[key] = value
|
||||
}
|
||||
|
||||
return SetMany(appName, updated, !noRestart)
|
||||
return SetMany(appName, updated, false, !noRestart)
|
||||
}
|
||||
|
||||
// SubShow implements the logic for config:show without app name validation
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
module github.com/dokku/dokku/plugins/config
|
||||
|
||||
go 1.25.1
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
|
||||
github.com/joho/godotenv v1.2.0
|
||||
github.com/onsi/gomega v1.38.2
|
||||
github.com/onsi/gomega v1.39.0
|
||||
github.com/ryanuber/columnize v2.1.2+incompatible
|
||||
github.com/spf13/pflag v1.0.10
|
||||
)
|
||||
@@ -25,11 +25,11 @@ require (
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pkg/sftp v1.13.5 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/crypto v0.43.0 // indirect
|
||||
golang.org/x/net v0.45.0 // indirect
|
||||
golang.org/x/sync v0.17.0 // indirect
|
||||
golang.org/x/sys v0.37.0 // indirect
|
||||
golang.org/x/text v0.30.0 // indirect
|
||||
golang.org/x/crypto v0.46.0 // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
golang.org/x/text v0.32.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/dokku/dokku/plugins/common => ../common
|
||||
|
||||
@@ -29,10 +29,10 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/melbahja/goph v1.4.0 h1:z0PgDbBFe66lRYl3v5dGb9aFgPy0kotuQ37QOwSQFqs=
|
||||
github.com/melbahja/goph v1.4.0/go.mod h1:uG+VfK2Dlhk+O32zFrRlc3kYKTlV6+BtvPWd/kK7U68=
|
||||
github.com/onsi/ginkgo/v2 v2.25.1 h1:Fwp6crTREKM+oA6Cz4MsO8RhKQzs2/gOIVOUscMAfZY=
|
||||
github.com/onsi/ginkgo/v2 v2.25.1/go.mod h1:ppTWQ1dh9KM/F1XgpeRqelR+zHVwV81DGRSDnFxK7Sk=
|
||||
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
|
||||
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
|
||||
github.com/onsi/ginkgo/v2 v2.25.3 h1:Ty8+Yi/ayDAGtk4XxmmfUy4GabvM+MegeB4cDLRi6nw=
|
||||
github.com/onsi/ginkgo/v2 v2.25.3/go.mod h1:43uiyQC4Ed2tkOzLsEYm7hnrb7UJTWHYNsuy3bG/snE=
|
||||
github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q=
|
||||
github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4=
|
||||
github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8=
|
||||
github.com/otiai10/copy v1.14.1/go.mod h1:oQwrEDDOci3IM8dJF0d8+jnbfPDllW6vUjNc3DoZm9I=
|
||||
github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
|
||||
@@ -59,20 +59,20 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
||||
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.45.0 h1:RLBg5JKixCy82FtLJpeNlVM0nrSqpCRYzVU1n8kj0tM=
|
||||
golang.org/x/net v0.45.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -83,25 +83,25 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
||||
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
|
||||
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
|
||||
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
|
||||
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
||||
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
|
||||
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
|
||||
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
|
||||
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core config plugin"
|
||||
version = "0.36.8"
|
||||
version = "0.37.6"
|
||||
[plugin.config]
|
||||
|
||||
@@ -24,6 +24,7 @@ Additional commands:`
|
||||
config:clear [--no-restart] (<app>|--global), Clears environment variables
|
||||
config:export [--format=FORMAT] [--merged] (<app>|--global), Export a global or app environment
|
||||
config:get [--quoted] (<app>|--global) KEY, Display a global or app-specific config value
|
||||
config:import [--no-restart] [--replace] (<app>|--global) [FILE|-], Import environment from file
|
||||
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
|
||||
|
||||
@@ -65,6 +65,22 @@ func main() {
|
||||
}
|
||||
keys := getKeys(args.Args(), *global)
|
||||
err = config.CommandGet(appName, keys, *global, *quoted)
|
||||
case "import":
|
||||
args := flag.NewFlagSet("config:import", flag.ExitOnError)
|
||||
global := args.Bool("global", false, "--global: use the global environment")
|
||||
noRestart := args.Bool("no-restart", false, "--no-restart: no restart")
|
||||
replace := args.Bool("replace", false, "--replace: replace existing config vars")
|
||||
format := args.String("format", "envfile", "--format: [ envfile | json ] which format to export as)")
|
||||
|
||||
args.Parse(os.Args[2:])
|
||||
var filename string
|
||||
if !*global {
|
||||
appName = args.Arg(0)
|
||||
filename = args.Arg(1)
|
||||
} else {
|
||||
filename = args.Arg(0)
|
||||
}
|
||||
err = config.CommandImport(appName, *global, *replace, *noRestart, *format, filename)
|
||||
case "keys":
|
||||
args := flag.NewFlagSet("config:keys", flag.ExitOnError)
|
||||
global := args.Bool("global", false, "--global: use the global environment")
|
||||
|
||||
@@ -42,6 +42,16 @@ func CommandGet(appName string, keys []string, global bool, quoted bool) error {
|
||||
return SubGet(appName, keys, quoted)
|
||||
}
|
||||
|
||||
// CommandImport imports environment variables from a file
|
||||
func CommandImport(appName string, global bool, replace bool, noRestart bool, format string, filename string) error {
|
||||
appName, err := getAppNameOrGlobal(appName, global)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return SubImport(appName, replace, noRestart, format, filename)
|
||||
}
|
||||
|
||||
// CommandKeys shows the keys set for the specified environment
|
||||
func CommandKeys(appName string, global bool, merged bool) error {
|
||||
appName, err := getAppNameOrGlobal(appName, global)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
SUBCOMMANDS = subcommands/list subcommands/report subcommands/run subcommands/set
|
||||
SUBCOMMANDS = subcommands/list subcommands/report subcommands/resume subcommands/run subcommands/set subcommands/suspend
|
||||
TRIGGERS = triggers/app-json-is-valid triggers/cron-get-property triggers/install triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-delete triggers/scheduler-stop
|
||||
BUILD = commands subcommands triggers
|
||||
PLUGIN_NAME = cron
|
||||
|
||||
@@ -2,6 +2,7 @@ package cron
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
appjson "github.com/dokku/dokku/plugins/app-json"
|
||||
@@ -27,35 +28,46 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
// TemplateCommand is a struct that represents a cron command
|
||||
type TemplateCommand struct {
|
||||
// ID is a unique identifier for the cron command
|
||||
const MaintenancePropertyPrefix = "maintenance."
|
||||
|
||||
// CronTask is a struct that represents a cron task
|
||||
type CronTask struct {
|
||||
// ID is a unique identifier for the cron task
|
||||
ID string `json:"id"`
|
||||
|
||||
// App is the app the cron command belongs to
|
||||
// App is the app the cron task belongs to
|
||||
App string `json:"app,omitempty"`
|
||||
|
||||
// Command is the command to run
|
||||
Command string `json:"command"`
|
||||
|
||||
// Global is whether the cron command is global
|
||||
// Global is whether the cron task is global
|
||||
Global bool `json:"global,omitempty"`
|
||||
|
||||
// Schedule is the cron schedule
|
||||
Schedule string `json:"schedule"`
|
||||
|
||||
// ConcurrencyPolicy is the concurrency policy for the cron command
|
||||
ConcurrencyPolicy string `json:"concurrency_policy"`
|
||||
|
||||
// AltCommand is an alternate command to run
|
||||
AltCommand string `json:"-"`
|
||||
|
||||
// LogFile is the log file to write to
|
||||
LogFile string `json:"-"`
|
||||
|
||||
// Maintenance is whether the cron command is in maintenance mode
|
||||
// AppInMaintenance is whether the app's cron is in maintenance mode
|
||||
AppInMaintenance bool `json:"app-in-maintenance"`
|
||||
|
||||
// Maintenance is whether the cron task is in maintenance mode
|
||||
TaskInMaintenance bool `json:"task-in-maintenance"`
|
||||
|
||||
// Maintenance is whether the cron task is in maintenance mode
|
||||
Maintenance bool `json:"maintenance"`
|
||||
}
|
||||
|
||||
// CronCommand returns the command to run for a given cron command
|
||||
func (t TemplateCommand) CronCommand() string {
|
||||
// DokkuRunCommand returns the dokku run command to execute for a given cron task
|
||||
func (t CronTask) DokkuRunCommand() string {
|
||||
if t.AltCommand != "" {
|
||||
if t.LogFile != "" {
|
||||
return fmt.Sprintf("%s &>> %s", t.AltCommand, t.LogFile)
|
||||
@@ -63,48 +75,57 @@ func (t TemplateCommand) CronCommand() string {
|
||||
return t.AltCommand
|
||||
}
|
||||
|
||||
return fmt.Sprintf("dokku run --cron-id %s %s %s", t.ID, t.App, t.Command)
|
||||
return fmt.Sprintf("dokku run --concurrency-policy %s --cron-id %s %s %s", t.ConcurrencyPolicy, t.ID, t.App, t.Command)
|
||||
}
|
||||
|
||||
// FetchCronEntriesInput is the input for the FetchCronEntries function
|
||||
type FetchCronEntriesInput struct {
|
||||
// FetchCronTasksInput is the input for the FetchCronTasks function
|
||||
type FetchCronTasksInput struct {
|
||||
AppName string
|
||||
AppJSON *appjson.AppJSON
|
||||
WarnToFailure bool
|
||||
}
|
||||
|
||||
// FetchCronEntries returns a list of cron commands for a given app
|
||||
func FetchCronEntries(input FetchCronEntriesInput) ([]TemplateCommand, error) {
|
||||
// FetchCronTasks returns a list of cron tasks for a given app
|
||||
func FetchCronTasks(input FetchCronTasksInput) ([]CronTask, error) {
|
||||
appName := input.AppName
|
||||
commands := []TemplateCommand{}
|
||||
isMaintenance := reportComputedMaintenance(appName) == "true"
|
||||
tasks := []CronTask{}
|
||||
isAppCronInMaintenance := reportComputedMaintenance(appName) == "true"
|
||||
|
||||
if input.AppJSON == nil && input.AppName == "" {
|
||||
return tasks, fmt.Errorf("Missing app name or app.json")
|
||||
}
|
||||
|
||||
if input.AppJSON == nil {
|
||||
appJSON, err := appjson.GetAppJSON(appName)
|
||||
if err != nil {
|
||||
return commands, fmt.Errorf("Unable to fetch app.json for app %s: %s", appName, err.Error())
|
||||
return tasks, fmt.Errorf("Unable to fetch app.json for app %s: %s", appName, err.Error())
|
||||
}
|
||||
|
||||
input.AppJSON = &appJSON
|
||||
}
|
||||
|
||||
if input.AppJSON.Cron == nil {
|
||||
return commands, nil
|
||||
return tasks, nil
|
||||
}
|
||||
|
||||
properties, err := common.PropertyGetAllByPrefix("cron", appName, MaintenancePropertyPrefix)
|
||||
if err != nil {
|
||||
return tasks, fmt.Errorf("Error getting maintenance properties: %w", err)
|
||||
}
|
||||
|
||||
for i, c := range input.AppJSON.Cron {
|
||||
if c.Command == "" {
|
||||
if input.WarnToFailure {
|
||||
return commands, fmt.Errorf("Missing cron command for app %s (index %d)", appName, i)
|
||||
return tasks, fmt.Errorf("Missing cron task command for app %s (index %d)", appName, i)
|
||||
}
|
||||
|
||||
common.LogWarn(fmt.Sprintf("Missing cron command for app %s (index %d)", appName, i))
|
||||
common.LogWarn(fmt.Sprintf("Missing cron task command for app %s (index %d)", appName, i))
|
||||
continue
|
||||
}
|
||||
|
||||
if c.Schedule == "" {
|
||||
if input.WarnToFailure {
|
||||
return commands, fmt.Errorf("Missing cron schedule for app %s (index %d)", appName, i)
|
||||
return tasks, fmt.Errorf("Missing cron schedule for app %s (index %d)", appName, i)
|
||||
}
|
||||
|
||||
common.LogWarn(fmt.Sprintf("Missing cron schedule for app %s (index %d)", appName, i))
|
||||
@@ -114,26 +135,49 @@ func FetchCronEntries(input FetchCronEntriesInput) ([]TemplateCommand, error) {
|
||||
parser := cronparser.NewParser(cronparser.Minute | cronparser.Hour | cronparser.Dom | cronparser.Month | cronparser.Dow | cronparser.Descriptor)
|
||||
_, err := parser.Parse(c.Schedule)
|
||||
if err != nil {
|
||||
return commands, fmt.Errorf("Invalid cron schedule for app %s (schedule %s): %s", appName, c.Schedule, err.Error())
|
||||
return tasks, fmt.Errorf("Invalid cron schedule for app %s (schedule %s): %s", appName, c.Schedule, err.Error())
|
||||
}
|
||||
|
||||
commands = append(commands, TemplateCommand{
|
||||
App: appName,
|
||||
Command: c.Command,
|
||||
Schedule: c.Schedule,
|
||||
ID: GenerateCommandID(appName, c),
|
||||
Maintenance: isMaintenance,
|
||||
cronID := GenerateCommandID(appName, c)
|
||||
maintenance := c.Maintenance
|
||||
if value, ok := properties[MaintenancePropertyPrefix+cronID]; ok {
|
||||
boolValue, err := strconv.ParseBool(value)
|
||||
if err != nil {
|
||||
return tasks, fmt.Errorf("Invalid maintenance property for app %s (schedule %s): %s", appName, c.Schedule, err.Error())
|
||||
}
|
||||
|
||||
// only override the maintenance value if the property is set to true
|
||||
if boolValue {
|
||||
maintenance = boolValue
|
||||
}
|
||||
}
|
||||
if c.ConcurrencyPolicy == "" {
|
||||
c.ConcurrencyPolicy = "allow"
|
||||
}
|
||||
if c.ConcurrencyPolicy != "allow" && c.ConcurrencyPolicy != "forbid" && c.ConcurrencyPolicy != "replace" {
|
||||
return tasks, fmt.Errorf("Invalid cron concurrency policy for app %s (schedule %s): %s", appName, c.Schedule, c.ConcurrencyPolicy)
|
||||
}
|
||||
|
||||
tasks = append(tasks, CronTask{
|
||||
App: appName,
|
||||
Command: c.Command,
|
||||
Schedule: c.Schedule,
|
||||
ID: cronID,
|
||||
ConcurrencyPolicy: c.ConcurrencyPolicy,
|
||||
Maintenance: isAppCronInMaintenance || maintenance,
|
||||
AppInMaintenance: isAppCronInMaintenance,
|
||||
TaskInMaintenance: maintenance,
|
||||
})
|
||||
}
|
||||
|
||||
return commands, nil
|
||||
return tasks, nil
|
||||
}
|
||||
|
||||
// FetchGlobalCronEntries returns a list of global cron commands
|
||||
// FetchGlobalCronTasks returns a list of global cron tasks
|
||||
// This function should only be used for the cron:list --global command
|
||||
// and not internally by the cron plugin
|
||||
func FetchGlobalCronEntries() ([]TemplateCommand, error) {
|
||||
commands := []TemplateCommand{}
|
||||
func FetchGlobalCronTasks() ([]CronTask, error) {
|
||||
tasks := []CronTask{}
|
||||
response, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
|
||||
Trigger: "cron-entries",
|
||||
Args: []string{"docker-local"},
|
||||
@@ -150,23 +194,25 @@ func FetchGlobalCronEntries() ([]TemplateCommand, error) {
|
||||
}
|
||||
|
||||
id := base36.EncodeToStringLc([]byte(strings.Join(parts, ";;;")))
|
||||
command := TemplateCommand{
|
||||
ID: id,
|
||||
Schedule: parts[0],
|
||||
Command: parts[1],
|
||||
AltCommand: parts[1],
|
||||
Maintenance: false,
|
||||
Global: true,
|
||||
task := CronTask{
|
||||
ID: id,
|
||||
Schedule: parts[0],
|
||||
Command: parts[1],
|
||||
AltCommand: parts[1],
|
||||
Global: true,
|
||||
Maintenance: false,
|
||||
TaskInMaintenance: false,
|
||||
AppInMaintenance: false,
|
||||
}
|
||||
if len(parts) == 3 {
|
||||
command.LogFile = parts[2]
|
||||
task.LogFile = parts[2]
|
||||
}
|
||||
commands = append(commands, command)
|
||||
tasks = append(tasks, task)
|
||||
}
|
||||
return commands, nil
|
||||
return tasks, nil
|
||||
}
|
||||
|
||||
// GenerateCommandID creates a unique ID for a given app/command/schedule combination
|
||||
func GenerateCommandID(appName string, c appjson.CronCommand) string {
|
||||
func GenerateCommandID(appName string, c appjson.CronTask) string {
|
||||
return base36.EncodeToStringLc([]byte(appName + "===" + c.Command + "===" + c.Schedule))
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user