Merge pull request #4336 from dokku/4306-stacks-set

Add ability to manage stacks on an app or global level …
This commit is contained in:
Jose Diaz-Gonzalez
2021-01-23 19:04:15 -05:00
committed by GitHub
21 changed files with 226 additions and 42 deletions

View File

@@ -13,6 +13,14 @@ trigger-builder-cnb-builder-build() {
return
fi
local stack="$(plugn trigger buildpack-stack-name "$APP")"
if [[ -z "$stack" ]]; then
DOKKU_CNB_STACK="$stack"
fi
dokku_log_info1 "Building $APP from cnb stack $DOKKU_CNB_STACK (experimental)..."
if ! command -v "pack" &>/dev/null; then
dokku_log_fail "Missing pack, install it"
fi
@@ -28,7 +36,7 @@ trigger-builder-cnb-builder-build() {
plugn trigger pre-build-cnb "$APP" "$SOURCECODE_WORK_DIR"
pack build "$IMAGE" --builder heroku/buildpacks --path "$SOURCECODE_WORK_DIR" --default-process web
pack build "$IMAGE" --builder "$DOKKU_CNB_BUILDER" --path "$SOURCECODE_WORK_DIR" --default-process web
echo "FROM $IMAGE" | suppress_output "$DOCKER_BIN" image build --label=com.dokku.image-stage=build --label=org.label-schema.schema-version=1.0 --label=org.label-schema.vendor=dokku --label=com.dokku.app-name=$APP --label=dokku -t "$IMAGE" -

View File

@@ -12,6 +12,8 @@ trigger-builder-dockerfile-builder-build() {
return
fi
dokku_log_info1 "Building $APP from Dockerfile"
local IMAGE=$(get_app_image_name "$APP")
local DOCKER_BUILD_LABEL_ARGS="--label=org.label-schema.schema-version=1.0 --label=org.label-schema.vendor=dokku --label=com.dokku.app-name=$APP"

View File

@@ -12,6 +12,14 @@ trigger-builder-herokuish-builder-build() {
return
fi
local stack="$(plugn trigger buildpack-stack-name "$APP")"
if [[ -n "$stack" ]]; then
dokku_log_info1 "Building $APP from $stack"
DOKKU_IMAGE="$stack"
else
dokku_log_info1 "Building $APP from herokuish"
fi
local IMAGE=$(get_app_image_name "$APP")
local DOKKU_APP_CACHE_DIR="$DOKKU_ROOT/$APP/cache"
local DOKKU_APP_HOST_CACHE_DIR="$DOKKU_HOST_ROOT/$APP/cache"
@@ -22,8 +30,6 @@ trigger-builder-herokuish-builder-build() {
pushd "$SOURCECODE_WORK_DIR" &>/dev/null
eval "$(config_export app "$APP")"
DOKKU_IMAGE="$(config_get "$APP" DOKKU_IMAGE || echo "$DOKKU_IMAGE")"
plugn trigger builder-create-dokku-image "$BUILDER_TYPE" "$APP" "$SOURCECODE_WORK_DIR" "$DOKKU_IMAGE"
NEW_DOKKU_IMAGE=$(plugn trigger builder-dokku-image "$BUILDER_TYPE" "$APP" "$SOURCECODE_WORK_DIR" "$DOKKU_IMAGE")
[[ -n "$NEW_DOKKU_IMAGE" ]] && DOKKU_IMAGE="$NEW_DOKKU_IMAGE"

View File

@@ -2,6 +2,7 @@
/subcommands/*
/triggers/*
/triggers
/buildpack-stack-name
/install
/post-*
/report

View File

@@ -1,5 +1,5 @@
SUBCOMMANDS = subcommands/add subcommands/clear subcommands/list subcommands/remove subcommands/report subcommands/set
TRIGGERS = triggers/install triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-delete triggers/post-extract triggers/report
SUBCOMMANDS = subcommands/add subcommands/clear subcommands/list subcommands/remove subcommands/report subcommands/set subcommands/set-property
TRIGGERS = triggers/buildpack-stack-name triggers/install triggers/post-app-clone-setup triggers/post-app-rename-setup triggers/post-delete triggers/post-extract triggers/report
BUILD = commands subcommands triggers
PLUGIN_NAME = buildpacks

View File

@@ -0,0 +1,13 @@
package buildpacks
var (
// DefaultProperties is a map of all valid buildpacks properties with corresponding default property values
DefaultProperties = map[string]string{
"stack": "",
}
// GlobalProperties is a map of all valid global buildpacks properties
GlobalProperties = map[string]bool{
"stack": true,
}
)

View File

@@ -1,6 +1,7 @@
package buildpacks
import (
"os"
"strings"
"github.com/dokku/dokku/plugins/common"
@@ -13,7 +14,10 @@ func ReportSingleApp(appName, infoFlag string) error {
}
flags := map[string]common.ReportFunc{
"--buildpacks-list": reportList,
"--buildpacks-computed-stack": reportComputedStack,
"--buildpacks-global-stack": reportGlobalStack,
"--buildpacks-list": reportList,
"--buildpacks-stack": reportStack,
}
flagKeys := []string{}
@@ -27,6 +31,28 @@ func ReportSingleApp(appName, infoFlag string) error {
return common.ReportSingleApp("buildpacks", appName, infoFlag, infoFlags, flagKeys, trimPrefix, uppercaseFirstCharacter)
}
func reportComputedStack(appName string) string {
if stack := common.PropertyGetDefault("buildpacks", appName, "stack", ""); stack != "" {
return stack
}
if stack := common.PropertyGetDefault("buildpacks", "--global", "stack", ""); stack != "" {
return stack
}
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_IMAGE"}...)
if dokkuImage := strings.TrimSpace(string(b[:])); dokkuImage != "" {
common.LogWarn("Deprecated: use buildpacks:set-property instead of specifying DOKKU_IMAGE environment variable")
return dokkuImage
}
return os.Getenv("DOKKU_IMAGE")
}
func reportGlobalStack(appName string) string {
return common.PropertyGetDefault("buildpacks", "--global", "stack", "")
}
func reportList(appName string) string {
buildpacks, err := common.PropertyListGet("buildpacks", appName, "buildpacks")
if err != nil {
@@ -35,3 +61,7 @@ func reportList(appName string) string {
return strings.Join(buildpacks, ",")
}
func reportStack(appName string) string {
return common.PropertyGetDefault("buildpacks", appName, "stack", "")
}

View File

@@ -24,6 +24,7 @@ Additional commands:`
buildpacks:remove <app> <buildpack>, Remove a buildpack set on the app
buildpacks:report [<app>] [<flag>], Displays a buildpack report for one or more apps
buildpacks:set [--index 1] <app> <buildpack>, Set new app buildpack at a given position defaulting to the first buildpack if no index is specified
buildpacks:set-property [--global|<app>] <key> <value>, Set or clear a buildpacks property for an app
`
)

View File

@@ -57,6 +57,19 @@ func main() {
appName := args.Arg(0)
buildpack := args.Arg(1)
err = buildpacks.CommandSet(appName, buildpack, *index)
case "set-property":
args := flag.NewFlagSet("buildpacks:set-property", 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 = buildpacks.CommandSetProperty(appName, property, value)
default:
common.LogFail(fmt.Sprintf("Invalid plugin subcommand call: %s", subcommand))
}

View File

@@ -18,8 +18,11 @@ func main() {
var err error
switch trigger {
case "buildpack-stack-name":
appName := flag.Arg(0)
err = buildpacks.TriggerBuildpackStackName(appName)
case "install":
buildpacks.TriggerInstall()
err = buildpacks.TriggerInstall()
case "post-app-clone-setup":
oldAppName := flag.Arg(0)
newAppName := flag.Arg(1)
@@ -30,11 +33,11 @@ func main() {
err = buildpacks.TriggerPostAppRenameSetup(oldAppName, newAppName)
case "post-delete":
appName := flag.Arg(0)
buildpacks.TriggerPostDelete(appName)
err = buildpacks.TriggerPostDelete(appName)
case "post-extract":
appName := flag.Arg(0)
sourceWorkDir := flag.Arg(1)
buildpacks.TriggerPostExtract(appName, sourceWorkDir)
err = buildpacks.TriggerPostExtract(appName, sourceWorkDir)
case "report":
appName := flag.Arg(0)
err = buildpacks.ReportSingleApp(appName, "")

View File

@@ -138,3 +138,18 @@ func CommandSet(appName string, buildpack string, index int) error {
return common.PropertyListSet("buildpacks", appName, "buildpacks", buildpack, index)
}
// CommandSetProperty implements buildpacks:set-property
func CommandSetProperty(appName string, property string, value string) error {
oldStack := ""
if property == "stack" {
oldStack = common.PropertyGet("buildpacks", appName, "stack")
}
common.CommandPropertySet("buildpacks", appName, property, value, DefaultProperties, GlobalProperties)
if property == "stack" && oldStack != value {
return common.PlugnTrigger("post-stack-set", []string{appName, value}...)
}
return nil
}

View File

@@ -5,15 +5,41 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/dokku/dokku/plugins/common"
)
// TriggerInstall runs the install step for the buildpacks plugin
func TriggerInstall() {
if err := common.PropertySetup("buildpacks"); err != nil {
common.LogFail(fmt.Sprintf("Unable to install the buildpacks plugin: %s", err.Error()))
// TriggerBuildpackStackName echos the stack name for the app
func TriggerBuildpackStackName(appName string) error {
if stack := common.PropertyGetDefault("buildpacks", appName, "stack", ""); stack != "" {
fmt.Println(stack)
return nil
}
if stack := common.PropertyGetDefault("buildpacks", "--global", "stack", ""); stack != "" {
fmt.Println(stack)
return nil
}
b, _ := common.PlugnTriggerOutput("config-get", []string{appName, "DOKKU_IMAGE"}...)
dokkuImage := strings.TrimSpace(string(b[:]))
if dokkuImage != "" {
common.LogWarn("Deprecated: use buildpacks:set-property instead of specifying DOKKU_IMAGE environment variable")
fmt.Println(dokkuImage)
return nil
}
return nil
}
// TriggerInstall runs the install step for the buildpacks plugin
func TriggerInstall() error {
if err := common.PropertySetup("buildpacks"); err != nil {
return fmt.Errorf("Unable to install the buildpacks plugin: %s", err.Error())
}
return nil
}
// TriggerPostAppCloneSetup creates new buildpacks files
@@ -40,29 +66,25 @@ func TriggerPostAppRenameSetup(oldAppName string, newAppName string) error {
}
// TriggerPostDelete destroys the buildpacks property for a given app container
func TriggerPostDelete(appName string) {
err := common.PropertyDestroy("buildpacks", appName)
if err != nil {
common.LogFail(err.Error())
}
func TriggerPostDelete(appName string) error {
return common.PropertyDestroy("buildpacks", appName)
}
// TriggerPostExtract writes a .buildpacks file into the app
func TriggerPostExtract(appName string, sourceWorkDir string) {
func TriggerPostExtract(appName string, sourceWorkDir string) error {
buildpacks, err := common.PropertyListGet("buildpacks", appName, "buildpacks")
if err != nil {
return
return nil
}
if len(buildpacks) == 0 {
return
return nil
}
buildpacksPath := filepath.Join(sourceWorkDir, ".buildpacks")
file, err := os.OpenFile(buildpacksPath, os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0600)
if err != nil {
common.LogFail(fmt.Sprintf("Error writing .buildpacks file: %s", err.Error()))
return
return fmt.Errorf("Error writing .buildpacks file: %s", err.Error())
}
w := bufio.NewWriter(file)
@@ -71,8 +93,9 @@ func TriggerPostExtract(appName string, sourceWorkDir string) {
}
if err = w.Flush(); err != nil {
common.LogFail(fmt.Sprintf("Error writing .buildpacks file: %s", err.Error()))
return
return fmt.Errorf("Error writing .buildpacks file: %s", err.Error())
}
file.Chmod(0600)
return nil
}

View File

@@ -713,9 +713,6 @@ dokku_receive() {
local DOKKU_CNB_EXPERIMENTAL="$(config_get "$APP" DOKKU_CNB_EXPERIMENTAL || true)"
if [[ "$DOKKU_CNB_EXPERIMENTAL" == "1" ]]; then
IMAGE_SOURCE_TYPE="cnb"
dokku_log_info1 "Building $APP from $IMAGE_SOURCE_TYPE (experimental)..."
else
dokku_log_info1 "Building $APP from $IMAGE_SOURCE_TYPE..."
fi
DOKKU_QUIET_OUTPUT=1 config_set --no-restart "$APP" DOKKU_APP_TYPE="$IMAGE_SOURCE_TYPE"

View File

@@ -10,7 +10,7 @@ import (
const MaxSize = "10m"
var (
// DefaultProperties is a map of all valid ps properties with corresponding default property values
// DefaultProperties is a map of all valid logs properties with corresponding default property values
DefaultProperties = map[string]string{
"max-size": "",
"vector-sink": "",

View File

@@ -3,3 +3,4 @@
/triggers/*
/triggers
/pre-delete
/post-stack-set

View File

@@ -1,5 +1,5 @@
SUBCOMMANDS = subcommands/gc subcommands/purge-cache
TRIGGERS = triggers/pre-delete
TRIGGERS = triggers/post-stack-set triggers/pre-delete
BUILD = commands subcommands triggers
PLUGIN_NAME = repo

View File

@@ -18,6 +18,9 @@ func main() {
var err error
switch trigger {
case "post-stack-set":
appName := flag.Arg(0)
err = repo.PurgeCache(appName)
case "pre-delete":
appName := flag.Arg(0)
err = repo.PurgeCache(appName)