refactor: decrease compile time for golang plugins

This change refactors the compiled golang plugins into 3 distinct binaries:

- commands: already existing
- subcommands/subcommands: entrypoint into all subcommands
- triggers: entrypoint into all triggers

It then further symlinks triggers and subcommands to the built binaries. This results in both a much faster build process as well as smaller package size.
This commit is contained in:
Jose Diaz-Gonzalez
2019-09-07 04:47:18 -04:00
parent f83a03a3dc
commit 6a7d2e5252
73 changed files with 865 additions and 1179 deletions

View File

@@ -1,4 +1,41 @@
GO_ARGS ?= -a
GO_REPO_ROOT := /go/src/github.com/dokku/dokku
BUILD_IMAGE := golang:1.12
.PHONY: build-in-docker build clean src-clean
build: $(BUILD)
build-in-docker: clean
mkdir -p /tmp/dokku-go-build-cache
docker run --rm \
-v $$PWD/../..:$(GO_REPO_ROOT) \
-v /tmp/dokku-go-build-cache:/root/.cache/go-build \
-e PLUGIN_NAME=$(PLUGIN_NAME) \
-w $(GO_REPO_ROOT)/plugins/$(PLUGIN_NAME) \
$(BUILD_IMAGE) \
bash -c "GO_ARGS='$(GO_ARGS)' make -j4 build" || exit $$?
clean:
rm -rf commands subcommands triggers
find . -xtype l -delete
commands: **/**/commands.go
go build $(GO_ARGS) -o commands src/commands/commands.go
subcommands:
go build $(GO_ARGS) -o subcommands/subcommands src/subcommands/subcommands.go
$(MAKE) $(SUBCOMMANDS)
subcommands/%:
ln -sf subcommands $@
src-clean:
rm -rf .gitignore src vendor Makefile *.go glide.*
triggers:
go build $(GO_ARGS) -o triggers src/triggers/triggers.go
$(MAKE) $(TRIGGERS)
triggers/%:
ln -sf triggers $(shell echo $@ | cut -d '/' -f2)

View File

@@ -1,6 +1,7 @@
/commands
/subcommands/*
/triggers/*
/triggers
/install
/post-delete
/post-extract

View File

@@ -1,37 +1,6 @@
include ../../common.mk
GO_ARGS ?= -a
SUBCOMMANDS = subcommands/add subcommands/clear subcommands/list subcommands/remove subcommands/report subcommands/set
TRIGGERS = triggers/install triggers/post-delete triggers/post-extract triggers/report
build-in-docker: clean
docker run --rm \
-v $$PWD/../..:$(GO_REPO_ROOT) \
-w $(GO_REPO_ROOT)/plugins/buildpacks \
$(BUILD_IMAGE) \
bash -c "GO_ARGS='$(GO_ARGS)' make -j4 build" || exit $$?
BUILD = commands subcommands triggers
PLUGIN_NAME = buildpacks
build: commands subcommands triggers
$(MAKE) triggers-copy
commands: **/**/commands.go
go build $(GO_ARGS) -o commands src/commands/commands.go
subcommands: $(SUBCOMMANDS)
subcommands/%: src/subcommands/*/%.go
go build $(GO_ARGS) -o $@ $<
clean:
rm -rf commands subcommands triggers install post-delete post-extract report
src-clean:
rm -rf .gitignore src triggers vendor Makefile *.go glide.*
triggers: $(TRIGGERS)
triggers/%: src/triggers/*/%.go
go build $(GO_ARGS) -o $@ $<
triggers-copy:
cp triggers/* .
include ../../common.mk

View File

@@ -1,19 +0,0 @@
package main
import (
"flag"
"os"
"github.com/dokku/dokku/plugins/buildpacks"
"github.com/dokku/dokku/plugins/common"
)
func main() {
args := flag.NewFlagSet("buildpacks:add", flag.ExitOnError)
index := args.Int("index", 0, "--index: the 1-based index of the URL in the list of URLs")
args.Parse(os.Args[2:])
err := buildpacks.CommandAdd(args.Args(), *index)
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -1,18 +0,0 @@
package main
import (
"flag"
"os"
"github.com/dokku/dokku/plugins/buildpacks"
"github.com/dokku/dokku/plugins/common"
)
func main() {
args := flag.NewFlagSet("buildpacks:clear", flag.ExitOnError)
args.Parse(os.Args[2:])
err := buildpacks.CommandClear(args.Args())
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -1,14 +0,0 @@
package main
import (
"flag"
"os"
"github.com/dokku/dokku/plugins/buildpacks"
)
func main() {
args := flag.NewFlagSet("buildpacks:list", flag.ExitOnError)
args.Parse(os.Args[2:])
buildpacks.CommandList(args.Args())
}

View File

@@ -1,19 +0,0 @@
package main
import (
"flag"
"os"
"github.com/dokku/dokku/plugins/buildpacks"
"github.com/dokku/dokku/plugins/common"
)
func main() {
args := flag.NewFlagSet("buildpacks:remove", flag.ExitOnError)
index := args.Int("index", 0, "--index: the 1-based index of the URL in the list of URLs")
args.Parse(os.Args[2:])
err := buildpacks.CommandRemove(args.Args(), *index)
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -1,34 +0,0 @@
package main
import (
"flag"
"strings"
"github.com/dokku/dokku/plugins/buildpacks"
"github.com/dokku/dokku/plugins/common"
)
// displays a buildpacks report for one or more apps
func main() {
flag.Parse()
appName := flag.Arg(1)
infoFlag := flag.Arg(2)
if strings.HasPrefix(appName, "--") {
infoFlag = appName
appName = ""
}
if len(appName) == 0 {
apps, err := common.DokkuApps()
if err != nil {
return
}
for _, appName := range apps {
buildpacks.ReportSingleApp(appName, infoFlag)
}
return
}
buildpacks.ReportSingleApp(appName, infoFlag)
}

View File

@@ -1,19 +0,0 @@
package main
import (
"flag"
"os"
"github.com/dokku/dokku/plugins/buildpacks"
"github.com/dokku/dokku/plugins/common"
)
func main() {
args := flag.NewFlagSet("buildpacks:set", flag.ExitOnError)
index := args.Int("index", 0, "--index: the 1-based index of the URL in the list of URLs")
args.Parse(os.Args[2:])
err := buildpacks.CommandSet(args.Args(), *index)
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -0,0 +1,55 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
"github.com/dokku/dokku/plugins/buildpacks"
"github.com/dokku/dokku/plugins/common"
)
// main entrypoint to all subcommands
func main() {
parts := strings.Split(os.Args[0], "/")
subcommand := parts[len(parts)-1]
var err error
switch subcommand {
case "add":
args := flag.NewFlagSet("buildpacks:add", flag.ExitOnError)
index := args.Int("index", 0, "--index: the 1-based index of the URL in the list of URLs")
args.Parse(os.Args[2:])
err = buildpacks.CommandAdd(args.Args(), *index)
case "clear":
args := flag.NewFlagSet("buildpacks:clear", flag.ExitOnError)
args.Parse(os.Args[2:])
err = buildpacks.CommandClear(args.Args())
case "list":
args := flag.NewFlagSet("buildpacks:list", flag.ExitOnError)
args.Parse(os.Args[2:])
buildpacks.CommandList(args.Args())
case "remove":
args := flag.NewFlagSet("buildpacks:remove", flag.ExitOnError)
index := args.Int("index", 0, "--index: the 1-based index of the URL in the list of URLs")
args.Parse(os.Args[2:])
err = buildpacks.CommandRemove(args.Args(), *index)
case "report":
flag.Parse()
appName := flag.Arg(1)
infoFlag := flag.Arg(2)
buildpacks.CommandReport(appName, infoFlag)
case "set":
args := flag.NewFlagSet("buildpacks:set", flag.ExitOnError)
index := args.Int("index", 0, "--index: the 1-based index of the URL in the list of URLs")
args.Parse(os.Args[2:])
err = buildpacks.CommandSet(args.Args(), *index)
default:
common.LogFail(fmt.Sprintf("Invalid plugin subcommand call: %s", subcommand))
}
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -1,14 +0,0 @@
package main
import (
"fmt"
"github.com/dokku/dokku/plugins/common"
)
// runs the install step for the buildpacks plugin
func main() {
if err := common.PropertySetup("buildpacks"); err != nil {
common.LogFail(fmt.Sprintf("Unable to install the buildpacks plugin: %s", err.Error()))
}
}

View File

@@ -1,18 +0,0 @@
package main
import (
"flag"
"github.com/dokku/dokku/plugins/common"
)
// destroys the buildpacks property for a given app container
func main() {
flag.Parse()
appName := flag.Arg(0)
err := common.PropertyDestroy("buildpacks", appName)
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -1,15 +0,0 @@
package main
import (
"flag"
"github.com/dokku/dokku/plugins/buildpacks"
)
// displays a buildpacks report for one or more apps
func main() {
flag.Parse()
appName := flag.Arg(0)
buildpacks.ReportSingleApp(appName, "")
}

View File

@@ -0,0 +1,35 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
"github.com/dokku/dokku/plugins/buildpacks"
"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()
switch trigger {
case "install":
buildpacks.TriggerInstall()
case "post-delete":
appName := flag.Arg(0)
buildpacks.TriggerPostDelete(appName)
case "post-extract":
appName := flag.Arg(0)
sourceWorkDir := flag.Arg(1)
buildpacks.TriggerPostExtract(appName, sourceWorkDir)
case "report":
appName := flag.Arg(0)
buildpacks.ReportSingleApp(appName, "")
default:
common.LogFail(fmt.Sprintf("Invalid plugin trigger call: %s", trigger))
}
}

View File

@@ -3,6 +3,7 @@ package buildpacks
import (
"errors"
"fmt"
"strings"
"github.com/dokku/dokku/plugins/common"
)
@@ -115,6 +116,27 @@ func CommandRemove(args []string, index int) (err error) {
return
}
// CommandReport displays a buildpacks report for one or more apps
func CommandReport(appName string, infoFlag string) {
if strings.HasPrefix(appName, "--") {
infoFlag = appName
appName = ""
}
if len(appName) == 0 {
apps, err := common.DokkuApps()
if err != nil {
return
}
for _, appName := range apps {
ReportSingleApp(appName, infoFlag)
}
return
}
ReportSingleApp(appName, infoFlag)
}
// CommandSet implements buildpacks:set
func CommandSet(args []string, index int) (err error) {
var appName string

View File

@@ -1,8 +1,7 @@
package main
package buildpacks
import (
"bufio"
"flag"
"fmt"
"os"
"path"
@@ -10,12 +9,23 @@ import (
"github.com/dokku/dokku/plugins/common"
)
// writes a .buildpacks file into the app
func main() {
flag.Parse()
appName := flag.Arg(0)
tmpWorkDir := flag.Arg(1)
// 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()))
}
}
// 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())
}
}
// writes a .buildpacks file into the app
func TriggerPostExtract(appName string, sourceWorkDir string) {
buildpacks, err := common.PropertyListGet("buildpacks", appName, "buildpacks")
if err != nil {
return
@@ -25,7 +35,7 @@ func main() {
return
}
buildpacksPath := path.Join(tmpWorkDir, ".buildpacks")
buildpacksPath := path.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()))

View File

@@ -1,2 +1,4 @@
/commands
/subcommands/*
/triggers/*
/triggers

View File

@@ -1,28 +1,5 @@
include ../../common.mk
GO_ARGS ?= -a
SUBCOMMANDS = subcommands/export subcommands/get subcommands/set subcommands/unset subcommands/keys subcommands/bundle
BUILD = commands subcommands
PLUGIN_NAME = config
build-in-docker: clean
docker run --rm \
-v $$PWD/../..:$(GO_REPO_ROOT) \
-w $(GO_REPO_ROOT)/plugins/config \
$(BUILD_IMAGE) \
bash -c "GO_ARGS='$(GO_ARGS)' make -j4 build" || exit $$?
build: commands subcommands
commands: **/**/commands.go
go build $(GO_ARGS) -o commands src/commands/commands.go
subcommands: $(SUBCOMMANDS)
subcommands/%: src/subcommands/*/%.go
go build $(GO_ARGS) -o $@ $<
clean:
rm -rf commands subcommands
src-clean:
rm -rf .gitignore src triggers vendor Makefile *.go glide.*
include ../../common.mk

View File

@@ -1,16 +0,0 @@
package main
import (
"flag"
"os"
"github.com/dokku/dokku/plugins/config"
)
func main() {
args := flag.NewFlagSet("config:bundle", flag.ExitOnError)
global := args.Bool("global", false, "--global: use the global environment")
merged := args.Bool("merged", false, "--merged: merge app environment and global environment")
args.Parse(os.Args[2:])
config.CommandBundle(args.Args(), *global, *merged)
}

View File

@@ -1,17 +0,0 @@
package main
import (
"flag"
"os"
"github.com/dokku/dokku/plugins/config"
)
//clear all entries from the given environment
func main() {
args := flag.NewFlagSet("config:clear", flag.ExitOnError)
global := args.Bool("global", false, "--global: use the global environment")
noRestart := args.Bool("no-restart", false, "--no-restart: no restart")
args.Parse(os.Args[2:])
config.CommandClear(args.Args(), *global, *noRestart)
}

View File

@@ -1,20 +0,0 @@
package main
import (
"flag"
"os"
"github.com/dokku/dokku/plugins/config"
)
// print the environment to stdout
func main() {
const defaultPrefix = "export "
const defaultSeparator = "\n"
args := flag.NewFlagSet("config:export", flag.ExitOnError)
global := args.Bool("global", false, "--global: use the global environment")
merged := args.Bool("merged", false, "--merged: merge app environment and global environment")
format := args.String("format", "exports", "--format: [ exports | envfile | docker-args | shell | pretty | json | json-list ] which format to export as)")
args.Parse(os.Args[2:])
config.CommandExport(args.Args(), *global, *merged, *format)
}

View File

@@ -1,17 +0,0 @@
package main
import (
"flag"
"os"
"github.com/dokku/dokku/plugins/config"
)
// get the given entries from the specified environment
func main() {
args := flag.NewFlagSet("config:get", flag.ExitOnError)
global := args.Bool("global", false, "--global: use the global environment")
quoted := args.Bool("quoted", false, "--quoted: get the value quoted")
args.Parse(os.Args[2:])
config.CommandGet(args.Args(), *global, *quoted)
}

View File

@@ -1,16 +0,0 @@
package main
import (
"flag"
"os"
"github.com/dokku/dokku/plugins/config"
)
func main() {
args := flag.NewFlagSet("config:keys", flag.ExitOnError)
global := args.Bool("global", false, "--global: use the global environment")
merged := args.Bool("merged", false, "--merged: merge app environment and global environment")
args.Parse(os.Args[2:])
config.CommandKeys(args.Args(), *global, *merged)
}

View File

@@ -1,18 +0,0 @@
package main
import (
"flag"
"os"
"github.com/dokku/dokku/plugins/config"
)
// set the given entries to the specified environment
func main() {
args := flag.NewFlagSet("config:set", flag.ExitOnError)
global := args.Bool("global", false, "--global: use the global environment")
encoded := args.Bool("encoded", false, "--encoded: interpret VALUEs as base64")
noRestart := args.Bool("no-restart", false, "--no-restart: no restart")
args.Parse(os.Args[2:])
config.CommandSet(args.Args(), *global, *noRestart, *encoded)
}

View File

@@ -0,0 +1,67 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/config"
)
// main entrypoint to all subcommands
func main() {
parts := strings.Split(os.Args[0], "/")
subcommand := parts[len(parts)-1]
switch subcommand {
case "bundle":
args := flag.NewFlagSet("config:bundle", flag.ExitOnError)
global := args.Bool("global", false, "--global: use the global environment")
merged := args.Bool("merged", false, "--merged: merge app environment and global environment")
args.Parse(os.Args[2:])
config.CommandBundle(args.Args(), *global, *merged)
case "clear":
args := flag.NewFlagSet("config:clear", flag.ExitOnError)
global := args.Bool("global", false, "--global: use the global environment")
noRestart := args.Bool("no-restart", false, "--no-restart: no restart")
args.Parse(os.Args[2:])
config.CommandClear(args.Args(), *global, *noRestart)
case "export":
args := flag.NewFlagSet("config:export", flag.ExitOnError)
global := args.Bool("global", false, "--global: use the global environment")
merged := args.Bool("merged", false, "--merged: merge app environment and global environment")
format := args.String("format", "exports", "--format: [ exports | envfile | docker-args | shell | pretty | json | json-list ] which format to export as)")
args.Parse(os.Args[2:])
config.CommandExport(args.Args(), *global, *merged, *format)
case "get":
args := flag.NewFlagSet("config:get", flag.ExitOnError)
global := args.Bool("global", false, "--global: use the global environment")
quoted := args.Bool("quoted", false, "--quoted: get the value quoted")
args.Parse(os.Args[2:])
config.CommandGet(args.Args(), *global, *quoted)
case "keys":
args := flag.NewFlagSet("config:keys", flag.ExitOnError)
global := args.Bool("global", false, "--global: use the global environment")
merged := args.Bool("merged", false, "--merged: merge app environment and global environment")
args.Parse(os.Args[2:])
config.CommandKeys(args.Args(), *global, *merged)
case "set":
args := flag.NewFlagSet("config:set", flag.ExitOnError)
global := args.Bool("global", false, "--global: use the global environment")
encoded := args.Bool("encoded", false, "--encoded: interpret VALUEs as base64")
noRestart := args.Bool("no-restart", false, "--no-restart: no restart")
args.Parse(os.Args[2:])
config.CommandSet(args.Args(), *global, *noRestart, *encoded)
case "unset":
args := flag.NewFlagSet("config:unset", flag.ExitOnError)
global := args.Bool("global", false, "--global: use the global environment")
noRestart := args.Bool("no-restart", false, "--no-restart: no restart")
args.Parse(os.Args[2:])
config.CommandUnset(args.Args(), *global, *noRestart)
default:
common.LogFail(fmt.Sprintf("Invalid plugin subcommand call: %s", subcommand))
}
}

View File

@@ -1,17 +0,0 @@
package main
import (
"flag"
"os"
"github.com/dokku/dokku/plugins/config"
)
//unset the given entries from the given environment
func main() {
args := flag.NewFlagSet("config:unset", flag.ExitOnError)
global := args.Bool("global", false, "--global: use the global environment")
noRestart := args.Bool("no-restart", false, "--no-restart: no restart")
args.Parse(os.Args[2:])
config.CommandUnset(args.Args(), *global, *noRestart)
}

View File

@@ -1,6 +1,7 @@
/commands
/subcommands/*
/triggers/*
/triggers
/network-*
/install
/post-app-clone-setup

View File

@@ -1,37 +1,6 @@
include ../../common.mk
GO_ARGS ?= -a
SUBCOMMANDS = subcommands/rebuild subcommands/rebuildall subcommands/report subcommands/set
TRIGGERS = triggers/install triggers/network-build-config triggers/network-compute-ports triggers/network-config-exists triggers/network-get-ipaddr triggers/network-get-listeners triggers/network-get-port triggers/network-get-property triggers/network-write-ipaddr triggers/network-write-port triggers/post-app-clone-setup triggers/post-create triggers/post-delete triggers/report
build-in-docker: clean
docker run --rm \
-v $$PWD/../..:$(GO_REPO_ROOT) \
-w $(GO_REPO_ROOT)/plugins/network \
$(BUILD_IMAGE) \
bash -c "GO_ARGS='$(GO_ARGS)' make -j4 build" || exit $$?
BUILD = commands subcommands triggers
PLUGIN_NAME = network
build: commands subcommands triggers
$(MAKE) triggers-copy
commands: **/**/commands.go
go build $(GO_ARGS) -o commands src/commands/commands.go
subcommands: $(SUBCOMMANDS)
subcommands/%: src/subcommands/*/%.go
go build $(GO_ARGS) -o $@ $<
clean:
rm -rf commands subcommands triggers network-* install post-app-clone-setup post-create post-delete report
src-clean:
rm -rf .gitignore src triggers vendor Makefile *.go glide.*
triggers: $(TRIGGERS)
triggers/%: src/triggers/*/%.go
go build $(GO_ARGS) -o $@ $<
triggers-copy:
cp triggers/* .
include ../../common.mk

View File

@@ -1,15 +0,0 @@
package main
import (
"flag"
"github.com/dokku/dokku/plugins/network"
)
// rebuilds network settings for an app
func main() {
flag.Parse()
appName := flag.Arg(1)
network.BuildConfig(appName)
}

View File

@@ -1,17 +0,0 @@
package main
import (
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/network"
)
// rebuilds network settings for all apps
func main() {
apps, err := common.DokkuApps()
if err != nil {
common.LogFail(err.Error())
}
for _, appName := range apps {
network.BuildConfig(appName)
}
}

View File

@@ -1,34 +0,0 @@
package main
import (
"flag"
"strings"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/network"
)
// displays a network report for one or more apps
func main() {
flag.Parse()
appName := flag.Arg(1)
infoFlag := flag.Arg(2)
if strings.HasPrefix(appName, "--") {
infoFlag = appName
appName = ""
}
if len(appName) == 0 {
apps, err := common.DokkuApps()
if err != nil {
return
}
for _, appName := range apps {
network.ReportSingleApp(appName, infoFlag)
}
return
}
network.ReportSingleApp(appName, infoFlag)
}

View File

@@ -1,22 +0,0 @@
package main
import (
"flag"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/network"
)
// set or clear a network property for an app
func main() {
flag.Parse()
appName := flag.Arg(1)
property := flag.Arg(2)
value := flag.Arg(3)
if property == "bind-all-interfaces" && value == "" {
value = "false"
}
common.CommandPropertySet("network", appName, property, value, network.DefaultProperties)
}

View File

@@ -0,0 +1,37 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/network"
)
// main entrypoint to all subcommands
func main() {
parts := strings.Split(os.Args[0], "/")
subcommand := parts[len(parts)-1]
flag.Parse()
switch subcommand {
case "rebuild":
appName := flag.Arg(1)
network.BuildConfig(appName)
case "rebuildall":
network.CommandRebuildall()
case "report":
appName := flag.Arg(1)
infoFlag := flag.Arg(2)
network.CommandReport(appName, infoFlag)
case "set":
appName := flag.Arg(1)
property := flag.Arg(2)
value := flag.Arg(3)
network.CommandSet(appName, property, value)
default:
common.LogFail(fmt.Sprintf("Invalid plugin subcommand call: %s", subcommand))
}
}

View File

@@ -1,36 +0,0 @@
package main
import (
"fmt"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/proxy"
)
// runs the install step for the network plugin
func main() {
if err := common.PropertySetup("network"); err != nil {
common.LogFail(fmt.Sprintf("Unable to install the network plugin: %s", err.Error()))
}
apps, err := common.DokkuApps()
if err != nil {
return
}
for _, appName := range apps {
if common.PropertyExists("network", appName, "bind-all-interfaces") {
continue
}
if proxy.IsAppProxyEnabled(appName) {
common.LogVerboseQuiet("Setting network property 'bind-all-interfaces' to false")
if err := common.PropertyWrite("network", appName, "bind-all-interfaces", "false"); err != nil {
common.LogWarn(err.Error())
}
} else {
common.LogVerboseQuiet("Setting network property 'bind-all-interfaces' to true")
if err := common.PropertyWrite("network", appName, "bind-all-interfaces", "true"); err != nil {
common.LogWarn(err.Error())
}
}
}
}

View File

@@ -1,15 +0,0 @@
package main
import (
"flag"
"github.com/dokku/dokku/plugins/network"
)
// rebuilds network settings for an app
func main() {
flag.Parse()
appName := flag.Arg(0)
network.BuildConfig(appName)
}

View File

@@ -1,46 +0,0 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
"unicode/utf8"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/config"
)
// computes the ports for a given app container
func main() {
flag.Parse()
appName := flag.Arg(0)
processType := flag.Arg(1)
isHerokuishContainer := common.ToBool(flag.Arg(2))
if processType != "web" {
return
}
var dockerfilePorts []string
if !isHerokuishContainer {
dokkuDockerfilePorts := strings.Trim(config.GetWithDefault(appName, "DOKKU_DOCKERFILE_PORTS", ""), " ")
if utf8.RuneCountInString(dokkuDockerfilePorts) > 0 {
dockerfilePorts = strings.Split(dokkuDockerfilePorts, " ")
}
}
var ports []string
if len(dockerfilePorts) == 0 {
ports = append(ports, "5000")
} else {
for _, port := range dockerfilePorts {
port = strings.TrimSuffix(strings.TrimSpace(port), "/tcp")
if port == "" || strings.HasSuffix(port, "/udp") {
continue
}
ports = append(ports, port)
}
}
fmt.Fprint(os.Stdout, strings.Join(ports, " "))
}

View File

@@ -1,22 +0,0 @@
package main
import (
"flag"
"fmt"
"os"
"github.com/dokku/dokku/plugins/network"
)
// writes true or false to stdout whether a given app has network config
func main() {
flag.Parse()
appName := flag.Arg(0)
if network.HasNetworkConfig(appName) {
fmt.Fprintln(os.Stdout, "true")
return
}
fmt.Fprintln(os.Stdout, "false")
}

View File

@@ -1,20 +0,0 @@
package main
import (
"flag"
"fmt"
"os"
"github.com/dokku/dokku/plugins/network"
)
// write the ipaddress to stdout for a given app container
func main() {
flag.Parse()
appName := flag.Arg(0)
processType := flag.Arg(1)
containerID := flag.Arg(2)
ipAddress := network.GetContainerIpaddress(appName, processType, containerID)
fmt.Fprintln(os.Stdout, ipAddress)
}

View File

@@ -1,19 +0,0 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
"github.com/dokku/dokku/plugins/network"
)
// returns the listeners (host:port combinations) for a given app container
func main() {
flag.Parse()
appName := flag.Arg(0)
listeners := network.GetListeners(appName)
fmt.Fprint(os.Stdout, strings.Join(listeners, " "))
}

View File

@@ -1,22 +0,0 @@
package main
import (
"flag"
"fmt"
"os"
"github.com/dokku/dokku/plugins/common"
network "github.com/dokku/dokku/plugins/network"
)
// write the port to stdout for a given app container
func main() {
flag.Parse()
appName := flag.Arg(0)
processType := flag.Arg(1)
isHerokuishContainer := common.ToBool(flag.Arg(2))
containerID := flag.Arg(3)
port := network.GetContainerPort(appName, processType, isHerokuishContainer, containerID)
fmt.Fprintln(os.Stdout, port)
}

View File

@@ -1,21 +0,0 @@
package main
import (
"flag"
"fmt"
"os"
"github.com/dokku/dokku/plugins/common"
network "github.com/dokku/dokku/plugins/network"
)
// writes the network property to stdout for a given app container
func main() {
flag.Parse()
appName := flag.Arg(0)
property := flag.Arg(1)
defaultValue := network.GetDefaultValue(property)
value := common.PropertyGetDefault("network", appName, property, defaultValue)
fmt.Fprintln(os.Stdout, value)
}

View File

@@ -1,41 +0,0 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
"github.com/dokku/dokku/plugins/common"
)
// writes the ip to disk
func main() {
flag.Parse()
appName := flag.Arg(0)
processType := flag.Arg(1)
containerIndex := flag.Arg(2)
ip := flag.Arg(3)
if appName == "" {
common.LogFail("Please specify an app to run the command on")
}
err := common.VerifyAppName(appName)
if err != nil {
common.LogFail(err.Error())
}
appRoot := strings.Join([]string{common.MustGetEnv("DOKKU_ROOT"), appName}, "/")
filename := fmt.Sprintf("%v/IP.%v.%v", appRoot, processType, containerIndex)
f, err := os.Create(filename)
if err != nil {
common.LogFail(err.Error())
}
defer f.Close()
ipBytes := []byte(ip)
_, err = f.Write(ipBytes)
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -1,41 +0,0 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
"github.com/dokku/dokku/plugins/common"
)
// writes the port to disk
func main() {
flag.Parse()
appName := flag.Arg(0)
processType := flag.Arg(1)
containerIndex := flag.Arg(2)
port := flag.Arg(3)
if appName == "" {
common.LogFail("Please specify an app to run the command on")
}
err := common.VerifyAppName(appName)
if err != nil {
common.LogFail(err.Error())
}
appRoot := strings.Join([]string{common.MustGetEnv("DOKKU_ROOT"), appName}, "/")
filename := fmt.Sprintf("%v/PORT.%v.%v", appRoot, processType, containerIndex)
f, err := os.Create(filename)
if err != nil {
common.LogFail(err.Error())
}
defer f.Close()
portBytes := []byte(port)
_, err = f.Write(portBytes)
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -1,19 +0,0 @@
package main
import (
"flag"
"os"
"github.com/dokku/dokku/plugins/network"
)
// cleanup network files for a new app clone
func main() {
flag.Parse()
appName := flag.Arg(1)
success := network.PostAppCloneSetup(appName)
if !success {
os.Exit(1)
}
}

View File

@@ -1,18 +0,0 @@
package main
import (
"flag"
"github.com/dokku/dokku/plugins/common"
)
// set bind-all-interfaces to false by default
func main() {
flag.Parse()
appName := flag.Arg(0)
err := common.PropertyWrite("network", appName, "bind-all-interfaces", "false")
if err != nil {
common.LogWarn(err.Error())
}
}

View File

@@ -1,18 +0,0 @@
package main
import (
"flag"
"github.com/dokku/dokku/plugins/common"
)
// destroys the network property for a given app container
func main() {
flag.Parse()
appName := flag.Arg(0)
err := common.PropertyDestroy("network", appName)
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -1,15 +0,0 @@
package main
import (
"flag"
"github.com/dokku/dokku/plugins/network"
)
// displays a network report for one or more apps
func main() {
flag.Parse()
appName := flag.Arg(0)
network.ReportSingleApp(appName, "")
}

View File

@@ -0,0 +1,78 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/network"
)
// main entrypoint to all triggers
func main() {
parts := strings.Split(os.Args[0], "/")
trigger := parts[len(parts)-1]
flag.Parse()
switch trigger {
case "install":
network.TriggerInstall()
case "network-build-config":
appName := flag.Arg(0)
network.BuildConfig(appName)
case "network-compute-ports":
appName := flag.Arg(0)
processType := flag.Arg(1)
isHerokuishContainer := common.ToBool(flag.Arg(2))
network.TriggerNetworkComputePorts(appName, processType, isHerokuishContainer)
case "network-config-exists":
appName := flag.Arg(0)
network.TriggerNetworkConfigExists(appName)
case "network-get-ipaddr":
appName := flag.Arg(0)
processType := flag.Arg(1)
containerID := flag.Arg(2)
network.TriggerNetworkGetIppaddr(appName, processType, containerID)
case "network-get-listeners":
appName := flag.Arg(0)
network.TriggerNetworkGetListeners(appName)
case "network-get-port":
appName := flag.Arg(0)
processType := flag.Arg(1)
isHerokuishContainer := common.ToBool(flag.Arg(2))
containerID := flag.Arg(3)
network.TriggerNetworkGetPort(appName, processType, isHerokuishContainer, containerID)
case "network-get-property":
appName := flag.Arg(0)
property := flag.Arg(1)
network.TriggerNetworkGetProperty(appName, property)
case "network-write-ipaddr":
appName := flag.Arg(0)
processType := flag.Arg(1)
containerIndex := flag.Arg(2)
ip := flag.Arg(3)
network.TriggerNetworkWriteIpaddr(appName, processType, containerIndex, ip)
case "network-write-port":
appName := flag.Arg(0)
processType := flag.Arg(1)
containerIndex := flag.Arg(2)
port := flag.Arg(3)
network.TriggerNetworkWritePort(appName, processType, containerIndex, port)
case "post-app-clone-setup":
appName := flag.Arg(1)
network.TriggerPostAppCloneSetup(appName)
case "post-create":
appName := flag.Arg(0)
network.TriggerPostCreate(appName)
case "post-delete":
appName := flag.Arg(0)
network.TriggerPostDelete(appName)
case "report":
appName := flag.Arg(0)
network.ReportSingleApp(appName, "")
default:
common.LogFail(fmt.Sprintf("Invalid plugin trigger call: %s", trigger))
}
}

View File

@@ -0,0 +1,48 @@
package network
import (
"strings"
"github.com/dokku/dokku/plugins/common"
)
// rebuilds network settings for all apps
func CommandRebuildall() {
apps, err := common.DokkuApps()
if err != nil {
common.LogFail(err.Error())
}
for _, appName := range apps {
BuildConfig(appName)
}
}
// displays a network report for one or more apps
func CommandReport(appName string, infoFlag string) {
if strings.HasPrefix(appName, "--") {
infoFlag = appName
appName = ""
}
if len(appName) == 0 {
apps, err := common.DokkuApps()
if err != nil {
return
}
for _, appName := range apps {
ReportSingleApp(appName, infoFlag)
}
return
}
ReportSingleApp(appName, infoFlag)
}
// set or clear a network property for an app
func CommandSet(appName string, property string, value string) {
if property == "bind-all-interfaces" && value == "" {
value = "false"
}
common.CommandPropertySet("network", appName, property, value, DefaultProperties)
}

178
plugins/network/triggers.go Normal file
View File

@@ -0,0 +1,178 @@
package network
import (
"fmt"
"os"
"strings"
"unicode/utf8"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/config"
"github.com/dokku/dokku/plugins/proxy"
)
// runs the install step for the network plugin
func TriggerInstall() {
if err := common.PropertySetup("network"); err != nil {
common.LogFail(fmt.Sprintf("Unable to install the network plugin: %s", err.Error()))
}
apps, err := common.DokkuApps()
if err != nil {
return
}
for _, appName := range apps {
if common.PropertyExists("network", appName, "bind-all-interfaces") {
continue
}
if proxy.IsAppProxyEnabled(appName) {
common.LogVerboseQuiet("Setting network property 'bind-all-interfaces' to false")
if err := common.PropertyWrite("network", appName, "bind-all-interfaces", "false"); err != nil {
common.LogWarn(err.Error())
}
} else {
common.LogVerboseQuiet("Setting network property 'bind-all-interfaces' to true")
if err := common.PropertyWrite("network", appName, "bind-all-interfaces", "true"); err != nil {
common.LogWarn(err.Error())
}
}
}
}
// computes the ports for a given app container
func TriggerNetworkComputePorts(appName string, processType string, isHerokuishContainer bool) {
if processType != "web" {
return
}
var dockerfilePorts []string
if !isHerokuishContainer {
dokkuDockerfilePorts := strings.Trim(config.GetWithDefault(appName, "DOKKU_DOCKERFILE_PORTS", ""), " ")
if utf8.RuneCountInString(dokkuDockerfilePorts) > 0 {
dockerfilePorts = strings.Split(dokkuDockerfilePorts, " ")
}
}
var ports []string
if len(dockerfilePorts) == 0 {
ports = append(ports, "5000")
} else {
for _, port := range dockerfilePorts {
port = strings.TrimSuffix(strings.TrimSpace(port), "/tcp")
if port == "" || strings.HasSuffix(port, "/udp") {
continue
}
ports = append(ports, port)
}
}
fmt.Fprint(os.Stdout, strings.Join(ports, " "))
}
// writes true or false to stdout whether a given app has network config
func TriggerNetworkConfigExists(appName string) {
if HasNetworkConfig(appName) {
fmt.Fprintln(os.Stdout, "true")
return
}
fmt.Fprintln(os.Stdout, "false")
}
// write the ipaddress to stdout for a given app container
func TriggerNetworkGetIppaddr(appName string, processType string, containerID string) {
ipAddress := GetContainerIpaddress(appName, processType, containerID)
fmt.Fprintln(os.Stdout, ipAddress)
}
// returns the listeners (host:port combinations) for a given app container
func TriggerNetworkGetListeners(appName string) {
listeners := GetListeners(appName)
fmt.Fprint(os.Stdout, strings.Join(listeners, " "))
}
// write the port to stdout for a given app container
func TriggerNetworkGetPort(appName string, processType string, isHerokuishContainer bool, containerID string) {
port := GetContainerPort(appName, processType, isHerokuishContainer, containerID)
fmt.Fprintln(os.Stdout, port)
}
// writes the network property to stdout for a given app container
func TriggerNetworkGetProperty(appName string, property string) {
defaultValue := GetDefaultValue(property)
value := common.PropertyGetDefault("network", appName, property, defaultValue)
fmt.Fprintln(os.Stdout, value)
}
// writes the ip to disk
func TriggerNetworkWriteIpaddr(appName string, processType string, containerIndex string, ip string) {
if appName == "" {
common.LogFail("Please specify an app to run the command on")
}
err := common.VerifyAppName(appName)
if err != nil {
common.LogFail(err.Error())
}
appRoot := strings.Join([]string{common.MustGetEnv("DOKKU_ROOT"), appName}, "/")
filename := fmt.Sprintf("%v/IP.%v.%v", appRoot, processType, containerIndex)
f, err := os.Create(filename)
if err != nil {
common.LogFail(err.Error())
}
defer f.Close()
ipBytes := []byte(ip)
_, err = f.Write(ipBytes)
if err != nil {
common.LogFail(err.Error())
}
}
// writes the port to disk
func TriggerNetworkWritePort(appName string, processType string, containerIndex string, port string) {
if appName == "" {
common.LogFail("Please specify an app to run the command on")
}
err := common.VerifyAppName(appName)
if err != nil {
common.LogFail(err.Error())
}
appRoot := strings.Join([]string{common.MustGetEnv("DOKKU_ROOT"), appName}, "/")
filename := fmt.Sprintf("%v/PORT.%v.%v", appRoot, processType, containerIndex)
f, err := os.Create(filename)
if err != nil {
common.LogFail(err.Error())
}
defer f.Close()
portBytes := []byte(port)
_, err = f.Write(portBytes)
if err != nil {
common.LogFail(err.Error())
}
}
// cleanup network files for a new app clone
func TriggerPostAppCloneSetup(appName string) {
success := PostAppCloneSetup(appName)
if !success {
os.Exit(1)
}
}
// set bind-all-interfaces to false by default
func TriggerPostCreate(appName string) {
err := common.PropertyWrite("network", appName, "bind-all-interfaces", "false")
if err != nil {
common.LogWarn(err.Error())
}
}
// destroys the network property for a given app container
func TriggerPostDelete(appName string) {
err := common.PropertyDestroy("network", appName)
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -1,2 +1,4 @@
/commands
/subcommands/*
/triggers/*
/triggers

View File

@@ -1,37 +1,6 @@
include ../../common.mk
GO_ARGS ?= -a
SUBCOMMANDS = subcommands/gc subcommands/purge-cache
TRIGGERS = triggers/pre-delete
build-in-docker: clean
docker run --rm \
-v $$PWD/../..:$(GO_REPO_ROOT) \
-w $(GO_REPO_ROOT)/plugins/repo \
$(BUILD_IMAGE) \
bash -c "GO_ARGS='$(GO_ARGS)' make -j4 build" || exit $$?
BUILD = commands subcommands triggers
PLUGIN_NAME = repo
build: commands subcommands triggers
$(MAKE) triggers-copy
commands: **/**/commands.go
go build $(GO_ARGS) -o commands src/commands/commands.go
subcommands: $(SUBCOMMANDS)
subcommands/%: src/subcommands/*/%.go
go build $(GO_ARGS) -o $@ $<
clean:
rm -rf commands subcommands triggers pre-delete
src-clean:
rm -rf .gitignore src triggers vendor Makefile *.go glide.*
triggers: $(TRIGGERS)
triggers/%: src/triggers/*/%.go
go build $(GO_ARGS) -o $@ $<
triggers-copy:
cp triggers/* .
include ../../common.mk

1
plugins/repo/pre-delete Symbolic link
View File

@@ -0,0 +1 @@
triggers

View File

@@ -1,22 +0,0 @@
package main
import (
"flag"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/repo"
)
// deletes the contents of the build cache stored in the repository
func main() {
flag.Parse()
appName := flag.Arg(1)
if appName == "" {
common.LogFail("Please specify an app to run the command on")
}
err := repo.PurgeCache(appName)
if err != nil {
common.LogWarn(err.Error())
}
}

View File

@@ -0,0 +1,35 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/repo"
)
// main entrypoint to all subcommands
func main() {
parts := strings.Split(os.Args[0], "/")
subcommand := parts[len(parts)-1]
flag.Parse()
var err error
switch subcommand {
case "gc":
flag.Parse()
appName := flag.Arg(1)
err = repo.CommandGc(appName)
case "purge-cache":
appName := flag.Arg(1)
err = repo.CommandPurgeCache(appName)
default:
common.LogFail(fmt.Sprintf("Invalid plugin subcommand call: %s", subcommand))
}
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -1,19 +0,0 @@
package main
import (
"flag"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/repo"
)
// destroys the buildpacks property for a given app container
func main() {
flag.Parse()
appName := flag.Arg(0)
err := repo.PurgeCache(appName)
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -0,0 +1,31 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/repo"
)
// 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 "pre-delete":
appName := flag.Arg(0)
err = repo.PurgeCache(appName)
default:
common.LogFail(fmt.Sprintf("Invalid plugin trigger call: %s", trigger))
}
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -1,22 +1,20 @@
package main
package repo
import (
"flag"
"errors"
"strings"
"github.com/dokku/dokku/plugins/common"
)
// runs 'git gc --aggressive' against the application's repo
func main() {
flag.Parse()
appName := flag.Arg(1)
// CommandGc runs 'git gc --aggressive' against the application's repo
func CommandGc(appName string) error {
if appName == "" {
common.LogFail("Please specify an app to run the command on")
return errors.New("Please specify an app to run the command on")
}
err := common.VerifyAppName(appName)
if err != nil {
common.LogFail(err.Error())
return err
}
appRoot := strings.Join([]string{common.MustGetEnv("DOKKU_ROOT"), appName}, "/")
@@ -26,4 +24,14 @@ func main() {
gitGcCmd := common.NewShellCmd("git gc --aggressive")
gitGcCmd.Env = cmdEnv
gitGcCmd.Execute()
return nil
}
// CommandPurgeCache deletes the contents of the build cache stored in the repository
func CommandPurgeCache(appName string) error {
if appName == "" {
common.LogFail("Please specify an app to run the command on")
}
return PurgeCache(appName)
}

View File

@@ -1,6 +1,7 @@
/commands
/subcommands/*
/triggers/*
/triggers
/install
/post-delete
/report

View File

@@ -1,38 +1,6 @@
include ../../common.mk
GO_ARGS ?= -a
SUBCOMMANDS = subcommands/limit subcommands/limit-clear subcommands/report subcommands/reserve subcommands/reserve-clear
TRIGGERS = triggers/docker-args-process-deploy triggers/install triggers/post-delete triggers/report triggers/resource-get-property
build-in-docker: clean
docker run --rm \
-v $$PWD/../..:$(GO_REPO_ROOT) \
-w $(GO_REPO_ROOT)/plugins/resource \
$(BUILD_IMAGE) \
bash -c "GO_ARGS='$(GO_ARGS)' make -j4 build" || exit $$?
BUILD = commands subcommands triggers
PLUGIN_NAME = resource
build: commands subcommands triggers
$(MAKE) triggers-copy
commands: **/**/commands.go
go build $(GO_ARGS) -o commands src/commands/commands.go
subcommands: $(SUBCOMMANDS)
subcommands/%: src/subcommands/*/%.go
go build $(GO_ARGS) -o $@ $<
clean:
rm -rf commands subcommands triggers docker-args-process-deploy docker-args-process-run install post-delete report resource-get-property
src-clean:
rm -rf .gitignore src triggers vendor Makefile *.go glide.*
triggers: $(TRIGGERS)
triggers/%: src/triggers/*/%.go
go build $(GO_ARGS) -o $@ $<
triggers-copy:
cp triggers/* .
ln -sf docker-args-process-deploy docker-args-process-run
include ../../common.mk

View File

@@ -1,20 +0,0 @@
package main
import (
"flag"
"os"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/resource"
)
func main() {
args := flag.NewFlagSet("resource:limit-clear", flag.ExitOnError)
processType := args.String("process-type", "", "process-type: A process type to clear")
args.Parse(os.Args[2:])
err := resource.CommandLimitClear(args.Args(), *processType)
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -1,35 +0,0 @@
package main
import (
"flag"
"os"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/resource"
)
func main() {
args := flag.NewFlagSet("resource:limit", flag.ExitOnError)
processType := args.String("process-type", "", "process-type: A process type to manage")
cpu := args.String("cpu", "", "cpu: The amount of cpu to limit processes by")
memory := args.String("memory", "", "memory: The amount of memory to limit processes by")
memorySwap := args.String("memory-swap", "", "memory-swap: The amount of swap memory to limit processes by")
network := args.String("network", "", "network: The amount of network bandwidth to limit processes by")
networkIngress := args.String("network-ingress", "", "network-ingress: The amount of ingress network bandwidth to limit processes by")
networkEgress := args.String("network-egress", "", "network-egress: The amount of egress network bandwidth to limit processes by")
args.Parse(os.Args[2:])
resources := resource.Resource{
CPU: *cpu,
Memory: *memory,
MemorySwap: *memorySwap,
Network: *network,
NetworkIngress: *networkIngress,
NetworkEgress: *networkEgress,
}
err := resource.CommandLimit(args.Args(), *processType, resources)
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -1,33 +0,0 @@
package main
import (
"flag"
"strings"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/resource"
)
// displays a resource report for one or more apps
func main() {
flag.Parse()
appName := flag.Arg(1)
infoFlag := flag.Arg(2)
if strings.HasPrefix(appName, "--") {
common.LogFail("The resource:report command does not support flags without an app name")
}
if len(appName) == 0 {
apps, err := common.DokkuApps()
if err != nil {
return
}
for _, appName := range apps {
resource.ReportSingleApp(appName, infoFlag)
}
return
}
resource.ReportSingleApp(appName, infoFlag)
}

View File

@@ -1,20 +0,0 @@
package main
import (
"flag"
"os"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/resource"
)
func main() {
args := flag.NewFlagSet("resource:reserve-clear", flag.ExitOnError)
processType := args.String("process-type", "", "process-type: A process type to clear")
args.Parse(os.Args[2:])
err := resource.CommandReserveClear(args.Args(), *processType)
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -1,35 +0,0 @@
package main
import (
"flag"
"os"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/resource"
)
func main() {
args := flag.NewFlagSet("resource:reserve", flag.ExitOnError)
processType := args.String("process-type", "", "process-type: A process type to manage")
cpu := args.String("cpu", "", "cpu: The amount of cpu to reserve for processes")
memory := args.String("memory", "", "memory: The amount of memory to reserve for processes")
memorySwap := args.String("memory-swap", "", "memory-swap: The amount of swap memory to reserve for processes")
network := args.String("network", "", "network: The amount of network bandwidth to reserve for processes")
networkIngress := args.String("network-ingress", "", "network-ingress: The amount of ingress network bandwidth to reserve for processes")
networkEgress := args.String("network-egress", "", "network-egress: The amount of egress network bandwidth to reserve for processes")
args.Parse(os.Args[2:])
resources := resource.Resource{
CPU: *cpu,
Memory: *memory,
MemorySwap: *memorySwap,
Network: *network,
NetworkIngress: *networkIngress,
NetworkEgress: *networkEgress,
}
err := resource.CommandReserve(args.Args(), *processType, resources)
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -0,0 +1,84 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/resource"
)
// main entrypoint to all subcommands
func main() {
parts := strings.Split(os.Args[0], "/")
subcommand := parts[len(parts)-1]
var err error
switch subcommand {
case "limit":
args := flag.NewFlagSet("resource:limit", flag.ExitOnError)
processType := args.String("process-type", "", "process-type: A process type to manage")
cpu := args.String("cpu", "", "cpu: The amount of cpu to limit processes by")
memory := args.String("memory", "", "memory: The amount of memory to limit processes by")
memorySwap := args.String("memory-swap", "", "memory-swap: The amount of swap memory to limit processes by")
network := args.String("network", "", "network: The amount of network bandwidth to limit processes by")
networkIngress := args.String("network-ingress", "", "network-ingress: The amount of ingress network bandwidth to limit processes by")
networkEgress := args.String("network-egress", "", "network-egress: The amount of egress network bandwidth to limit processes by")
args.Parse(os.Args[2:])
resources := resource.Resource{
CPU: *cpu,
Memory: *memory,
MemorySwap: *memorySwap,
Network: *network,
NetworkIngress: *networkIngress,
NetworkEgress: *networkEgress,
}
err = resource.CommandLimit(args.Args(), *processType, resources)
case "limit-clear":
args := flag.NewFlagSet("resource:limit-clear", flag.ExitOnError)
processType := args.String("process-type", "", "process-type: A process type to clear")
args.Parse(os.Args[2:])
err = resource.CommandLimitClear(args.Args(), *processType)
case "report":
flag.Parse()
appName := flag.Arg(1)
infoFlag := flag.Arg(2)
resource.CommandReport(appName, infoFlag)
case "reserve":
args := flag.NewFlagSet("resource:reserve", flag.ExitOnError)
processType := args.String("process-type", "", "process-type: A process type to manage")
cpu := args.String("cpu", "", "cpu: The amount of cpu to reserve for processes")
memory := args.String("memory", "", "memory: The amount of memory to reserve for processes")
memorySwap := args.String("memory-swap", "", "memory-swap: The amount of swap memory to reserve for processes")
network := args.String("network", "", "network: The amount of network bandwidth to reserve for processes")
networkIngress := args.String("network-ingress", "", "network-ingress: The amount of ingress network bandwidth to reserve for processes")
networkEgress := args.String("network-egress", "", "network-egress: The amount of egress network bandwidth to reserve for processes")
args.Parse(os.Args[2:])
resources := resource.Resource{
CPU: *cpu,
Memory: *memory,
MemorySwap: *memorySwap,
Network: *network,
NetworkIngress: *networkIngress,
NetworkEgress: *networkEgress,
}
err = resource.CommandReserve(args.Args(), *processType, resources)
case "reserve-clear":
args := flag.NewFlagSet("resource:reserve-clear", flag.ExitOnError)
processType := args.String("process-type", "", "process-type: A process type to clear")
args.Parse(os.Args[2:])
err = resource.CommandReserveClear(args.Args(), *processType)
default:
common.LogFail(fmt.Sprintf("Invalid plugin subcommand call: %s", subcommand))
}
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -1,14 +0,0 @@
package main
import (
"fmt"
"github.com/dokku/dokku/plugins/common"
)
// runs the install step for the resource plugin
func main() {
if err := common.PropertySetup("resource"); err != nil {
common.LogFail(fmt.Sprintf("Unable to install the resource plugin: %s", err.Error()))
}
}

View File

@@ -1,18 +0,0 @@
package main
import (
"flag"
"github.com/dokku/dokku/plugins/common"
)
// destroys the resource property for a given app container
func main() {
flag.Parse()
appName := flag.Arg(0)
err := common.PropertyDestroy("resource", appName)
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -1,15 +0,0 @@
package main
import (
"flag"
"github.com/dokku/dokku/plugins/resource"
)
// displays a resource report for one or more apps
func main() {
flag.Parse()
appName := flag.Arg(0)
resource.ReportSingleApp(appName, "")
}

View File

@@ -1,26 +0,0 @@
package main
import (
"flag"
"fmt"
"os"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/resource"
)
// writes the resource key to stdout for a given app container
func main() {
flag.Parse()
appName := flag.Arg(0)
processType := flag.Arg(1)
resourceType := flag.Arg(2)
key := flag.Arg(3)
value, err := resource.GetResourceValue(appName, processType, resourceType, key)
if err != nil {
common.LogFail(err.Error())
}
fmt.Fprintln(os.Stdout, value)
}

View File

@@ -0,0 +1,46 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
"github.com/dokku/dokku/plugins/common"
"github.com/dokku/dokku/plugins/resource"
)
// 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 "docker-args-process-deploy":
appName := flag.Arg(0)
processType := flag.Arg(3)
err = resource.TriggerDockerArgsProcessDeploy(appName, processType)
case "install":
err = resource.TriggerInstall()
case "post-delete":
appName := flag.Arg(0)
err = resource.TriggerPostDelete(appName)
case "report":
appName := flag.Arg(0)
resource.ReportSingleApp(appName, "")
case "resource-get-property":
appName := flag.Arg(0)
processType := flag.Arg(1)
resourceType := flag.Arg(2)
key := flag.Arg(3)
err = resource.TriggerResourceGetProperty(appName, processType, resourceType, key)
default:
common.LogFail(fmt.Sprintf("Invalid plugin trigger call: %s", trigger))
}
if err != nil {
common.LogFail(err.Error())
}
}

View File

@@ -2,6 +2,8 @@ package resource
import (
"fmt"
"strings"
"github.com/dokku/dokku/plugins/common"
)
@@ -26,6 +28,27 @@ func CommandLimitClear(args []string, processType string) error {
return nil
}
// CommandReport displays a resource report for one or more apps
func CommandReport(appName string, infoFlag string) {
if strings.HasPrefix(appName, "--") {
infoFlag = appName
appName = ""
}
if len(appName) == 0 {
apps, err := common.DokkuApps()
if err != nil {
return
}
for _, appName := range apps {
ReportSingleApp(appName, infoFlag)
}
return
}
ReportSingleApp(appName, infoFlag)
}
// CommandReserve implements resource:reserve
func CommandReserve(args []string, processType string, r Resource) error {
appName, err := getAppName(args)

View File

@@ -1,7 +1,7 @@
package main
package resource
import (
"flag"
"errors"
"fmt"
"io/ioutil"
"os"
@@ -10,26 +10,22 @@ import (
"github.com/dokku/dokku/plugins/common"
)
// outputs the process-specific docker options
func main() {
// TriggerDockerArgsProcessDeploy outputs the process-specific docker options
func TriggerDockerArgsProcessDeploy(appName string, processType string) error {
stdin, err := ioutil.ReadAll(os.Stdin)
if err != nil {
common.LogFail(err.Error())
return err
}
flag.Parse()
appName := flag.Arg(0)
processType := flag.Arg(3)
if os.Getenv("DOKKU_OMIT_RESOURCE_ARGS") == "1" {
fmt.Print(string(stdin))
return
return nil
}
resources, err := common.PropertyGetAll("resource", appName)
if err != nil {
fmt.Print(string(stdin))
return
return nil
}
limits := make(map[string]string)
@@ -86,4 +82,29 @@ func main() {
}
fmt.Print(string(stdin))
return nil
}
// TriggerInstall runs the install step for the resource plugin
func TriggerInstall() error {
if err := common.PropertySetup("resource"); err != nil {
return errors.New(fmt.Sprintf("Unable to install the resource plugin: %s", err.Error()))
}
return nil
}
// TriggerPostDelete destroys the resource property for a given app container
func TriggerPostDelete(appName string) error {
return common.PropertyDestroy("resource", appName)
}
// writes the resource key to stdout for a given app container
func TriggerResourceGetProperty(appName string, processType string, resourceType string, key string) error {
value, err := GetResourceValue(appName, processType, resourceType, key)
if err != nil {
return err
}
fmt.Fprintln(os.Stdout, value)
return nil
}