Merge branch 'master' into cn
Some checks failed
dependency-updates / prepare (push) Has been cancelled
dependency-updates / update / ${{ matrix.name }} (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled

* master: (546 commits)
  chore(deps): bump gunicorn in /tests/apps/dockerfile-release
  chore(deps): bump github.com/traefik/traefik/v2
  chore(deps): bump gunicorn from 26.0.0 to 26.1.0 in /tests/apps/multi
  chore(deps): bump gunicorn in /tests/apps/python-flask
  chore(deps): bump pygments from 2.20.0 to 2.21.0 in /docs/_build
  chore: bump herokuish to 0.11.16
  chore: bump go modules
  chore(deps): bump golang.org/x/crypto in /plugins/common
  chore(deps): bump sqlparse in /tests/apps/dockerfile-release
  chore(deps): bump helm.sh/helm/v3 in /plugins/scheduler-k3s
  chore(deps): bump golang in /tests/apps/zombies-dockerfile-no-tini
  chore(deps): bump golang in /tests/apps/go-fail-postdeploy
  chore(deps): bump golang in /tests/apps/go-fail-predeploy
  chore(deps): bump golang from 1.26.5 to 1.26.6 in /tests/apps/gogrpc
  chore(deps): bump golang in /tests/apps/zombies-dockerfile-tini
  chore(deps): bump google.golang.org/protobuf in /tests/apps/gogrpc
  fix: retire cron containers past their active deadline
  Release 0.38.27
  fix: report traefik dns-provider env vars as global keys
  fix: do not require a local image for k3s deploys
  ...

# Conflicts:
#	common.mk
#	contrib/dependencies.json
This commit is contained in:
apple
2026-08-22 17:40:33 +08:00
810 changed files with 54461 additions and 7873 deletions

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core standard plugin"
version = "0.37.9"
version = "0.38.27"
[plugin.config]

View File

@@ -28,7 +28,7 @@ cmd-report() {
dokku_log_info1 "herokuish version: "
if [[ "$ARCHITECTURE" == "arm64" ]]; then
dokku_log_warn "herokuish not supported on $ARCHITECTURE architecture"
elif verify_image "$DOKKU_IMAGE"; then
elif fn-verify-app-image "" "$DOKKU_IMAGE"; then
"$DOCKER_BIN" container run $DOKKU_GLOBAL_RUN_ARGS --rm "$DOKKU_IMAGE" herokuish version | sed "s/^/ /"
else
dokku_log_warn "Herokuish image $DOKKU_IMAGE is not available"

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core events logging plugin"
version = "0.37.9"
version = "0.38.27"
[plugin.config]

View File

@@ -24,11 +24,56 @@ var (
}
)
// EnvVarValue represents an environment variable definition in app.json
// It supports both simple string values and complex object definitions
type EnvVarValue struct {
// Description provides context for the env var (used in prompts)
Description string `json:"description,omitempty"`
// Value is the default value for the env var
Value string `json:"value,omitempty"`
// Required indicates if the env var must have a value (defaults to true per Heroku spec)
Required *bool `json:"required,omitempty"`
// Generator specifies how to auto-generate a value (currently only "secret" is supported)
Generator string `json:"generator,omitempty"`
// Sync indicates if the value should be set on every deploy, not just first
Sync bool `json:"sync,omitempty"`
}
// UnmarshalJSON handles both string and object formats for env vars
func (e *EnvVarValue) UnmarshalJSON(data []byte) error {
var str string
if err := json.Unmarshal(data, &str); err == nil {
e.Value = str
return nil
}
type envVarAlias EnvVarValue
return json.Unmarshal(data, (*envVarAlias)(e))
}
// IsRequired returns true if the env var is required (defaults to true per Heroku spec)
func (e *EnvVarValue) IsRequired() bool {
if e.Required == nil {
return true
}
return *e.Required
}
// AppJSON is a struct that represents an app.json file as understood by Dokku
type AppJSON struct {
// Buildpacks is a list of buildpacks to use for the app
Buildpacks []Buildpack `json:"buildpacks"`
// Cron is a list of cron tasks to execute
Cron []CronTask `json:"cron"`
// Env is a map of environment variables to set
Env map[string]EnvVarValue `json:"env,omitempty"`
// Formation is a map of process types to scale
Formation map[string]Formation `json:"formation"`
@@ -51,6 +96,12 @@ type AppJSON struct {
} `json:"scripts"`
}
// Buildpack is a struct that represents a single buildpack
type Buildpack struct {
// URL is the URL of the buildpack
URL string `json:"url"`
}
// CronTask is a struct that represents a single cron task from an app.json file
type CronTask struct {
// Command is the command to execute

View File

@@ -1,16 +1,21 @@
package appjson
import (
"bufio"
"crypto/rand"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
"sort"
"strconv"
"strings"
"github.com/dokku/dokku/plugins/common"
shellquote "github.com/kballard/go-shellquote"
"github.com/mattn/go-isatty"
)
func constructScript(command string, shell string, isHerokuishImage bool, isCnbImage bool, dockerfileEntrypoint string) []string {
@@ -455,3 +460,199 @@ func setScale(appName string) error {
})
return err
}
// generateSecret generates a cryptographically secure random hex string of specified length
func generateSecret(length int) (string, error) {
bytes := make([]byte, length/2)
if _, err := rand.Read(bytes); err != nil {
return "", fmt.Errorf("failed to generate secret: %w", err)
}
return hex.EncodeToString(bytes), nil
}
// isInteractive returns true if stdin is a terminal (TTY available)
func isInteractive() bool {
return isatty.IsTerminal(os.Stdin.Fd()) || isatty.IsCygwinTerminal(os.Stdin.Fd())
}
// promptForValue prompts the user for an environment variable value
func promptForValue(varName string, envVar EnvVarValue) (string, error) {
prompt := fmt.Sprintf("Enter value for %s", varName)
if envVar.Description != "" {
prompt = fmt.Sprintf("Enter value for %s (%s)", varName, envVar.Description)
}
common.LogInfo1(prompt)
fmt.Print("> ")
reader := bufio.NewReader(os.Stdin)
response, err := reader.ReadString('\n')
if err != nil {
return "", err
}
return strings.TrimSpace(response), nil
}
// getCurrentConfig retrieves the current config values for an app
func getCurrentConfig(appName string) (map[string]string, error) {
results, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-export",
Args: []string{appName, "false", "true", "json"},
})
if err != nil {
return nil, fmt.Errorf("failed to get current config: %w", err)
}
var currentConfig map[string]string
if err := json.Unmarshal(results.StdoutBytes(), &currentConfig); err != nil {
return nil, fmt.Errorf("failed to parse current config: %w", err)
}
return currentConfig, nil
}
// setConfigVars sets multiple config vars for an app without triggering restart
func setConfigVars(appName string, vars map[string]string) error {
if len(vars) == 0 {
return nil
}
// Build arguments for config-set trigger: --no-restart flag, appName, key=value pairs
args := []string{"--no-restart", appName}
for key, value := range vars {
args = append(args, fmt.Sprintf("%s=%s", key, value))
}
_, err := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-set",
Args: args,
StreamStdio: true,
})
if err != nil {
return fmt.Errorf("failed to set config vars: %w", err)
}
return nil
}
// processAppJSONEnv processes env vars from app.json and sets them as config
func processAppJSONEnv(appName string) error {
appJSON, err := GetAppJSON(appName)
if err != nil {
return err
}
if len(appJSON.Env) == 0 {
return nil
}
common.LogInfo1("Processing app.json env vars")
isFirstDeploy := common.PropertyGet("common", appName, "deployed") != "true"
// Check if env vars have been processed for this deploy
envProcessedProperty := "appjson-env-processed"
alreadyProcessed := common.PropertyGet("app-json", appName, envProcessedProperty) == "executed"
// Get current config values
currentConfig, err := getCurrentConfig(appName)
if err != nil {
return err
}
varsToSet := make(map[string]string)
interactive := isInteractive()
// Sort keys for deterministic ordering
var keys []string
for k := range appJSON.Env {
keys = append(keys, k)
}
sort.Strings(keys)
for _, varName := range keys {
envVar := appJSON.Env[varName]
// Determine if we should process this var
shouldProcess := false
if isFirstDeploy && !alreadyProcessed {
// First deploy: process all vars
shouldProcess = true
} else if envVar.Sync {
// Subsequent deploy with sync: always process sync vars
shouldProcess = true
}
if !shouldProcess {
continue
}
// Check if already set (for first deploy, skip if already has value and not sync)
currentValue, hasValue := currentConfig[varName]
if hasValue && currentValue != "" && !envVar.Sync {
common.LogDebug(fmt.Sprintf("Skipping %s: already set", varName))
continue
}
// Determine the value
var value string
// Handle generator
if envVar.Generator == "secret" {
if !hasValue || currentValue == "" || envVar.Sync {
generated, err := generateSecret(64)
if err != nil {
return fmt.Errorf("failed to generate secret for %s: %w", varName, err)
}
value = generated
common.LogDebug(fmt.Sprintf("Generated secret for %s", varName))
} else {
continue // Already has value, not sync
}
} else if envVar.Value != "" {
// Use default value
value = envVar.Value
} else if interactive {
// Prompt user
prompted, err := promptForValue(varName, envVar)
if err != nil {
if envVar.IsRequired() {
return fmt.Errorf("required env var %s has no value and prompt failed: %w", varName, err)
}
continue
}
if prompted == "" && envVar.IsRequired() {
return fmt.Errorf("required env var %s cannot be empty", varName)
}
value = prompted
} else {
// No TTY, no default, no generator
if envVar.IsRequired() {
return fmt.Errorf("required env var %s has no value, no default, and no TTY for prompt", varName)
}
continue
}
if value != "" {
varsToSet[varName] = value
}
}
if len(varsToSet) == 0 {
common.LogVerbose("No env vars to set from app.json")
if !isFirstDeploy {
return common.PropertyWrite("app-json", appName, envProcessedProperty, "executed")
}
return nil
}
// Set the config vars without restart (we're in middle of deploy)
common.LogInfo1(fmt.Sprintf("Setting %d env var(s) from app.json", len(varsToSet)))
if err := setConfigVars(appName, varsToSet); err != nil {
return fmt.Errorf("failed to set env vars: %w", err)
}
// Mark as processed
return common.PropertyWrite("app-json", appName, envProcessedProperty, "executed")
}

View File

@@ -1,10 +1,11 @@
module github.com/dokku/dokku/plugins/app-json
go 1.25.5
go 1.26.2
require (
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/mattn/go-isatty v0.0.24
github.com/spf13/pflag v1.0.10
github.com/tailscale/hujson v0.0.0-20250605163823-992244df8c5a
k8s.io/utils v0.0.0-20240102154912-e7106e64919e
@@ -17,16 +18,15 @@ require (
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/melbahja/goph v1.5.0 // indirect
github.com/melbahja/goph v1.5.2 // indirect
github.com/otiai10/copy v1.14.1 // indirect
github.com/otiai10/mint v1.6.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/sftp v1.13.10 // indirect
github.com/pkg/sftp v1.13.11 // indirect
github.com/ryanuber/columnize v2.1.2+incompatible // indirect
golang.org/x/crypto v0.50.0 // indirect
golang.org/x/sync v0.20.0 // indirect
golang.org/x/sys v0.43.0 // indirect
golang.org/x/crypto v0.55.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.47.0 // indirect
)
replace github.com/dokku/dokku/plugins/common => ../common

View File

@@ -16,45 +16,44 @@ github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/melbahja/goph v1.5.0 h1:RQUBpLvfg3i7fjfG8rTcSWyMjVRfdhwrrfQhjYee4dQ=
github.com/melbahja/goph v1.5.0/go.mod h1:dDwo+44cmvfDLdiVpc6fJxexf5BA5yEDUeE5YgtuDO4=
github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28=
github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg=
github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI=
github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A=
github.com/melbahja/goph v1.5.2 h1:2eoR45SLF3LyM6tnIhnpjakvXTjtQMJqOK/mp1PYojM=
github.com/melbahja/goph v1.5.2/go.mod h1:T+5uoB1PDP6EeK2qXerf5gRh7b6IF8u37GK2ckEi9FU=
github.com/onsi/gomega v1.42.1 h1:iN1rCUX+44NZ1Dc97MPoeFYbFR0vh8zxoxMFwKdyZ6I=
github.com/onsi/gomega v1.42.1/go.mod h1:REff/hsDsodHoKlWsP2mAPhu1+5/6hVYNf9rIEBpeSg=
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=
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.10 h1:+5FbKNTe5Z9aspU88DPIKJ9z2KZoaGCu6Sr6kKR/5mU=
github.com/pkg/sftp v1.13.10/go.mod h1:bJ1a7uDhrX/4OII+agvy28lzRvQrmIQuaHrcI1HbeGA=
github.com/pkg/sftp v1.13.11 h1:0N92SLTB8JqASJB14ZLHHzFnBV8mG9zw4K7jghEFWuE=
github.com/pkg/sftp v1.13.11/go.mod h1:uNkH9roSXglNJqM+glJJi+TQXQUm0fXFWqCFmT8hsN0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/ryanuber/columnize v2.1.2+incompatible h1:C89EOx/XBWwIXl8wm8OPJBd7kPF25UfsK2X7Ph/zCAk=
github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
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=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ=

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core app-json plugin"
version = "0.37.9"
version = "0.38.27"
[plugin.config]

View File

@@ -6,14 +6,24 @@ import (
// ReportSingleApp is an internal function that displays the builder report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
flags := map[string]common.ReportFunc{
"--app-json-computed-selected": reportComputedAppjsonpath,
"--app-json-global-selected": reportGlobalAppjsonpath,
"--app-json-selected": reportAppjsonpath,
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--app-json-computed-appjson-path": reportComputedAppjsonpath,
"--app-json-global-appjson-path": reportGlobalAppjsonpath,
}
} else {
flags = map[string]common.ReportFunc{
"--app-json-computed-appjson-path": reportComputedAppjsonpath,
"--app-json-global-appjson-path": reportGlobalAppjsonpath,
"--app-json-appjson-path": reportAppjsonpath,
}
}
flagKeys := []string{}
@@ -21,10 +31,18 @@ func ReportSingleApp(appName string, format string, infoFlag string) error {
flagKeys = append(flagKeys, flagKey)
}
trimPrefix := false
uppercaseFirstCharacter := true
infoFlags := common.CollectReport(appName, infoFlag, flags)
return common.ReportSingleApp("app-json", appName, infoFlag, infoFlags, flagKeys, format, trimPrefix, uppercaseFirstCharacter)
return common.ReportSingleApp(common.ReportSingleAppInput{
ReportType: "app-json",
AppName: appName,
InfoFlag: infoFlag,
InfoFlags: infoFlags,
InfoFlagKeys: flagKeys,
Format: format,
TrimPrefix: true,
UppercaseFirstCharacter: true,
EmitLegacyPrefix: true,
})
}
func reportComputedAppjsonpath(appName string) string {
@@ -32,12 +50,15 @@ func reportComputedAppjsonpath(appName string) string {
if value == "" {
value = reportGlobalAppjsonpath(appName)
}
if value == "" {
value = "app.json"
}
return value
}
func reportGlobalAppjsonpath(appName string) string {
return common.PropertyGetDefault("app-json", "--global", "appjson-path", "app.json")
return common.PropertyGet("app-json", "--global", "appjson-path")
}
func reportAppjsonpath(appName string) string {

View File

@@ -21,11 +21,14 @@ func main() {
case "report":
args := flag.NewFlagSet("app-json:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("appjson", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("appjson", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = appjson.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = appjson.CommandReport(appName, *format, reportArgs.InfoFlag)
}
case "set":
args := flag.NewFlagSet("app-json:set", flag.ExitOnError)

View File

@@ -71,6 +71,11 @@ func TriggerCorePostDeploy(appName string) error {
// TriggerCorePostExtract ensures that the main app.json is the one specified by app-json-path
func TriggerCorePostExtract(appName string, sourceWorkDir string) error {
// Clear the env-processed property on new source extraction to allow re-processing
if err := common.PropertyDelete("app-json", appName, "appjson-env-processed"); err != nil {
return err
}
destination := common.GetAppDataDirectory("app-json", appName)
appJSONPath := strings.Trim(reportComputedAppjsonpath(appName), "/")
if appJSONPath == "" {
@@ -181,7 +186,20 @@ func TriggerPostDelete(appName string) error {
}
// TriggerPostDeploy is a trigger to execute the postdeploy deployment task
//
// The task is looked up before the image name is resolved because resolving it
// asserts the image exists on the local docker daemon. That assertion does not
// hold for schedulers running workloads off this host, which are free to reap
// the local copy while the app keeps running in a cluster. An app with no
// postdeploy task needs no image at all, so it should not be made to fail here.
func TriggerPostDeploy(appName string, imageTag string) error {
command, err := getPhaseScript(appName, "postdeploy")
if err == nil && command == "" {
common.LogInfo1("Checking for postdeploy task")
common.LogVerbose("No postdeploy task found, skipping")
return nil
}
image, err := common.GetDeployingAppImageName(appName, imageTag, "")
if err != nil {
return err
@@ -190,7 +208,13 @@ func TriggerPostDeploy(appName string, imageTag string) error {
return executeScript(appName, image, imageTag, "postdeploy")
}
// TriggerPreReleaseBuilder processes app.json env vars and executes the predeploy task
func TriggerPreReleaseBuilder(builderType string, appName string, image string) error {
// Process app.json env vars before predeploy script
if err := processAppJSONEnv(appName); err != nil {
return err
}
parts := strings.Split(image, ":")
imageTag := parts[len(parts)-1]
return executeScript(appName, image, imageTag, "predeploy")

View File

@@ -1,4 +1,4 @@
SUBCOMMANDS = subcommands/clone subcommands/create subcommands/destroy subcommands/exists subcommands/list subcommands/lock subcommands/locked subcommands/rename subcommands/report subcommands/unlock
SUBCOMMANDS = subcommands/clone subcommands/create subcommands/destroy subcommands/exists subcommands/list subcommands/lock subcommands/locked subcommands/rename subcommands/report subcommands/set subcommands/unlock
TRIGGERS = triggers/app-create triggers/app-destroy triggers/app-exists triggers/app-maybe-create triggers/deploy-source-set triggers/install triggers/post-app-clone-setup triggers/post-app-rename triggers/post-app-rename-setup triggers/post-create triggers/post-delete triggers/report
BUILD = commands subcommands triggers
PLUGIN_NAME = apps

View File

@@ -5,11 +5,11 @@ var (
DefaultProperties = map[string]string{
"deploy-source": "",
"deploy-source-metadata": "",
"disable-autocreation": "",
}
// GlobalProperties is a map of all valid global apps properties
GlobalProperties = map[string]bool{
"deploy-source": true,
"deploy-source-metadata": true,
"disable-autocreation": true,
}
)

View File

@@ -132,11 +132,7 @@ func maybeCreateApp(appName string) error {
return nil
}
results, _ := common.CallPlugnTrigger(common.PlugnTriggerInput{
Trigger: "config-get-global",
Args: []string{"DOKKU_DISABLE_APP_AUTOCREATION"},
})
disableAutocreate := results.StdoutContents()
disableAutocreate := common.PropertyGetDefault("apps", "--global", "disable-autocreation", "")
if disableAutocreate == "true" {
common.LogWarn("App auto-creation disabled.")
return fmt.Errorf("Re-enable app auto-creation or create an app with 'dokku apps:create %s'", appName)

View File

@@ -1,6 +1,6 @@
module github.com/dokku/dokku/plugins/apps
go 1.25.5
go 1.26.2
require (
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
@@ -15,15 +15,15 @@ require (
github.com/kr/fs v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/melbahja/goph v1.5.0 // indirect
github.com/melbahja/goph v1.5.2 // indirect
github.com/otiai10/copy v1.14.1 // indirect
github.com/otiai10/mint v1.6.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/sftp v1.13.10 // indirect
github.com/pkg/sftp v1.13.11 // indirect
github.com/ryanuber/columnize v2.1.2+incompatible // indirect
golang.org/x/crypto v0.50.0 // indirect
golang.org/x/sync v0.20.0 // indirect
golang.org/x/sys v0.43.0 // indirect
golang.org/x/crypto v0.55.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.47.0 // indirect
)
replace github.com/dokku/dokku/plugins/common => ../common

View File

@@ -16,40 +16,40 @@ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHP
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/melbahja/goph v1.5.0 h1:RQUBpLvfg3i7fjfG8rTcSWyMjVRfdhwrrfQhjYee4dQ=
github.com/melbahja/goph v1.5.0/go.mod h1:dDwo+44cmvfDLdiVpc6fJxexf5BA5yEDUeE5YgtuDO4=
github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28=
github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg=
github.com/melbahja/goph v1.5.2 h1:2eoR45SLF3LyM6tnIhnpjakvXTjtQMJqOK/mp1PYojM=
github.com/melbahja/goph v1.5.2/go.mod h1:T+5uoB1PDP6EeK2qXerf5gRh7b6IF8u37GK2ckEi9FU=
github.com/onsi/gomega v1.42.1 h1:iN1rCUX+44NZ1Dc97MPoeFYbFR0vh8zxoxMFwKdyZ6I=
github.com/onsi/gomega v1.42.1/go.mod h1:REff/hsDsodHoKlWsP2mAPhu1+5/6hVYNf9rIEBpeSg=
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=
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.10 h1:+5FbKNTe5Z9aspU88DPIKJ9z2KZoaGCu6Sr6kKR/5mU=
github.com/pkg/sftp v1.13.10/go.mod h1:bJ1a7uDhrX/4OII+agvy28lzRvQrmIQuaHrcI1HbeGA=
github.com/pkg/sftp v1.13.11 h1:0N92SLTB8JqASJB14ZLHHzFnBV8mG9zw4K7jghEFWuE=
github.com/pkg/sftp v1.13.11/go.mod h1:uNkH9roSXglNJqM+glJJi+TQXQUm0fXFWqCFmT8hsN0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/ryanuber/columnize v2.1.2+incompatible h1:C89EOx/XBWwIXl8wm8OPJBd7kPF25UfsK2X7Ph/zCAk=
github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core apps plugin"
version = "0.37.9"
version = "0.38.27"
[plugin.config]

View File

@@ -9,16 +9,26 @@ import (
// ReportSingleApp is an internal function that displays the app report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if err := common.VerifyAppName(appName); err != nil {
return err
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
flags := map[string]common.ReportFunc{
"--app-created-at": reportCreatedAt,
"--app-deploy-source": reportDeploySource,
"--app-deploy-source-metadata": reportDeploySourceMetadata,
"--app-dir": reportDir,
"--app-locked": reportLocked,
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--app-global-disable-autocreation": reportGlobalDisableAutocreation,
}
} else {
flags = map[string]common.ReportFunc{
"--app-created-at": reportCreatedAt,
"--app-deploy-source": reportDeploySource,
"--app-deploy-source-metadata": reportDeploySourceMetadata,
"--app-dir": reportDir,
"--app-global-disable-autocreation": reportGlobalDisableAutocreation,
"--app-locked": reportLocked,
}
}
flagKeys := []string{}
@@ -26,10 +36,18 @@ func ReportSingleApp(appName string, format string, infoFlag string) error {
flagKeys = append(flagKeys, flagKey)
}
trimPrefix := false
uppercaseFirstCharacter := true
infoFlags := common.CollectReport(appName, infoFlag, flags)
return common.ReportSingleApp("app", appName, infoFlag, infoFlags, flagKeys, format, trimPrefix, uppercaseFirstCharacter)
return common.ReportSingleApp(common.ReportSingleAppInput{
ReportType: "app",
AppName: appName,
InfoFlag: infoFlag,
InfoFlags: infoFlags,
InfoFlagKeys: flagKeys,
Format: format,
TrimPrefix: true,
UppercaseFirstCharacter: true,
EmitLegacyPrefix: true,
})
}
func reportCreatedAt(appName string) string {
@@ -52,6 +70,10 @@ func reportDir(appName string) string {
return common.AppRoot(appName)
}
func reportGlobalDisableAutocreation(appName string) string {
return common.PropertyGet("apps", "--global", "disable-autocreation")
}
func reportLocked(appName string) string {
locked := "false"
if appIsLocked(appName) {

View File

@@ -23,11 +23,12 @@ Additional commands:`
apps:create <app>, Create a new app
apps:destroy <app>, Permanently destroy an app
apps:exists <app>, Checks if an app exists
apps:list, List your apps
apps:list [--format stdout|json], List your apps
apps:lock <app>, Locks an app for deployment
apps:locked <app>, Checks if an app is locked for deployment
apps:rename <old-app> <new-app>, Rename an app
apps:report [<app>] [<flag>], Display report about an app
apps:set <app>|--global <key> <value>, Set or clear an apps property
apps:unlock <app>, Unlocks an app for deployment`
)
@@ -42,7 +43,7 @@ func main() {
args.Usage = usage
args.Parse(os.Args[2:])
if err := apps.CommandList(); err != nil {
if err := apps.CommandList("stdout"); err != nil {
common.LogFailWithError(err)
}
case "apps:help":

View File

@@ -44,8 +44,9 @@ func main() {
err = apps.CommandExists(appName)
case "list":
args := flag.NewFlagSet("apps:list", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
args.Parse(os.Args[2:])
err = apps.CommandList()
err = apps.CommandList(*format)
case "lock":
args := flag.NewFlagSet("apps:lock", flag.ExitOnError)
args.Parse(os.Args[2:])
@@ -66,12 +67,28 @@ func main() {
case "report":
args := flag.NewFlagSet("apps:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
osArgs, infoFlag, flagErr := common.ParseReportArgs("apps", os.Args[2:])
reportArgs, flagErr := common.ParseReportArgs("apps", os.Args[2:])
if flagErr == nil {
args.Parse(osArgs)
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
err = apps.CommandReport(appName, *format, infoFlag)
if reportArgs.IsGlobal {
appName = "--global"
}
err = apps.CommandReport(appName, *format, reportArgs.InfoFlag)
}
case "set":
args := flag.NewFlagSet("apps:set", flag.ExitOnError)
global := args.Bool("global", false, "--global: set a global property")
args.Parse(os.Args[2:])
appName := args.Arg(0)
property := args.Arg(1)
value := args.Arg(2)
if *global {
appName = "--global"
property = args.Arg(0)
value = args.Arg(1)
}
err = apps.CommandSet(appName, property, value)
case "unlock":
args := flag.NewFlagSet("apps:unlock", flag.ExitOnError)
args.Parse(os.Args[2:])

View File

@@ -1,6 +1,7 @@
package apps
import (
"encoding/json"
"errors"
"fmt"
"os"
@@ -98,9 +99,26 @@ func CommandExists(appName string) error {
}
// CommandList lists all apps
func CommandList() error {
common.LogInfo2Quiet("My Apps")
func CommandList(format string) error {
apps, err := common.DokkuApps()
if format == "json" {
if err != nil && !errors.Is(err, common.NoAppsExist) {
return err
}
appList := []string{}
appList = append(appList, apps...)
out, err := json.Marshal(appList)
if err != nil {
return err
}
common.Log(string(out))
return nil
}
common.LogInfo2Quiet("My Apps")
if err != nil {
common.LogWarn(err.Error())
return nil
@@ -226,6 +244,15 @@ func CommandReport(appName string, format string, infoFlag string) error {
return ReportSingleApp(appName, format, infoFlag)
}
// CommandSet set or clear an apps property for an app
func CommandSet(appName string, property string, value string) error {
if appName != "--global" && property == "disable-autocreation" {
common.LogFail("Property can only be specified globally")
}
common.CommandPropertySet("apps", appName, property, value, DefaultProperties, GlobalProperties)
return nil
}
// CommandUnlock unlocks an app for deployment
func CommandUnlock(appName string) error {
if err := common.VerifyAppName(appName); err != nil {

View File

@@ -53,6 +53,15 @@ func TriggerInstall() error {
return nil
}
if err := common.MigrateConfigToProperties("apps", []common.MigrateConfigEntry{
{
GlobalConfigVar: "DOKKU_DISABLE_APP_AUTOCREATION",
Property: "disable-autocreation",
},
}); err != nil {
return err
}
// migrate all created-at values from app mod-time to property
for _, appName := range apps {
if common.PropertyExists("apps", appName, "created-at") {

4
plugins/builder-dockerfile/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/report
/report-subcommand
/triggers
/subcommands/report

View File

@@ -0,0 +1,13 @@
GOARCH ?= amd64
TRIGGERS = triggers/report
BUILD = report-subcommand triggers
PLUGIN_NAME = builder-dockerfile
clean-report-subcommand:
rm -rf report-subcommand
report-subcommand: clean-report-subcommand src/subcommands/subcommands.go
GOARCH=$(GOARCH) go build -mod=readonly -ldflags="-s -w" $(GO_ARGS) -o report-subcommand src/subcommands/subcommands.go
ln -sf ../report-subcommand subcommands/report
include ../../common.mk

View File

@@ -33,11 +33,14 @@ trigger-builder-dockerfile-builder-build() {
plugn trigger pre-build "$BUILDER_TYPE" "$APP" "$SOURCECODE_WORK_DIR"
local DOCKER_ARGS=$(: | plugn trigger docker-args-build "$APP" "$BUILDER_TYPE")
DOCKER_ARGS+=$(: | plugn trigger docker-args-process-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 DOCKER_ARGS_ARRAY=()
while IFS= read -r -d '' arg; do
DOCKER_ARGS_ARRAY+=("$arg")
done < <(fn-docker-args-split "$DOCKER_ARGS")
set -- "${DOCKER_ARGS_ARRAY[@]}"
declare -a DOCKERFILE_ARGS
while true; do
@@ -141,6 +144,28 @@ trigger-builder-dockerfile-builder-build() {
DOCKERFILE_ARGS+=("--label" "${1#--label=}")
shift 1
;;
--memory | -m)
DOCKERFILE_ARGS+=("--memory")
DOCKERFILE_ARGS+=("$2")
shift 2
;;
--memory=* | -m=*)
if [[ "$1" == "--memory=*" ]]; then
DOCKERFILE_ARGS+=("--memory" "${1#--memory=}")
elif [[ "$1" == "-m=*" ]]; then
DOCKERFILE_ARGS+=("--memory" "${1#-m=}")
fi
shift 1
;;
--memory-swap)
DOCKERFILE_ARGS+=("--memory-swap")
DOCKERFILE_ARGS+=("$2")
shift 2
;;
--memory-swap=*)
DOCKERFILE_ARGS+=("--memory-swap" "${1#--memory-swap=}")
shift 1
;;
--network)
DOCKERFILE_ARGS+=("--network")
DOCKERFILE_ARGS+=("$2")
@@ -205,7 +230,7 @@ trigger-builder-dockerfile-builder-build() {
shift 1
;;
--ssh)
DOCKERFILE_ARGS+=("--platform")
DOCKERFILE_ARGS+=("--ssh")
DOCKERFILE_ARGS+=("$2")
shift 2
;;
@@ -213,6 +238,15 @@ trigger-builder-dockerfile-builder-build() {
DOCKERFILE_ARGS+=("--ssh" "${1#--ssh=}")
shift 1
;;
--tag)
DOCKERFILE_ARGS+=("--tag")
DOCKERFILE_ARGS+=("$2")
shift 2
;;
--tag=*)
DOCKERFILE_ARGS+=("--tag" "${1#--tag=}")
shift 1
;;
--target)
DOCKERFILE_ARGS+=("--target")
DOCKERFILE_ARGS+=("$2")
@@ -223,12 +257,12 @@ trigger-builder-dockerfile-builder-build() {
shift 1
;;
--ulimit)
DOCKERFILE_ARGS+=("--tag")
DOCKERFILE_ARGS+=("--ulimit")
DOCKERFILE_ARGS+=("$2")
shift 2
;;
--tag=*)
DOCKERFILE_ARGS+=("--tag" "${1#--tag=}")
--ulimit=*)
DOCKERFILE_ARGS+=("--ulimit" "${1#--ulimit=}")
shift 1
;;
--check | -D | --debug | --no-cache)

View File

@@ -10,7 +10,7 @@ trigger-builder-dockerfile-core-post-extract() {
declare APP="$1" SOURCECODE_WORK_DIR="$2"
local NEW_DOCKERFILE="$(fn-builder-dockerfile-computed-dockerfile-path "$APP")"
pushd "$TMP_WORK_DIR" >/dev/null
pushd "$SOURCECODE_WORK_DIR" >/dev/null
if [[ -z "$NEW_DOCKERFILE" ]]; then
return

View File

@@ -0,0 +1,29 @@
module github.com/dokku/dokku/plugins/builder-dockerfile
go 1.26.2
require (
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
github.com/spf13/pflag v1.0.10
)
require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/fatih/color v1.19.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/melbahja/goph v1.5.2 // indirect
github.com/otiai10/copy v1.14.1 // indirect
github.com/otiai10/mint v1.6.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/sftp v1.13.11 // indirect
github.com/ryanuber/columnize v2.1.2+incompatible // indirect
golang.org/x/crypto v0.55.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.47.0 // indirect
)
replace github.com/dokku/dokku/plugins/common => ../common

View File

@@ -0,0 +1,55 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/melbahja/goph v1.5.2 h1:2eoR45SLF3LyM6tnIhnpjakvXTjtQMJqOK/mp1PYojM=
github.com/melbahja/goph v1.5.2/go.mod h1:T+5uoB1PDP6EeK2qXerf5gRh7b6IF8u37GK2ckEi9FU=
github.com/onsi/gomega v1.42.1 h1:iN1rCUX+44NZ1Dc97MPoeFYbFR0vh8zxoxMFwKdyZ6I=
github.com/onsi/gomega v1.42.1/go.mod h1:REff/hsDsodHoKlWsP2mAPhu1+5/6hVYNf9rIEBpeSg=
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=
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.11 h1:0N92SLTB8JqASJB14ZLHHzFnBV8mG9zw4K7jghEFWuE=
github.com/pkg/sftp v1.13.11/go.mod h1:uNkH9roSXglNJqM+glJJi+TQXQUm0fXFWqCFmT8hsN0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/ryanuber/columnize v2.1.2+incompatible h1:C89EOx/XBWwIXl8wm8OPJBd7kPF25UfsK2X7Ph/zCAk=
github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -4,68 +4,6 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-builder-dockerfile-report() {
declare desc="displays a builder-dockerfile report for one or more apps"
declare cmd="builder-dockerfile: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-dockerfile-report-single "$app" "$INFO_FLAG" | tee || true
done
else
cmd-builder-dockerfile-report-single "$APP" "$INFO_FLAG"
fi
}
cmd-builder-dockerfile-report-single() {
declare APP="$1" INFO_FLAG="$2"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
local flag_map=(
"--builder-dockerfile-computed-dockerfile-path: $(fn-builder-dockerfile-computed-dockerfile-path "$APP")"
"--builder-dockerfile-global-dockerfile-path: $(fn-builder-dockerfile-global-dockerfile-path "$APP")"
"--builder-dockerfile-dockerfile-path: $(fn-builder-dockerfile-dockerfile-path "$APP")"
)
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} builder-dockerfile 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-dockerfile-computed-dockerfile-path() {
declare APP="$1"
@@ -73,6 +11,9 @@ fn-builder-dockerfile-computed-dockerfile-path() {
if [[ "$file" == "" ]]; then
file="$(fn-builder-dockerfile-global-dockerfile-path "$APP")"
fi
if [[ "$file" == "" ]]; then
file="Dockerfile"
fi
echo "$file"
}
@@ -80,7 +21,7 @@ fn-builder-dockerfile-computed-dockerfile-path() {
fn-builder-dockerfile-global-dockerfile-path() {
declare APP="$1"
fn-plugin-property-get-default "builder-dockerfile" "--global" "dockerfile-path" "Dockerfile"
fn-plugin-property-get-default "builder-dockerfile" "--global" "dockerfile-path" ""
}
fn-builder-dockerfile-dockerfile-path() {

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core builder-dockerfile plugin"
version = "0.37.9"
version = "0.38.27"
[plugin.config]

View File

@@ -1,6 +0,0 @@
#!/usr/bin/env bash
source "$PLUGIN_AVAILABLE_PATH/builder-dockerfile/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-builder-dockerfile-report-single "$@"

View File

@@ -0,0 +1,66 @@
package builderdockerfile
import (
"github.com/dokku/dokku/plugins/common"
)
// ReportSingleApp is an internal function that displays the builder-dockerfile report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--builder-dockerfile-computed-dockerfile-path": reportComputedDockerfilePath,
"--builder-dockerfile-global-dockerfile-path": reportGlobalDockerfilePath,
}
} else {
flags = map[string]common.ReportFunc{
"--builder-dockerfile-computed-dockerfile-path": reportComputedDockerfilePath,
"--builder-dockerfile-global-dockerfile-path": reportGlobalDockerfilePath,
"--builder-dockerfile-dockerfile-path": reportDockerfilePath,
}
}
flagKeys := []string{}
for flagKey := range flags {
flagKeys = append(flagKeys, flagKey)
}
infoFlags := common.CollectReport(appName, infoFlag, flags)
return common.ReportSingleApp(common.ReportSingleAppInput{
ReportType: "builder-dockerfile",
AppName: appName,
InfoFlag: infoFlag,
InfoFlags: infoFlags,
InfoFlagKeys: flagKeys,
Format: format,
TrimPrefix: true,
UppercaseFirstCharacter: true,
EmitLegacyPrefix: false,
})
}
func reportDockerfilePath(appName string) string {
return common.PropertyGet("builder-dockerfile", appName, "dockerfile-path")
}
func reportGlobalDockerfilePath(appName string) string {
return common.PropertyGet("builder-dockerfile", "--global", "dockerfile-path")
}
func reportComputedDockerfilePath(appName string) string {
value := reportDockerfilePath(appName)
if value == "" {
value = reportGlobalDockerfilePath(appName)
}
if value == "" {
value = "Dockerfile"
}
return value
}

View File

@@ -0,0 +1,40 @@
package main
import (
"fmt"
"os"
"strings"
builderdockerfile "github.com/dokku/dokku/plugins/builder-dockerfile"
"github.com/dokku/dokku/plugins/common"
flag "github.com/spf13/pflag"
)
// main entrypoint to all subcommands
func main() {
parts := strings.Split(os.Args[0], "/")
subcommand := parts[len(parts)-1]
var err error
switch subcommand {
case "report":
args := flag.NewFlagSet("builder-dockerfile:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
reportArgs, flagErr := common.ParseReportArgs("builder-dockerfile", os.Args[2:])
if flagErr == nil {
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
if reportArgs.IsGlobal {
appName = "--global"
}
err = builderdockerfile.CommandReport(appName, *format, reportArgs.InfoFlag)
}
default:
err = fmt.Errorf("Invalid plugin subcommand call: %s", subcommand)
}
if err != nil {
common.LogFailWithError(err)
}
}

View File

@@ -0,0 +1,31 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
builderdockerfile "github.com/dokku/dokku/plugins/builder-dockerfile"
"github.com/dokku/dokku/plugins/common"
)
// main entrypoint to all triggers
func main() {
parts := strings.Split(os.Args[0], "/")
trigger := parts[len(parts)-1]
flag.Parse()
var err error
switch trigger {
case "report":
appName := flag.Arg(0)
err = builderdockerfile.ReportSingleApp(appName, "", "")
default:
err = fmt.Errorf("Invalid plugin trigger call: %s", trigger)
}
if err != nil {
common.LogFailWithError(err)
}
}

View File

@@ -0,0 +1,29 @@
package builderdockerfile
import (
"errors"
"github.com/dokku/dokku/plugins/common"
)
// CommandReport displays a builder-dockerfile report for one or more apps
func CommandReport(appName string, format string, infoFlag string) error {
if len(appName) == 0 {
apps, err := common.DokkuApps()
if err != nil {
if errors.Is(err, common.NoAppsExist) {
common.LogWarn(err.Error())
return nil
}
return err
}
for _, appName := range apps {
if err := ReportSingleApp(appName, format, infoFlag); err != nil {
return err
}
}
return nil
}
return ReportSingleApp(appName, format, infoFlag)
}

View File

@@ -1,6 +0,0 @@
#!/usr/bin/env bash
source "$PLUGIN_AVAILABLE_PATH/builder-dockerfile/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-builder-dockerfile-report "$@"

4
plugins/builder-herokuish/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/report
/report-subcommand
/triggers
/subcommands/report

View File

@@ -0,0 +1,13 @@
GOARCH ?= amd64
TRIGGERS = triggers/report
BUILD = report-subcommand triggers
PLUGIN_NAME = builder-herokuish
clean-report-subcommand:
rm -rf report-subcommand
report-subcommand: clean-report-subcommand src/subcommands/subcommands.go
GOARCH=$(GOARCH) go build -mod=readonly -ldflags="-s -w" $(GO_ARGS) -o report-subcommand src/subcommands/subcommands.go
ln -sf ../report-subcommand subcommands/report
include ../../common.mk

View File

@@ -69,16 +69,18 @@ trigger-builder-herokuish-builder-build() {
DOCKER_ARGS+=" --env=TRACE=true "
DOCKER_ARGS+=" --env=BUILDPACK_XTRACE=1 "
fi
DOCKER_ARGS+=$(: | plugn trigger docker-args-process-build "$APP" "$BUILDER_TYPE")
DOCKER_ARGS+=" $(: | plugn trigger docker-args-process-build "$APP" "$BUILDER_TYPE")"
declare -a ARG_ARRAY
eval "ARG_ARRAY=($DOCKER_ARGS)"
declare -a ARG_ARRAY=()
while IFS= read -r -d '' arg; do
ARG_ARRAY+=("$arg")
done < <(fn-docker-args-split "$DOCKER_ARGS")
local DOKKU_CONTAINER_EXIT_CODE=0
fn-builder-herokuish-ensure-cache "$APP"
if ! CID=$("$DOCKER_BIN" container create "${DOCKER_RUN_LABEL_ARGS[@]}" $DOKKU_GLOBAL_RUN_ARGS -v "cache-$APP:/cache" --env=CACHE_PATH=/cache "${ARG_ARRAY[@]}" "$IMAGE" /build); then
plugn trigger scheduler-register-retired "$APP" "$CID"
dokku_log_warn "Failure during app build"
dokku_log_warn "Failure creating container during app build"
return 1
fi
@@ -86,14 +88,14 @@ trigger-builder-herokuish-builder-build() {
"$DOCKER_BIN" container start "$CID" >/dev/null || DOKKU_CONTAINER_EXIT_CODE=$?
if ! "$DOCKER_BIN" container attach "$CID"; then
plugn trigger scheduler-register-retired "$APP" "$CID"
dokku_log_warn "Failure during app build"
dokku_log_warn "Failure starting container during app build"
return 1
fi
DOKKU_CONTAINER_EXIT_CODE="$("$DOCKER_BIN" container wait "$CID" 2>/dev/null || echo "$DOKKU_CONTAINER_EXIT_CODE")"
if [[ "$DOKKU_CONTAINER_EXIT_CODE" -ne 0 ]]; then
plugn trigger scheduler-register-retired "$APP" "$CID"
dokku_log_warn "Failure during app build"
dokku_log_warn "Failure attaching to container during app build"
return 1
fi

View File

@@ -0,0 +1,29 @@
module github.com/dokku/dokku/plugins/builder-herokuish
go 1.26.2
require (
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
github.com/spf13/pflag v1.0.10
)
require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/fatih/color v1.19.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/melbahja/goph v1.5.2 // indirect
github.com/otiai10/copy v1.14.1 // indirect
github.com/otiai10/mint v1.6.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/sftp v1.13.11 // indirect
github.com/ryanuber/columnize v2.1.2+incompatible // indirect
golang.org/x/crypto v0.55.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.47.0 // indirect
)
replace github.com/dokku/dokku/plugins/common => ../common

View File

@@ -0,0 +1,55 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/melbahja/goph v1.5.2 h1:2eoR45SLF3LyM6tnIhnpjakvXTjtQMJqOK/mp1PYojM=
github.com/melbahja/goph v1.5.2/go.mod h1:T+5uoB1PDP6EeK2qXerf5gRh7b6IF8u37GK2ckEi9FU=
github.com/onsi/gomega v1.42.1 h1:iN1rCUX+44NZ1Dc97MPoeFYbFR0vh8zxoxMFwKdyZ6I=
github.com/onsi/gomega v1.42.1/go.mod h1:REff/hsDsodHoKlWsP2mAPhu1+5/6hVYNf9rIEBpeSg=
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=
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.11 h1:0N92SLTB8JqASJB14ZLHHzFnBV8mG9zw4K7jghEFWuE=
github.com/pkg/sftp v1.13.11/go.mod h1:uNkH9roSXglNJqM+glJJi+TQXQUm0fXFWqCFmT8hsN0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/ryanuber/columnize v2.1.2+incompatible h1:C89EOx/XBWwIXl8wm8OPJBd7kPF25UfsK2X7Ph/zCAk=
github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

72
plugins/builder-herokuish/internal-functions Executable file → Normal file
View File

@@ -4,68 +4,6 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-builder-herokuish-report() {
declare desc="displays a builder-herokuish report for one or more apps"
declare cmd="builder-herokuish: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-herokuish-report-single "$app" "$INFO_FLAG" | tee || true
done
else
cmd-builder-herokuish-report-single "$APP" "$INFO_FLAG"
fi
}
cmd-builder-herokuish-report-single() {
declare APP="$1" INFO_FLAG="$2"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
local flag_map=(
"--builder-herokuish-computed-allowed: $(fn-builder-herokuish-computed-allowed "$APP")"
"--builder-herokuish-global-allowed: $(fn-builder-herokuish-global-allowed)"
"--builder-herokuish-allowed: $(fn-builder-herokuish-allowed "$APP")"
)
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} builder-herokuish 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-herokuish-computed-allowed() {
declare APP="$1"
@@ -73,16 +11,16 @@ fn-builder-herokuish-computed-allowed() {
if [[ -z "$allowed" ]]; then
allowed="$(fn-builder-herokuish-global-allowed)"
fi
if [[ -z "$allowed" ]]; then
allowed="true"
[[ "$(dpkg --print-architecture 2>/dev/null || true)" != "amd64" ]] && allowed="false"
fi
echo "$allowed"
}
fn-builder-herokuish-global-allowed() {
local default_value="true"
[[ "$(dpkg --print-architecture 2>/dev/null || true)" != "amd64" ]] && default_value="false"
fn-plugin-property-get-default "builder-herokuish" "--global" "allowed" "$default_value"
fn-plugin-property-get-default "builder-herokuish" "--global" "allowed" ""
}
fn-builder-herokuish-allowed() {

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core builder-herokuish plugin"
version = "0.37.9"
version = "0.38.27"
[plugin.config]

View File

@@ -1,6 +0,0 @@
#!/usr/bin/env bash
source "$PLUGIN_AVAILABLE_PATH/builder-herokuish/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-builder-herokuish-report-single "$@"

View File

@@ -0,0 +1,83 @@
package builderherokuish
import (
"github.com/dokku/dokku/plugins/common"
)
// ReportSingleApp is an internal function that displays the builder-herokuish report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--builder-herokuish-computed-allowed": reportComputedAllowed,
"--builder-herokuish-global-allowed": reportGlobalAllowed,
}
} else {
flags = map[string]common.ReportFunc{
"--builder-herokuish-computed-allowed": reportComputedAllowed,
"--builder-herokuish-global-allowed": reportGlobalAllowed,
"--builder-herokuish-allowed": reportAllowed,
}
}
flagKeys := []string{}
for flagKey := range flags {
flagKeys = append(flagKeys, flagKey)
}
infoFlags := common.CollectReport(appName, infoFlag, flags)
return common.ReportSingleApp(common.ReportSingleAppInput{
ReportType: "builder-herokuish",
AppName: appName,
InfoFlag: infoFlag,
InfoFlags: infoFlags,
InfoFlagKeys: flagKeys,
Format: format,
TrimPrefix: true,
UppercaseFirstCharacter: true,
EmitLegacyPrefix: false,
})
}
func reportAllowed(appName string) string {
return common.PropertyGet("builder-herokuish", appName, "allowed")
}
func reportGlobalAllowed(appName string) string {
return common.PropertyGet("builder-herokuish", "--global", "allowed")
}
func reportComputedAllowed(appName string) string {
allowed := reportAllowed(appName)
if allowed == "" {
allowed = reportGlobalAllowed(appName)
}
if allowed == "" {
allowed = "true"
if hostArchitecture() != "amd64" {
allowed = "false"
}
}
return allowed
}
// hostArchitecture returns the dpkg architecture of the host, or an empty string
// when it cannot be determined (matching the bash `dpkg --print-architecture` check)
func hostArchitecture() string {
result, err := common.CallExecCommand(common.ExecCommandInput{
Command: "dpkg",
Args: []string{"--print-architecture"},
})
if err != nil {
return ""
}
return result.StdoutContents()
}

View File

@@ -0,0 +1,40 @@
package main
import (
"fmt"
"os"
"strings"
builderherokuish "github.com/dokku/dokku/plugins/builder-herokuish"
"github.com/dokku/dokku/plugins/common"
flag "github.com/spf13/pflag"
)
// main entrypoint to all subcommands
func main() {
parts := strings.Split(os.Args[0], "/")
subcommand := parts[len(parts)-1]
var err error
switch subcommand {
case "report":
args := flag.NewFlagSet("builder-herokuish:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
reportArgs, flagErr := common.ParseReportArgs("builder-herokuish", os.Args[2:])
if flagErr == nil {
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
if reportArgs.IsGlobal {
appName = "--global"
}
err = builderherokuish.CommandReport(appName, *format, reportArgs.InfoFlag)
}
default:
err = fmt.Errorf("Invalid plugin subcommand call: %s", subcommand)
}
if err != nil {
common.LogFailWithError(err)
}
}

View File

@@ -0,0 +1,31 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
builderherokuish "github.com/dokku/dokku/plugins/builder-herokuish"
"github.com/dokku/dokku/plugins/common"
)
// main entrypoint to all triggers
func main() {
parts := strings.Split(os.Args[0], "/")
trigger := parts[len(parts)-1]
flag.Parse()
var err error
switch trigger {
case "report":
appName := flag.Arg(0)
err = builderherokuish.ReportSingleApp(appName, "", "")
default:
err = fmt.Errorf("Invalid plugin trigger call: %s", trigger)
}
if err != nil {
common.LogFailWithError(err)
}
}

View File

@@ -0,0 +1,29 @@
package builderherokuish
import (
"errors"
"github.com/dokku/dokku/plugins/common"
)
// CommandReport displays a builder-herokuish report for one or more apps
func CommandReport(appName string, format string, infoFlag string) error {
if len(appName) == 0 {
apps, err := common.DokkuApps()
if err != nil {
if errors.Is(err, common.NoAppsExist) {
common.LogWarn(err.Error())
return nil
}
return err
}
for _, appName := range apps {
if err := ReportSingleApp(appName, format, infoFlag); err != nil {
return err
}
}
return nil
}
return ReportSingleApp(appName, format, infoFlag)
}

View File

@@ -1,6 +0,0 @@
#!/usr/bin/env bash
source "$PLUGIN_AVAILABLE_PATH/builder-herokuish/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-builder-herokuish-report "$@"

4
plugins/builder-lambda/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/report
/report-subcommand
/triggers
/subcommands/report

View File

@@ -0,0 +1,13 @@
GOARCH ?= amd64
TRIGGERS = triggers/report
BUILD = report-subcommand triggers
PLUGIN_NAME = builder-lambda
clean-report-subcommand:
rm -rf report-subcommand
report-subcommand: clean-report-subcommand src/subcommands/subcommands.go
GOARCH=$(GOARCH) go build -mod=readonly -ldflags="-s -w" $(GO_ARGS) -o report-subcommand src/subcommands/subcommands.go
ln -sf ../report-subcommand subcommands/report
include ../../common.mk

View File

@@ -10,7 +10,7 @@ trigger-builder-lambda-core-post-extract() {
declare APP="$1" SOURCECODE_WORK_DIR="$2"
local NEW_LAMBDA_YML="$(fn-builder-lambda-computed-lambdayml-path "$APP")"
pushd "$TMP_WORK_DIR" >/dev/null
pushd "$SOURCECODE_WORK_DIR" >/dev/null
if [[ -z "$NEW_LAMBDA_YML" ]]; then
return

View File

@@ -0,0 +1,29 @@
module github.com/dokku/dokku/plugins/builder-lambda
go 1.26.2
require (
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
github.com/spf13/pflag v1.0.10
)
require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/fatih/color v1.19.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/melbahja/goph v1.5.2 // indirect
github.com/otiai10/copy v1.14.1 // indirect
github.com/otiai10/mint v1.6.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/sftp v1.13.11 // indirect
github.com/ryanuber/columnize v2.1.2+incompatible // indirect
golang.org/x/crypto v0.55.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.47.0 // indirect
)
replace github.com/dokku/dokku/plugins/common => ../common

View File

@@ -0,0 +1,55 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/melbahja/goph v1.5.2 h1:2eoR45SLF3LyM6tnIhnpjakvXTjtQMJqOK/mp1PYojM=
github.com/melbahja/goph v1.5.2/go.mod h1:T+5uoB1PDP6EeK2qXerf5gRh7b6IF8u37GK2ckEi9FU=
github.com/onsi/gomega v1.42.1 h1:iN1rCUX+44NZ1Dc97MPoeFYbFR0vh8zxoxMFwKdyZ6I=
github.com/onsi/gomega v1.42.1/go.mod h1:REff/hsDsodHoKlWsP2mAPhu1+5/6hVYNf9rIEBpeSg=
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=
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.11 h1:0N92SLTB8JqASJB14ZLHHzFnBV8mG9zw4K7jghEFWuE=
github.com/pkg/sftp v1.13.11/go.mod h1:uNkH9roSXglNJqM+glJJi+TQXQUm0fXFWqCFmT8hsN0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/ryanuber/columnize v2.1.2+incompatible h1:C89EOx/XBWwIXl8wm8OPJBd7kPF25UfsK2X7Ph/zCAk=
github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

67
plugins/builder-lambda/internal-functions Executable file → Normal file
View File

@@ -4,68 +4,6 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-builder-lambda-report() {
declare desc="displays a builder-lambda report for one or more apps"
declare cmd="builder-lambda: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-lambda-report-single "$app" "$INFO_FLAG" | tee || true
done
else
cmd-builder-lambda-report-single "$APP" "$INFO_FLAG"
fi
}
cmd-builder-lambda-report-single() {
declare APP="$1" INFO_FLAG="$2"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
local flag_map=(
"--builder-lambda-computed-lambdayml-path: $(fn-builder-lambda-computed-lambdayml-path "$APP")"
"--builder-lambda-global-lambdayml-path: $(fn-builder-lambda-global-lambdayml-path "$APP")"
"--builder-lambda-lambdayml-path: $(fn-builder-lambda-lambdayml-path "$APP")"
)
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} builder-lambda 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-lambda-computed-lambdayml-path() {
declare APP="$1"
@@ -73,6 +11,9 @@ fn-builder-lambda-computed-lambdayml-path() {
if [[ "$file" == "" ]]; then
file="$(fn-builder-lambda-global-lambdayml-path "$APP")"
fi
if [[ "$file" == "" ]]; then
file="lambda.yml"
fi
echo "$file"
}
@@ -80,7 +21,7 @@ fn-builder-lambda-computed-lambdayml-path() {
fn-builder-lambda-global-lambdayml-path() {
declare APP="$1"
fn-plugin-property-get-default "builder-lambda" "--global" "lambdayml-path" "lambda.yml"
fn-plugin-property-get-default "builder-lambda" "--global" "lambdayml-path" ""
}
fn-builder-lambda-lambdayml-path() {

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core builder-lambda plugin"
version = "0.37.9"
version = "0.38.27"
[plugin.config]

View File

@@ -1,6 +0,0 @@
#!/usr/bin/env bash
source "$PLUGIN_AVAILABLE_PATH/builder-lambda/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-builder-lambda-report-single "$@"

View File

@@ -0,0 +1,66 @@
package builderlambda
import (
"github.com/dokku/dokku/plugins/common"
)
// ReportSingleApp is an internal function that displays the builder-lambda report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--builder-lambda-computed-lambdayml-path": reportComputedLambdaymlPath,
"--builder-lambda-global-lambdayml-path": reportGlobalLambdaymlPath,
}
} else {
flags = map[string]common.ReportFunc{
"--builder-lambda-computed-lambdayml-path": reportComputedLambdaymlPath,
"--builder-lambda-global-lambdayml-path": reportGlobalLambdaymlPath,
"--builder-lambda-lambdayml-path": reportLambdaymlPath,
}
}
flagKeys := []string{}
for flagKey := range flags {
flagKeys = append(flagKeys, flagKey)
}
infoFlags := common.CollectReport(appName, infoFlag, flags)
return common.ReportSingleApp(common.ReportSingleAppInput{
ReportType: "builder-lambda",
AppName: appName,
InfoFlag: infoFlag,
InfoFlags: infoFlags,
InfoFlagKeys: flagKeys,
Format: format,
TrimPrefix: true,
UppercaseFirstCharacter: true,
EmitLegacyPrefix: false,
})
}
func reportLambdaymlPath(appName string) string {
return common.PropertyGet("builder-lambda", appName, "lambdayml-path")
}
func reportGlobalLambdaymlPath(appName string) string {
return common.PropertyGet("builder-lambda", "--global", "lambdayml-path")
}
func reportComputedLambdaymlPath(appName string) string {
value := reportLambdaymlPath(appName)
if value == "" {
value = reportGlobalLambdaymlPath(appName)
}
if value == "" {
value = "lambda.yml"
}
return value
}

View File

@@ -0,0 +1,40 @@
package main
import (
"fmt"
"os"
"strings"
builderlambda "github.com/dokku/dokku/plugins/builder-lambda"
"github.com/dokku/dokku/plugins/common"
flag "github.com/spf13/pflag"
)
// main entrypoint to all subcommands
func main() {
parts := strings.Split(os.Args[0], "/")
subcommand := parts[len(parts)-1]
var err error
switch subcommand {
case "report":
args := flag.NewFlagSet("builder-lambda:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
reportArgs, flagErr := common.ParseReportArgs("builder-lambda", os.Args[2:])
if flagErr == nil {
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
if reportArgs.IsGlobal {
appName = "--global"
}
err = builderlambda.CommandReport(appName, *format, reportArgs.InfoFlag)
}
default:
err = fmt.Errorf("Invalid plugin subcommand call: %s", subcommand)
}
if err != nil {
common.LogFailWithError(err)
}
}

View File

@@ -0,0 +1,31 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
builderlambda "github.com/dokku/dokku/plugins/builder-lambda"
"github.com/dokku/dokku/plugins/common"
)
// main entrypoint to all triggers
func main() {
parts := strings.Split(os.Args[0], "/")
trigger := parts[len(parts)-1]
flag.Parse()
var err error
switch trigger {
case "report":
appName := flag.Arg(0)
err = builderlambda.ReportSingleApp(appName, "", "")
default:
err = fmt.Errorf("Invalid plugin trigger call: %s", trigger)
}
if err != nil {
common.LogFailWithError(err)
}
}

View File

@@ -0,0 +1,29 @@
package builderlambda
import (
"errors"
"github.com/dokku/dokku/plugins/common"
)
// CommandReport displays a builder-lambda report for one or more apps
func CommandReport(appName string, format string, infoFlag string) error {
if len(appName) == 0 {
apps, err := common.DokkuApps()
if err != nil {
if errors.Is(err, common.NoAppsExist) {
common.LogWarn(err.Error())
return nil
}
return err
}
for _, appName := range apps {
if err := ReportSingleApp(appName, format, infoFlag); err != nil {
return err
}
}
return nil
}
return ReportSingleApp(appName, format, infoFlag)
}

View File

@@ -1,6 +0,0 @@
#!/usr/bin/env bash
source "$PLUGIN_AVAILABLE_PATH/builder-lambda/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-builder-lambda-report "$@"

4
plugins/builder-nixpacks/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/report
/report-subcommand
/triggers
/subcommands/report

View File

@@ -0,0 +1,13 @@
GOARCH ?= amd64
TRIGGERS = triggers/report
BUILD = report-subcommand triggers
PLUGIN_NAME = builder-nixpacks
clean-report-subcommand:
rm -rf report-subcommand
report-subcommand: clean-report-subcommand src/subcommands/subcommands.go
GOARCH=$(GOARCH) go build -mod=readonly -ldflags="-s -w" $(GO_ARGS) -o report-subcommand src/subcommands/subcommands.go
ln -sf ../report-subcommand subcommands/report
include ../../common.mk

View File

@@ -34,11 +34,14 @@ trigger-builder-nixpacks-builder-build() {
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+=" $(: | 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 DOCKER_ARGS_ARRAY=()
while IFS= read -r -d '' arg; do
DOCKER_ARGS_ARRAY+=("$arg")
done < <(fn-docker-args-split "$DOCKER_ARGS")
set -- "${DOCKER_ARGS_ARRAY[@]}"
declare -a NIXPACKS_ARGS
while true; do

View File

@@ -10,7 +10,7 @@ trigger-builder-nixpacks-core-post-extract() {
declare APP="$1" SOURCECODE_WORK_DIR="$2"
local NEW_NIXPACKS_YML="$(fn-builder-nixpacks-computed-nixpackstoml-path "$APP")"
pushd "$TMP_WORK_DIR" >/dev/null
pushd "$SOURCECODE_WORK_DIR" >/dev/null
if [[ -z "$NEW_NIXPACKS_YML" ]]; then
return

View File

@@ -0,0 +1,29 @@
module github.com/dokku/dokku/plugins/builder-nixpacks
go 1.26.2
require (
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
github.com/spf13/pflag v1.0.10
)
require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/fatih/color v1.19.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/melbahja/goph v1.5.2 // indirect
github.com/otiai10/copy v1.14.1 // indirect
github.com/otiai10/mint v1.6.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/sftp v1.13.11 // indirect
github.com/ryanuber/columnize v2.1.2+incompatible // indirect
golang.org/x/crypto v0.55.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.47.0 // indirect
)
replace github.com/dokku/dokku/plugins/common => ../common

View File

@@ -0,0 +1,55 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/melbahja/goph v1.5.2 h1:2eoR45SLF3LyM6tnIhnpjakvXTjtQMJqOK/mp1PYojM=
github.com/melbahja/goph v1.5.2/go.mod h1:T+5uoB1PDP6EeK2qXerf5gRh7b6IF8u37GK2ckEi9FU=
github.com/onsi/gomega v1.42.1 h1:iN1rCUX+44NZ1Dc97MPoeFYbFR0vh8zxoxMFwKdyZ6I=
github.com/onsi/gomega v1.42.1/go.mod h1:REff/hsDsodHoKlWsP2mAPhu1+5/6hVYNf9rIEBpeSg=
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=
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.11 h1:0N92SLTB8JqASJB14ZLHHzFnBV8mG9zw4K7jghEFWuE=
github.com/pkg/sftp v1.13.11/go.mod h1:uNkH9roSXglNJqM+glJJi+TQXQUm0fXFWqCFmT8hsN0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/ryanuber/columnize v2.1.2+incompatible h1:C89EOx/XBWwIXl8wm8OPJBd7kPF25UfsK2X7Ph/zCAk=
github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

67
plugins/builder-nixpacks/internal-functions Executable file → Normal file
View File

@@ -4,68 +4,6 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-builder-nixpacks-report() {
declare desc="displays a builder-nixpacks report for one or more apps"
declare cmd="builder-nixpacks: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-nixpacks-report-single "$app" "$INFO_FLAG" | tee || true
done
else
cmd-builder-nixpacks-report-single "$APP" "$INFO_FLAG"
fi
}
cmd-builder-nixpacks-report-single() {
declare APP="$1" INFO_FLAG="$2"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
local flag_map=(
"--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")"
)
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} builder-nixpacks 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-nixpacks-computed-nixpackstoml-path() {
declare APP="$1"
@@ -73,6 +11,9 @@ fn-builder-nixpacks-computed-nixpackstoml-path() {
if [[ "$file" == "" ]]; then
file="$(fn-builder-nixpacks-global-nixpackstoml-path "$APP")"
fi
if [[ "$file" == "" ]]; then
file="nixpacks.toml"
fi
echo "$file"
}
@@ -80,7 +21,7 @@ fn-builder-nixpacks-computed-nixpackstoml-path() {
fn-builder-nixpacks-global-nixpackstoml-path() {
declare APP="$1"
fn-plugin-property-get "builder-nixpacks" "--global" "nixpackstoml-path" "nixpacks.toml"
fn-plugin-property-get "builder-nixpacks" "--global" "nixpackstoml-path" ""
}
fn-builder-nixpacks-nixpackstoml-path() {

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core builder-nixpacks plugin"
version = "0.37.9"
version = "0.38.27"
[plugin.config]

View File

@@ -1,6 +0,0 @@
#!/usr/bin/env bash
source "$PLUGIN_AVAILABLE_PATH/builder-nixpacks/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-builder-nixpacks-report-single "$@"

View File

@@ -0,0 +1,66 @@
package buildernixpacks
import (
"github.com/dokku/dokku/plugins/common"
)
// ReportSingleApp is an internal function that displays the builder-nixpacks report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--builder-nixpacks-computed-nixpackstoml-path": reportComputedNixpackstomlPath,
"--builder-nixpacks-global-nixpackstoml-path": reportGlobalNixpackstomlPath,
}
} else {
flags = map[string]common.ReportFunc{
"--builder-nixpacks-computed-nixpackstoml-path": reportComputedNixpackstomlPath,
"--builder-nixpacks-global-nixpackstoml-path": reportGlobalNixpackstomlPath,
"--builder-nixpacks-nixpackstoml-path": reportNixpackstomlPath,
}
}
flagKeys := []string{}
for flagKey := range flags {
flagKeys = append(flagKeys, flagKey)
}
infoFlags := common.CollectReport(appName, infoFlag, flags)
return common.ReportSingleApp(common.ReportSingleAppInput{
ReportType: "builder-nixpacks",
AppName: appName,
InfoFlag: infoFlag,
InfoFlags: infoFlags,
InfoFlagKeys: flagKeys,
Format: format,
TrimPrefix: true,
UppercaseFirstCharacter: true,
EmitLegacyPrefix: false,
})
}
func reportNixpackstomlPath(appName string) string {
return common.PropertyGet("builder-nixpacks", appName, "nixpackstoml-path")
}
func reportGlobalNixpackstomlPath(appName string) string {
return common.PropertyGet("builder-nixpacks", "--global", "nixpackstoml-path")
}
func reportComputedNixpackstomlPath(appName string) string {
value := reportNixpackstomlPath(appName)
if value == "" {
value = reportGlobalNixpackstomlPath(appName)
}
if value == "" {
value = "nixpacks.toml"
}
return value
}

View File

@@ -0,0 +1,40 @@
package main
import (
"fmt"
"os"
"strings"
buildernixpacks "github.com/dokku/dokku/plugins/builder-nixpacks"
"github.com/dokku/dokku/plugins/common"
flag "github.com/spf13/pflag"
)
// main entrypoint to all subcommands
func main() {
parts := strings.Split(os.Args[0], "/")
subcommand := parts[len(parts)-1]
var err error
switch subcommand {
case "report":
args := flag.NewFlagSet("builder-nixpacks:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
reportArgs, flagErr := common.ParseReportArgs("builder-nixpacks", os.Args[2:])
if flagErr == nil {
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
if reportArgs.IsGlobal {
appName = "--global"
}
err = buildernixpacks.CommandReport(appName, *format, reportArgs.InfoFlag)
}
default:
err = fmt.Errorf("Invalid plugin subcommand call: %s", subcommand)
}
if err != nil {
common.LogFailWithError(err)
}
}

View File

@@ -0,0 +1,31 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
buildernixpacks "github.com/dokku/dokku/plugins/builder-nixpacks"
"github.com/dokku/dokku/plugins/common"
)
// main entrypoint to all triggers
func main() {
parts := strings.Split(os.Args[0], "/")
trigger := parts[len(parts)-1]
flag.Parse()
var err error
switch trigger {
case "report":
appName := flag.Arg(0)
err = buildernixpacks.ReportSingleApp(appName, "", "")
default:
err = fmt.Errorf("Invalid plugin trigger call: %s", trigger)
}
if err != nil {
common.LogFailWithError(err)
}
}

View File

@@ -0,0 +1,29 @@
package buildernixpacks
import (
"errors"
"github.com/dokku/dokku/plugins/common"
)
// CommandReport displays a builder-nixpacks report for one or more apps
func CommandReport(appName string, format string, infoFlag string) error {
if len(appName) == 0 {
apps, err := common.DokkuApps()
if err != nil {
if errors.Is(err, common.NoAppsExist) {
common.LogWarn(err.Error())
return nil
}
return err
}
for _, appName := range apps {
if err := ReportSingleApp(appName, format, infoFlag); err != nil {
return err
}
}
return nil
}
return ReportSingleApp(appName, format, infoFlag)
}

View File

@@ -1,6 +0,0 @@
#!/usr/bin/env bash
source "$PLUGIN_AVAILABLE_PATH/builder-nixpacks/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-builder-nixpacks-report "$@"

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core builder-null plugin"
version = "0.37.9"
version = "0.38.27"
[plugin.config]

4
plugins/builder-pack/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/report
/report-subcommand
/triggers
/subcommands/report

View File

@@ -0,0 +1,13 @@
GOARCH ?= amd64
TRIGGERS = triggers/report
BUILD = report-subcommand triggers
PLUGIN_NAME = builder-pack
clean-report-subcommand:
rm -rf report-subcommand
report-subcommand: clean-report-subcommand src/subcommands/subcommands.go
GOARCH=$(GOARCH) go build -mod=readonly -ldflags="-s -w" $(GO_ARGS) -o report-subcommand src/subcommands/subcommands.go
ln -sf ../report-subcommand subcommands/report
include ../../common.mk

View File

@@ -38,11 +38,14 @@ 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")
DOCKER_ARGS+=$(: | plugn trigger docker-args-process-build "$APP" "$BUILDER_TYPE")
DOCKER_ARGS+=" $(: | plugn trigger docker-args-process-build "$APP" "$BUILDER_TYPE")"
[[ "$DOKKU_TRACE" ]] && DOCKER_ARGS+=" --env=TRACE=true "
DOCKER_ARGS=" $DOCKER_ARGS "
eval set -- "$DOCKER_ARGS"
declare -a DOCKER_ARGS_ARRAY=()
while IFS= read -r -d '' arg; do
DOCKER_ARGS_ARRAY+=("$arg")
done < <(fn-docker-args-split "$DOCKER_ARGS")
set -- "${DOCKER_ARGS_ARRAY[@]}"
declare -a PACK_ARGS
while true; do

View File

@@ -10,7 +10,7 @@ trigger-builder-pack-core-post-extract() {
declare APP="$1" SOURCECODE_WORK_DIR="$2"
local NEW_PROJECT_TOML="$(fn-builder-pack-computed-projecttoml-path "$APP")"
pushd "$TMP_WORK_DIR" >/dev/null
pushd "$SOURCECODE_WORK_DIR" >/dev/null
if [[ -z "$NEW_PROJECT_TOML" ]]; then
return

View File

@@ -20,10 +20,10 @@ trigger-builder-pack-docker-args-process-deploy() {
if [[ "$inject_launcher" == "true" ]]; then
# without this, the command and arguments are passed as args to the default process type
output="--entrypoint launcher "
output=" --entrypoint launcher"
fi
echo -n "$STDIN$output"
echo -n "$STDIN $output"
}
trigger-builder-pack-docker-args-process-deploy "$@"

View File

@@ -0,0 +1,29 @@
module github.com/dokku/dokku/plugins/builder-pack
go 1.26.2
require (
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
github.com/spf13/pflag v1.0.10
)
require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/fatih/color v1.19.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/melbahja/goph v1.5.2 // indirect
github.com/otiai10/copy v1.14.1 // indirect
github.com/otiai10/mint v1.6.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/sftp v1.13.11 // indirect
github.com/ryanuber/columnize v2.1.2+incompatible // indirect
golang.org/x/crypto v0.55.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.47.0 // indirect
)
replace github.com/dokku/dokku/plugins/common => ../common

View File

@@ -0,0 +1,55 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/melbahja/goph v1.5.2 h1:2eoR45SLF3LyM6tnIhnpjakvXTjtQMJqOK/mp1PYojM=
github.com/melbahja/goph v1.5.2/go.mod h1:T+5uoB1PDP6EeK2qXerf5gRh7b6IF8u37GK2ckEi9FU=
github.com/onsi/gomega v1.42.1 h1:iN1rCUX+44NZ1Dc97MPoeFYbFR0vh8zxoxMFwKdyZ6I=
github.com/onsi/gomega v1.42.1/go.mod h1:REff/hsDsodHoKlWsP2mAPhu1+5/6hVYNf9rIEBpeSg=
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=
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.11 h1:0N92SLTB8JqASJB14ZLHHzFnBV8mG9zw4K7jghEFWuE=
github.com/pkg/sftp v1.13.11/go.mod h1:uNkH9roSXglNJqM+glJJi+TQXQUm0fXFWqCFmT8hsN0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/ryanuber/columnize v2.1.2+incompatible h1:C89EOx/XBWwIXl8wm8OPJBd7kPF25UfsK2X7Ph/zCAk=
github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

67
plugins/builder-pack/internal-functions Executable file → Normal file
View File

@@ -4,68 +4,6 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-builder-pack-report() {
declare desc="displays a builder-pack report for one or more apps"
declare cmd="builder-pack: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-pack-report-single "$app" "$INFO_FLAG" | tee || true
done
else
cmd-builder-pack-report-single "$APP" "$INFO_FLAG"
fi
}
cmd-builder-pack-report-single() {
declare APP="$1" INFO_FLAG="$2"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
local flag_map=(
"--builder-pack-computed-projecttoml-path: $(fn-builder-pack-computed-projecttoml-path "$APP")"
"--builder-pack-global-projecttoml-path: $(fn-builder-pack-global-projecttoml-path "$APP")"
"--builder-pack-projecttoml-path: $(fn-builder-pack-projecttoml-path "$APP")"
)
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} builder-pack 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-pack-computed-projecttoml-path() {
declare APP="$1"
@@ -73,6 +11,9 @@ fn-builder-pack-computed-projecttoml-path() {
if [[ "$file" == "" ]]; then
file="$(fn-builder-pack-global-projecttoml-path "$APP")"
fi
if [[ "$file" == "" ]]; then
file="project.toml"
fi
echo "$file"
}
@@ -80,7 +21,7 @@ fn-builder-pack-computed-projecttoml-path() {
fn-builder-pack-global-projecttoml-path() {
declare APP="$1"
fn-plugin-property-get-default "builder-pack" "--global" "projecttoml-path" "project.toml"
fn-plugin-property-get-default "builder-pack" "--global" "projecttoml-path" ""
}
fn-builder-pack-projecttoml-path() {

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core builder-pack plugin"
version = "0.37.9"
version = "0.38.27"
[plugin.config]

View File

@@ -1,6 +0,0 @@
#!/usr/bin/env bash
source "$PLUGIN_AVAILABLE_PATH/builder-pack/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-builder-pack-report-single "$@"

View File

@@ -0,0 +1,66 @@
package builderpack
import (
"github.com/dokku/dokku/plugins/common"
)
// ReportSingleApp is an internal function that displays the builder-pack report for one or more apps
func ReportSingleApp(appName string, format string, infoFlag string) error {
if appName != "--global" {
if err := common.VerifyAppName(appName); err != nil {
return err
}
}
var flags map[string]common.ReportFunc
if appName == "--global" {
flags = map[string]common.ReportFunc{
"--builder-pack-computed-projecttoml-path": reportComputedProjecttomlPath,
"--builder-pack-global-projecttoml-path": reportGlobalProjecttomlPath,
}
} else {
flags = map[string]common.ReportFunc{
"--builder-pack-computed-projecttoml-path": reportComputedProjecttomlPath,
"--builder-pack-global-projecttoml-path": reportGlobalProjecttomlPath,
"--builder-pack-projecttoml-path": reportProjecttomlPath,
}
}
flagKeys := []string{}
for flagKey := range flags {
flagKeys = append(flagKeys, flagKey)
}
infoFlags := common.CollectReport(appName, infoFlag, flags)
return common.ReportSingleApp(common.ReportSingleAppInput{
ReportType: "builder-pack",
AppName: appName,
InfoFlag: infoFlag,
InfoFlags: infoFlags,
InfoFlagKeys: flagKeys,
Format: format,
TrimPrefix: true,
UppercaseFirstCharacter: true,
EmitLegacyPrefix: false,
})
}
func reportProjecttomlPath(appName string) string {
return common.PropertyGet("builder-pack", appName, "projecttoml-path")
}
func reportGlobalProjecttomlPath(appName string) string {
return common.PropertyGet("builder-pack", "--global", "projecttoml-path")
}
func reportComputedProjecttomlPath(appName string) string {
value := reportProjecttomlPath(appName)
if value == "" {
value = reportGlobalProjecttomlPath(appName)
}
if value == "" {
value = "project.toml"
}
return value
}

View File

@@ -0,0 +1,40 @@
package main
import (
"fmt"
"os"
"strings"
builderpack "github.com/dokku/dokku/plugins/builder-pack"
"github.com/dokku/dokku/plugins/common"
flag "github.com/spf13/pflag"
)
// main entrypoint to all subcommands
func main() {
parts := strings.Split(os.Args[0], "/")
subcommand := parts[len(parts)-1]
var err error
switch subcommand {
case "report":
args := flag.NewFlagSet("builder-pack:report", flag.ExitOnError)
format := args.String("format", "stdout", "format: [ stdout | json ]")
reportArgs, flagErr := common.ParseReportArgs("builder-pack", os.Args[2:])
if flagErr == nil {
args.Parse(reportArgs.OSArgs)
appName := args.Arg(0)
if reportArgs.IsGlobal {
appName = "--global"
}
err = builderpack.CommandReport(appName, *format, reportArgs.InfoFlag)
}
default:
err = fmt.Errorf("Invalid plugin subcommand call: %s", subcommand)
}
if err != nil {
common.LogFailWithError(err)
}
}

View File

@@ -0,0 +1,31 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
builderpack "github.com/dokku/dokku/plugins/builder-pack"
"github.com/dokku/dokku/plugins/common"
)
// main entrypoint to all triggers
func main() {
parts := strings.Split(os.Args[0], "/")
trigger := parts[len(parts)-1]
flag.Parse()
var err error
switch trigger {
case "report":
appName := flag.Arg(0)
err = builderpack.ReportSingleApp(appName, "", "")
default:
err = fmt.Errorf("Invalid plugin trigger call: %s", trigger)
}
if err != nil {
common.LogFailWithError(err)
}
}

View File

@@ -0,0 +1,29 @@
package builderpack
import (
"errors"
"github.com/dokku/dokku/plugins/common"
)
// CommandReport displays a builder-pack report for one or more apps
func CommandReport(appName string, format string, infoFlag string) error {
if len(appName) == 0 {
apps, err := common.DokkuApps()
if err != nil {
if errors.Is(err, common.NoAppsExist) {
common.LogWarn(err.Error())
return nil
}
return err
}
for _, appName := range apps {
if err := ReportSingleApp(appName, format, infoFlag); err != nil {
return err
}
}
return nil
}
return ReportSingleApp(appName, format, infoFlag)
}

View File

@@ -1,6 +0,0 @@
#!/usr/bin/env bash
source "$PLUGIN_AVAILABLE_PATH/builder-pack/internal-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-builder-pack-report "$@"

4
plugins/builder-railpack/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/report
/report-subcommand
/triggers
/subcommands/report

View File

@@ -0,0 +1,13 @@
GOARCH ?= amd64
TRIGGERS = triggers/report
BUILD = report-subcommand triggers
PLUGIN_NAME = builder-railpack
clean-report-subcommand:
rm -rf report-subcommand
report-subcommand: clean-report-subcommand src/subcommands/subcommands.go
GOARCH=$(GOARCH) go build -mod=readonly -ldflags="-s -w" $(GO_ARGS) -o report-subcommand src/subcommands/subcommands.go
ln -sf ../report-subcommand subcommands/report
include ../../common.mk

View File

@@ -34,10 +34,13 @@ trigger-builder-railpack-builder-build() {
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+=" $(: | plugn trigger docker-args-process-build "$APP" "$BUILDER_TYPE")"
DOCKER_ARGS=" $DOCKER_ARGS "
eval set -- "$DOCKER_ARGS"
declare -a DOCKER_ARGS_ARRAY=()
while IFS= read -r -d '' arg; do
DOCKER_ARGS_ARRAY+=("$arg")
done < <(fn-docker-args-split "$DOCKER_ARGS")
set -- "${DOCKER_ARGS_ARRAY[@]}"
declare -a RAILPACK_ARGS
while true; do

View File

@@ -10,7 +10,7 @@ trigger-builder-railpack-core-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
pushd "$SOURCECODE_WORK_DIR" >/dev/null
if [[ -z "$NEW_RAILPACK_JSON" ]]; then
return

View File

@@ -0,0 +1,29 @@
module github.com/dokku/dokku/plugins/builder-railpack
go 1.26.2
require (
github.com/dokku/dokku/plugins/common v0.0.0-00010101000000-000000000000
github.com/spf13/pflag v1.0.10
)
require (
github.com/alexellis/go-execute/v2 v2.2.1 // indirect
github.com/fatih/color v1.19.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/melbahja/goph v1.5.2 // indirect
github.com/otiai10/copy v1.14.1 // indirect
github.com/otiai10/mint v1.6.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/sftp v1.13.11 // indirect
github.com/ryanuber/columnize v2.1.2+incompatible // indirect
golang.org/x/crypto v0.55.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.47.0 // indirect
)
replace github.com/dokku/dokku/plugins/common => ../common

View File

@@ -0,0 +1,55 @@
github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhse743RdOI=
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/melbahja/goph v1.5.2 h1:2eoR45SLF3LyM6tnIhnpjakvXTjtQMJqOK/mp1PYojM=
github.com/melbahja/goph v1.5.2/go.mod h1:T+5uoB1PDP6EeK2qXerf5gRh7b6IF8u37GK2ckEi9FU=
github.com/onsi/gomega v1.42.1 h1:iN1rCUX+44NZ1Dc97MPoeFYbFR0vh8zxoxMFwKdyZ6I=
github.com/onsi/gomega v1.42.1/go.mod h1:REff/hsDsodHoKlWsP2mAPhu1+5/6hVYNf9rIEBpeSg=
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=
github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.11 h1:0N92SLTB8JqASJB14ZLHHzFnBV8mG9zw4K7jghEFWuE=
github.com/pkg/sftp v1.13.11/go.mod h1:uNkH9roSXglNJqM+glJJi+TQXQUm0fXFWqCFmT8hsN0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/ryanuber/columnize v2.1.2+incompatible h1:C89EOx/XBWwIXl8wm8OPJBd7kPF25UfsK2X7Ph/zCAk=
github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

67
plugins/builder-railpack/internal-functions Executable file → Normal file
View File

@@ -4,68 +4,6 @@ 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"
@@ -73,6 +11,9 @@ fn-builder-railpack-computed-railpackjson-path() {
if [[ "$file" == "" ]]; then
file="$(fn-builder-railpack-global-railpackjson-path "$APP")"
fi
if [[ "$file" == "" ]]; then
file="railpack.json"
fi
echo "$file"
}
@@ -80,7 +21,7 @@ fn-builder-railpack-computed-railpackjson-path() {
fn-builder-railpack-global-railpackjson-path() {
declare APP="$1"
fn-plugin-property-get "builder-railpack" "--global" "railpackjson-path" "railpack.json"
fn-plugin-property-get "builder-railpack" "--global" "railpackjson-path" ""
}
fn-builder-railpack-railpackjson-path() {

View File

@@ -1,4 +1,4 @@
[plugin]
description = "dokku core builder-railpack plugin"
version = "0.37.9"
version = "0.38.27"
[plugin.config]

Some files were not shown because too many files have changed in this diff Show More