From 41560ed02ce939822fc121972bda3b2a89cf6831 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 11:36:05 -0400 Subject: [PATCH 01/48] feat: ignore built binary --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 9417d10..efee0c0 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ validation/* .env* *Procfile + +procfile-util From 720f5b5bf8ec407eb4f2243a99c160818c679de1 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 11:37:11 -0400 Subject: [PATCH 02/48] feat: add support for exporting an init file --- Makefile | 1 + README.md | 24 ++ bindata.go | 350 ++++++++++++++++++ export.go | 295 +++++++++++++++ go.mod | 1 + go.sum | 2 + main.go | 149 +++++++- templates/runit/log/run.tmpl | 7 + templates/runit/run.tmpl | 4 + .../systemd-user/default/program.service.tmpl | 16 + templates/systemd/default/master.target.tmpl | 5 + .../systemd/default/program.service.tmpl | 33 ++ 12 files changed, 880 insertions(+), 7 deletions(-) create mode 100644 bindata.go create mode 100644 export.go create mode 100644 templates/runit/log/run.tmpl create mode 100644 templates/runit/run.tmpl create mode 100644 templates/systemd-user/default/program.service.tmpl create mode 100644 templates/systemd/default/master.target.tmpl create mode 100644 templates/systemd/default/program.service.tmpl diff --git a/Makefile b/Makefile index f3b71e9..49db4b0 100644 --- a/Makefile +++ b/Makefile @@ -43,6 +43,7 @@ targets = $(addsuffix -in-docker, $(LIST)) @echo "VERSION=$(VERSION)" >> .env.docker build: + @go-bindata templates/... @$(MAKE) build/darwin/$(NAME) @$(MAKE) build/linux/$(NAME) @$(MAKE) build/deb/$(NAME)_$(VERSION)_amd64.deb diff --git a/README.md b/README.md index bae8a21..df76709 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,30 @@ procfile-util expand --allow-getenv --env-file .env procfile-util expand --allow-getenv --env-file .env --default-port 3000 ``` +### export + +> export the application to another process management format + +Due to argument parsing limitations, the `--location` flag is currently required. + +In addition, not all formats support all arguments, and not all arguments have examples below. + +```shell +# export systemd init files to the `tmp` directory +# support formats include: [runit, systemd, systemd-user] +# the default format is: systemd +procfile-util export --format systemd --location tmpp + +# override the app name +procfile-util export --location tmp --app node-js-app + +# set the group and user used to launch processes +procfile-util export --location tmp --group root --user root + +# set a working directory path for the process +procfile-util export --location tmp --working-directory /root +``` + ### list > list all process types in a procfile diff --git a/bindata.go b/bindata.go new file mode 100644 index 0000000..ef8ac50 --- /dev/null +++ b/bindata.go @@ -0,0 +1,350 @@ +// Code generated for package main by go-bindata DO NOT EDIT. (@generated) +// sources: +// templates/runit/log/run.tmpl +// templates/runit/run.tmpl +// templates/systemd/default/master.target.tmpl +// templates/systemd/default/program.service.tmpl +// templates/systemd-user/default/program.service.tmpl +package main + +import ( + "bytes" + "compress/gzip" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + "time" +) + +func bindataRead(data []byte, name string) ([]byte, error) { + gz, err := gzip.NewReader(bytes.NewBuffer(data)) + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + + var buf bytes.Buffer + _, err = io.Copy(&buf, gz) + clErr := gz.Close() + + if err != nil { + return nil, fmt.Errorf("Read %q: %v", name, err) + } + if clErr != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +type asset struct { + bytes []byte + info os.FileInfo +} + +type bindataFileInfo struct { + name string + size int64 + mode os.FileMode + modTime time.Time +} + +// Name return file name +func (fi bindataFileInfo) Name() string { + return fi.name +} + +// Size return file size +func (fi bindataFileInfo) Size() int64 { + return fi.size +} + +// Mode return file mode +func (fi bindataFileInfo) Mode() os.FileMode { + return fi.mode +} + +// Mode return file modify time +func (fi bindataFileInfo) ModTime() time.Time { + return fi.modTime +} + +// IsDir return file whether a directory +func (fi bindataFileInfo) IsDir() bool { + return fi.mode&os.ModeDir != 0 +} + +// Sys return file is sys mode +func (fi bindataFileInfo) Sys() interface{} { + return nil +} + +var _templatesRunitLogRunTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x8c\xcf\x0a\x82\x40\x10\x87\xef\xf3\x14\xbf\x2c\xbc\x6d\x46\x10\x9d\x3a\x7b\x11\x7c\x84\xa8\x75\x50\x49\xdd\xc5\x59\xfb\x83\xce\xbb\xc7\x42\x1e\xba\x7d\xcc\x37\xbf\x6f\xbb\xc9\xee\xed\x90\x49\x43\xc2\x01\x86\x89\x8a\x32\xbf\xcc\x33\xf6\x9d\xab\xa1\x9a\x45\xbc\x79\xbf\xa2\x1f\x9d\x65\x91\x6b\xf8\x78\x86\xaa\x89\xb7\x61\xea\xa1\x4a\x14\x58\x02\x4c\x85\x64\x57\x94\x79\x82\x65\x41\xff\xa8\xda\x11\xc6\xc3\xf4\x38\x9e\x4f\x87\x55\xa5\x29\x6c\xe3\x5e\x03\xe2\x7c\x12\x1e\xa1\xfa\x73\xc4\x6f\xb6\xb0\x8d\x8f\xad\xe9\xef\x41\x9e\x9d\xab\xd7\x3c\x7d\x03\x00\x00\xff\xff\x0a\xaa\x1d\x31\xba\x00\x00\x00") + +func templatesRunitLogRunTmplBytes() ([]byte, error) { + return bindataRead( + _templatesRunitLogRunTmpl, + "templates/runit/log/run.tmpl", + ) +} + +func templatesRunitLogRunTmpl() (*asset, error) { + bytes, err := templatesRunitLogRunTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/runit/log/run.tmpl", size: 186, mode: os.FileMode(420), modTime: time.Unix(1584456288, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesRunitRunTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x34\x8d\x4d\x0a\x02\x31\x0c\x46\xf7\x73\x8a\x88\xe0\xae\x16\x3d\x80\x57\x19\x6a\x1a\x9c\xa2\x4d\x4a\x7f\xd4\x61\xc8\xdd\xa5\x95\xd9\xbd\x17\xf2\xf8\x8e\x07\x7b\x0f\x6c\xcb\x32\xa1\x87\x6d\x83\xf3\x47\xf2\x33\xf0\x63\xf6\x21\x13\x56\xc9\x2b\xa8\x4e\xf4\x25\x84\xeb\xed\x74\xf9\x13\x2e\xa9\x54\x30\x6d\x04\xad\x50\x06\x55\x30\x34\xf4\x25\xe8\x6a\x10\x06\x55\xdb\xdd\xa5\x04\xaa\xa6\x63\xca\x82\x54\xca\x5c\xd7\x44\xfb\x8d\x5b\xec\x9f\xc4\xef\x51\xa3\xc4\xe8\xd8\xf7\xcd\x5f\x00\x00\x00\xff\xff\xb9\xe8\x41\x7e\x9a\x00\x00\x00") + +func templatesRunitRunTmplBytes() ([]byte, error) { + return bindataRead( + _templatesRunitRunTmpl, + "templates/runit/run.tmpl", + ) +} + +func templatesRunitRunTmpl() (*asset, error) { + bytes, err := templatesRunitRunTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/runit/run.tmpl", size: 154, mode: os.FileMode(420), modTime: time.Unix(1584458764, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesSystemdDefaultMasterTargetTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8a\x0e\xcd\xcb\x2c\x89\xe5\x0a\x4f\xcc\x2b\x29\xb6\xad\xae\x56\x28\x4a\xcc\x4b\x4f\x55\x50\x29\x4b\xcc\x29\x4d\x55\xb0\xb2\x55\xd0\x2b\x28\xca\x4f\x4e\x2d\x2e\x4e\x2d\x56\xa8\xad\xad\xae\x86\xc9\xd4\xd6\x2a\x54\x57\x2b\xa4\xe6\xa5\x28\xd4\xd6\x72\x71\x45\x7b\xe6\x15\x97\x24\xe6\xe4\x40\xcc\x49\x4d\x71\xaa\xb4\xcd\x2d\xcd\x29\xc9\xd4\x2d\x2d\x4e\x2d\xd2\x2b\x49\x2c\x4a\x4f\x2d\xe1\x02\x04\x00\x00\xff\xff\x4f\xc2\xa4\x0c\x6a\x00\x00\x00") + +func templatesSystemdDefaultMasterTargetTmplBytes() ([]byte, error) { + return bindataRead( + _templatesSystemdDefaultMasterTargetTmpl, + "templates/systemd/default/master.target.tmpl", + ) +} + +func templatesSystemdDefaultMasterTargetTmpl() (*asset, error) { + bytes, err := templatesSystemdDefaultMasterTargetTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/systemd/default/master.target.tmpl", size: 106, mode: os.FileMode(420), modTime: time.Unix(1584336786, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesSystemdDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x92\xc1\x6a\xe3\x3c\x10\x80\xef\x7e\x0a\x11\xfa\xd3\xcb\x9f\x98\x85\x3d\x2d\xe8\xd6\x74\x09\xdb\x6d\x4a\xdd\xd0\x43\x29\x41\x95\xc6\xee\x50\x79\x64\x46\xe3\x34\xc6\xf8\xdd\x17\xa9\x9b\xa4\xb4\xbb\x7b\xb2\xf4\xcd\x37\xa3\xd1\x58\x0f\x1b\x42\x79\x2c\xc6\x71\xae\xb0\x56\x0b\x07\xd1\x32\x76\x82\x81\xd4\x34\x15\x17\xa7\xad\x1e\xc7\x4f\xe1\x71\x54\x40\x2e\xad\x6e\x0c\xcb\xba\xce\x8e\xe9\x3a\x35\x4d\x0b\x31\xdc\x80\x14\x95\x84\xee\xfe\x19\x68\x43\x04\xe0\xc0\xe9\x01\x62\x51\x3c\x54\xc0\x3b\xb4\xf0\x58\x6c\x22\x70\x4e\xeb\x23\x70\xaa\xf4\x9d\x43\xdf\x65\xd2\xa4\x55\x42\xf7\x81\x5f\x90\x9a\x0b\x64\xb0\x12\x78\xc8\xd1\xd7\x37\xb8\x75\x07\x9a\xcc\x25\xed\x90\x03\xb5\x40\xa2\x6f\xd6\xb7\x77\xd9\xec\x02\xcb\xa7\x60\xf5\xae\xd7\x79\xb6\x38\x58\x88\x71\x4b\xa6\x85\x0f\xf6\x25\x7a\xd0\xf3\x12\xc4\x96\x0e\x6a\xd3\x7b\x29\x0f\xc9\x7f\x37\xe3\x10\x6d\xa0\x1a\x9b\xf2\x74\x50\x1e\x33\x1b\x6a\x40\x9d\xbd\xc0\xf0\xbf\x3a\xdb\x19\xdf\x83\xfa\xa6\xd5\x02\x68\xf7\xb1\xc9\xd9\x38\x66\x4f\x4d\x53\xea\xf6\xb7\x3c\x4d\xb3\x77\x83\x5f\xee\xc1\x56\x62\x58\x74\xf9\x84\x54\x3e\x99\xf8\xac\xe6\xde\xaa\x73\xd8\x83\x55\x73\xa3\x66\xff\xbe\xe7\x4c\x25\x68\x43\xdb\x9a\x5c\xf0\xbc\xb8\x85\x98\xeb\x19\xff\x6a\x86\x78\xd8\x56\x60\xf5\x97\xaf\xb1\xa8\xc4\x90\x33\xec\x56\xd4\xf5\xa2\xa9\xf7\xfe\x88\xd6\xbd\x24\x16\x87\xe8\x43\x73\xa4\x4b\xe6\xc0\x47\x98\x3f\x2b\x07\x24\x58\x23\xb0\xfe\x8f\x8a\x1f\xe8\xfd\xcf\xe0\x40\xb7\xb8\x07\x57\xdc\x61\x0b\xa1\x97\xf4\x6e\xd2\x99\xa9\x3b\x79\x43\xe9\xba\xc7\x87\x4a\x68\xf3\x6f\xba\x46\x0b\x59\x3a\x80\xd3\x68\x0e\xaa\xc7\x16\x65\x1b\x3a\xa0\x6d\x8d\x1e\x62\x8a\x5d\x25\x76\xbd\xbe\x5c\x5d\x2d\x73\xf6\x9f\x9c\x53\xa5\x5f\x01\x00\x00\xff\xff\xcd\x06\x2d\xbd\x25\x03\x00\x00") + +func templatesSystemdDefaultProgramServiceTmplBytes() ([]byte, error) { + return bindataRead( + _templatesSystemdDefaultProgramServiceTmpl, + "templates/systemd/default/program.service.tmpl", + ) +} + +func templatesSystemdDefaultProgramServiceTmpl() (*asset, error) { + bytes, err := templatesSystemdDefaultProgramServiceTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/systemd/default/program.service.tmpl", size: 805, mode: os.FileMode(420), modTime: time.Unix(1584458757, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesSystemdUserDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x8f\x41\x6a\xf3\x30\x10\x85\xf7\x3a\x85\x2f\x10\xfb\x04\xde\xfc\x24\x3f\x74\x95\x12\xa7\x64\x11\x42\x18\xa4\x89\x3b\xad\x34\x12\xa3\x71\x52\x63\x7c\xf7\x62\x85\x12\x9a\x45\x97\x7a\xdf\x37\x8f\xa7\xe3\x1b\x93\x9e\xcc\x34\xad\x2a\xba\x54\xb5\xc3\x6c\x85\x92\x52\xe4\x6a\x9e\xcd\xfa\xf1\x6c\xa7\xe9\x19\x4f\x53\x85\xec\x16\xaf\x32\xc7\x0e\xe5\x4a\x16\x4f\x66\x3f\x26\x6c\x33\x85\xe4\xd1\x6c\xf8\x4a\x12\x39\x20\x6b\xfb\xba\xdd\xed\x4b\x49\x8a\xa2\xcb\xd1\x2f\xd8\x15\x04\x29\x55\xf3\xbc\x2a\x96\x44\x8b\x39\x9f\x19\x02\x3e\xd9\xff\xc9\x63\x5b\xa4\xf7\x58\x60\x53\xdb\xc8\x17\xea\x9b\x3c\x66\xc5\xe0\x9a\x21\xa3\x34\x7f\x17\xd6\xf8\x28\x34\x9b\x2f\xb4\x9d\x82\x68\x59\x61\x63\x08\x70\xff\xd8\x0e\x73\x89\xc1\xdf\x60\xcc\xe6\x10\xe5\x93\xb8\x5f\x93\xa0\xd5\x28\x63\xd1\x6f\xf7\xf0\xec\x7e\xd2\xe5\xb0\x53\x60\x07\xe2\xb6\x83\xa6\x41\xdb\x8f\x38\x08\x83\x37\xe6\xf8\xc2\x59\xc1\xfb\x93\x39\x00\x2b\xba\x7f\x63\x1b\x06\xaf\xb4\x5a\x26\xd7\x0a\xd2\xa3\x9a\xef\x00\x00\x00\xff\xff\x46\xb5\xdd\x93\x95\x01\x00\x00") + +func templatesSystemdUserDefaultProgramServiceTmplBytes() ([]byte, error) { + return bindataRead( + _templatesSystemdUserDefaultProgramServiceTmpl, + "templates/systemd-user/default/program.service.tmpl", + ) +} + +func templatesSystemdUserDefaultProgramServiceTmpl() (*asset, error) { + bytes, err := templatesSystemdUserDefaultProgramServiceTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/systemd-user/default/program.service.tmpl", size: 405, mode: os.FileMode(420), modTime: time.Unix(1584458760, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +// Asset loads and returns the asset for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func Asset(name string) ([]byte, error) { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) + } + return a.bytes, nil + } + return nil, fmt.Errorf("Asset %s not found", name) +} + +// MustAsset is like Asset but panics when Asset would return an error. +// It simplifies safe initialization of global variables. +func MustAsset(name string) []byte { + a, err := Asset(name) + if err != nil { + panic("asset: Asset(" + name + "): " + err.Error()) + } + + return a +} + +// AssetInfo loads and returns the asset info for the given name. +// It returns an error if the asset could not be found or +// could not be loaded. +func AssetInfo(name string) (os.FileInfo, error) { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { + a, err := f() + if err != nil { + return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) + } + return a.info, nil + } + return nil, fmt.Errorf("AssetInfo %s not found", name) +} + +// AssetNames returns the names of the assets. +func AssetNames() []string { + names := make([]string, 0, len(_bindata)) + for name := range _bindata { + names = append(names, name) + } + return names +} + +// _bindata is a table, holding each asset generator, mapped to its name. +var _bindata = map[string]func() (*asset, error){ + "templates/runit/log/run.tmpl": templatesRunitLogRunTmpl, + "templates/runit/run.tmpl": templatesRunitRunTmpl, + "templates/systemd/default/master.target.tmpl": templatesSystemdDefaultMasterTargetTmpl, + "templates/systemd/default/program.service.tmpl": templatesSystemdDefaultProgramServiceTmpl, + "templates/systemd-user/default/program.service.tmpl": templatesSystemdUserDefaultProgramServiceTmpl, +} + +// AssetDir returns the file names below a certain +// directory embedded in the file by go-bindata. +// For example if you run go-bindata on data/... and data contains the +// following hierarchy: +// data/ +// foo.txt +// img/ +// a.png +// b.png +// then AssetDir("data") would return []string{"foo.txt", "img"} +// AssetDir("data/img") would return []string{"a.png", "b.png"} +// AssetDir("foo.txt") and AssetDir("notexist") would return an error +// AssetDir("") will return []string{"data"}. +func AssetDir(name string) ([]string, error) { + node := _bintree + if len(name) != 0 { + cannonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(cannonicalName, "/") + for _, p := range pathList { + node = node.Children[p] + if node == nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + } + } + if node.Func != nil { + return nil, fmt.Errorf("Asset %s not found", name) + } + rv := make([]string, 0, len(node.Children)) + for childName := range node.Children { + rv = append(rv, childName) + } + return rv, nil +} + +type bintree struct { + Func func() (*asset, error) + Children map[string]*bintree +} + +var _bintree = &bintree{nil, map[string]*bintree{ + "templates": &bintree{nil, map[string]*bintree{ + "runit": &bintree{nil, map[string]*bintree{ + "log": &bintree{nil, map[string]*bintree{ + "run.tmpl": &bintree{templatesRunitLogRunTmpl, map[string]*bintree{}}, + }}, + "run.tmpl": &bintree{templatesRunitRunTmpl, map[string]*bintree{}}, + }}, + "systemd": &bintree{nil, map[string]*bintree{ + "default": &bintree{nil, map[string]*bintree{ + "master.target.tmpl": &bintree{templatesSystemdDefaultMasterTargetTmpl, map[string]*bintree{}}, + "program.service.tmpl": &bintree{templatesSystemdDefaultProgramServiceTmpl, map[string]*bintree{}}, + }}, + }}, + "systemd-user": &bintree{nil, map[string]*bintree{ + "default": &bintree{nil, map[string]*bintree{ + "program.service.tmpl": &bintree{templatesSystemdUserDefaultProgramServiceTmpl, map[string]*bintree{}}, + }}, + }}, + }}, +}} + +// RestoreAsset restores an asset under the given directory +func RestoreAsset(dir, name string) error { + data, err := Asset(name) + if err != nil { + return err + } + info, err := AssetInfo(name) + if err != nil { + return err + } + err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) + if err != nil { + return err + } + err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + if err != nil { + return err + } + err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) + if err != nil { + return err + } + return nil +} + +// RestoreAssets restores an asset under the given directory recursively +func RestoreAssets(dir, name string) error { + children, err := AssetDir(name) + // File + if err != nil { + return RestoreAsset(dir, name) + } + // Dir + for _, child := range children { + err = RestoreAssets(dir, filepath.Join(name, child)) + if err != nil { + return err + } + } + return nil +} + +func _filePath(dir, name string) string { + cannonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) +} diff --git a/export.go b/export.go new file mode 100644 index 0000000..390f75b --- /dev/null +++ b/export.go @@ -0,0 +1,295 @@ +package main + +import ( + "fmt" + "os" + "strconv" + "text/template" +) + +func exportRunit(app string, entries []procfileEntry, formations map[string]formationEntry, location string, defaultPort int, vars map[string]interface{}) bool { + run, err := Asset("templates/runit/run.tmpl") + if err != nil { + fmt.Fprintf(os.Stderr, "error: %s\n", err) + return false + } + + log, err := Asset("templates/runit/log/run.tmpl") + if err != nil { + fmt.Fprintf(os.Stderr, "error: %s\n", err) + return false + } + + r, err := template.New("run").Parse(string(run)) + if err != nil { + fmt.Fprintf(os.Stderr, "error parsing template: %s\n", err) + return false + } + + l, err := template.New("log").Parse(string(log)) + if err != nil { + fmt.Fprintf(os.Stderr, "error parsing template: %s\n", err) + return false + } + + if _, err := os.Stat(location); os.IsNotExist(err) { + os.MkdirAll(location, os.ModePerm) + } + + for i, entry := range entries { + count := processCount(entry, formations) + + num := 1 + for num <= count { + processDirectory := fmt.Sprintf("%s-%s-%d", app, entry.Name, num) + folderPath := location + "/" + processDirectory + processName := fmt.Sprintf("%s.%d", entry.Name, num) + + fmt.Println("creating:", app+"-"+processName) + os.MkdirAll(folderPath, os.ModePerm) + + fmt.Println("creating:", app+"-"+processName+"/env") + os.MkdirAll(folderPath+"/env", os.ModePerm) + + fmt.Println("creating:", app+"-"+processName+"/log") + os.MkdirAll(folderPath+"/log", os.ModePerm) + + port := portFor(i, num, defaultPort) + + config := vars + config["command"] = entry.Command + config["num"] = num + config["port"] = port + config["process_name"] = processName + config["process_type"] = entry.Name + if config["description"] == "" { + config["description"] = fmt.Sprintf("%s process for %s", processName, app) + } + + fmt.Println("writing:", app+"-"+processName+"/run") + f, err := os.Create(folderPath + "/run") + if err != nil { + fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) + return false + } + defer f.Close() + + if err = r.Execute(f, config); err != nil { + fmt.Fprintf(os.Stderr, "error writing output: %s\n", err) + return false + } + + fmt.Println("setting", app+"-"+processName+"/run", "to mode 755") + if err := os.Chmod(folderPath+"/run", 0755); err != nil { + fmt.Fprintf(os.Stderr, "error setting mode: %s\n", err) + return false + } + + env, ok := config["env"].(map[string]string) + if !ok { + fmt.Fprintf(os.Stderr, "invalid env map\n") + return false + } + + env["PORT"] = strconv.Itoa(port) + env["PS"] = app + "-" + processName + + for key, value := range env { + fmt.Println("writing:", app+"-"+processName+"/env/"+key) + f, err = os.Create(folderPath + "/env/" + key) + if err != nil { + fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) + return false + } + defer f.Close() + + if _, err = f.WriteString(value); err != nil { + fmt.Fprintf(os.Stderr, "error writing output: %s\n", err) + return false + } + + if err = f.Sync(); err != nil { + fmt.Fprintf(os.Stderr, "error syncing output: %s\n", err) + return false + } + } + + fmt.Println("writing:", app+"-"+processName+"/log/run") + f, err = os.Create(folderPath + "/log/run") + if err != nil { + fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) + return false + } + defer f.Close() + + if err = l.Execute(f, config); err != nil { + fmt.Fprintf(os.Stderr, "error writing output: %s\n", err) + return false + } + + fmt.Println("setting", app+"-"+processName+"/log/run", "to mode 755") + if err := os.Chmod(folderPath+"/log/run", 0755); err != nil { + fmt.Fprintf(os.Stderr, "error setting mode: %s\n", err) + return false + } + + num += 1 + } + } + + return true +} + +func exportSystemd(app string, entries []procfileEntry, formations map[string]formationEntry, location string, defaultPort int, vars map[string]interface{}) bool { + target, err := Asset("templates/systemd/default/master.target.tmpl") + if err != nil { + fmt.Fprintf(os.Stderr, "error: %s\n", err) + return false + } + + service, err := Asset("templates/systemd/default/program.service.tmpl") + if err != nil { + fmt.Fprintf(os.Stderr, "error: %s\n", err) + return false + } + + t, err := template.New("target").Parse(string(target)) + if err != nil { + fmt.Fprintf(os.Stderr, "error parsing template: %s\n", err) + return false + } + + s, err := template.New("service").Parse(string(service)) + if err != nil { + fmt.Fprintf(os.Stderr, "error parsing template: %s\n", err) + return false + } + + if _, err := os.Stat(location); os.IsNotExist(err) { + os.MkdirAll(location, os.ModePerm) + } + + processes := []string{} + for i, entry := range entries { + count := processCount(entry, formations) + + num := 1 + for num <= count { + processName := fmt.Sprintf("%s.%d", entry.Name, num) + processes = append(processes, fmt.Sprintf("%s.service", processName)) + fmt.Println("writing:", app+"-"+processName+".service") + + config := vars + config["command"] = entry.Command + config["num"] = num + config["port"] = portFor(i, num, defaultPort) + config["process_name"] = processName + config["process_type"] = entry.Name + if config["description"] == "" { + config["description"] = fmt.Sprintf("%s process for %s", processName, app) + } + + f, err := os.Create(location + "/" + app + "-" + processName + ".service") + if err != nil { + fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) + return false + } + defer f.Close() + + if err = s.Execute(f, config); err != nil { + fmt.Fprintf(os.Stderr, "error writing output: %s\n", err) + return false + } + + num += 1 + } + } + + config := vars + config["processes"] = processes + fmt.Println("writing:", app+".target") + f, err := os.Create(location + "/" + app + ".target") + if err != nil { + fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) + return false + } + defer f.Close() + + if err = t.Execute(f, config); err != nil { + fmt.Fprintf(os.Stderr, "error writing output: %s\n", err) + return false + } + + return true +} + +func exportSystemdUser(app string, entries []procfileEntry, formations map[string]formationEntry, location string, defaultPort int, vars map[string]interface{}) bool { + service, err := Asset("templates/systemd-user/default/program.service.tmpl") + if err != nil { + fmt.Fprintf(os.Stderr, "error: %s\n", err) + return false + } + + s, err := template.New("service").Parse(string(service)) + if err != nil { + fmt.Fprintf(os.Stderr, "error parsing template: %s\n", err) + return false + } + + if _, err := os.Stat(location); os.IsNotExist(err) { + os.MkdirAll(location, os.ModePerm) + } + + processes := []string{} + for i, entry := range entries { + count := processCount(entry, formations) + + num := 1 + for num <= count { + processName := fmt.Sprintf("%s.%d", entry.Name, num) + processes = append(processes, fmt.Sprintf("%s.service", processName)) + fmt.Println("writing:", app+"-"+processName+".service") + + config := vars + config["command"] = entry.Command + config["num"] = num + config["port"] = portFor(i, num, defaultPort) + config["process_name"] = processName + config["process_type"] = entry.Name + if config["description"] == "" { + config["description"] = fmt.Sprintf("%s process for %s", processName, app) + } + + f, err := os.Create(location + "/" + app + "-" + processName + ".service") + if err != nil { + fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) + return false + } + defer f.Close() + + if err = s.Execute(f, config); err != nil { + fmt.Fprintf(os.Stderr, "error writing output: %s\n", err) + return false + } + + num += 1 + } + } + + return true +} + +func processCount(entry procfileEntry, formations map[string]formationEntry) int { + count := 0 + if f, ok := formations["all"]; ok { + count = f.Count + } + if f, ok := formations[entry.Name]; ok { + count = f.Count + } + return count +} + +func portFor(processIndex int, instance int, base int) int { + return 5000 + (processIndex * 100) + (instance - 1) +} diff --git a/go.mod b/go.mod index c4672ee..0ffe593 100644 --- a/go.mod +++ b/go.mod @@ -5,5 +5,6 @@ go 1.12 require ( github.com/akamensky/argparse v0.0.0-20180405044306-95911c018170 github.com/andrew-d/go-termutil v0.0.0-20150726205930-009166a695a2 + github.com/go-bindata/go-bindata v3.1.2+incompatible // indirect github.com/joho/godotenv v1.2.0 ) diff --git a/go.sum b/go.sum index 60acdd4..9c10069 100644 --- a/go.sum +++ b/go.sum @@ -2,5 +2,7 @@ github.com/akamensky/argparse v0.0.0-20180405044306-95911c018170 h1:JuYOgmyY+ckp github.com/akamensky/argparse v0.0.0-20180405044306-95911c018170/go.mod h1:pdh+2piXurh466J9tqIqq39/9GO2Y8nZt6Cxzu18T9A= github.com/andrew-d/go-termutil v0.0.0-20150726205930-009166a695a2 h1:axBiC50cNZOs7ygH5BgQp4N+aYrZ2DNpWZ1KG3VOSOM= github.com/andrew-d/go-termutil v0.0.0-20150726205930-009166a695a2/go.mod h1:jnzFpU88PccN/tPPhCpnNU8mZphvKxYM9lLNkd8e+os= +github.com/go-bindata/go-bindata v3.1.2+incompatible h1:5vjJMVhowQdPzjE1LdxyFF7YFTXg5IgGVW4gBr5IbvE= +github.com/go-bindata/go-bindata v3.1.2+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo= github.com/joho/godotenv v1.2.0 h1:vGTvz69FzUFp+X4/bAkb0j5BoLC+9bpqTWY8mjhA9pc= github.com/joho/godotenv v1.2.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= diff --git a/main.go b/main.go index bb2cc25..1fe66ab 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ import ( "os" "regexp" "sort" + "strconv" "strings" "github.com/akamensky/argparse" @@ -19,6 +20,11 @@ type procfileEntry struct { Command string } +type formationEntry struct { + Name string + Count int +} + const portEnvVar = "PORT" // Version contains the procfile-util version @@ -169,13 +175,13 @@ func parseProcfile(path string, delimiter string) ([]procfileEntry, error) { return entries, nil } -func expandEnv(e procfileEntry, envPath string, allowEnv bool, defaultPort string) (string, error) { +func expandEnv(e procfileEntry, envPath string, allowEnv bool, defaultPort int) (string, error) { baseExpandFunc := func(key string) string { if key == "PS" { return os.Getenv("PS") } if key == portEnvVar { - return defaultPort + return string(defaultPort) } return "" } @@ -256,7 +262,7 @@ func existsCommand(entries []procfileEntry, processType string) bool { return false } -func expandCommand(entries []procfileEntry, envPath string, allowGetenv bool, processType string, defaultPort string, delimiter string) bool { +func expandCommand(entries []procfileEntry, envPath string, allowGetenv bool, processType string, defaultPort int, delimiter string) bool { hasErrors := false var expandedEntries []procfileEntry for _, entry := range entries { @@ -283,6 +289,111 @@ func expandCommand(entries []procfileEntry, envPath string, allowGetenv bool, pr return true } +func exportCommand(entries []procfileEntry, app string, description string, envPath string, format string, formation string, group string, home string, limitOpenFiles string, location string, logPath string, nice string, workingDirectoryPath string, runPath string, timeout int, user string, defaultPort int) bool { + if format == "" { + fmt.Fprintf(os.Stderr, "no format specified\n") + return false + } + if location == "" { + fmt.Fprintf(os.Stderr, "no output location specified\n") + return false + } + formats := map[string]bool{ + "runit": true, + "systemd": true, + "systemd-user": true, + } + + if _, ok := formats[format]; !ok { + fmt.Fprintf(os.Stderr, "invalid format type: %s\n", format) + return false + } + + formations, err := parseFormation(formation) + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + return false + } + + if user == "" { + user = app + } + + if group == "" { + group = app + } + + if home == "" { + home = "/home/" + app + } + + env := make(map[string]string) + if envPath != "" { + b, err := ioutil.ReadFile(envPath) + if err != nil { + fmt.Fprintf(os.Stderr, "error reading env file: %s\n", err) + return false + } + + content := string(b) + env, err = godotenv.Unmarshal(content) + if err != nil { + fmt.Fprintf(os.Stderr, "error parsing env file: %s\n", err) + return false + } + } + + vars := make(map[string]interface{}) + vars["app"] = app + vars["description"] = description + vars["env"] = env + vars["group"] = group + vars["home"] = home + vars["log"] = logPath + vars["location"] = location + vars["limit_open_files"] = limitOpenFiles + vars["nice"] = nice + vars["working_directory"] = workingDirectoryPath + vars["timeout"] = strconv.Itoa(timeout) + vars["user"] = user + + if format == "runit" { + return exportRunit(app, entries, formations, location, defaultPort, vars) + } + + if format == "systemd" { + return exportSystemd(app, entries, formations, location, defaultPort, vars) + } + + if format == "systemd-user" { + return exportSystemdUser(app, entries, formations, location, defaultPort, vars) + } + + return false +} + +func parseFormation(formation string) (map[string]formationEntry, error) { + entries := make(map[string]formationEntry) + for _, formation := range strings.Split(formation, ",") { + parts := strings.Split(formation, "=") + if len(parts) != 2 { + return entries, fmt.Errorf("invalid formation: %s", formation) + } + + i, err := strconv.Atoi(parts[1]) + if err != nil { + return entries, fmt.Errorf("invalid formation: %s", err) + } + + entries[parts[0]] = formationEntry{ + Name: parts[0], + Count: i, + } + } + + return entries, nil +} + func deleteCommand(entries []procfileEntry, processType string, writePath string, stdout bool, delimiter string, path string) bool { var validEntries []procfileEntry for _, entry := range entries { @@ -315,7 +426,7 @@ func setCommand(entries []procfileEntry, processType string, command string, wri return outputProcfile(path, writePath, delimiter, stdout, validEntries) } -func showCommand(entries []procfileEntry, envPath string, allowGetenv bool, processType string, defaultPort string) bool { +func showCommand(entries []procfileEntry, envPath string, allowGetenv bool, processType string, defaultPort int) bool { var foundEntry procfileEntry for _, entry := range entries { if processType == entry.Name { @@ -340,11 +451,17 @@ func showCommand(entries []procfileEntry, envPath string, allowGetenv bool, proc } func main() { + workingDirectoryPath, err := os.Getwd() + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(1) + } + parser := argparse.NewParser("procfile-util", "A procfile parsing tool") loglevelFlag := parser.Selector("l", "loglevel", []string{"info", "debug"}, &argparse.Options{Default: "info", Help: "loglevel to use"}) procfileFlag := parser.String("P", "procfile", &argparse.Options{Default: "Procfile", Help: "path to a procfile"}) delimiterFlag := parser.String("D", "delimiter", &argparse.Options{Default: ":", Help: "delimiter in use within procfile"}) - defaultPortFlag := parser.String("d", "default-port", &argparse.Options{Default: "5000", Help: "default port to use"}) + defaultPortFlag := parser.Int("d", "default-port", &argparse.Options{Default: 5000, Help: "default port to use"}) versionFlag := parser.Flag("v", "version", &argparse.Options{Help: "show version"}) checkCmd := parser.NewCommand("check", "check that the specified procfile is valid") @@ -362,6 +479,23 @@ func main() { envPathExpandFlag := expandCmd.String("e", "env-file", &argparse.Options{Help: "path to a dotenv file"}) processTypeExpandFlag := expandCmd.String("p", "process-type", &argparse.Options{Help: "name of process to expand"}) + exportCmd := parser.NewCommand("export", "export the application to another process management format") + appExportFlag := exportCmd.String("", "app", &argparse.Options{Default: "app", Help: "name of app"}) + descriptionExportFlag := exportCmd.String("", "description", &argparse.Options{Help: "process description"}) + envPathExportFlag := exportCmd.String("e", "env-file", &argparse.Options{Help: "path to a dotenv file"}) + formatExportFlag := exportCmd.String("", "format", &argparse.Options{Help: "format to export"}) + formationExportFlag := exportCmd.String("", "formation", &argparse.Options{Default: "all=1", Help: "specify what processes will run and how many"}) + groupExportFlag := exportCmd.String("", "group", &argparse.Options{Help: "group to run the command as"}) + homeExportFlag := exportCmd.String("", "group", &argparse.Options{Help: "home directory for program"}) + limitOpenFilesExportFlag := exportCmd.String("", "limit-open-files", &argparse.Options{Help: "maximum number of open files, sockets, etc. (setrlimit RLIMIT_NOFILE)"}) + locationExportFlag := exportCmd.String("", "location", &argparse.Options{Help: "location to output to"}) + logPathExportFlag := exportCmd.String("", "log-path", &argparse.Options{Default: "/var/log", Help: "log directory"}) + niceExportFlag := exportCmd.String("", "nice", &argparse.Options{Help: "nice level to add to this program before running"}) + workingDirectoryPathExportFlag := exportCmd.String("", "working-directory-path", &argparse.Options{Default: workingDirectoryPath, Help: "working directory path for app"}) + runExportFlag := exportCmd.String("", "run", &argparse.Options{Help: "run pid file directory, defaults to /var/run/"}) + timeoutExportFlag := exportCmd.Int("", "timeout", &argparse.Options{Default: 5, Help: "amount of time (in seconds) processes have to shutdown gracefully before receiving a SIGKILL"}) + userExportFlag := exportCmd.String("", "user", &argparse.Options{Help: "user to run the command as"}) + listCmd := parser.NewCommand("list", "list all process types in a procfile") setCmd := parser.NewCommand("set", "set the command for a process type in a file") @@ -375,8 +509,7 @@ func main() { envPathShowFlag := showCmd.String("e", "env-file", &argparse.Options{Help: "path to a dotenv file"}) processTypeShowFlag := showCmd.String("p", "process-type", &argparse.Options{Help: "name of process to show", Required: true}) - err := parser.Parse(os.Args) - if err != nil { + if err = parser.Parse(os.Args); err != nil { fmt.Fprintf(os.Stderr, "%s\n", parser.Usage(err)) os.Exit(1) return @@ -406,6 +539,8 @@ func main() { success = existsCommand(entries, *processTypeExistsFlag) } else if expandCmd.Happened() { success = expandCommand(entries, *envPathExpandFlag, *allowGetenvExpandFlag, *processTypeExpandFlag, *defaultPortFlag, *delimiterFlag) + } else if exportCmd.Happened() { + success = exportCommand(entries, *appExportFlag, *descriptionExportFlag, *envPathExportFlag, *formatExportFlag, *formationExportFlag, *groupExportFlag, *homeExportFlag, *limitOpenFilesExportFlag, *locationExportFlag, *logPathExportFlag, *niceExportFlag, *workingDirectoryPathExportFlag, *runExportFlag, *timeoutExportFlag, *userExportFlag, *defaultPortFlag) } else if listCmd.Happened() { success = listCommand(entries) } else if setCmd.Happened() { diff --git a/templates/runit/log/run.tmpl b/templates/runit/log/run.tmpl new file mode 100644 index 0000000..730a502 --- /dev/null +++ b/templates/runit/log/run.tmpl @@ -0,0 +1,7 @@ +#!/bin/sh +set -e + +LOG={{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }} + +test -d "$LOG" || mkdir -p -m 2750 "$LOG" && chown {{ .user }} "$LOG" +exec chpst -u {{ .user }} svlogd "$LOG" diff --git a/templates/runit/run.tmpl b/templates/runit/run.tmpl new file mode 100644 index 0000000..03dc9cc --- /dev/null +++ b/templates/runit/run.tmpl @@ -0,0 +1,4 @@ +#!/bin/sh +cd {{ .working_directory }} +exec 2>&1 +exec chpst -u {{ .user }} -e {{ .location }}/{{ .app }}-{{ .process_type }}-{{ .num }}/env {{ .command }} diff --git a/templates/systemd-user/default/program.service.tmpl b/templates/systemd-user/default/program.service.tmpl new file mode 100644 index 0000000..e6cd0be --- /dev/null +++ b/templates/systemd-user/default/program.service.tmpl @@ -0,0 +1,16 @@ +[Unit] +{{- if .description }} +Description={{ .description }}{{ end }} + +[Service] +Type=simple +Environment=PORT={{ .port }} +Environment=PS={{ .app }}-{{ .process_name }} +EnvironmentFile=-{{ .home }}/.config/systemd/user/{{ .app }}-{{ .process_name }}.environment +ExecStart={{ .command }} +Restart=always +WorkingDirectory={{ .working_directory }} +StandardOutput=journal + +[Install] +WantedBy=multi-user.target diff --git a/templates/systemd/default/master.target.tmpl b/templates/systemd/default/master.target.tmpl new file mode 100644 index 0000000..ba4755f --- /dev/null +++ b/templates/systemd/default/master.target.tmpl @@ -0,0 +1,5 @@ +[Unit] +Wants={{ range $value := .processes }}{{ $value }} {{ end }} + +[Install] +WantedBy=multi-user.target diff --git a/templates/systemd/default/program.service.tmpl b/templates/systemd/default/program.service.tmpl new file mode 100644 index 0000000..d7a9137 --- /dev/null +++ b/templates/systemd/default/program.service.tmpl @@ -0,0 +1,33 @@ +[Unit] +{{- if .description }} +Description={{ .description }}{{ end }} +PartOf={{ .app }}.target +StopWhenUnneeded=yes + +[Service] +User={{ .user }} +Group={{ .group }} +WorkingDirectory={{ .working_directory }} +Environment=PORT={{ .port }} +Environment=PS={{ .app }}-{{ .process_name }} +EnvironmentFile=-/etc/default/{{ .app }} +EnvironmentFile=-/etc/sysconfig/{{ .app }} +{{- range $key, $value := .env }} +Environment="{{ $key }}={{ $value }}" +{{ end }} +ExecStart=/bin/bash -lc 'exec -a "{{ .app }}-{{ .process_name }}" {{ .command }}' +Restart=always +RestartSec=14s +StandardInput=null +StandardOutput=syslog +StandardError=syslog +SyslogIdentifier=%n +KillMode=mixed +TimeoutStopSec={{ .timeout }} + +{{- if .nice }} +Nice={{ .nice }} +{{ end }} +{{- if .limit_open_files }} +LimitNOFILE={{ .limit_open_files }} +{{ end }} From 9aff3cd18af021d617a50a224f36dfd4dd20f69c Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 11:39:00 -0400 Subject: [PATCH 03/48] fix: disable docker layer caching It isn't free anymore --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7be2716..fa4c93f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,7 +2,7 @@ version: 2 jobs: build: machine: - docker_layer_caching: true + docker_layer_caching: false steps: - checkout - run: From 78de20c224d02ef1fb0cbc1125d9c87408074fa0 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 11:42:17 -0400 Subject: [PATCH 04/48] fix: install go-bindata --- Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 49db4b0..1935bc7 100644 --- a/Makefile +++ b/Makefile @@ -42,8 +42,7 @@ targets = $(addsuffix -in-docker, $(LIST)) @echo "PACKAGECLOUD_TOKEN=$(PACKAGECLOUD_TOKEN)" >> .env.docker @echo "VERSION=$(VERSION)" >> .env.docker -build: - @go-bindata templates/... +build: prebuild @$(MAKE) build/darwin/$(NAME) @$(MAKE) build/linux/$(NAME) @$(MAKE) build/deb/$(NAME)_$(VERSION)_amd64.deb @@ -171,3 +170,7 @@ validate: ls -lah build/deb build/rpm validation sha1sum build/deb/$(NAME)_$(VERSION)_amd64.deb sha1sum build/rpm/$(NAME)-$(VERSION)-1.x86_64.rpm + +prebuild: + go get -u github.com/go-bindata/go-bindata/... + go-bindata templates/... From 9d8352fded6a67f5ac2698ce63bdbf8345acd9ea Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 12:21:57 -0400 Subject: [PATCH 05/48] feat: add support for launchd --- README.md | 2 +- bindata.go | 33 +++++++++++++++-- export.go | 55 ++++++++++++++++++++++++++++ main.go | 9 +++++ templates/launchd/launchd.plist.tmpl | 33 +++++++++++++++++ 5 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 templates/launchd/launchd.plist.tmpl diff --git a/README.md b/README.md index df76709..e30f1d7 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ In addition, not all formats support all arguments, and not all arguments have e ```shell # export systemd init files to the `tmp` directory -# support formats include: [runit, systemd, systemd-user] +# support formats include: [launchd, runit, systemd, systemd-user] # the default format is: systemd procfile-util export --format systemd --location tmpp diff --git a/bindata.go b/bindata.go index ef8ac50..e7388ee 100644 --- a/bindata.go +++ b/bindata.go @@ -1,5 +1,6 @@ // Code generated for package main by go-bindata DO NOT EDIT. (@generated) // sources: +// templates/launchd/launchd.plist.tmpl // templates/runit/log/run.tmpl // templates/runit/run.tmpl // templates/systemd/default/master.target.tmpl @@ -81,6 +82,26 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } +var _templatesLaunchdLaunchdPlistTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x93\x41\x6f\xda\x4e\x10\xc5\xef\x7c\x8a\xf9\x5b\x1c\xff\x78\xe1\x56\x45\xc6\x11\x0d\x54\x8a\x8a\x82\x95\x40\xab\x9e\xd0\xc6\x3b\x75\x56\xd8\xbb\xee\xec\x1a\x6a\x59\xfb\xdd\xab\x35\xb8\x98\x24\x54\x3d\xf5\x36\x1a\xbd\x79\xbf\x37\xab\xd9\xe8\xf6\x67\x91\xc3\x1e\xc9\x48\xad\xa6\xc1\x24\x1c\x07\x80\x2a\xd5\x42\xaa\x6c\x1a\x6c\xd6\x9f\x46\x1f\x82\xdb\x78\x10\xfd\x37\x5f\xdd\xad\xbf\x25\x0b\x28\x73\x69\x2c\x24\x9b\x8f\xcb\xfb\x3b\x08\x46\x8c\xcd\xca\x32\x47\xc6\xe6\xeb\x39\x24\xcb\xfb\xa7\x35\x4c\xc2\x31\x63\x8b\x87\x00\x82\x17\x6b\xcb\x1b\xc6\x0e\x87\x43\xc8\xbd\x2a\x4c\x75\xe1\x85\x86\x25\xa4\x4b\x24\x5b\x2f\xa5\xb1\xa3\x49\x38\x0e\x85\x15\x41\x3c\x88\x8e\xee\x17\x71\xe2\x41\x24\x64\x6a\xe3\x01\x00\x40\xb4\xc3\x3a\x5e\xf2\x67\xcc\x23\xe6\xcb\x63\xd3\x58\x92\x2a\x8b\x9b\x06\x3c\x07\x9c\x1b\xf9\xb2\x24\x9d\xa2\x31\x5b\x5b\x97\xd8\xf5\x54\x55\x80\x73\x11\x3b\x4d\x9c\x3d\x17\x6a\x2f\x49\xab\x02\x95\xfd\xc2\x49\xf2\xe7\x1c\x4d\x1f\x71\x8e\xf0\x7b\x24\x59\x3d\xae\x7b\x92\xd7\x49\x4a\x4d\xf6\x0d\xab\x69\x46\x40\x5c\x65\x08\xc3\x1d\xd6\xff\xc3\x70\xcf\xf3\x0a\xe1\x66\x0a\x21\xaa\x3d\x38\x77\x89\x68\x9a\x56\xd7\xda\x5c\x03\x9d\x2c\x7a\xa4\xa6\x01\x54\xa2\x33\x8b\xd8\xab\xe7\x4b\x48\x67\xc4\x8b\x19\x65\x95\x5f\xf7\x62\x4d\x4e\xc4\xeb\x37\x51\x53\x5d\x14\x5c\x89\x36\xe6\xa9\xde\x72\xca\xcc\x45\xde\x33\x5c\x7e\x07\xfc\x71\x9e\x0a\x86\xfe\xa5\x02\x70\xce\xa7\xed\xde\xc5\x87\xcc\x0d\x9e\xba\x9d\xf6\xd8\x6f\x8b\xab\xeb\xf4\x32\xb6\xfb\x7c\x46\x2c\x67\xb9\xdc\x63\x7f\x11\x4b\x15\xb2\x9e\xe8\xb1\x52\x33\xbb\xd4\x5c\xfc\x49\xf4\x64\xb9\x12\x9c\xc4\xaa\xb2\x09\xb7\x2f\x57\x4e\x2c\xd7\x19\x38\xc7\xce\xd7\xc6\xfe\xfa\xf0\xfc\xec\x3b\xc7\xd7\x71\x17\x44\x9a\xfe\x29\x79\x63\x90\x1e\x78\x81\x57\x80\x95\x41\x7a\xff\xbf\x7c\xd5\xb4\x93\x2a\x9b\x4b\xc2\xd4\x6a\xaa\xaf\x18\x1c\x8e\xb2\xad\xe8\x74\x17\x6e\xdd\x69\x46\xac\xfd\xf7\xf1\xe0\x57\x00\x00\x00\xff\xff\x2d\x1b\xa9\x26\x8e\x04\x00\x00") + +func templatesLaunchdLaunchdPlistTmplBytes() ([]byte, error) { + return bindataRead( + _templatesLaunchdLaunchdPlistTmpl, + "templates/launchd/launchd.plist.tmpl", + ) +} + +func templatesLaunchdLaunchdPlistTmpl() (*asset, error) { + bytes, err := templatesLaunchdLaunchdPlistTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/launchd/launchd.plist.tmpl", size: 1166, mode: os.FileMode(420), modTime: time.Unix(1584462008, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + var _templatesRunitLogRunTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x8c\xcf\x0a\x82\x40\x10\x87\xef\xf3\x14\xbf\x2c\xbc\x6d\x46\x10\x9d\x3a\x7b\x11\x7c\x84\xa8\x75\x50\x49\xdd\xc5\x59\xfb\x83\xce\xbb\xc7\x42\x1e\xba\x7d\xcc\x37\xbf\x6f\xbb\xc9\xee\xed\x90\x49\x43\xc2\x01\x86\x89\x8a\x32\xbf\xcc\x33\xf6\x9d\xab\xa1\x9a\x45\xbc\x79\xbf\xa2\x1f\x9d\x65\x91\x6b\xf8\x78\x86\xaa\x89\xb7\x61\xea\xa1\x4a\x14\x58\x02\x4c\x85\x64\x57\x94\x79\x82\x65\x41\xff\xa8\xda\x11\xc6\xc3\xf4\x38\x9e\x4f\x87\x55\xa5\x29\x6c\xe3\x5e\x03\xe2\x7c\x12\x1e\xa1\xfa\x73\xc4\x6f\xb6\xb0\x8d\x8f\xad\xe9\xef\x41\x9e\x9d\xab\xd7\x3c\x7d\x03\x00\x00\xff\xff\x0a\xaa\x1d\x31\xba\x00\x00\x00") func templatesRunitLogRunTmplBytes() ([]byte, error) { @@ -141,7 +162,7 @@ func templatesSystemdDefaultMasterTargetTmpl() (*asset, error) { return a, nil } -var _templatesSystemdDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x92\xc1\x6a\xe3\x3c\x10\x80\xef\x7e\x0a\x11\xfa\xd3\xcb\x9f\x98\x85\x3d\x2d\xe8\xd6\x74\x09\xdb\x6d\x4a\xdd\xd0\x43\x29\x41\x95\xc6\xee\x50\x79\x64\x46\xe3\x34\xc6\xf8\xdd\x17\xa9\x9b\xa4\xb4\xbb\x7b\xb2\xf4\xcd\x37\xa3\xd1\x58\x0f\x1b\x42\x79\x2c\xc6\x71\xae\xb0\x56\x0b\x07\xd1\x32\x76\x82\x81\xd4\x34\x15\x17\xa7\xad\x1e\xc7\x4f\xe1\x71\x54\x40\x2e\xad\x6e\x0c\xcb\xba\xce\x8e\xe9\x3a\x35\x4d\x0b\x31\xdc\x80\x14\x95\x84\xee\xfe\x19\x68\x43\x04\xe0\xc0\xe9\x01\x62\x51\x3c\x54\xc0\x3b\xb4\xf0\x58\x6c\x22\x70\x4e\xeb\x23\x70\xaa\xf4\x9d\x43\xdf\x65\xd2\xa4\x55\x42\xf7\x81\x5f\x90\x9a\x0b\x64\xb0\x12\x78\xc8\xd1\xd7\x37\xb8\x75\x07\x9a\xcc\x25\xed\x90\x03\xb5\x40\xa2\x6f\xd6\xb7\x77\xd9\xec\x02\xcb\xa7\x60\xf5\xae\xd7\x79\xb6\x38\x58\x88\x71\x4b\xa6\x85\x0f\xf6\x25\x7a\xd0\xf3\x12\xc4\x96\x0e\x6a\xd3\x7b\x29\x0f\xc9\x7f\x37\xe3\x10\x6d\xa0\x1a\x9b\xf2\x74\x50\x1e\x33\x1b\x6a\x40\x9d\xbd\xc0\xf0\xbf\x3a\xdb\x19\xdf\x83\xfa\xa6\xd5\x02\x68\xf7\xb1\xc9\xd9\x38\x66\x4f\x4d\x53\xea\xf6\xb7\x3c\x4d\xb3\x77\x83\x5f\xee\xc1\x56\x62\x58\x74\xf9\x84\x54\x3e\x99\xf8\xac\xe6\xde\xaa\x73\xd8\x83\x55\x73\xa3\x66\xff\xbe\xe7\x4c\x25\x68\x43\xdb\x9a\x5c\xf0\xbc\xb8\x85\x98\xeb\x19\xff\x6a\x86\x78\xd8\x56\x60\xf5\x97\xaf\xb1\xa8\xc4\x90\x33\xec\x56\xd4\xf5\xa2\xa9\xf7\xfe\x88\xd6\xbd\x24\x16\x87\xe8\x43\x73\xa4\x4b\xe6\xc0\x47\x98\x3f\x2b\x07\x24\x58\x23\xb0\xfe\x8f\x8a\x1f\xe8\xfd\xcf\xe0\x40\xb7\xb8\x07\x57\xdc\x61\x0b\xa1\x97\xf4\x6e\xd2\x99\xa9\x3b\x79\x43\xe9\xba\xc7\x87\x4a\x68\xf3\x6f\xba\x46\x0b\x59\x3a\x80\xd3\x68\x0e\xaa\xc7\x16\x65\x1b\x3a\xa0\x6d\x8d\x1e\x62\x8a\x5d\x25\x76\xbd\xbe\x5c\x5d\x2d\x73\xf6\x9f\x9c\x53\xa5\x5f\x01\x00\x00\xff\xff\xcd\x06\x2d\xbd\x25\x03\x00\x00") +var _templatesSystemdDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x92\x51\x6b\xdb\x3e\x10\xc0\xdf\xf5\x29\x44\xe8\x9f\xbe\xfc\x13\x33\xd8\xd3\xc0\x6f\x4d\x47\x58\xd7\x94\xba\xa1\x0f\xa5\x04\x55\x3a\xbb\x47\xe5\x93\x39\x9d\xd3\x18\xe3\xef\x3e\xa4\x2e\xc9\xc8\x36\xd8\x93\xa5\xdf\xfd\xee\x74\x27\xeb\x69\x43\x28\xcf\x6a\x1c\xe7\x1a\x6b\xbd\x70\x10\x2d\x63\x27\x18\x48\x4f\x93\xba\x3a\x6d\xcb\x71\x3c\x0f\x8f\xa3\x06\x72\xc9\xbb\x33\x2c\xeb\x3a\x2b\xa6\xeb\xf4\x34\x2d\xc4\x70\x03\xa2\x2a\x09\xdd\xe3\x2b\xd0\x86\x08\xc0\x81\x2b\x07\x88\x4a\x3d\x55\xc0\x3b\xb4\xf0\xac\x36\x11\x38\xa7\xf5\x11\x38\x55\xfa\xca\xa1\xef\x32\x69\xd2\x2a\xa1\xc7\xc0\x6f\x48\xcd\x15\x32\x58\x09\x3c\xe4\xe8\xfb\x07\xdc\xba\x03\x4d\xe6\x92\x76\xc8\x81\x5a\x20\x29\xef\xd6\xf7\x0f\xd9\xec\x02\xcb\x6f\xc1\xea\x97\x5e\xe7\xd9\xe2\x60\x21\xc6\xad\x0c\x1d\xa4\xfe\x13\xa3\xbe\x3d\x4b\xbc\x46\x0f\xe5\xbc\x00\xb1\x85\x83\xda\xf4\x5e\x8a\x43\x9d\xbf\x9b\x71\x88\x36\x50\x8d\x4d\x71\x3a\x33\x5f\x38\x1b\x6a\x40\x5f\xbc\xc1\xf0\xbf\xbe\xd8\x19\xdf\x83\xfe\x52\xea\x05\xd0\xee\xbc\xdf\xd9\x38\x66\x4f\x4f\x53\x6a\xfc\xa7\x3c\x4d\x33\x75\xfa\x07\xcb\x3d\xd8\x4a\x0c\x4b\x59\xbc\x20\x15\x2f\x26\xbe\xea\xb9\xb7\xfa\x12\xf6\x60\xf5\xdc\xe8\xd9\x3f\x8f\x3c\xd3\x69\x6d\x43\xdb\x9a\x5c\xfb\x52\xdd\x43\xcc\xa5\x8d\x7f\x37\x43\x3c\x6c\x2b\xb0\xe5\xa7\xcf\x51\x55\x62\xc8\x19\x76\x2b\xea\x7a\x29\xa9\xf7\xfe\x88\xd6\xbd\x24\x16\x87\xe8\x43\x73\xa4\x4b\xe6\xc0\x47\x98\x3f\x2b\x07\x24\x58\x23\x70\xf9\x1f\xa9\x6f\xe8\xfd\xf7\xe0\xa0\x6c\x71\x0f\x4e\x3d\x60\x0b\xa1\x97\xf4\x9a\xd2\x99\xa9\x3b\xf9\x40\x69\xf2\xe3\xeb\x25\xb4\x69\x12\x75\x8b\x16\xb2\x74\x00\xa7\x5b\x3a\xa8\x1e\x5b\x94\x6d\xe8\x80\xb6\x35\x7a\x88\x29\x76\x93\xd8\xed\xfa\x7a\x75\xb3\xcc\xd9\x7f\x72\x4e\x95\x7e\x04\x00\x00\xff\xff\xb7\xf7\x3a\x4f\x3a\x03\x00\x00") func templatesSystemdDefaultProgramServiceTmplBytes() ([]byte, error) { return bindataRead( @@ -156,12 +177,12 @@ func templatesSystemdDefaultProgramServiceTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/systemd/default/program.service.tmpl", size: 805, mode: os.FileMode(420), modTime: time.Unix(1584458757, 0)} + info := bindataFileInfo{name: "templates/systemd/default/program.service.tmpl", size: 826, mode: os.FileMode(420), modTime: time.Unix(1584460118, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templatesSystemdUserDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x8f\x41\x6a\xf3\x30\x10\x85\xf7\x3a\x85\x2f\x10\xfb\x04\xde\xfc\x24\x3f\x74\x95\x12\xa7\x64\x11\x42\x18\xa4\x89\x3b\xad\x34\x12\xa3\x71\x52\x63\x7c\xf7\x62\x85\x12\x9a\x45\x97\x7a\xdf\x37\x8f\xa7\xe3\x1b\x93\x9e\xcc\x34\xad\x2a\xba\x54\xb5\xc3\x6c\x85\x92\x52\xe4\x6a\x9e\xcd\xfa\xf1\x6c\xa7\xe9\x19\x4f\x53\x85\xec\x16\xaf\x32\xc7\x0e\xe5\x4a\x16\x4f\x66\x3f\x26\x6c\x33\x85\xe4\xd1\x6c\xf8\x4a\x12\x39\x20\x6b\xfb\xba\xdd\xed\x4b\x49\x8a\xa2\xcb\xd1\x2f\xd8\x15\x04\x29\x55\xf3\xbc\x2a\x96\x44\x8b\x39\x9f\x19\x02\x3e\xd9\xff\xc9\x63\x5b\xa4\xf7\x58\x60\x53\xdb\xc8\x17\xea\x9b\x3c\x66\xc5\xe0\x9a\x21\xa3\x34\x7f\x17\xd6\xf8\x28\x34\x9b\x2f\xb4\x9d\x82\x68\x59\x61\x63\x08\x70\xff\xd8\x0e\x73\x89\xc1\xdf\x60\xcc\xe6\x10\xe5\x93\xb8\x5f\x93\xa0\xd5\x28\x63\xd1\x6f\xf7\xf0\xec\x7e\xd2\xe5\xb0\x53\x60\x07\xe2\xb6\x83\xa6\x41\xdb\x8f\x38\x08\x83\x37\xe6\xf8\xc2\x59\xc1\xfb\x93\x39\x00\x2b\xba\x7f\x63\x1b\x06\xaf\xb4\x5a\x26\xd7\x0a\xd2\xa3\x9a\xef\x00\x00\x00\xff\xff\x46\xb5\xdd\x93\x95\x01\x00\x00") +var _templatesSystemdUserDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x8f\x41\x6a\xf3\x30\x10\x85\xf7\x3a\x85\x2e\x10\xfb\x04\xde\xfc\x24\x3f\x74\x95\x12\xa7\x64\x11\x42\x10\xd2\xc4\x9d\x56\x1a\x89\xd1\x38\xa9\x31\xbe\x7b\x91\x42\x09\xcd\xaa\x4b\x7d\xef\x7b\x8f\xd1\xf1\x8d\x50\x4e\x6a\x9e\x57\x1a\x2f\xba\x71\x90\x2d\x63\x12\x8c\xa4\x97\x45\xad\x1f\xcf\x6e\x9e\x9f\xe3\x79\xd6\x40\xae\x78\x5a\x1d\x7b\xe0\x2b\x5a\x38\xa9\xfd\x94\xa0\xcb\x18\x92\x07\xb5\xa1\x2b\x72\xa4\x00\x24\xdd\xeb\x76\xb7\xaf\x23\x29\xb2\x94\xd2\xaf\xb0\xaf\x91\x49\x49\x2f\xcb\xaa\x5a\x1c\x2d\xe4\x7c\x96\x29\x81\x5e\x96\xa6\x30\x1a\xc3\x53\xf1\x3f\x7a\xe8\xaa\xff\x1e\x43\xf1\xda\xc6\x46\xba\xe0\xd0\xe6\x29\x0b\x04\xd7\x8e\x19\xb8\xfd\xf3\x76\x03\x8f\x6d\xb5\xf9\x02\xdb\x8b\x61\xa9\xb7\xd9\x18\x82\xb9\x7f\x77\x07\xb9\x62\xe3\x6f\x66\xca\xea\x10\xf9\x13\x69\x58\x23\x83\x95\xc8\x53\xd5\x6f\x77\x78\x76\x3f\xb4\x14\x7b\x31\xe4\x0c\xbb\xed\x28\x69\x94\xee\x23\x8e\x4c\xc6\x2b\x75\x7c\xa1\x2c\xc6\xfb\x93\x3a\x18\x12\x70\xff\xa6\x2e\x8c\x5e\x70\x55\xae\x6f\xc4\xf0\x00\xa2\xbe\x03\x00\x00\xff\xff\x88\xfb\xad\x15\xab\x01\x00\x00") func templatesSystemdUserDefaultProgramServiceTmplBytes() ([]byte, error) { return bindataRead( @@ -176,7 +197,7 @@ func templatesSystemdUserDefaultProgramServiceTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/systemd-user/default/program.service.tmpl", size: 405, mode: os.FileMode(420), modTime: time.Unix(1584458760, 0)} + info := bindataFileInfo{name: "templates/systemd-user/default/program.service.tmpl", size: 427, mode: os.FileMode(420), modTime: time.Unix(1584460126, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -233,6 +254,7 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ + "templates/launchd/launchd.plist.tmpl": templatesLaunchdLaunchdPlistTmpl, "templates/runit/log/run.tmpl": templatesRunitLogRunTmpl, "templates/runit/run.tmpl": templatesRunitRunTmpl, "templates/systemd/default/master.target.tmpl": templatesSystemdDefaultMasterTargetTmpl, @@ -282,6 +304,9 @@ type bintree struct { var _bintree = &bintree{nil, map[string]*bintree{ "templates": &bintree{nil, map[string]*bintree{ + "launchd": &bintree{nil, map[string]*bintree{ + "launchd.plist.tmpl": &bintree{templatesLaunchdLaunchdPlistTmpl, map[string]*bintree{}}, + }}, "runit": &bintree{nil, map[string]*bintree{ "log": &bintree{nil, map[string]*bintree{ "run.tmpl": &bintree{templatesRunitLogRunTmpl, map[string]*bintree{}}, diff --git a/export.go b/export.go index 390f75b..59f80f0 100644 --- a/export.go +++ b/export.go @@ -7,6 +7,61 @@ import ( "text/template" ) +func exportLaunchd(app string, entries []procfileEntry, formations map[string]formationEntry, location string, defaultPort int, vars map[string]interface{}) bool { + service, err := Asset("templates/launchd/launchd.plist.tmpl") + if err != nil { + fmt.Fprintf(os.Stderr, "error: %s\n", err) + return false + } + + s, err := template.New("service").Parse(string(service)) + if err != nil { + fmt.Fprintf(os.Stderr, "error parsing template: %s\n", err) + return false + } + + if _, err := os.Stat(location); os.IsNotExist(err) { + os.MkdirAll(location, os.ModePerm) + } + + for i, entry := range entries { + count := processCount(entry, formations) + + num := 1 + for num <= count { + processName := fmt.Sprintf("%s-%d", entry.Name, num) + fmt.Println("writing:", app+"-"+processName+".plist") + + config := vars + config["command"] = entry.Command + config["command_args"] = entry.commandArgs() + config["num"] = num + config["port"] = strconv.Itoa(portFor(i, num, defaultPort)) + config["process_name"] = processName + config["process_type"] = entry.Name + if config["description"] == "" { + config["description"] = fmt.Sprintf("%s process for %s", processName, app) + } + + f, err := os.Create(location + "/" + app + "-" + processName + ".plist") + if err != nil { + fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) + return false + } + defer f.Close() + + if err = s.Execute(f, config); err != nil { + fmt.Fprintf(os.Stderr, "error writing output: %s\n", err) + return false + } + + num += 1 + } + } + + return true +} + func exportRunit(app string, entries []procfileEntry, formations map[string]formationEntry, location string, defaultPort int, vars map[string]interface{}) bool { run, err := Asset("templates/runit/run.tmpl") if err != nil { diff --git a/main.go b/main.go index 1fe66ab..d082210 100644 --- a/main.go +++ b/main.go @@ -25,6 +25,10 @@ type formationEntry struct { Count int } +func (p *procfileEntry) commandArgs() []string { + return strings.Fields(p.Command) +} + const portEnvVar = "PORT" // Version contains the procfile-util version @@ -299,6 +303,7 @@ func exportCommand(entries []procfileEntry, app string, description string, envP return false } formats := map[string]bool{ + "launchd": true, "runit": true, "systemd": true, "systemd-user": true, @@ -357,6 +362,10 @@ func exportCommand(entries []procfileEntry, app string, description string, envP vars["timeout"] = strconv.Itoa(timeout) vars["user"] = user + if format == "launchd" { + return exportLaunchd(app, entries, formations, location, defaultPort, vars) + } + if format == "runit" { return exportRunit(app, entries, formations, location, defaultPort, vars) } diff --git a/templates/launchd/launchd.plist.tmpl b/templates/launchd/launchd.plist.tmpl new file mode 100644 index 0000000..6e34ee6 --- /dev/null +++ b/templates/launchd/launchd.plist.tmpl @@ -0,0 +1,33 @@ + + + + + Label + {{ .app }}-{{ .process_type }}-{{ .num }} + EnvironmentVariables + + PORT + {{ .port }} + {{- range $key, $value := .env }} + {{ $key }} + {{ $value }}{{ end }} + + ProgramArguments + + {{- range $command := .command_args }} + {{ if eq $command "$PORT" }}{{ $.port }}{{ else }}{{ $command }}{{ end }}{{ end }} + + KeepAlive + + RunAtLoad + + StandardOutPath + {{ .log }}/{{ .app }}/{{ .app }}-{{ .process_type }}-{{ .num }}.log + StandardErrorPath + {{ .log }}/{{ .app }}/{{ .app }}-{{ .process_type }}-{{ .num }}.log + UserName + {{ .user }} + WorkingDirectory + {{ .working_directory }} + + From 5cb02e7c2999c1757c9d39a5eb2577869eab3d6d Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 12:23:49 -0400 Subject: [PATCH 06/48] feat: minor fixes around file and process names --- export.go | 15 +++++++++------ .../systemd-user/default/program.service.tmpl | 4 ++-- templates/systemd/default/program.service.tmpl | 4 ++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/export.go b/export.go index 59f80f0..75a0839 100644 --- a/export.go +++ b/export.go @@ -98,7 +98,7 @@ func exportRunit(app string, entries []procfileEntry, formations map[string]form for num <= count { processDirectory := fmt.Sprintf("%s-%s-%d", app, entry.Name, num) folderPath := location + "/" + processDirectory - processName := fmt.Sprintf("%s.%d", entry.Name, num) + processName := fmt.Sprintf("%s-%d", entry.Name, num) fmt.Println("creating:", app+"-"+processName) os.MkdirAll(folderPath, os.ModePerm) @@ -113,6 +113,7 @@ func exportRunit(app string, entries []procfileEntry, formations map[string]form config := vars config["command"] = entry.Command + config["command_args"] = entry.commandArgs() config["num"] = num config["port"] = port config["process_name"] = processName @@ -230,12 +231,14 @@ func exportSystemd(app string, entries []procfileEntry, formations map[string]fo num := 1 for num <= count { - processName := fmt.Sprintf("%s.%d", entry.Name, num) - processes = append(processes, fmt.Sprintf("%s.service", processName)) - fmt.Println("writing:", app+"-"+processName+".service") + processName := fmt.Sprintf("%s-%d", entry.Name, num) + fileName := fmt.Sprintf("%s.%d", entry.Name, num) + processes = append(processes, fmt.Sprintf(app+"-%s.service", fileName)) + fmt.Println("writing:", app+"-"+fileName+".service") config := vars config["command"] = entry.Command + config["command_args"] = entry.commandArgs() config["num"] = num config["port"] = portFor(i, num, defaultPort) config["process_name"] = processName @@ -244,7 +247,7 @@ func exportSystemd(app string, entries []procfileEntry, formations map[string]fo config["description"] = fmt.Sprintf("%s process for %s", processName, app) } - f, err := os.Create(location + "/" + app + "-" + processName + ".service") + f, err := os.Create(location + "/" + app + "-" + fileName + ".service") if err != nil { fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) return false @@ -301,7 +304,7 @@ func exportSystemdUser(app string, entries []procfileEntry, formations map[strin num := 1 for num <= count { - processName := fmt.Sprintf("%s.%d", entry.Name, num) + processName := fmt.Sprintf("%s-%d", entry.Name, num) processes = append(processes, fmt.Sprintf("%s.service", processName)) fmt.Println("writing:", app+"-"+processName+".service") diff --git a/templates/systemd-user/default/program.service.tmpl b/templates/systemd-user/default/program.service.tmpl index e6cd0be..690433e 100644 --- a/templates/systemd-user/default/program.service.tmpl +++ b/templates/systemd-user/default/program.service.tmpl @@ -5,8 +5,8 @@ Description={{ .description }}{{ end }} [Service] Type=simple Environment=PORT={{ .port }} -Environment=PS={{ .app }}-{{ .process_name }} -EnvironmentFile=-{{ .home }}/.config/systemd/user/{{ .app }}-{{ .process_name }}.environment +Environment=PS={{ .app }}-{{ .process_type }}.{{ .num }} +EnvironmentFile=-{{ .home }}/.config/systemd/user/{{ .app }}-{{ .process_type }}.{{ .num }}.environment ExecStart={{ .command }} Restart=always WorkingDirectory={{ .working_directory }} diff --git a/templates/systemd/default/program.service.tmpl b/templates/systemd/default/program.service.tmpl index d7a9137..51b3f7c 100644 --- a/templates/systemd/default/program.service.tmpl +++ b/templates/systemd/default/program.service.tmpl @@ -9,13 +9,13 @@ User={{ .user }} Group={{ .group }} WorkingDirectory={{ .working_directory }} Environment=PORT={{ .port }} -Environment=PS={{ .app }}-{{ .process_name }} +Environment=PS={{ .app }}-{{ .process_type }}.{{ .num }} EnvironmentFile=-/etc/default/{{ .app }} EnvironmentFile=-/etc/sysconfig/{{ .app }} {{- range $key, $value := .env }} Environment="{{ $key }}={{ $value }}" {{ end }} -ExecStart=/bin/bash -lc 'exec -a "{{ .app }}-{{ .process_name }}" {{ .command }}' +ExecStart=/bin/bash -lc 'exec -a "{{ .app }}-{{ .process_type }}.{{ .num }}" {{ .command }}' Restart=always RestartSec=14s StandardInput=null From e3766fb8cb10b24702e23356a1c08bfffeacc3bd Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 13:06:09 -0400 Subject: [PATCH 07/48] chore: rename master => control --- export.go | 2 +- .../systemd/default/{master.target.tmpl => control.target.tmpl} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename templates/systemd/default/{master.target.tmpl => control.target.tmpl} (100%) diff --git a/export.go b/export.go index 75a0839..2c83dec 100644 --- a/export.go +++ b/export.go @@ -197,7 +197,7 @@ func exportRunit(app string, entries []procfileEntry, formations map[string]form } func exportSystemd(app string, entries []procfileEntry, formations map[string]formationEntry, location string, defaultPort int, vars map[string]interface{}) bool { - target, err := Asset("templates/systemd/default/master.target.tmpl") + target, err := Asset("templates/systemd/default/control.target.tmpl") if err != nil { fmt.Fprintf(os.Stderr, "error: %s\n", err) return false diff --git a/templates/systemd/default/master.target.tmpl b/templates/systemd/default/control.target.tmpl similarity index 100% rename from templates/systemd/default/master.target.tmpl rename to templates/systemd/default/control.target.tmpl From 27afee91e765f198dbc9759983003bb6a0556b82 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 13:06:28 -0400 Subject: [PATCH 08/48] feat: add ps variable --- export.go | 4 ++++ templates/systemd-user/default/program.service.tmpl | 4 ++-- templates/systemd/default/program.service.tmpl | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/export.go b/export.go index 2c83dec..6c8aea5 100644 --- a/export.go +++ b/export.go @@ -39,6 +39,7 @@ func exportLaunchd(app string, entries []procfileEntry, formations map[string]fo config["port"] = strconv.Itoa(portFor(i, num, defaultPort)) config["process_name"] = processName config["process_type"] = entry.Name + config["ps"] = app + "-" + entry.Name + "." + num if config["description"] == "" { config["description"] = fmt.Sprintf("%s process for %s", processName, app) } @@ -118,6 +119,7 @@ func exportRunit(app string, entries []procfileEntry, formations map[string]form config["port"] = port config["process_name"] = processName config["process_type"] = entry.Name + config["ps"] = app + "-" + entry.Name + "." + num if config["description"] == "" { config["description"] = fmt.Sprintf("%s process for %s", processName, app) } @@ -243,6 +245,7 @@ func exportSystemd(app string, entries []procfileEntry, formations map[string]fo config["port"] = portFor(i, num, defaultPort) config["process_name"] = processName config["process_type"] = entry.Name + config["ps"] = app + "-" + entry.Name + "." + num if config["description"] == "" { config["description"] = fmt.Sprintf("%s process for %s", processName, app) } @@ -314,6 +317,7 @@ func exportSystemdUser(app string, entries []procfileEntry, formations map[strin config["port"] = portFor(i, num, defaultPort) config["process_name"] = processName config["process_type"] = entry.Name + config["ps"] = app + "-" + entry.Name + "." + num if config["description"] == "" { config["description"] = fmt.Sprintf("%s process for %s", processName, app) } diff --git a/templates/systemd-user/default/program.service.tmpl b/templates/systemd-user/default/program.service.tmpl index 690433e..415722f 100644 --- a/templates/systemd-user/default/program.service.tmpl +++ b/templates/systemd-user/default/program.service.tmpl @@ -5,8 +5,8 @@ Description={{ .description }}{{ end }} [Service] Type=simple Environment=PORT={{ .port }} -Environment=PS={{ .app }}-{{ .process_type }}.{{ .num }} -EnvironmentFile=-{{ .home }}/.config/systemd/user/{{ .app }}-{{ .process_type }}.{{ .num }}.environment +Environment=PS={{ .ps }} +EnvironmentFile=-{{ .home }}/.config/systemd/user/{{ .ps }}.environment ExecStart={{ .command }} Restart=always WorkingDirectory={{ .working_directory }} diff --git a/templates/systemd/default/program.service.tmpl b/templates/systemd/default/program.service.tmpl index 51b3f7c..9fd44b0 100644 --- a/templates/systemd/default/program.service.tmpl +++ b/templates/systemd/default/program.service.tmpl @@ -9,13 +9,13 @@ User={{ .user }} Group={{ .group }} WorkingDirectory={{ .working_directory }} Environment=PORT={{ .port }} -Environment=PS={{ .app }}-{{ .process_type }}.{{ .num }} +Environment=PS={{ .ps }} EnvironmentFile=-/etc/default/{{ .app }} EnvironmentFile=-/etc/sysconfig/{{ .app }} {{- range $key, $value := .env }} Environment="{{ $key }}={{ $value }}" {{ end }} -ExecStart=/bin/bash -lc 'exec -a "{{ .app }}-{{ .process_type }}.{{ .num }}" {{ .command }}' +ExecStart=/bin/bash -lc 'exec -a "{{ .ps }}" {{ .command }}' Restart=always RestartSec=14s StandardInput=null From 1759f8331be485b5a2ad1d21c6a43bd59204eb0a Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 13:06:41 -0400 Subject: [PATCH 09/48] feat: set PS for launchd apps --- templates/launchd/launchd.plist.tmpl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/launchd/launchd.plist.tmpl b/templates/launchd/launchd.plist.tmpl index 6e34ee6..c1b3700 100644 --- a/templates/launchd/launchd.plist.tmpl +++ b/templates/launchd/launchd.plist.tmpl @@ -8,6 +8,8 @@ PORT {{ .port }} + PS + {{ .ps }} {{- range $key, $value := .env }} {{ $key }} {{ $value }}{{ end }} From 2a01ba883cee01138f177a218e69437fbffd129f Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 13:11:55 -0400 Subject: [PATCH 10/48] refactor: move template variable generation to a function --- export.go | 67 +++++++++++++++++++------------------------------------ 1 file changed, 23 insertions(+), 44 deletions(-) diff --git a/export.go b/export.go index 6c8aea5..72e7b7c 100644 --- a/export.go +++ b/export.go @@ -32,17 +32,8 @@ func exportLaunchd(app string, entries []procfileEntry, formations map[string]fo processName := fmt.Sprintf("%s-%d", entry.Name, num) fmt.Println("writing:", app+"-"+processName+".plist") - config := vars - config["command"] = entry.Command - config["command_args"] = entry.commandArgs() - config["num"] = num - config["port"] = strconv.Itoa(portFor(i, num, defaultPort)) - config["process_name"] = processName - config["process_type"] = entry.Name - config["ps"] = app + "-" + entry.Name + "." + num - if config["description"] == "" { - config["description"] = fmt.Sprintf("%s process for %s", processName, app) - } + port := portFor(i, num, defaultPort) + config := templateVars(app, entry, processName, num, port, vars) f, err := os.Create(location + "/" + app + "-" + processName + ".plist") if err != nil { @@ -111,18 +102,7 @@ func exportRunit(app string, entries []procfileEntry, formations map[string]form os.MkdirAll(folderPath+"/log", os.ModePerm) port := portFor(i, num, defaultPort) - - config := vars - config["command"] = entry.Command - config["command_args"] = entry.commandArgs() - config["num"] = num - config["port"] = port - config["process_name"] = processName - config["process_type"] = entry.Name - config["ps"] = app + "-" + entry.Name + "." + num - if config["description"] == "" { - config["description"] = fmt.Sprintf("%s process for %s", processName, app) - } + config := templateVars(app, entry, processName, num, port, vars) fmt.Println("writing:", app+"-"+processName+"/run") f, err := os.Create(folderPath + "/run") @@ -238,17 +218,8 @@ func exportSystemd(app string, entries []procfileEntry, formations map[string]fo processes = append(processes, fmt.Sprintf(app+"-%s.service", fileName)) fmt.Println("writing:", app+"-"+fileName+".service") - config := vars - config["command"] = entry.Command - config["command_args"] = entry.commandArgs() - config["num"] = num - config["port"] = portFor(i, num, defaultPort) - config["process_name"] = processName - config["process_type"] = entry.Name - config["ps"] = app + "-" + entry.Name + "." + num - if config["description"] == "" { - config["description"] = fmt.Sprintf("%s process for %s", processName, app) - } + port := portFor(i, num, defaultPort) + config := templateVars(app, entry, processName, num, port, vars) f, err := os.Create(location + "/" + app + "-" + fileName + ".service") if err != nil { @@ -311,16 +282,8 @@ func exportSystemdUser(app string, entries []procfileEntry, formations map[strin processes = append(processes, fmt.Sprintf("%s.service", processName)) fmt.Println("writing:", app+"-"+processName+".service") - config := vars - config["command"] = entry.Command - config["num"] = num - config["port"] = portFor(i, num, defaultPort) - config["process_name"] = processName - config["process_type"] = entry.Name - config["ps"] = app + "-" + entry.Name + "." + num - if config["description"] == "" { - config["description"] = fmt.Sprintf("%s process for %s", processName, app) - } + port := portFor(i, num, defaultPort) + config := templateVars(app, entry, processName, num, port, vars) f, err := os.Create(location + "/" + app + "-" + processName + ".service") if err != nil { @@ -355,3 +318,19 @@ func processCount(entry procfileEntry, formations map[string]formationEntry) int func portFor(processIndex int, instance int, base int) int { return 5000 + (processIndex * 100) + (instance - 1) } + +func templateVars(app string, entry procfileEntry, processName string, num int, port int, vars map[string]interface{}) map[string]interface{} { + config := vars + config["command"] = entry.Command + config["command_args"] = entry.commandArgs() + config["num"] = num + config["port"] = strconv.Itoa(port) + config["process_name"] = processName + config["process_type"] = entry.Name + config["ps"] = app + "-" + entry.Name + "." + num + if config["description"] == "" { + config["description"] = fmt.Sprintf("%s process for %s", processName, app) + } + + return config +} From af12f5de766fc265bb1ba85420da9f9c3e5663d1 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 13:27:40 -0400 Subject: [PATCH 11/48] fix: properly handle conversions in variables --- export.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/export.go b/export.go index 72e7b7c..c529e25 100644 --- a/export.go +++ b/export.go @@ -324,10 +324,10 @@ func templateVars(app string, entry procfileEntry, processName string, num int, config["command"] = entry.Command config["command_args"] = entry.commandArgs() config["num"] = num - config["port"] = strconv.Itoa(port) + config["port"] = port config["process_name"] = processName config["process_type"] = entry.Name - config["ps"] = app + "-" + entry.Name + "." + num + config["ps"] = app + "-" + entry.Name + "." + strconv.Itoa(num) if config["description"] == "" { config["description"] = fmt.Sprintf("%s process for %s", processName, app) } From b36812bb41a15a8b0998b5a1ce11db8b7c4c4a3d Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 13:28:02 -0400 Subject: [PATCH 12/48] refactor: reduce duplication in loading and writing files --- export.go | 177 +++++++++++++++++------------------------------------- 1 file changed, 54 insertions(+), 123 deletions(-) diff --git a/export.go b/export.go index c529e25..c1abeb3 100644 --- a/export.go +++ b/export.go @@ -8,15 +8,9 @@ import ( ) func exportLaunchd(app string, entries []procfileEntry, formations map[string]formationEntry, location string, defaultPort int, vars map[string]interface{}) bool { - service, err := Asset("templates/launchd/launchd.plist.tmpl") + s, err := loadTemplate("launchd", "templates/launchd/launchd.plist.tmpl") if err != nil { - fmt.Fprintf(os.Stderr, "error: %s\n", err) - return false - } - - s, err := template.New("service").Parse(string(service)) - if err != nil { - fmt.Fprintf(os.Stderr, "error parsing template: %s\n", err) + fmt.Fprintf(os.Stderr, "%s\n", err) return false } @@ -34,16 +28,7 @@ func exportLaunchd(app string, entries []procfileEntry, formations map[string]fo port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) - - f, err := os.Create(location + "/" + app + "-" + processName + ".plist") - if err != nil { - fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) - return false - } - defer f.Close() - - if err = s.Execute(f, config); err != nil { - fmt.Fprintf(os.Stderr, "error writing output: %s\n", err) + if !writeOutput(s, location+"/"+app+"-"+processName+".plist", config) { return false } @@ -55,27 +40,14 @@ func exportLaunchd(app string, entries []procfileEntry, formations map[string]fo } func exportRunit(app string, entries []procfileEntry, formations map[string]formationEntry, location string, defaultPort int, vars map[string]interface{}) bool { - run, err := Asset("templates/runit/run.tmpl") + r, err := loadTemplate("run", "templates/runit/run.tmpl") if err != nil { - fmt.Fprintf(os.Stderr, "error: %s\n", err) + fmt.Fprintf(os.Stderr, "%s\n", err) return false } - - log, err := Asset("templates/runit/log/run.tmpl") + l, err := loadTemplate("log", "templates/runit/log/run.tmpl") if err != nil { - fmt.Fprintf(os.Stderr, "error: %s\n", err) - return false - } - - r, err := template.New("run").Parse(string(run)) - if err != nil { - fmt.Fprintf(os.Stderr, "error parsing template: %s\n", err) - return false - } - - l, err := template.New("log").Parse(string(log)) - if err != nil { - fmt.Fprintf(os.Stderr, "error parsing template: %s\n", err) + fmt.Fprintf(os.Stderr, "%s\n", err) return false } @@ -105,21 +77,7 @@ func exportRunit(app string, entries []procfileEntry, formations map[string]form config := templateVars(app, entry, processName, num, port, vars) fmt.Println("writing:", app+"-"+processName+"/run") - f, err := os.Create(folderPath + "/run") - if err != nil { - fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) - return false - } - defer f.Close() - - if err = r.Execute(f, config); err != nil { - fmt.Fprintf(os.Stderr, "error writing output: %s\n", err) - return false - } - - fmt.Println("setting", app+"-"+processName+"/run", "to mode 755") - if err := os.Chmod(folderPath+"/run", 0755); err != nil { - fmt.Fprintf(os.Stderr, "error setting mode: %s\n", err) + if !writeOutput(r, folderPath+"/run", config) { return false } @@ -134,7 +92,7 @@ func exportRunit(app string, entries []procfileEntry, formations map[string]form for key, value := range env { fmt.Println("writing:", app+"-"+processName+"/env/"+key) - f, err = os.Create(folderPath + "/env/" + key) + f, err := os.Create(folderPath + "/env/" + key) if err != nil { fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) return false @@ -153,21 +111,7 @@ func exportRunit(app string, entries []procfileEntry, formations map[string]form } fmt.Println("writing:", app+"-"+processName+"/log/run") - f, err = os.Create(folderPath + "/log/run") - if err != nil { - fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) - return false - } - defer f.Close() - - if err = l.Execute(f, config); err != nil { - fmt.Fprintf(os.Stderr, "error writing output: %s\n", err) - return false - } - - fmt.Println("setting", app+"-"+processName+"/log/run", "to mode 755") - if err := os.Chmod(folderPath+"/log/run", 0755); err != nil { - fmt.Fprintf(os.Stderr, "error setting mode: %s\n", err) + if !writeOutput(l, folderPath+"/log/run", config) { return false } @@ -179,27 +123,15 @@ func exportRunit(app string, entries []procfileEntry, formations map[string]form } func exportSystemd(app string, entries []procfileEntry, formations map[string]formationEntry, location string, defaultPort int, vars map[string]interface{}) bool { - target, err := Asset("templates/systemd/default/control.target.tmpl") + t, err := loadTemplate("target", "templates/systemd/default/control.target.tmpl") if err != nil { - fmt.Fprintf(os.Stderr, "error: %s\n", err) + fmt.Fprintf(os.Stderr, "%s\n", err) return false } - service, err := Asset("templates/systemd/default/program.service.tmpl") + s, err := loadTemplate("service", "templates/systemd/default/program.service.tmpl") if err != nil { - fmt.Fprintf(os.Stderr, "error: %s\n", err) - return false - } - - t, err := template.New("target").Parse(string(target)) - if err != nil { - fmt.Fprintf(os.Stderr, "error parsing template: %s\n", err) - return false - } - - s, err := template.New("service").Parse(string(service)) - if err != nil { - fmt.Fprintf(os.Stderr, "error parsing template: %s\n", err) + fmt.Fprintf(os.Stderr, "%s\n", err) return false } @@ -220,16 +152,7 @@ func exportSystemd(app string, entries []procfileEntry, formations map[string]fo port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) - - f, err := os.Create(location + "/" + app + "-" + fileName + ".service") - if err != nil { - fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) - return false - } - defer f.Close() - - if err = s.Execute(f, config); err != nil { - fmt.Fprintf(os.Stderr, "error writing output: %s\n", err) + if !writeOutput(s, location+"/"+app+"-"+fileName+".service", config) { return false } @@ -240,31 +163,13 @@ func exportSystemd(app string, entries []procfileEntry, formations map[string]fo config := vars config["processes"] = processes fmt.Println("writing:", app+".target") - f, err := os.Create(location + "/" + app + ".target") - if err != nil { - fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) - return false - } - defer f.Close() - - if err = t.Execute(f, config); err != nil { - fmt.Fprintf(os.Stderr, "error writing output: %s\n", err) - return false - } - - return true + return writeOutput(t, location+"/"+app+".target", config) } func exportSystemdUser(app string, entries []procfileEntry, formations map[string]formationEntry, location string, defaultPort int, vars map[string]interface{}) bool { - service, err := Asset("templates/systemd-user/default/program.service.tmpl") + s, err := loadTemplate("service", "templates/systemd-user/default/program.service.tmpl") if err != nil { - fmt.Fprintf(os.Stderr, "error: %s\n", err) - return false - } - - s, err := template.New("service").Parse(string(service)) - if err != nil { - fmt.Fprintf(os.Stderr, "error parsing template: %s\n", err) + fmt.Fprintf(os.Stderr, "%s\n", err) return false } @@ -284,16 +189,7 @@ func exportSystemdUser(app string, entries []procfileEntry, formations map[strin port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) - - f, err := os.Create(location + "/" + app + "-" + processName + ".service") - if err != nil { - fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) - return false - } - defer f.Close() - - if err = s.Execute(f, config); err != nil { - fmt.Fprintf(os.Stderr, "error writing output: %s\n", err) + if !writeOutput(s, location+"/"+app+"-"+processName+".service", config) { return false } @@ -334,3 +230,38 @@ func templateVars(app string, entry procfileEntry, processName string, num int, return config } + +func writeOutput(t *template.Template, outputPath string, variables map[string]interface{}) bool { + f, err := os.Create(outputPath) + if err != nil { + fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) + return false + } + defer f.Close() + + if err = t.Execute(f, variables); err != nil { + fmt.Fprintf(os.Stderr, "error writing output: %s\n", err) + return false + } + + if err := os.Chmod(outputPath, 0755); err != nil { + fmt.Fprintf(os.Stderr, "error setting mode: %s\n", err) + return false + } + + return true +} + +func loadTemplate(name string, filename string) (*template.Template, error) { + asset, err := Asset(filename) + if err != nil { + return nil, err + } + + t, err := template.New(name).Parse(string(asset)) + if err != nil { + return nil, fmt.Errorf("error parsing template: %s", err) + } + + return t, nil +} From f6eed8a0ceb18aa1b373067402bbf340d56ff7cc Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 13:44:31 -0400 Subject: [PATCH 13/48] refactor: minor variable change --- export.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/export.go b/export.go index c1abeb3..d57da85 100644 --- a/export.go +++ b/export.go @@ -8,7 +8,7 @@ import ( ) func exportLaunchd(app string, entries []procfileEntry, formations map[string]formationEntry, location string, defaultPort int, vars map[string]interface{}) bool { - s, err := loadTemplate("launchd", "templates/launchd/launchd.plist.tmpl") + l, err := loadTemplate("launchd", "templates/launchd/launchd.plist.tmpl") if err != nil { fmt.Fprintf(os.Stderr, "%s\n", err) return false @@ -28,7 +28,7 @@ func exportLaunchd(app string, entries []procfileEntry, formations map[string]fo port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) - if !writeOutput(s, location+"/"+app+"-"+processName+".plist", config) { + if !writeOutput(l, location+"/"+app+"-"+processName+".plist", config) { return false } From 3fc54ca1896c3169286247b0301d787e631f7c5e Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 13:44:45 -0400 Subject: [PATCH 14/48] chore: formatting --- export.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/export.go b/export.go index d57da85..ad72e41 100644 --- a/export.go +++ b/export.go @@ -19,9 +19,9 @@ func exportLaunchd(app string, entries []procfileEntry, formations map[string]fo } for i, entry := range entries { + num := 1 count := processCount(entry, formations) - num := 1 for num <= count { processName := fmt.Sprintf("%s-%d", entry.Name, num) fmt.Println("writing:", app+"-"+processName+".plist") @@ -56,9 +56,9 @@ func exportRunit(app string, entries []procfileEntry, formations map[string]form } for i, entry := range entries { + num := 1 count := processCount(entry, formations) - num := 1 for num <= count { processDirectory := fmt.Sprintf("%s-%s-%d", app, entry.Name, num) folderPath := location + "/" + processDirectory @@ -141,9 +141,9 @@ func exportSystemd(app string, entries []procfileEntry, formations map[string]fo processes := []string{} for i, entry := range entries { + num := 1 count := processCount(entry, formations) - num := 1 for num <= count { processName := fmt.Sprintf("%s-%d", entry.Name, num) fileName := fmt.Sprintf("%s.%d", entry.Name, num) @@ -179,9 +179,9 @@ func exportSystemdUser(app string, entries []procfileEntry, formations map[strin processes := []string{} for i, entry := range entries { + num := 1 count := processCount(entry, formations) - num := 1 for num <= count { processName := fmt.Sprintf("%s-%d", entry.Name, num) processes = append(processes, fmt.Sprintf("%s.service", processName)) From 8f532c7e32514407b7789a115e557db8aa530bd6 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 13:44:52 -0400 Subject: [PATCH 15/48] chore: remove unused variable --- export.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/export.go b/export.go index ad72e41..872908a 100644 --- a/export.go +++ b/export.go @@ -177,14 +177,12 @@ func exportSystemdUser(app string, entries []procfileEntry, formations map[strin os.MkdirAll(location, os.ModePerm) } - processes := []string{} for i, entry := range entries { num := 1 count := processCount(entry, formations) for num <= count { processName := fmt.Sprintf("%s-%d", entry.Name, num) - processes = append(processes, fmt.Sprintf("%s.service", processName)) fmt.Println("writing:", app+"-"+processName+".service") port := portFor(i, num, defaultPort) From 317750e027ff5fc7c18de7a72f9d1696ac08d709 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 13:45:29 -0400 Subject: [PATCH 16/48] feat: add upstart support --- bindata.go | 105 +++++++++++++++--- export.go | 53 +++++++++ main.go | 5 + templates/upstart/default/control.conf.tmpl | 4 + .../upstart/default/process-type.conf.tmpl | 4 + templates/upstart/default/program.conf.tmpl | 29 +++++ 6 files changed, 184 insertions(+), 16 deletions(-) create mode 100644 templates/upstart/default/control.conf.tmpl create mode 100644 templates/upstart/default/process-type.conf.tmpl create mode 100644 templates/upstart/default/program.conf.tmpl diff --git a/bindata.go b/bindata.go index e7388ee..0980bcc 100644 --- a/bindata.go +++ b/bindata.go @@ -3,9 +3,12 @@ // templates/launchd/launchd.plist.tmpl // templates/runit/log/run.tmpl // templates/runit/run.tmpl -// templates/systemd/default/master.target.tmpl +// templates/systemd/default/control.target.tmpl // templates/systemd/default/program.service.tmpl // templates/systemd-user/default/program.service.tmpl +// templates/upstart/default/control.conf.tmpl +// templates/upstart/default/process-type.conf.tmpl +// templates/upstart/default/program.conf.tmpl package main import ( @@ -82,7 +85,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _templatesLaunchdLaunchdPlistTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x93\x41\x6f\xda\x4e\x10\xc5\xef\x7c\x8a\xf9\x5b\x1c\xff\x78\xe1\x56\x45\xc6\x11\x0d\x54\x8a\x8a\x82\x95\x40\xab\x9e\xd0\xc6\x3b\x75\x56\xd8\xbb\xee\xec\x1a\x6a\x59\xfb\xdd\xab\x35\xb8\x98\x24\x54\x3d\xf5\x36\x1a\xbd\x79\xbf\x37\xab\xd9\xe8\xf6\x67\x91\xc3\x1e\xc9\x48\xad\xa6\xc1\x24\x1c\x07\x80\x2a\xd5\x42\xaa\x6c\x1a\x6c\xd6\x9f\x46\x1f\x82\xdb\x78\x10\xfd\x37\x5f\xdd\xad\xbf\x25\x0b\x28\x73\x69\x2c\x24\x9b\x8f\xcb\xfb\x3b\x08\x46\x8c\xcd\xca\x32\x47\xc6\xe6\xeb\x39\x24\xcb\xfb\xa7\x35\x4c\xc2\x31\x63\x8b\x87\x00\x82\x17\x6b\xcb\x1b\xc6\x0e\x87\x43\xc8\xbd\x2a\x4c\x75\xe1\x85\x86\x25\xa4\x4b\x24\x5b\x2f\xa5\xb1\xa3\x49\x38\x0e\x85\x15\x41\x3c\x88\x8e\xee\x17\x71\xe2\x41\x24\x64\x6a\xe3\x01\x00\x40\xb4\xc3\x3a\x5e\xf2\x67\xcc\x23\xe6\xcb\x63\xd3\x58\x92\x2a\x8b\x9b\x06\x3c\x07\x9c\x1b\xf9\xb2\x24\x9d\xa2\x31\x5b\x5b\x97\xd8\xf5\x54\x55\x80\x73\x11\x3b\x4d\x9c\x3d\x17\x6a\x2f\x49\xab\x02\x95\xfd\xc2\x49\xf2\xe7\x1c\x4d\x1f\x71\x8e\xf0\x7b\x24\x59\x3d\xae\x7b\x92\xd7\x49\x4a\x4d\xf6\x0d\xab\x69\x46\x40\x5c\x65\x08\xc3\x1d\xd6\xff\xc3\x70\xcf\xf3\x0a\xe1\x66\x0a\x21\xaa\x3d\x38\x77\x89\x68\x9a\x56\xd7\xda\x5c\x03\x9d\x2c\x7a\xa4\xa6\x01\x54\xa2\x33\x8b\xd8\xab\xe7\x4b\x48\x67\xc4\x8b\x19\x65\x95\x5f\xf7\x62\x4d\x4e\xc4\xeb\x37\x51\x53\x5d\x14\x5c\x89\x36\xe6\xa9\xde\x72\xca\xcc\x45\xde\x33\x5c\x7e\x07\xfc\x71\x9e\x0a\x86\xfe\xa5\x02\x70\xce\xa7\xed\xde\xc5\x87\xcc\x0d\x9e\xba\x9d\xf6\xd8\x6f\x8b\xab\xeb\xf4\x32\xb6\xfb\x7c\x46\x2c\x67\xb9\xdc\x63\x7f\x11\x4b\x15\xb2\x9e\xe8\xb1\x52\x33\xbb\xd4\x5c\xfc\x49\xf4\x64\xb9\x12\x9c\xc4\xaa\xb2\x09\xb7\x2f\x57\x4e\x2c\xd7\x19\x38\xc7\xce\xd7\xc6\xfe\xfa\xf0\xfc\xec\x3b\xc7\xd7\x71\x17\x44\x9a\xfe\x29\x79\x63\x90\x1e\x78\x81\x57\x80\x95\x41\x7a\xff\xbf\x7c\xd5\xb4\x93\x2a\x9b\x4b\xc2\xd4\x6a\xaa\xaf\x18\x1c\x8e\xb2\xad\xe8\x74\x17\x6e\xdd\x69\x46\xac\xfd\xf7\xf1\xe0\x57\x00\x00\x00\xff\xff\x2d\x1b\xa9\x26\x8e\x04\x00\x00") +var _templatesLaunchdLaunchdPlistTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x54\xcd\x6e\xda\x40\x10\xbe\xf3\x14\x53\x2b\xc7\xe2\x85\x5b\x15\x19\x47\x34\x50\x29\x2a\x0a\x56\x80\x56\x3d\xa1\x8d\x3d\x75\x56\xd8\xbb\xee\xec\x1a\x6a\x59\xfb\xee\xd5\x1a\x5c\x9b\x10\xa2\x9e\x7a\x1b\x8d\xbe\xbf\x1d\x7d\x76\x70\xf7\x3b\xcf\x60\x8f\xa4\x85\x92\x13\x6f\xec\x8f\x3c\x40\x19\xab\x44\xc8\x74\xe2\x6d\xd6\x5f\x86\x9f\xbc\xbb\x70\x10\x7c\x98\x2d\xef\xd7\x3f\xa2\x39\x14\x99\xd0\x06\xa2\xcd\xe7\xc5\xc3\x3d\x78\x43\xc6\xa6\x45\x91\x21\x63\xb3\xf5\x0c\xa2\xc5\xc3\x6a\x0d\x63\x7f\xc4\xd8\xfc\xd1\x03\xef\xc5\x98\xe2\x96\xb1\xc3\xe1\xe0\x73\x87\xf2\x63\x95\x3b\xa0\x66\x11\xa9\x02\xc9\x54\x0b\xa1\xcd\x70\xec\x8f\xfc\xc4\x24\x5e\x38\x08\x8e\xea\x67\x71\xc2\x41\x90\x88\xd8\x84\x03\x00\x80\x60\x87\x55\xb8\xe0\xcf\x98\x05\xcc\x8d\xc7\xa5\x36\x24\x64\x1a\xd6\x35\x38\x1f\xb0\x76\xe8\xc6\x82\x54\x8c\x5a\x6f\x4d\x55\x60\xbb\x93\x65\x0e\xd6\x06\xec\xc4\xe8\x34\xe7\x72\x2f\x48\xc9\x1c\xa5\xf9\xc6\x49\xf0\xe7\x0c\x75\xdf\xa2\x8b\xf0\x97\x12\x2d\x9f\xd6\x3d\xc8\xeb\x24\x85\x22\x73\xe1\xd5\x91\x57\xef\x51\xf5\x05\xb1\xae\x87\x40\x5c\xa6\x08\x37\x3b\xac\x3e\xc2\xcd\x9e\x67\x25\xc2\xed\x04\x7c\x94\x7b\xb0\xf6\x5c\xbe\xae\x1b\x5c\x23\x73\xcd\xe6\x24\xd1\x73\xaa\x6b\x40\x99\xb4\x62\x01\x7b\x75\xf7\x88\x54\x4a\x3c\x9f\x52\x5a\xba\x3b\x9d\xdd\x87\x13\xf1\xea\x22\x6a\xac\xf2\x9c\xcb\xa4\x89\x79\x9a\xb7\x9c\x52\x7d\x96\xb7\x33\x17\x3f\x01\x7f\x75\x2c\xef\xc6\x9d\xd8\x03\x6b\x5d\xda\xf6\xa0\x2e\x64\xa6\xf1\xb4\x6d\xb1\xc7\x7d\x33\x5c\x7d\x4e\x2f\x63\xf3\x9e\xaf\x88\xc5\x34\x13\x7b\xec\x3f\xc4\x50\x89\xac\x07\x7a\x2a\xe5\xd4\x2c\x14\x4f\xde\x03\xad\x0c\x97\x09\xa7\x64\x59\x9a\x88\x9b\x97\x2b\xdd\xcc\x54\x0a\xd6\xb2\xae\xa6\xec\x9f\x1b\xeb\xb8\x6f\xb4\xb6\xf5\x9d\x13\x29\xfa\xaf\xce\x1b\x8d\xf4\xc8\x73\xbc\x62\x58\x6a\xa4\xb7\x3f\xb4\xef\x8a\x76\x42\xa6\x33\x41\x18\x1b\x45\xd5\x15\x81\xc3\x11\xb6\x4d\x5a\xdc\x99\x5a\x5b\xcd\x80\x35\x3f\x8c\x70\xf0\x27\x00\x00\xff\xff\x17\x6e\x65\x70\xc7\x04\x00\x00") func templatesLaunchdLaunchdPlistTmplBytes() ([]byte, error) { return bindataRead( @@ -97,7 +100,7 @@ func templatesLaunchdLaunchdPlistTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/launchd/launchd.plist.tmpl", size: 1166, mode: os.FileMode(420), modTime: time.Unix(1584462008, 0)} + info := bindataFileInfo{name: "templates/launchd/launchd.plist.tmpl", size: 1223, mode: os.FileMode(420), modTime: time.Unix(1584464125, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -142,27 +145,27 @@ func templatesRunitRunTmpl() (*asset, error) { return a, nil } -var _templatesSystemdDefaultMasterTargetTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8a\x0e\xcd\xcb\x2c\x89\xe5\x0a\x4f\xcc\x2b\x29\xb6\xad\xae\x56\x28\x4a\xcc\x4b\x4f\x55\x50\x29\x4b\xcc\x29\x4d\x55\xb0\xb2\x55\xd0\x2b\x28\xca\x4f\x4e\x2d\x2e\x4e\x2d\x56\xa8\xad\xad\xae\x86\xc9\xd4\xd6\x2a\x54\x57\x2b\xa4\xe6\xa5\x28\xd4\xd6\x72\x71\x45\x7b\xe6\x15\x97\x24\xe6\xe4\x40\xcc\x49\x4d\x71\xaa\xb4\xcd\x2d\xcd\x29\xc9\xd4\x2d\x2d\x4e\x2d\xd2\x2b\x49\x2c\x4a\x4f\x2d\xe1\x02\x04\x00\x00\xff\xff\x4f\xc2\xa4\x0c\x6a\x00\x00\x00") +var _templatesSystemdDefaultControlTargetTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8a\x0e\xcd\xcb\x2c\x89\xe5\x0a\x4f\xcc\x2b\x29\xb6\xad\xae\x56\x28\x4a\xcc\x4b\x4f\x55\x50\x29\x4b\xcc\x29\x4d\x55\xb0\xb2\x55\xd0\x2b\x28\xca\x4f\x4e\x2d\x2e\x4e\x2d\x56\xa8\xad\xad\xae\x86\xc9\xd4\xd6\x2a\x54\x57\x2b\xa4\xe6\xa5\x28\xd4\xd6\x72\x71\x45\x7b\xe6\x15\x97\x24\xe6\xe4\x40\xcc\x49\x4d\x71\xaa\xb4\xcd\x2d\xcd\x29\xc9\xd4\x2d\x2d\x4e\x2d\xd2\x2b\x49\x2c\x4a\x4f\x2d\xe1\x02\x04\x00\x00\xff\xff\x4f\xc2\xa4\x0c\x6a\x00\x00\x00") -func templatesSystemdDefaultMasterTargetTmplBytes() ([]byte, error) { +func templatesSystemdDefaultControlTargetTmplBytes() ([]byte, error) { return bindataRead( - _templatesSystemdDefaultMasterTargetTmpl, - "templates/systemd/default/master.target.tmpl", + _templatesSystemdDefaultControlTargetTmpl, + "templates/systemd/default/control.target.tmpl", ) } -func templatesSystemdDefaultMasterTargetTmpl() (*asset, error) { - bytes, err := templatesSystemdDefaultMasterTargetTmplBytes() +func templatesSystemdDefaultControlTargetTmpl() (*asset, error) { + bytes, err := templatesSystemdDefaultControlTargetTmplBytes() if err != nil { return nil, err } - info := bindataFileInfo{name: "templates/systemd/default/master.target.tmpl", size: 106, mode: os.FileMode(420), modTime: time.Unix(1584336786, 0)} + info := bindataFileInfo{name: "templates/systemd/default/control.target.tmpl", size: 106, mode: os.FileMode(420), modTime: time.Unix(1584336786, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templatesSystemdDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x92\x51\x6b\xdb\x3e\x10\xc0\xdf\xf5\x29\x44\xe8\x9f\xbe\xfc\x13\x33\xd8\xd3\xc0\x6f\x4d\x47\x58\xd7\x94\xba\xa1\x0f\xa5\x04\x55\x3a\xbb\x47\xe5\x93\x39\x9d\xd3\x18\xe3\xef\x3e\xa4\x2e\xc9\xc8\x36\xd8\x93\xa5\xdf\xfd\xee\x74\x27\xeb\x69\x43\x28\xcf\x6a\x1c\xe7\x1a\x6b\xbd\x70\x10\x2d\x63\x27\x18\x48\x4f\x93\xba\x3a\x6d\xcb\x71\x3c\x0f\x8f\xa3\x06\x72\xc9\xbb\x33\x2c\xeb\x3a\x2b\xa6\xeb\xf4\x34\x2d\xc4\x70\x03\xa2\x2a\x09\xdd\xe3\x2b\xd0\x86\x08\xc0\x81\x2b\x07\x88\x4a\x3d\x55\xc0\x3b\xb4\xf0\xac\x36\x11\x38\xa7\xf5\x11\x38\x55\xfa\xca\xa1\xef\x32\x69\xd2\x2a\xa1\xc7\xc0\x6f\x48\xcd\x15\x32\x58\x09\x3c\xe4\xe8\xfb\x07\xdc\xba\x03\x4d\xe6\x92\x76\xc8\x81\x5a\x20\x29\xef\xd6\xf7\x0f\xd9\xec\x02\xcb\x6f\xc1\xea\x97\x5e\xe7\xd9\xe2\x60\x21\xc6\xad\x0c\x1d\xa4\xfe\x13\xa3\xbe\x3d\x4b\xbc\x46\x0f\xe5\xbc\x00\xb1\x85\x83\xda\xf4\x5e\x8a\x43\x9d\xbf\x9b\x71\x88\x36\x50\x8d\x4d\x71\x3a\x33\x5f\x38\x1b\x6a\x40\x5f\xbc\xc1\xf0\xbf\xbe\xd8\x19\xdf\x83\xfe\x52\xea\x05\xd0\xee\xbc\xdf\xd9\x38\x66\x4f\x4f\x53\x6a\xfc\xa7\x3c\x4d\x33\x75\xfa\x07\xcb\x3d\xd8\x4a\x0c\x4b\x59\xbc\x20\x15\x2f\x26\xbe\xea\xb9\xb7\xfa\x12\xf6\x60\xf5\xdc\xe8\xd9\x3f\x8f\x3c\xd3\x69\x6d\x43\xdb\x9a\x5c\xfb\x52\xdd\x43\xcc\xa5\x8d\x7f\x37\x43\x3c\x6c\x2b\xb0\xe5\xa7\xcf\x51\x55\x62\xc8\x19\x76\x2b\xea\x7a\x29\xa9\xf7\xfe\x88\xd6\xbd\x24\x16\x87\xe8\x43\x73\xa4\x4b\xe6\xc0\x47\x98\x3f\x2b\x07\x24\x58\x23\x70\xf9\x1f\xa9\x6f\xe8\xfd\xf7\xe0\xa0\x6c\x71\x0f\x4e\x3d\x60\x0b\xa1\x97\xf4\x9a\xd2\x99\xa9\x3b\xf9\x40\x69\xf2\xe3\xeb\x25\xb4\x69\x12\x75\x8b\x16\xb2\x74\x00\xa7\x5b\x3a\xa8\x1e\x5b\x94\x6d\xe8\x80\xb6\x35\x7a\x88\x29\x76\x93\xd8\xed\xfa\x7a\x75\xb3\xcc\xd9\x7f\x72\x4e\x95\x7e\x04\x00\x00\xff\xff\xb7\xf7\x3a\x4f\x3a\x03\x00\x00") +var _templatesSystemdDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x92\xc1\x6a\xe3\x3c\x10\x80\xef\x7a\x0a\x11\xfa\xd3\xcb\x9f\x98\x85\x3d\x2d\xe8\xd6\x74\x09\xdb\x6d\x4a\xdd\xd0\x43\x29\x41\x95\xc6\xee\x50\x79\x64\xa4\x71\x1a\x63\xfc\xee\x8b\x94\x8d\x0d\xd9\xdd\x93\xa5\x6f\xbe\x91\x67\x46\x7a\xd9\x11\xf2\xab\x18\x86\xa5\xc4\x4a\xae\x2c\x44\x13\xb0\x65\xf4\x24\xc7\x51\xdc\xcc\x5b\x35\x0c\x97\xe1\x61\x90\x40\x36\x79\x0f\x3a\xf0\xb6\xca\x8a\x6e\x5b\x39\x8e\x2b\xd6\xa1\x06\x16\x25\xfb\xf6\xf9\x1d\x68\x47\x04\x60\xc1\xaa\x1e\xa2\x10\x2f\x25\x84\x03\x1a\x78\x15\xbb\x08\x21\xa7\x75\x11\x42\x3a\xe9\x7b\xf0\x5d\x9b\x49\x9d\x56\x09\x3d\xfb\xf0\x81\x54\xdf\x60\x00\xc3\x3e\xf4\x39\xfa\x79\x82\x7b\x7b\xa6\xc9\x5c\xd3\x01\x83\xa7\x06\x88\xd5\xc3\xf6\xf1\x29\x9b\xad\x0f\xfc\x47\xb0\x3c\x85\xe2\x45\xe0\x16\x1d\xa8\x65\x01\x6c\x0a\x0b\x95\xee\x1c\x17\xe7\x9e\xfe\x6d\xc6\x3e\x1a\x4f\x15\xd6\xc5\xdc\x7f\x1e\x68\xd0\x54\x83\xbc\xfa\x80\xfe\x7f\x79\x75\xd0\xae\x03\xf9\x4d\xc9\x15\xd0\xe1\xb2\x9e\xc5\x30\x64\x4f\x8e\x63\x2a\xec\xb7\x3c\x8e\x0b\x31\xcf\x78\x7d\x04\x53\xb2\x0e\xac\x8a\x37\xa4\xe2\x4d\xc7\x77\xb9\x74\x46\x5e\xc3\x11\x8c\x5c\x6a\xb9\x98\x5a\x5a\xc8\xb4\x34\xbe\x69\x74\xce\xbd\x16\x8f\x10\x73\xaa\x76\x9f\xba\x8f\xe7\x6d\x09\x46\x7d\xf9\x1a\x45\xc9\x9a\xac\x0e\x76\x43\x6d\xc7\x8a\x3a\xe7\x26\xb4\xed\x38\xb1\xd8\x47\xe7\xeb\x89\xae\x43\xf0\x61\x82\xf9\xb3\xb1\x40\x8c\x15\x42\x50\xff\x91\xf8\x81\xce\xfd\xf4\x16\x54\x83\x47\xb0\xe2\x09\x1b\xf0\x1d\xa7\xd7\x90\xfe\x99\xaa\xe3\x13\x4a\x9d\x4d\xaf\x8f\xd0\xa4\xae\xc5\x3d\x1a\xc8\xd2\x19\xcc\x53\x38\xab\x0e\x1b\xe4\xbd\x6f\x81\xf6\x15\x3a\xc8\x17\x79\x97\xd8\xfd\xf6\x76\x73\xb7\xce\xd9\x7f\x73\xe6\x93\x7e\x05\x00\x00\xff\xff\x88\x3d\x27\x0c\xfa\x02\x00\x00") func templatesSystemdDefaultProgramServiceTmplBytes() ([]byte, error) { return bindataRead( @@ -177,12 +180,12 @@ func templatesSystemdDefaultProgramServiceTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/systemd/default/program.service.tmpl", size: 826, mode: os.FileMode(420), modTime: time.Unix(1584460118, 0)} + info := bindataFileInfo{name: "templates/systemd/default/program.service.tmpl", size: 762, mode: os.FileMode(420), modTime: time.Unix(1584464031, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templatesSystemdUserDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x8f\x41\x6a\xf3\x30\x10\x85\xf7\x3a\x85\x2e\x10\xfb\x04\xde\xfc\x24\x3f\x74\x95\x12\xa7\x64\x11\x42\x10\xd2\xc4\x9d\x56\x1a\x89\xd1\x38\xa9\x31\xbe\x7b\x91\x42\x09\xcd\xaa\x4b\x7d\xef\x7b\x8f\xd1\xf1\x8d\x50\x4e\x6a\x9e\x57\x1a\x2f\xba\x71\x90\x2d\x63\x12\x8c\xa4\x97\x45\xad\x1f\xcf\x6e\x9e\x9f\xe3\x79\xd6\x40\xae\x78\x5a\x1d\x7b\xe0\x2b\x5a\x38\xa9\xfd\x94\xa0\xcb\x18\x92\x07\xb5\xa1\x2b\x72\xa4\x00\x24\xdd\xeb\x76\xb7\xaf\x23\x29\xb2\x94\xd2\xaf\xb0\xaf\x91\x49\x49\x2f\xcb\xaa\x5a\x1c\x2d\xe4\x7c\x96\x29\x81\x5e\x96\xa6\x30\x1a\xc3\x53\xf1\x3f\x7a\xe8\xaa\xff\x1e\x43\xf1\xda\xc6\x46\xba\xe0\xd0\xe6\x29\x0b\x04\xd7\x8e\x19\xb8\xfd\xf3\x76\x03\x8f\x6d\xb5\xf9\x02\xdb\x8b\x61\xa9\xb7\xd9\x18\x82\xb9\x7f\x77\x07\xb9\x62\xe3\x6f\x66\xca\xea\x10\xf9\x13\x69\x58\x23\x83\x95\xc8\x53\xd5\x6f\x77\x78\x76\x3f\xb4\x14\x7b\x31\xe4\x0c\xbb\xed\x28\x69\x94\xee\x23\x8e\x4c\xc6\x2b\x75\x7c\xa1\x2c\xc6\xfb\x93\x3a\x18\x12\x70\xff\xa6\x2e\x8c\x5e\x70\x55\xae\x6f\xc4\xf0\x00\xa2\xbe\x03\x00\x00\xff\xff\x88\xfb\xad\x15\xab\x01\x00\x00") +var _templatesSystemdUserDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\x8e\x41\x6a\xc3\x30\x10\x45\xf7\x3a\x85\x2e\x10\xfb\x04\xda\x94\xa4\xd0\x55\x4a\x9c\x92\x45\x30\x45\x48\x13\x77\x5a\x69\x64\x46\xe3\xa4\x46\xf8\xee\xc5\x36\x6d\x68\x96\xf3\xdf\xbc\xcf\x3f\xbf\x11\x4a\xab\x4a\xd9\x68\xbc\xe8\xca\x43\x76\x8c\xbd\x60\x22\x3d\x4d\x6a\x7b\x3f\x4d\x29\x8f\xb8\x14\x0d\xe4\xe7\x3f\xad\xce\x0d\xf0\x15\x1d\xb4\xea\x38\xf6\x60\x32\xc6\x3e\x80\xda\xd1\x15\x39\x51\x04\x12\xf3\xba\x3f\x1c\x97\x92\x3e\xb1\xcc\xd2\x3f\xd8\xac\x28\x3f\x80\x67\x0c\x60\x36\x33\xfa\x48\x11\xf4\x34\xd5\x95\x4b\x74\xc1\xae\xce\x63\x16\x88\xbe\x1e\x32\x70\xfd\xe7\x56\x70\x77\xd5\xee\x1b\x5c\x23\x96\x65\xe9\x76\x29\x46\xbb\xce\x3d\x40\x5e\x62\x1b\x6e\x76\xcc\xea\x94\xf8\x0b\xa9\xdb\x22\x83\x93\xc4\xe3\xf2\x7e\x5b\xc3\x77\xff\x9b\xce\x62\x23\x96\xbc\x65\xbf\x1f\xa4\x1f\xc4\x7c\xa6\x81\xc9\x06\xa5\xce\x2f\x94\xc5\x86\xd0\xaa\x93\x25\x01\xff\x34\x9a\x38\x04\xc1\xcd\xbc\xae\x12\xcb\x1d\x88\xfa\x09\x00\x00\xff\xff\xd3\x11\x0c\x91\x6b\x01\x00\x00") func templatesSystemdUserDefaultProgramServiceTmplBytes() ([]byte, error) { return bindataRead( @@ -197,7 +200,67 @@ func templatesSystemdUserDefaultProgramServiceTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/systemd-user/default/program.service.tmpl", size: 427, mode: os.FileMode(420), modTime: time.Unix(1584460126, 0)} + info := bindataFileInfo{name: "templates/systemd-user/default/program.service.tmpl", size: 363, mode: os.FileMode(420), modTime: time.Unix(1584464041, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesUpstartDefaultControlConfTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x4a\x49\x2d\x4e\x2e\xca\x2c\x28\xc9\xcc\xcf\x53\xa8\xae\x56\xd0\x4b\x2c\x28\x50\xa8\xad\xe5\xe2\x2a\x2e\x49\x2c\x2a\x51\xc8\xcf\x53\xd0\x00\xb3\x52\x53\x14\xf2\x52\x4b\xca\xf3\x8b\xb2\x33\xf3\xd2\x35\xb9\x8a\x4b\xf2\x0b\x40\x92\x45\xa5\x79\x39\xa9\x65\xa9\x39\x0a\xd1\x06\x66\xb1\x5c\x80\x00\x00\x00\xff\xff\x88\x35\x19\x59\x4c\x00\x00\x00") + +func templatesUpstartDefaultControlConfTmplBytes() ([]byte, error) { + return bindataRead( + _templatesUpstartDefaultControlConfTmpl, + "templates/upstart/default/control.conf.tmpl", + ) +} + +func templatesUpstartDefaultControlConfTmpl() (*asset, error) { + bytes, err := templatesUpstartDefaultControlConfTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/upstart/default/control.conf.tmpl", size: 76, mode: os.FileMode(420), modTime: time.Unix(1584463645, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesUpstartDefaultProcessTypeConfTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\xcb\x31\x0a\x42\x41\x0c\x84\xe1\x3e\xa7\x98\x52\x0b\xc5\xca\xcb\x88\xc8\x63\x0d\xb2\xb0\x24\x21\x89\x82\x2c\xb9\xbb\xac\x95\x76\x3f\x7c\x33\x77\x8e\xe6\xdd\xb2\xab\x60\x4e\x1c\x37\x33\x54\x1d\x56\x9a\x6b\xe3\x88\x5b\xbe\x8d\x51\x45\x14\xb9\x79\x42\x05\xdf\xe8\xf2\xf8\x79\x50\xa4\xda\xb2\x9d\x3f\x65\xf0\x8b\x07\x2e\xa7\xf3\x15\xea\x58\x62\xff\xeb\x3d\x7d\x02\x00\x00\xff\xff\xc1\x84\x51\xbe\x78\x00\x00\x00") + +func templatesUpstartDefaultProcessTypeConfTmplBytes() ([]byte, error) { + return bindataRead( + _templatesUpstartDefaultProcessTypeConfTmpl, + "templates/upstart/default/process-type.conf.tmpl", + ) +} + +func templatesUpstartDefaultProcessTypeConfTmpl() (*asset, error) { + bytes, err := templatesUpstartDefaultProcessTypeConfTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/upstart/default/process-type.conf.tmpl", size: 120, mode: os.FileMode(420), modTime: time.Unix(1584463645, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _templatesUpstartDefaultProgramConfTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x52\xc1\x6e\x13\x31\x10\xbd\xfb\x2b\xde\xa1\x6a\x1b\xa1\xcd\x02\x37\x0e\xed\xa9\x97\x9e\x88\x80\x5b\xa9\xda\x95\x3d\xd9\x58\x24\x1e\x6b\x66\x4c\x89\xda\xfd\x77\xe4\xcd\x96\xb6\x90\x8a\x20\x71\xb3\xdf\xcc\x7b\xf3\xe6\x69\x02\xa9\x97\x98\x2d\x72\xc2\xfd\x3d\xe6\x5d\xce\x18\x86\xa6\x3e\xb3\xb0\x27\xd5\x1b\xdb\x66\x7a\xc4\x52\xd9\x60\x18\x9c\x53\xeb\xc4\xc0\x09\xa7\xe3\x2b\xa6\xfe\x2f\x6c\xb0\x60\x4f\xeb\xcc\xa9\x71\x9e\x84\x38\xe7\x43\x85\xfe\x68\x9d\x39\xa7\x64\x25\x86\x11\x2b\x4a\x52\x7d\x2a\x59\x3f\x41\xbd\x70\xa9\x8d\xce\xaf\x42\x14\x8c\xd8\x1d\xcb\xb7\x98\xfa\x9b\x10\x85\xbc\xb1\x6c\x6b\x5d\x48\x73\x77\x97\x9c\xdb\x05\xe3\x00\xfa\x91\x59\x0c\x8b\x8f\x9f\xbe\x9c\x8d\x8e\xea\x6f\x18\x9e\x55\x3e\xef\x70\xdd\xa1\x57\x68\x04\x2d\x99\x6f\x03\x2d\xbb\xb2\xb6\xf6\xd1\x67\xf5\x7f\x8d\xe3\x63\xcc\x5f\xad\xbf\xe0\xeb\x56\x3d\xa7\x65\xec\xdb\xa7\x4d\x5f\x08\xec\x6b\x70\x80\x0f\xaf\xef\x57\x5d\x93\x1f\xeb\x9e\x37\x9b\x2e\x85\x2a\xfa\xd5\x01\xc0\xf9\x39\xda\xef\x9d\xb4\x6b\x7e\x2e\xd8\xee\xbb\x06\xb5\xc0\xc5\xe6\x6b\xee\x27\xee\xfb\x7f\x23\x93\x48\x25\x3b\x4a\x01\x53\xd2\x2e\xb3\x5a\xb3\x3b\xad\x5f\xe1\x2f\x2e\x2f\xce\x6e\xd5\x3a\x2b\x7a\xf8\x81\xe2\x01\xd4\x0b\x65\x34\x1c\x71\x72\x7a\xf5\xb6\xf9\x70\xfd\x66\x76\x74\x82\x07\xac\xa8\x0b\x68\xd2\xbb\xdb\x1a\x84\x5f\x31\x8e\x16\x97\x17\x98\xac\x4b\x49\xbf\x5b\x3f\x68\xde\x3c\xc7\xb0\x6f\x13\xce\x4f\x8b\xc8\x06\xcd\xf2\xff\x8e\xf9\x19\x00\x00\xff\xff\x33\xff\x89\xa3\xbd\x03\x00\x00") + +func templatesUpstartDefaultProgramConfTmplBytes() ([]byte, error) { + return bindataRead( + _templatesUpstartDefaultProgramConfTmpl, + "templates/upstart/default/program.conf.tmpl", + ) +} + +func templatesUpstartDefaultProgramConfTmpl() (*asset, error) { + bytes, err := templatesUpstartDefaultProgramConfTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/upstart/default/program.conf.tmpl", size: 957, mode: os.FileMode(420), modTime: time.Unix(1584464146, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -257,9 +320,12 @@ var _bindata = map[string]func() (*asset, error){ "templates/launchd/launchd.plist.tmpl": templatesLaunchdLaunchdPlistTmpl, "templates/runit/log/run.tmpl": templatesRunitLogRunTmpl, "templates/runit/run.tmpl": templatesRunitRunTmpl, - "templates/systemd/default/master.target.tmpl": templatesSystemdDefaultMasterTargetTmpl, + "templates/systemd/default/control.target.tmpl": templatesSystemdDefaultControlTargetTmpl, "templates/systemd/default/program.service.tmpl": templatesSystemdDefaultProgramServiceTmpl, "templates/systemd-user/default/program.service.tmpl": templatesSystemdUserDefaultProgramServiceTmpl, + "templates/upstart/default/control.conf.tmpl": templatesUpstartDefaultControlConfTmpl, + "templates/upstart/default/process-type.conf.tmpl": templatesUpstartDefaultProcessTypeConfTmpl, + "templates/upstart/default/program.conf.tmpl": templatesUpstartDefaultProgramConfTmpl, } // AssetDir returns the file names below a certain @@ -315,7 +381,7 @@ var _bintree = &bintree{nil, map[string]*bintree{ }}, "systemd": &bintree{nil, map[string]*bintree{ "default": &bintree{nil, map[string]*bintree{ - "master.target.tmpl": &bintree{templatesSystemdDefaultMasterTargetTmpl, map[string]*bintree{}}, + "control.target.tmpl": &bintree{templatesSystemdDefaultControlTargetTmpl, map[string]*bintree{}}, "program.service.tmpl": &bintree{templatesSystemdDefaultProgramServiceTmpl, map[string]*bintree{}}, }}, }}, @@ -324,6 +390,13 @@ var _bintree = &bintree{nil, map[string]*bintree{ "program.service.tmpl": &bintree{templatesSystemdUserDefaultProgramServiceTmpl, map[string]*bintree{}}, }}, }}, + "upstart": &bintree{nil, map[string]*bintree{ + "default": &bintree{nil, map[string]*bintree{ + "control.conf.tmpl": &bintree{templatesUpstartDefaultControlConfTmpl, map[string]*bintree{}}, + "process-type.conf.tmpl": &bintree{templatesUpstartDefaultProcessTypeConfTmpl, map[string]*bintree{}}, + "program.conf.tmpl": &bintree{templatesUpstartDefaultProgramConfTmpl, map[string]*bintree{}}, + }}, + }}, }}, }} diff --git a/export.go b/export.go index 872908a..64f4b55 100644 --- a/export.go +++ b/export.go @@ -198,6 +198,59 @@ func exportSystemdUser(app string, entries []procfileEntry, formations map[strin return true } +func exportUpstart(app string, entries []procfileEntry, formations map[string]formationEntry, location string, defaultPort int, vars map[string]interface{}) bool { + p, err := loadTemplate("program", "templates/upstart/default/program.conf.tmpl") + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + return false + } + + c, err := loadTemplate("app", "templates/upstart/default/control.conf.tmpl") + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + return false + } + + t, err := loadTemplate("process-type", "templates/upstart/default/process-type.conf.tmpl") + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + return false + } + + if _, err := os.Stat(location); os.IsNotExist(err) { + os.MkdirAll(location, os.ModePerm) + } + + for i, entry := range entries { + num := 1 + count := processCount(entry, formations) + + variables := vars + variables["process_type"] = entry.Name + fmt.Println("writing:", app+"-"+entry.Name+".conf") + if !writeOutput(t, location+"/"+app+"-"+entry.Name+".conf", variables) { + return false + } + + for num <= count { + processName := fmt.Sprintf("%s-%d", entry.Name, num) + fileName := fmt.Sprintf("%s-%d", entry.Name, num) + fmt.Println("writing:", app+"-"+fileName+".conf") + + port := portFor(i, num, defaultPort) + config := templateVars(app, entry, processName, num, port, vars) + if !writeOutput(p, location+"/"+app+"-"+fileName+".conf", config) { + return false + } + + num += 1 + } + } + + config := vars + fmt.Println("writing:", app+".conf") + return writeOutput(c, location+"/"+app+".conf", config) +} func processCount(entry procfileEntry, formations map[string]formationEntry) int { count := 0 if f, ok := formations["all"]; ok { diff --git a/main.go b/main.go index d082210..da75e2e 100644 --- a/main.go +++ b/main.go @@ -307,6 +307,7 @@ func exportCommand(entries []procfileEntry, app string, description string, envP "runit": true, "systemd": true, "systemd-user": true, + "upstart": true, } if _, ok := formats[format]; !ok { @@ -378,6 +379,10 @@ func exportCommand(entries []procfileEntry, app string, description string, envP return exportSystemdUser(app, entries, formations, location, defaultPort, vars) } + if format == "upstart" { + return exportUpstart(app, entries, formations, location, defaultPort, vars) + } + return false } diff --git a/templates/upstart/default/control.conf.tmpl b/templates/upstart/default/control.conf.tmpl new file mode 100644 index 0000000..0ddf36c --- /dev/null +++ b/templates/upstart/default/control.conf.tmpl @@ -0,0 +1,4 @@ +description {{ .app }} + +start on (started networking) +stop on runlevel [06] diff --git a/templates/upstart/default/process-type.conf.tmpl b/templates/upstart/default/process-type.conf.tmpl new file mode 100644 index 0000000..5e14cf1 --- /dev/null +++ b/templates/upstart/default/process-type.conf.tmpl @@ -0,0 +1,4 @@ +description {{ .app }}-{{ .process_type }} + +start on starting {{ .app }} +stop on (runlevel [06] or stopping {{ .app }}) diff --git a/templates/upstart/default/program.conf.tmpl b/templates/upstart/default/program.conf.tmpl new file mode 100644 index 0000000..0aa7598 --- /dev/null +++ b/templates/upstart/default/program.conf.tmpl @@ -0,0 +1,29 @@ +description {{ .app }}-{{ .process_type }}-{{ .num }} + +start on (starting {{ .app }}-{{ .process_type }} or starting {{ .app }}) +stop on (stopping {{ .app }}-{{ .process_type }} or stopping {{ .app }}) + +setuid {{ .user }} +setgid {{ .group }} +chdir {{ .working_directory }} +respawn + +script + export PORT={{ .port }} + export PS={{ .ps }} + [ -r /etc/default/{{ .app }} ] && . /etc/default/{{ .app }} + [ -r /etc/sysconfig/{{ .app }} ] && . /etc/sysconfig/{{ .app }} + cd {{ .working_directory }} + exec {{ .command }} \ + >> /var/log/{{ .app }}/{{ .process_type }}-stdout.log \ + 2>> /var/log/{{ .app }}/{{ .process_type }}-stderr.log +end script + +post-start script + PID=`status {{ .app }}-{{ .process_type }}-{{ .num }} | egrep -oi '([0-9]+)$' | head -n1` + echo $PID > /var/run/{{ .app }}/{{ .app }}-{{ .process_type }}-{{ .num }}.pid +end script + +post-stop script + rm -f /var/run/{{ .app }}/{{ .app }}-{{ .process_type }}-{{ .num }}.pid +end script From b8af8ed1696762365b06cf8165a583138c1b3fad Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 14:04:53 -0400 Subject: [PATCH 17/48] refactor: rename command_args to command_list --- bindata.go | 4 ++-- export.go | 2 +- main.go | 2 +- templates/launchd/launchd.plist.tmpl | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bindata.go b/bindata.go index 0980bcc..63c5e32 100644 --- a/bindata.go +++ b/bindata.go @@ -85,7 +85,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _templatesLaunchdLaunchdPlistTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x54\xcd\x6e\xda\x40\x10\xbe\xf3\x14\x53\x2b\xc7\xe2\x85\x5b\x15\x19\x47\x34\x50\x29\x2a\x0a\x56\x80\x56\x3d\xa1\x8d\x3d\x75\x56\xd8\xbb\xee\xec\x1a\x6a\x59\xfb\xee\xd5\x1a\x5c\x9b\x10\xa2\x9e\x7a\x1b\x8d\xbe\xbf\x1d\x7d\x76\x70\xf7\x3b\xcf\x60\x8f\xa4\x85\x92\x13\x6f\xec\x8f\x3c\x40\x19\xab\x44\xc8\x74\xe2\x6d\xd6\x5f\x86\x9f\xbc\xbb\x70\x10\x7c\x98\x2d\xef\xd7\x3f\xa2\x39\x14\x99\xd0\x06\xa2\xcd\xe7\xc5\xc3\x3d\x78\x43\xc6\xa6\x45\x91\x21\x63\xb3\xf5\x0c\xa2\xc5\xc3\x6a\x0d\x63\x7f\xc4\xd8\xfc\xd1\x03\xef\xc5\x98\xe2\x96\xb1\xc3\xe1\xe0\x73\x87\xf2\x63\x95\x3b\xa0\x66\x11\xa9\x02\xc9\x54\x0b\xa1\xcd\x70\xec\x8f\xfc\xc4\x24\x5e\x38\x08\x8e\xea\x67\x71\xc2\x41\x90\x88\xd8\x84\x03\x00\x80\x60\x87\x55\xb8\xe0\xcf\x98\x05\xcc\x8d\xc7\xa5\x36\x24\x64\x1a\xd6\x35\x38\x1f\xb0\x76\xe8\xc6\x82\x54\x8c\x5a\x6f\x4d\x55\x60\xbb\x93\x65\x0e\xd6\x06\xec\xc4\xe8\x34\xe7\x72\x2f\x48\xc9\x1c\xa5\xf9\xc6\x49\xf0\xe7\x0c\x75\xdf\xa2\x8b\xf0\x97\x12\x2d\x9f\xd6\x3d\xc8\xeb\x24\x85\x22\x73\xe1\xd5\x91\x57\xef\x51\xf5\x05\xb1\xae\x87\x40\x5c\xa6\x08\x37\x3b\xac\x3e\xc2\xcd\x9e\x67\x25\xc2\xed\x04\x7c\x94\x7b\xb0\xf6\x5c\xbe\xae\x1b\x5c\x23\x73\xcd\xe6\x24\xd1\x73\xaa\x6b\x40\x99\xb4\x62\x01\x7b\x75\xf7\x88\x54\x4a\x3c\x9f\x52\x5a\xba\x3b\x9d\xdd\x87\x13\xf1\xea\x22\x6a\xac\xf2\x9c\xcb\xa4\x89\x79\x9a\xb7\x9c\x52\x7d\x96\xb7\x33\x17\x3f\x01\x7f\x75\x2c\xef\xc6\x9d\xd8\x03\x6b\x5d\xda\xf6\xa0\x2e\x64\xa6\xf1\xb4\x6d\xb1\xc7\x7d\x33\x5c\x7d\x4e\x2f\x63\xf3\x9e\xaf\x88\xc5\x34\x13\x7b\xec\x3f\xc4\x50\x89\xac\x07\x7a\x2a\xe5\xd4\x2c\x14\x4f\xde\x03\xad\x0c\x97\x09\xa7\x64\x59\x9a\x88\x9b\x97\x2b\xdd\xcc\x54\x0a\xd6\xb2\xae\xa6\xec\x9f\x1b\xeb\xb8\x6f\xb4\xb6\xf5\x9d\x13\x29\xfa\xaf\xce\x1b\x8d\xf4\xc8\x73\xbc\x62\x58\x6a\xa4\xb7\x3f\xb4\xef\x8a\x76\x42\xa6\x33\x41\x18\x1b\x45\xd5\x15\x81\xc3\x11\xb6\x4d\x5a\xdc\x99\x5a\x5b\xcd\x80\x35\x3f\x8c\x70\xf0\x27\x00\x00\xff\xff\x17\x6e\x65\x70\xc7\x04\x00\x00") +var _templatesLaunchdLaunchdPlistTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x54\x5f\x6f\xda\x30\x10\x7f\xe7\x53\xdc\xa2\x3e\x8e\x18\xde\xa6\x2a\xa4\x62\x85\x49\xd5\x50\x89\x0a\x6c\xda\x13\x72\x93\x5b\x6a\x91\xd8\xd9\xd9\x81\x45\x91\xbf\xfb\xe4\x40\x96\x50\x4a\xb5\xa7\xbd\x9d\x4e\xbf\x7f\x77\xb9\x38\xb8\xfb\x9d\x67\xb0\x47\xd2\x42\xc9\x89\x37\xf6\x47\x1e\xa0\x8c\x55\x22\x64\x3a\xf1\x36\xeb\x2f\xc3\x4f\xde\x5d\x38\x08\x3e\xcc\x96\xf7\xeb\x1f\xd1\x1c\x8a\x4c\x68\x03\xd1\xe6\xf3\xe2\xe1\x1e\xbc\x21\x63\xd3\xa2\xc8\x90\xb1\xd9\x7a\x06\xd1\xe2\x61\xb5\x86\xb1\x3f\x62\x6c\xfe\xe8\x81\xf7\x62\x4c\x71\xcb\xd8\xe1\x70\xf0\xb9\x43\xf9\xb1\xca\x1d\x50\xb3\x88\x54\x81\x64\xaa\x85\xd0\x66\x38\xf6\x47\x7e\x62\x12\x2f\x1c\x04\x47\xf5\xb3\x38\xe1\x20\x48\x44\x6c\xc2\x01\x00\x40\xb0\xc3\x2a\x5c\xf0\x67\xcc\x02\xe6\xca\x63\x53\x1b\x12\x32\x0d\xeb\x1a\x9c\x0f\x58\x3b\x74\x65\x41\x2a\x46\xad\xb7\xa6\x2a\xb0\xed\xc9\x32\x07\x6b\x03\x76\x62\x74\x9a\x73\xb9\x17\xa4\x64\x8e\xd2\x7c\xe3\x24\xf8\x73\x86\xba\x6f\xd1\x45\xf8\x4b\x89\x96\x4f\xeb\x1e\xe4\x75\x92\x42\x91\xb9\xf0\xea\xc8\xab\xf7\xa8\xfa\x82\x58\xd7\x43\x20\x2e\x53\x84\x9b\x1d\x56\x1f\xe1\x66\xcf\xb3\x12\xe1\x76\x02\x3e\xca\x3d\x58\x7b\x2e\x5f\xd7\x0d\xae\x91\xb9\x66\x73\x92\xe8\x39\xd5\x35\xa0\x4c\x5a\xb1\x80\xbd\xda\x7b\x44\x2a\x25\x9e\x4f\x29\x2d\xdd\x9e\xce\xf6\xc3\x89\x78\x75\x11\x35\x56\x79\xce\x65\xd2\xc4\x3c\xd5\xdb\xe6\x0b\xf7\xf3\x76\xe6\xe2\x27\xe0\xaf\x8e\xe5\xdd\xb8\x15\x7b\x60\xad\x4b\xdb\x2e\xd4\x85\xcc\x34\x9e\xba\x2d\xf6\xd8\x6f\x8a\xab\xe3\xf4\x32\x36\xf3\x7c\x45\x2c\xa6\x99\xd8\x63\x7f\x10\x43\x25\xb2\x1e\xe8\xa9\x94\x53\xb3\x50\x3c\x79\x0f\xb4\x32\x5c\x26\x9c\x92\x65\x69\x22\x6e\x5e\xae\xdc\x66\xa6\x52\xb0\x96\x75\x67\xca\xfe\xf9\x62\x1d\xf7\x8d\xab\x6d\x7d\xe7\x44\x8a\xfe\xab\xf3\x46\x23\x3d\xf2\x1c\xaf\x18\x96\x1a\xe9\xed\x1f\xed\xbb\xa2\x9d\x90\xe9\x4c\x10\xc6\x46\x51\x75\x45\xe0\x70\x84\x6d\x93\x16\x77\xa6\xd6\x9e\x66\xc0\x9a\x07\x23\x1c\xfc\x09\x00\x00\xff\xff\x04\x77\x46\x4f\xc7\x04\x00\x00") func templatesLaunchdLaunchdPlistTmplBytes() ([]byte, error) { return bindataRead( @@ -100,7 +100,7 @@ func templatesLaunchdLaunchdPlistTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/launchd/launchd.plist.tmpl", size: 1223, mode: os.FileMode(420), modTime: time.Unix(1584464125, 0)} + info := bindataFileInfo{name: "templates/launchd/launchd.plist.tmpl", size: 1223, mode: os.FileMode(420), modTime: time.Unix(1584467755, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/export.go b/export.go index 64f4b55..edb6e74 100644 --- a/export.go +++ b/export.go @@ -269,7 +269,7 @@ func portFor(processIndex int, instance int, base int) int { func templateVars(app string, entry procfileEntry, processName string, num int, port int, vars map[string]interface{}) map[string]interface{} { config := vars config["command"] = entry.Command - config["command_args"] = entry.commandArgs() + config["command_list"] = entry.commandList() config["num"] = num config["port"] = port config["process_name"] = processName diff --git a/main.go b/main.go index da75e2e..8060cd4 100644 --- a/main.go +++ b/main.go @@ -25,7 +25,7 @@ type formationEntry struct { Count int } -func (p *procfileEntry) commandArgs() []string { +func (p *procfileEntry) commandList() []string { return strings.Fields(p.Command) } diff --git a/templates/launchd/launchd.plist.tmpl b/templates/launchd/launchd.plist.tmpl index c1b3700..0139d81 100644 --- a/templates/launchd/launchd.plist.tmpl +++ b/templates/launchd/launchd.plist.tmpl @@ -16,7 +16,7 @@ ProgramArguments - {{- range $command := .command_args }} + {{- range $command := .command_list }} {{ if eq $command "$PORT" }}{{ $.port }}{{ else }}{{ $command }}{{ end }}{{ end }} KeepAlive From 5e34d18236f0ba37664a79dabab319ab491d7833 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 14:05:03 -0400 Subject: [PATCH 18/48] fix: add missing process type --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e30f1d7..91fb803 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ In addition, not all formats support all arguments, and not all arguments have e ```shell # export systemd init files to the `tmp` directory -# support formats include: [launchd, runit, systemd, systemd-user] +# support formats include: [launchd, runit, systemd, systemd-user, upstart] # the default format is: systemd procfile-util export --format systemd --location tmpp From 461395b28fa6ea36c96e3360bc47bd3da7a3dbfd Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 14:51:06 -0400 Subject: [PATCH 19/48] fix: respect .log --- bindata.go | 4 ++-- templates/upstart/default/program.conf.tmpl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bindata.go b/bindata.go index 63c5e32..5dd5942 100644 --- a/bindata.go +++ b/bindata.go @@ -245,7 +245,7 @@ func templatesUpstartDefaultProcessTypeConfTmpl() (*asset, error) { return a, nil } -var _templatesUpstartDefaultProgramConfTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x52\xc1\x6e\x13\x31\x10\xbd\xfb\x2b\xde\xa1\x6a\x1b\xa1\xcd\x02\x37\x0e\xed\xa9\x97\x9e\x88\x80\x5b\xa9\xda\x95\x3d\xd9\x58\x24\x1e\x6b\x66\x4c\x89\xda\xfd\x77\xe4\xcd\x96\xb6\x90\x8a\x20\x71\xb3\xdf\xcc\x7b\xf3\xe6\x69\x02\xa9\x97\x98\x2d\x72\xc2\xfd\x3d\xe6\x5d\xce\x18\x86\xa6\x3e\xb3\xb0\x27\xd5\x1b\xdb\x66\x7a\xc4\x52\xd9\x60\x18\x9c\x53\xeb\xc4\xc0\x09\xa7\xe3\x2b\xa6\xfe\x2f\x6c\xb0\x60\x4f\xeb\xcc\xa9\x71\x9e\x84\x38\xe7\x43\x85\xfe\x68\x9d\x39\xa7\x64\x25\x86\x11\x2b\x4a\x52\x7d\x2a\x59\x3f\x41\xbd\x70\xa9\x8d\xce\xaf\x42\x14\x8c\xd8\x1d\xcb\xb7\x98\xfa\x9b\x10\x85\xbc\xb1\x6c\x6b\x5d\x48\x73\x77\x97\x9c\xdb\x05\xe3\x00\xfa\x91\x59\x0c\x8b\x8f\x9f\xbe\x9c\x8d\x8e\xea\x6f\x18\x9e\x55\x3e\xef\x70\xdd\xa1\x57\x68\x04\x2d\x99\x6f\x03\x2d\xbb\xb2\xb6\xf6\xd1\x67\xf5\x7f\x8d\xe3\x63\xcc\x5f\xad\xbf\xe0\xeb\x56\x3d\xa7\x65\xec\xdb\xa7\x4d\x5f\x08\xec\x6b\x70\x80\x0f\xaf\xef\x57\x5d\x93\x1f\xeb\x9e\x37\x9b\x2e\x85\x2a\xfa\xd5\x01\xc0\xf9\x39\xda\xef\x9d\xb4\x6b\x7e\x2e\xd8\xee\xbb\x06\xb5\xc0\xc5\xe6\x6b\xee\x27\xee\xfb\x7f\x23\x93\x48\x25\x3b\x4a\x01\x53\xd2\x2e\xb3\x5a\xb3\x3b\xad\x5f\xe1\x2f\x2e\x2f\xce\x6e\xd5\x3a\x2b\x7a\xf8\x81\xe2\x01\xd4\x0b\x65\x34\x1c\x71\x72\x7a\xf5\xb6\xf9\x70\xfd\x66\x76\x74\x82\x07\xac\xa8\x0b\x68\xd2\xbb\xdb\x1a\x84\x5f\x31\x8e\x16\x97\x17\x98\xac\x4b\x49\xbf\x5b\x3f\x68\xde\x3c\xc7\xb0\x6f\x13\xce\x4f\x8b\xc8\x06\xcd\xf2\xff\x8e\xf9\x19\x00\x00\xff\xff\x33\xff\x89\xa3\xbd\x03\x00\x00") +var _templatesUpstartDefaultProgramConfTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x52\xc1\x6e\x13\x41\x0c\xbd\xcf\x57\xbc\x43\xd5\x36\x42\x9b\x05\x6e\x1c\x9a\x53\x2f\x3d\x11\x01\xb7\x52\xb5\xab\x19\x67\x33\xa2\x19\x8f\x6c\x2f\x25\x6a\xe7\xdf\xd1\xec\xa6\xb4\x85\x54\x04\x89\xdb\xec\xf3\xf3\xf3\x7b\x5e\x07\x52\x2f\x31\x5b\xe4\x84\xfb\x7b\xcc\xbb\x9c\x51\x4a\x53\x9f\x59\xd8\x93\xea\xb5\x6d\x33\x3d\x62\x69\xd8\xa0\x14\xe7\xd4\x3a\x31\x70\xc2\xe9\xf8\x8a\xa9\xff\x4b\x37\x58\xb0\x87\x3a\x73\x6a\x9c\x77\x42\x9c\xf3\xa1\x42\x7f\x50\x67\xce\x29\xd9\x10\xc3\x88\x0d\x4a\x52\x7d\x2a\x59\xbf\x83\x7a\xe1\xa1\x12\x9d\x5f\x87\x28\x18\xb1\x3b\x96\x6f\x31\xf5\xd7\x21\x0a\x79\x63\xd9\xd6\xba\x90\xe6\xee\x2e\x39\x37\x2d\xc6\x01\xf4\x23\xb3\x18\x96\x1f\x3f\x7d\x39\x1b\x1d\xd5\xaf\x52\x9e\x55\x3e\x4f\xb8\x4e\xe8\x25\x1a\x41\x4b\xe6\xdb\x40\xab\x6e\xb8\xb5\xf6\xd1\x67\xf5\x7f\x85\xe3\x63\xcc\x5f\xad\xbf\xe8\xd7\xad\x7a\x4e\xab\xd8\xb7\x4f\x49\x5f\x08\xec\x23\x38\xc0\x87\xd7\xf3\x55\xd7\xe4\xc7\xba\xe7\xcd\xa6\x4b\xa1\x8a\x7e\x75\x00\xb0\x58\x8c\xf8\x2d\xf7\x28\xe5\x99\x64\xbb\xef\x1e\xd4\x02\x0f\x36\x92\xa7\xee\xf7\xff\xda\x4e\x22\x95\xec\x28\x05\xec\xb6\xed\x32\xab\x35\xd3\x79\xfd\xfa\x01\xcb\x8b\xf3\xb3\x1b\xb5\xce\x06\x3d\xfc\x48\xf1\x00\xea\x85\x32\x1a\x8e\x38\x39\xbd\x7c\xdb\x7c\xb8\x7a\x33\x3b\x3a\xc1\x03\xd6\xd4\x05\x34\xe9\xdd\x4d\x5d\x86\x5f\x33\x8e\x96\x17\xe7\x58\xa0\xfd\xde\x49\x2b\x43\xfa\xdd\xfa\x41\xf3\xe6\x39\x86\x7d\x49\x38\x3f\x05\x91\x0d\x9a\xd5\xff\x1d\xf3\x33\x00\x00\xff\xff\x99\xdb\x24\x5f\xc1\x03\x00\x00") func templatesUpstartDefaultProgramConfTmplBytes() ([]byte, error) { return bindataRead( @@ -260,7 +260,7 @@ func templatesUpstartDefaultProgramConfTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/upstart/default/program.conf.tmpl", size: 957, mode: os.FileMode(420), modTime: time.Unix(1584464146, 0)} + info := bindataFileInfo{name: "templates/upstart/default/program.conf.tmpl", size: 961, mode: os.FileMode(420), modTime: time.Unix(1584468680, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/templates/upstart/default/program.conf.tmpl b/templates/upstart/default/program.conf.tmpl index 0aa7598..7c58923 100644 --- a/templates/upstart/default/program.conf.tmpl +++ b/templates/upstart/default/program.conf.tmpl @@ -15,8 +15,8 @@ script [ -r /etc/sysconfig/{{ .app }} ] && . /etc/sysconfig/{{ .app }} cd {{ .working_directory }} exec {{ .command }} \ - >> /var/log/{{ .app }}/{{ .process_type }}-stdout.log \ - 2>> /var/log/{{ .app }}/{{ .process_type }}-stderr.log + >> {{ .log }}/{{ .app }}/{{ .process_type }}-stdout.log \ + 2>> {{ .log }}/{{ .app }}/{{ .process_type }}-stderr.log end script post-start script From a60d21e34fd6640fa9f883362f86ee25ccf134ac Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 14:51:42 -0400 Subject: [PATCH 20/48] feat: add support for sysv --- bindata.go | 27 ++++ export.go | 33 ++++ go.mod | 1 + go.sum | 2 + main.go | 70 ++++++++- templates/sysv/default/init.sh.tmpl | 224 ++++++++++++++++++++++++++++ 6 files changed, 355 insertions(+), 2 deletions(-) create mode 100644 templates/sysv/default/init.sh.tmpl diff --git a/bindata.go b/bindata.go index 5dd5942..b497af8 100644 --- a/bindata.go +++ b/bindata.go @@ -6,6 +6,7 @@ // templates/systemd/default/control.target.tmpl // templates/systemd/default/program.service.tmpl // templates/systemd-user/default/program.service.tmpl +// templates/sysv/default/init.sh.tmpl // templates/upstart/default/control.conf.tmpl // templates/upstart/default/process-type.conf.tmpl // templates/upstart/default/program.conf.tmpl @@ -205,6 +206,26 @@ func templatesSystemdUserDefaultProgramServiceTmpl() (*asset, error) { return a, nil } +var _templatesSysvDefaultInitShTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x57\x6d\x73\xdb\x36\x12\xfe\xce\x5f\xb1\xa1\x34\x76\x92\xd3\x8b\xed\x5c\xef\x66\x9c\x71\x7a\x69\xe3\xf6\x34\x4d\x6c\x8f\xa5\x4e\x6f\xa6\xed\x28\x10\xb1\x14\x71\x22\x01\x16\x00\x2d\xab\xb6\xfe\xfb\xcd\x02\x20\x45\xda\x52\x2f\xc9\x07\x47\x04\x76\x9f\x5d\xec\xcb\x83\x45\xef\xc5\x78\x21\xe4\xd8\x64\x51\x0f\x26\x52\x58\x30\x89\x16\xa5\x85\x54\x69\x78\x78\x80\x11\x2b\x4b\xd8\x6e\x87\xf4\xb3\xd4\x2a\x41\x63\xe6\x76\x53\x62\xbd\x26\xab\x02\xb6\xdb\xa8\x07\x9f\x98\x90\x96\x09\x89\x1c\x16\x1b\xd2\x14\x29\x8c\x58\x65\x33\xa5\x61\xbb\x75\x48\xad\x0f\x94\xdc\xab\xfd\x88\x12\x35\xb3\x5e\xab\xcc\x91\x19\xd4\x95\x1c\x91\x33\x45\x99\x63\x81\xd2\xed\x31\x83\x1c\x94\x84\x8f\xd3\xef\xe0\x7b\xa5\x11\xde\x8c\x4e\xcf\xa3\x1e\x00\xbc\x86\x29\x26\x56\x28\x69\xce\xe1\xec\x64\x74\x36\xa0\xbf\x6f\xa2\x5e\xd4\xeb\xf5\xe0\xbb\xcb\x1f\x27\x57\x30\xb9\x9a\xcc\x60\x72\xf5\xc3\x75\xd4\x83\x1b\xad\xee\x04\x47\x73\x0e\xcd\xbf\xaf\x39\xe5\x2d\xfe\x51\x09\x8d\x7c\x38\xb5\x4c\x5b\x07\xd2\xd7\x58\x28\x8b\xf3\xd4\x40\xdf\x6c\x4c\xae\x96\x5d\x39\x55\x7a\x5b\x7b\xe5\x3e\x60\xca\xaa\xdc\xb6\xe0\xe0\x0c\xde\xc0\xdf\xe1\x9b\xce\x66\x8d\x01\x27\x70\x0a\xff\x88\x7a\x30\xcd\x94\xb6\xc3\x0f\xe8\x93\x25\x94\x3c\xaf\x43\xae\x24\xce\x73\x21\x71\xce\x77\x9b\x21\x01\x87\xb7\x9a\x74\x74\x10\x77\xe1\xe9\x2a\xb8\xd0\x5e\x5e\x7d\x68\x05\x36\xba\x79\x3f\xfb\xf7\xc5\xd8\x2c\x84\x3c\x1f\x57\x46\x87\x5f\xcd\xe7\x42\xc8\x08\xef\x4b\xa5\x2d\x90\x64\x14\x49\x56\xe0\xc5\x97\x47\xbe\xd4\x6a\xa9\x59\x71\x11\xc4\xe8\xf7\x76\x1b\x31\xbd\x34\x1e\x44\x2f\x8d\x13\x13\x3c\x15\x39\x5e\xc4\xe3\x3b\xa6\xc7\xba\x92\xe3\x3e\x19\x1a\x95\x82\xc7\x51\x65\x50\x5f\xc4\x24\x4e\xbf\x60\xbb\x8d\xa3\xa5\x56\x55\xe9\xd7\xdc\x4f\xb7\x98\x64\x5a\x29\xeb\x57\xd7\x4a\xaf\x84\x5c\xce\xb9\xd0\x98\x58\xa5\x37\x41\x82\x0b\xfd\x57\x02\x52\x24\xe8\xf7\xe9\x17\xad\x3c\x3c\x0c\x5d\x7a\x72\x51\x08\x3b\x4f\x94\x46\x5e\x15\x64\x2f\xea\xae\x78\xad\x67\x52\xf1\x2e\x49\x4f\x90\xca\xca\x8a\x02\x5b\x40\x7e\xa1\x83\xd3\xc8\x1c\x84\xe1\xcc\xb2\x1d\x06\x7d\xb5\x01\xc2\xee\x41\x6d\x8a\xf9\xdc\x88\x3f\x5b\x6e\x34\x4b\x6d\x9c\xb6\xdc\x41\xb0\x5c\x25\x2b\xe4\xf3\x02\x0b\x1f\xcd\x68\xcf\x72\x1b\xf4\xa9\xfc\x41\x60\x55\xa2\x74\x2e\x98\x1d\xea\x6e\xad\x0d\xd9\x91\x3c\x88\x47\x55\x34\x0f\x35\xdb\xc6\xec\xae\xb7\x71\x9f\x69\x1c\xc4\x2e\xb3\x8d\x11\x09\xcb\x9f\x85\xe1\xc9\x46\x1b\xfd\xb9\xce\x41\x78\x63\x59\xb2\x7a\x92\xb1\xdd\x5a\x1b\xb4\x23\xd9\xc2\x23\x82\x4e\xc1\x66\xc2\x80\x30\x60\xd0\x82\x55\x70\x3a\x00\x9b\xa1\x84\x35\xfd\xf9\x6c\xac\x2a\x3f\xd3\x6e\xc2\xf2\x1c\xf9\x80\xec\xdb\x0c\x21\x04\x00\x32\x66\xa2\x1e\x48\x65\x01\xef\x05\xb1\xfc\x5a\xd8\x4c\x48\x60\xa0\x91\x19\x25\xd9\x22\x47\xa0\xc2\x1d\xc0\x74\xf2\xe3\x4f\x93\x8f\x1f\x61\x2d\xf2\x1c\x16\x08\x06\xa5\x05\x89\xf7\x96\x2e\x8a\x59\x86\xc0\x3d\x55\xc2\x02\x33\x76\x27\x94\x26\xb3\x56\x81\x11\x45\x99\x6f\x20\x57\x4b\x60\x50\xa0\x31\x6c\x89\x10\x07\x02\x01\x72\x10\x52\x26\x72\xe4\x6f\xc1\x58\xc2\xd6\x95\x94\x42\x2e\xe3\x88\xcc\xcd\xaf\xaf\xe6\xd3\xd9\xf5\xcd\x7c\x36\xf9\x74\x79\xfd\xf3\xec\xe2\x84\x8e\xfd\x0b\x1d\x2e\x57\x8c\x0b\xb9\x6c\xec\x32\xc9\xc1\x6c\x4c\xa2\x64\x2a\x96\xe0\x4a\x67\x00\x6b\x84\xca\x20\x7c\xa6\xe8\x0c\xd9\x67\x72\xa8\x60\x2b\x8c\x7a\xc0\xf2\x1c\xee\x98\x16\x74\x44\x03\xac\xb2\xaa\x60\x96\x72\x97\x6f\x40\x48\xab\x00\xe5\x9d\xd0\x4a\xd2\xf5\xb7\x13\x1c\x45\x1e\x29\xfa\x15\x86\x1a\xc6\x68\x93\x71\xb0\x3f\xae\x99\x14\xb6\x5b\xf8\x1d\x8e\x8e\x60\x74\x70\xbf\xa5\xdd\x78\x3c\xde\x31\x71\x47\x7d\x9f\x80\x73\xe2\x6f\xac\xa1\xf3\xeb\xdb\x99\xa7\x65\xfa\xda\x6e\x9b\xf5\xa9\x5f\x75\x8d\x41\x36\xff\x84\xb8\x4f\x6c\x18\x7b\x0b\x8e\x22\x4f\xa2\xc8\x6a\x96\xe0\xcb\x57\xf0\x10\x01\xe5\x69\x89\x1a\x86\x16\x62\x67\x5e\x48\x61\x47\x7c\xfc\xc5\xd7\x44\x0c\x71\xff\x5f\x71\xb4\x8d\x22\x2c\x84\x0d\xa0\xce\x80\xdf\x00\xc0\x24\x53\x8d\x90\xa1\x4b\x37\x48\x3d\x3c\x8c\x5f\xc3\x04\xb8\x72\x05\x49\x69\x3b\x36\xd5\x31\x64\xa8\x91\xf2\xa6\x2b\x09\xcc\x00\x03\x2e\xd2\x14\x35\xa5\xc5\x5d\x22\x0b\x4c\x18\x09\xb7\xeb\x9a\x14\x23\x7f\x77\x1a\xcb\x36\x86\x14\xdd\x3e\x23\xbd\x01\x90\x06\xd5\x8e\xaa\x34\x84\x0b\x8b\x4c\x24\xca\xcd\x4f\x5e\x54\x70\x50\xa9\x77\x81\xfc\xb1\x19\x06\xc4\xba\x76\xd7\x48\x85\x82\x92\x23\x0f\xfe\x8d\xe0\x63\x95\xac\x44\xbe\x71\x4d\x08\xc7\xfe\x1a\x3b\x6e\x34\x94\x84\xeb\xe9\x7f\x06\xf0\x83\x46\xfc\x6e\xfa\x61\xe0\x6a\xf6\xa3\x90\xd5\x7d\x80\xa6\xa2\x34\x55\xe9\xb2\x67\xd6\xc2\x26\x19\x79\x49\xc7\x34\x4e\x56\x58\x10\xf2\x4e\xad\xd0\x00\xde\x63\x72\x87\x20\x8a\x02\xb9\x60\x16\xf3\x0d\xb0\xd4\xa2\x06\x6f\x54\xc8\xe5\x08\x5e\x8f\x29\xf1\x00\x3d\xb8\x94\xa6\xd2\x3e\x46\xd4\x89\xbb\xab\xd2\x33\x47\x55\x42\xa2\x34\xad\xe5\x9b\x51\x04\x44\x13\xbf\xc2\x0b\x18\x72\xf0\x3c\xa4\x96\xe0\x72\xfb\xfb\x5b\xcf\x2e\xce\xdd\x62\xc5\x85\xee\x0a\xb8\xf5\x24\x53\x6b\x09\x71\x9f\xdc\x8e\xcf\xe3\xbe\xbb\xd6\xe3\xbd\x82\x85\xe2\xf0\xcf\x6f\xbe\x79\xb6\x97\x8a\xc8\x15\x84\x27\xcc\x52\xa3\xab\x13\x2a\xe3\xe0\x5b\xdc\xbf\xb9\xbd\x9c\xce\xde\xdf\xce\x62\x78\x71\x01\xb1\x54\x54\xd3\xde\x3b\x87\xed\xb8\xb1\x51\x24\x86\x31\x03\x60\x0b\x17\x58\x5a\x1a\x45\x3e\x95\x41\xe0\xf1\x11\x34\xda\x4a\x4b\xe8\x7f\xeb\xed\xbb\xa9\xab\x66\x5a\xc2\x9b\xba\x30\x31\xb9\x69\x33\x03\xcb\xc1\xd8\x2a\x4d\x61\x81\xa9\xd2\x98\x31\xc9\x5b\x8e\x57\x81\xc0\x33\xcc\xf3\x30\x00\x3e\x5f\x6a\xdb\xb8\xad\x64\x5d\xc7\x54\x30\x2f\x5a\x58\xd4\xac\xb0\xdd\xba\xff\x86\xb2\x6e\xe4\x9d\x3e\x84\xc4\xc3\x70\xe8\xea\xa5\xc4\x64\x4f\x0e\xfa\x5e\x28\x06\x93\xc1\x30\x01\x9f\x87\x30\xb6\x7e\x8d\xb7\x2e\x7d\x1c\x7e\x23\x40\x2e\xf4\x6f\x1e\x88\x6a\x92\xd6\x82\xfb\xbf\xc5\xd0\xa7\xb1\x30\x02\x88\xe1\xdd\x3b\xa8\x93\xbc\xdd\xb6\xf8\x64\xbc\x8f\x4f\x8c\xe5\xaa\xb2\x4e\xf8\xec\x6b\x15\x51\x6b\x27\x7c\xe4\x43\x5a\xbf\x6e\xea\xa6\x76\xbd\x9e\x6a\x55\x38\x62\x19\x51\x99\xb8\x46\x36\x16\x19\x87\x82\x71\x2f\x99\x2a\xbd\x42\x5e\x13\x8a\x43\x5a\xd6\x48\xc2\xb1\x81\xc6\xe6\x2e\x64\xe0\x08\x2e\x51\x92\x0b\x37\xa0\x2f\xd0\xae\x11\x65\xc7\xe6\x5a\x0b\xea\x4a\x07\x45\xbd\xcc\x1a\xb6\x2a\x95\x31\x62\x41\x0d\x6c\x68\x90\x75\xef\x3e\x63\x99\xad\xcc\xa8\xe6\xcb\xfe\x0b\x78\x07\xfd\x00\x45\x07\x23\x76\xa5\x22\x60\x05\xfa\x82\x46\x4e\x39\x08\x45\x7c\xe2\xb9\x55\x95\x81\x5a\x7b\x30\xd3\x1b\x60\x90\xe2\xda\x5d\xe7\xee\x66\x5e\x91\xf7\xb3\xcb\xdb\x4f\xed\x92\xf3\x0d\xe6\xad\xb7\xfb\xa9\x14\xfc\xa2\xff\x32\x61\x64\x34\xb8\x11\xbf\x72\x3b\x81\xdc\x7f\x12\x79\x4e\xce\x7b\x97\x5e\x12\x7d\x92\xe0\x2b\x37\x52\xd0\xf4\x40\x96\x7c\x99\x38\xc3\x43\x67\x99\x44\x42\xbf\xfe\xc2\x84\x7f\xf2\x0a\x37\xc8\xd0\x40\xe2\x9b\xd4\xad\x81\x90\x70\x5a\x3f\xcc\xe0\x2d\x70\x15\x28\x33\x98\x27\xed\xbd\xe6\xad\x02\x2e\x70\x34\x1a\xc5\xbb\x0b\x81\xce\xf6\xf8\x08\x0b\x8d\x6c\x55\xaf\xe6\x88\x25\x9c\xba\x2f\xae\xa4\xe7\xfa\xbd\x91\x68\x18\x68\xdf\x7c\x12\xc3\x10\xff\x80\xd3\x2e\x17\xb5\xdc\x9c\x89\x02\x55\x65\x69\xbc\x4a\x32\xe4\x23\xf8\xbf\x61\x23\x2b\x23\x80\x19\x8d\x79\x05\xdb\x80\x46\x43\xd3\x8e\x90\xe0\x9e\x04\xb9\x32\xa6\x39\x5a\x1d\x5a\x37\xa8\x35\xa1\x75\x9d\xd9\x2a\x17\x92\x09\xa3\x5e\x63\xa0\x46\xc0\xdc\xe0\x5e\xa5\xc3\x83\x5a\xa3\xeb\x48\xb3\x03\xf1\x14\xa0\x44\x1e\xa4\x9d\x6c\x2a\xc2\x08\x60\x2b\x13\x0a\xd5\x85\x76\x98\xb6\x8a\xac\x1b\xca\xc3\x65\x28\x52\x28\x0d\x0c\x4b\x77\x6e\x78\x07\x63\x8e\x77\x63\x59\xe5\x39\x9c\xb5\x3f\x3a\x69\xe9\x35\x2d\xb8\xd8\xf8\x41\x9a\x74\x85\x69\x8e\xd6\xc8\x4d\xac\x0b\x3e\x0d\x02\x0b\xac\xc7\x86\x01\x2c\x2a\xa2\x02\x66\x8f\x0d\xac\x33\x66\x61\xa3\x2a\x58\xa2\xf5\xb1\xfd\x6f\x65\x6c\xdd\xfd\x66\x07\x35\xbb\xfe\x70\xfd\xd2\x08\x63\x30\x7f\x75\x0e\xdf\x67\x98\xac\xfc\x58\x4e\xe6\x83\x3b\x06\xb1\x70\x3d\xba\xf0\x6c\x64\x28\x82\x61\x86\x51\x12\x61\x8d\x0d\x1c\xde\x97\x98\xd8\x11\x4c\xec\x31\x27\x71\x77\x41\x58\xe5\xe6\xa7\x94\x1e\x66\x8e\xe7\xbc\xab\xfe\xbb\xa2\x87\x0f\xf1\xdb\x20\x4c\xfe\x98\x0c\x1a\x38\xa3\xa8\xff\x68\x46\x36\xf4\xe3\x8f\x4a\x58\x04\xb6\x5e\xad\x99\xe6\x35\xac\x9b\x90\xdc\xa3\xc2\x60\x7d\xae\x86\x78\x9e\x94\x40\x58\x3f\xf3\xb1\x76\x53\x90\x30\xc0\x89\x6b\xc9\x23\x8a\xb7\x63\x47\xbc\x17\xc6\x9a\x5d\x6d\x34\x10\x01\xe0\x4d\x17\x80\x1c\x0f\x49\x6a\x0a\x29\x55\x3a\xc1\x79\x8b\xf5\xf6\xb6\x2f\xed\x47\x2d\x1e\x38\x3a\xea\x34\xcd\x9e\xda\xf2\xe8\xfb\x86\x91\xfa\x77\x33\xc0\x76\xb7\xa3\xda\xc8\x45\xff\xdb\xa8\x2e\xee\x7e\xb0\x3b\x5c\x5a\x38\xe9\x16\xb7\x6f\x97\x9b\x1a\x21\x51\x45\x41\x17\x85\xef\x3a\x5f\x53\x89\xe2\x58\x43\xb8\xbb\x8b\x2a\x6e\x2d\x4c\xe6\x9e\x5a\x2b\x51\x06\x2e\xef\x42\x0c\xdc\xeb\xb0\x9e\x98\x2e\xa4\xa2\x14\x6e\xa8\x8a\x5b\xa3\xcc\x28\xae\x07\x9f\x7a\x12\xf2\x66\x22\x7a\xb9\x36\x53\x0a\xe5\x1c\xe2\xfe\x69\x0c\x82\x9c\x76\x31\x1f\x3a\x63\x8f\xf5\x5f\x55\x3e\xd6\xcb\xaa\x7c\x0c\xae\x74\xee\x8a\xf7\xd6\x62\x51\x3a\xbe\x3e\xee\x9f\x1e\xd3\x5c\xfc\xe5\x0f\x0c\x07\xf4\xf6\x6d\x84\x86\x25\x7f\xe5\x8f\xb7\xd8\x3a\xf4\x6e\x44\x89\xfb\x27\xb1\xbf\x35\x6b\x30\x80\x96\x4e\x38\xb7\x9b\x71\x14\xc7\x0b\x37\x12\xd6\xe9\x73\x19\x20\x92\x3f\xa9\xa7\xe1\x3d\x64\x27\x0c\xb0\x5c\x23\xe3\x9b\xdd\x73\x36\x48\xdd\x0b\xeb\x41\x9e\x76\xca\xce\x9f\x5a\xea\xdb\xa8\x45\xab\xc1\x49\x55\xbe\xf2\x5c\xec\xbe\x77\x71\x7e\x05\xbb\xf2\x6f\x0e\x64\x2b\xf3\x95\x27\x82\xbf\x3a\x52\xe7\x28\x07\x68\xbe\xdb\x9b\x71\xfb\x04\x4f\x8e\xee\x9c\xec\x54\xc7\xd3\x16\xdb\x6e\xbf\x6c\xd6\xef\xce\xf1\xdd\xd8\x75\x47\x56\x17\x9d\xa3\xa3\xa7\xb9\x7f\xed\xed\xfb\x97\xe9\xcf\x86\x2d\xf1\x1c\xfa\xd3\xef\x6f\x27\x37\xb3\xab\xf7\x9f\x2e\xe1\xc1\x97\x76\xb7\xd8\x5b\x65\xde\xde\x54\xe5\xa3\x8f\x76\x5d\xf9\xdb\x18\xde\x1d\x9d\xed\x22\xf0\x26\x6a\x95\x6f\xed\xec\xff\x02\x00\x00\xff\xff\xd3\x72\x03\xe2\x03\x18\x00\x00") + +func templatesSysvDefaultInitShTmplBytes() ([]byte, error) { + return bindataRead( + _templatesSysvDefaultInitShTmpl, + "templates/sysv/default/init.sh.tmpl", + ) +} + +func templatesSysvDefaultInitShTmpl() (*asset, error) { + bytes, err := templatesSysvDefaultInitShTmplBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "templates/sysv/default/init.sh.tmpl", size: 6147, mode: os.FileMode(420), modTime: time.Unix(1584470819, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + var _templatesUpstartDefaultControlConfTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x4a\x49\x2d\x4e\x2e\xca\x2c\x28\xc9\xcc\xcf\x53\xa8\xae\x56\xd0\x4b\x2c\x28\x50\xa8\xad\xe5\xe2\x2a\x2e\x49\x2c\x2a\x51\xc8\xcf\x53\xd0\x00\xb3\x52\x53\x14\xf2\x52\x4b\xca\xf3\x8b\xb2\x33\xf3\xd2\x35\xb9\x8a\x4b\xf2\x0b\x40\x92\x45\xa5\x79\x39\xa9\x65\xa9\x39\x0a\xd1\x06\x66\xb1\x5c\x80\x00\x00\x00\xff\xff\x88\x35\x19\x59\x4c\x00\x00\x00") func templatesUpstartDefaultControlConfTmplBytes() ([]byte, error) { @@ -323,6 +344,7 @@ var _bindata = map[string]func() (*asset, error){ "templates/systemd/default/control.target.tmpl": templatesSystemdDefaultControlTargetTmpl, "templates/systemd/default/program.service.tmpl": templatesSystemdDefaultProgramServiceTmpl, "templates/systemd-user/default/program.service.tmpl": templatesSystemdUserDefaultProgramServiceTmpl, + "templates/sysv/default/init.sh.tmpl": templatesSysvDefaultInitShTmpl, "templates/upstart/default/control.conf.tmpl": templatesUpstartDefaultControlConfTmpl, "templates/upstart/default/process-type.conf.tmpl": templatesUpstartDefaultProcessTypeConfTmpl, "templates/upstart/default/program.conf.tmpl": templatesUpstartDefaultProgramConfTmpl, @@ -390,6 +412,11 @@ var _bintree = &bintree{nil, map[string]*bintree{ "program.service.tmpl": &bintree{templatesSystemdUserDefaultProgramServiceTmpl, map[string]*bintree{}}, }}, }}, + "sysv": &bintree{nil, map[string]*bintree{ + "default": &bintree{nil, map[string]*bintree{ + "init.sh.tmpl": &bintree{templatesSysvDefaultInitShTmpl, map[string]*bintree{}}, + }}, + }}, "upstart": &bintree{nil, map[string]*bintree{ "default": &bintree{nil, map[string]*bintree{ "control.conf.tmpl": &bintree{templatesUpstartDefaultControlConfTmpl, map[string]*bintree{}}, diff --git a/export.go b/export.go index edb6e74..c151e43 100644 --- a/export.go +++ b/export.go @@ -198,6 +198,37 @@ func exportSystemdUser(app string, entries []procfileEntry, formations map[strin return true } +func exportSysv(app string, entries []procfileEntry, formations map[string]formationEntry, location string, defaultPort int, vars map[string]interface{}) bool { + l, err := loadTemplate("launchd", "templates/sysv/default/init.sh.tmpl") + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + return false + } + + if _, err := os.Stat(location); os.IsNotExist(err) { + os.MkdirAll(location, os.ModePerm) + } + + for i, entry := range entries { + num := 1 + count := processCount(entry, formations) + + for num <= count { + processName := fmt.Sprintf("%s-%d", entry.Name, num) + fmt.Println("writing:", app+"-"+processName) + + port := portFor(i, num, defaultPort) + config := templateVars(app, entry, processName, num, port, vars) + if !writeOutput(l, location+"/"+app+"-"+processName, config) { + return false + } + + num += 1 + } + } + + return true +} func exportUpstart(app string, entries []procfileEntry, formations map[string]formationEntry, location string, defaultPort int, vars map[string]interface{}) bool { p, err := loadTemplate("program", "templates/upstart/default/program.conf.tmpl") if err != nil { @@ -268,12 +299,14 @@ func portFor(processIndex int, instance int, base int) int { func templateVars(app string, entry procfileEntry, processName string, num int, port int, vars map[string]interface{}) map[string]interface{} { config := vars + config["args"] = entry.args() config["command"] = entry.Command config["command_list"] = entry.commandList() config["num"] = num config["port"] = port config["process_name"] = processName config["process_type"] = entry.Name + config["program"] = entry.program() config["ps"] = app + "-" + entry.Name + "." + strconv.Itoa(num) if config["description"] == "" { config["description"] = fmt.Sprintf("%s process for %s", processName, app) diff --git a/go.mod b/go.mod index 0ffe593..6b22373 100644 --- a/go.mod +++ b/go.mod @@ -7,4 +7,5 @@ require ( github.com/andrew-d/go-termutil v0.0.0-20150726205930-009166a695a2 github.com/go-bindata/go-bindata v3.1.2+incompatible // indirect github.com/joho/godotenv v1.2.0 + gopkg.in/alessio/shellescape.v1 v1.0.0-20170105083845-52074bc9df61 // indirect ) diff --git a/go.sum b/go.sum index 9c10069..071f9c4 100644 --- a/go.sum +++ b/go.sum @@ -6,3 +6,5 @@ github.com/go-bindata/go-bindata v3.1.2+incompatible h1:5vjJMVhowQdPzjE1LdxyFF7Y github.com/go-bindata/go-bindata v3.1.2+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo= github.com/joho/godotenv v1.2.0 h1:vGTvz69FzUFp+X4/bAkb0j5BoLC+9bpqTWY8mjhA9pc= github.com/joho/godotenv v1.2.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +gopkg.in/alessio/shellescape.v1 v1.0.0-20170105083845-52074bc9df61 h1:8ajkpB4hXVftY5ko905id+dOnmorcS2CHNxxHLLDcFM= +gopkg.in/alessio/shellescape.v1 v1.0.0-20170105083845-52074bc9df61/go.mod h1:IfMagxm39Ys4ybJrDb7W3Ob8RwxftP0Yy+or/NVz1O8= diff --git a/main.go b/main.go index 8060cd4..e898a02 100644 --- a/main.go +++ b/main.go @@ -13,6 +13,7 @@ import ( "github.com/akamensky/argparse" "github.com/andrew-d/go-termutil" "github.com/joho/godotenv" + "gopkg.in/alessio/shellescape.v1" ) type procfileEntry struct { @@ -29,6 +30,14 @@ func (p *procfileEntry) commandList() []string { return strings.Fields(p.Command) } +func (p *procfileEntry) program() string { + return strings.Fields(p.Command)[0] +} + +func (p *procfileEntry) args() string { + return shellescape.Quote(strings.Join(strings.Fields(p.Command)[1:], " ")) +} + const portEnvVar = "PORT" // Version contains the procfile-util version @@ -293,7 +302,7 @@ func expandCommand(entries []procfileEntry, envPath string, allowGetenv bool, pr return true } -func exportCommand(entries []procfileEntry, app string, description string, envPath string, format string, formation string, group string, home string, limitOpenFiles string, location string, logPath string, nice string, workingDirectoryPath string, runPath string, timeout int, user string, defaultPort int) bool { +func exportCommand(entries []procfileEntry, app string, description string, envPath string, format string, formation string, group string, home string, limitCoredump string, limitCputime string, limitData string, limitFileSize string, limitLockedMemory string, limitOpenFiles string, limitUserProcesses string, limitPhysicalMemory string, limitStackSize string, location string, logPath string, nice string, prestart string, workingDirectoryPath string, runPath string, timeout int, user string, defaultPort int) bool { if format == "" { fmt.Fprintf(os.Stderr, "no format specified\n") return false @@ -307,6 +316,7 @@ func exportCommand(entries []procfileEntry, app string, description string, envP "runit": true, "systemd": true, "systemd-user": true, + "sysv": true, "upstart": true, } @@ -357,10 +367,20 @@ func exportCommand(entries []procfileEntry, app string, description string, envP vars["home"] = home vars["log"] = logPath vars["location"] = location + vars["limit_coredump"] = limitCoredump + vars["limit_cputime"] = limitCputime + vars["limit_data"] = limitData + vars["limit_file_size"] = limitFileSize + vars["limit_locked_memory"] = limitLockedMemory vars["limit_open_files"] = limitOpenFiles + vars["limit_user_processes"] = limitUserProcesses + vars["limit_physical_memory"] = limitPhysicalMemory + vars["limit_stack_size"] = limitStackSize vars["nice"] = nice + vars["prestart"] = prestart vars["working_directory"] = workingDirectoryPath vars["timeout"] = strconv.Itoa(timeout) + vars["ulimit_shell"] = ulimitShell(limitCoredump, limitCputime, limitData, limitFileSize, limitLockedMemory, limitOpenFiles, limitUserProcesses, limitPhysicalMemory, limitStackSize) vars["user"] = user if format == "launchd" { @@ -379,6 +399,10 @@ func exportCommand(entries []procfileEntry, app string, description string, envP return exportSystemdUser(app, entries, formations, location, defaultPort, vars) } + if format == "sysv" { + return exportSysv(app, entries, formations, location, defaultPort, vars) + } + if format == "upstart" { return exportUpstart(app, entries, formations, location, defaultPort, vars) } @@ -386,6 +410,39 @@ func exportCommand(entries []procfileEntry, app string, description string, envP return false } +func ulimitShell(limitCoredump string, limitCputime string, limitData string, limitFileSize string, limitLockedMemory string, limitOpenFiles string, limitUserProcesses string, limitPhysicalMemory string, limitStackSize string) string { + s := []string{} + if limitCoredump != "" { + s = append(s, "ulimit -c ${limit_coredump}") + } + if limitCputime != "" { + s = append(s, "ulimit -t ${limit_cputime}") + } + if limitData != "" { + s = append(s, "ulimit -d ${limit_data}") + } + if limitFileSize != "" { + s = append(s, "ulimit -f ${limit_file_size}") + } + if limitLockedMemory != "" { + s = append(s, "ulimit -l ${limit_locked_memory}") + } + if limitOpenFiles != "" { + s = append(s, "ulimit -n ${limit_open_files}") + } + if limitUserProcesses != "" { + s = append(s, "ulimit -u ${limit_user_processes}") + } + if limitPhysicalMemory != "" { + s = append(s, "ulimit -m ${limit_physical_memory}") + } + if limitStackSize != "" { + s = append(s, "ulimit -s ${limit_stack_size}") + } + + return strings.Join(s, "\n") +} + func parseFormation(formation string) (map[string]formationEntry, error) { entries := make(map[string]formationEntry) for _, formation := range strings.Split(formation, ",") { @@ -501,10 +558,19 @@ func main() { formationExportFlag := exportCmd.String("", "formation", &argparse.Options{Default: "all=1", Help: "specify what processes will run and how many"}) groupExportFlag := exportCmd.String("", "group", &argparse.Options{Help: "group to run the command as"}) homeExportFlag := exportCmd.String("", "group", &argparse.Options{Help: "home directory for program"}) + limitCoredumpExportFlag := exportCmd.String("", "limit-coredump", &argparse.Options{Help: "Largest size (in blocks) of a core file that can be created. (setrlimit RLIMIT_CORE)"}) + limitCputimeExportFlag := exportCmd.String("", "limit-cputime", &argparse.Options{Help: "Maximum amount of cpu time (in seconds) a program may use. (setrlimit RLIMIT_CPU)"}) + limitDataExportFlag := exportCmd.String("", "limit-data", &argparse.Options{Help: "Maximum data segment size (setrlimit RLIMIT_DATA)"}) + limitFileSizeExportFlag := exportCmd.String("", "limit-file-size", &argparse.Options{Help: "Maximum size (in blocks) of a file receiving writes (setrlimit RLIMIT_FSIZE)"}) + limitLockedMemoryExportFlag := exportCmd.String("", "limit-locked-memory", &argparse.Options{Help: "Maximum amount of memory (in bytes) lockable with mlock(2) (setrlimit RLIMIT_MEMLOCK)"}) limitOpenFilesExportFlag := exportCmd.String("", "limit-open-files", &argparse.Options{Help: "maximum number of open files, sockets, etc. (setrlimit RLIMIT_NOFILE)"}) + limitUserProcessesExportFlag := exportCmd.String("", "limit-user-processes", &argparse.Options{Help: "Maximum number of running processes (or threads!) for this user id. Not recommended because this setting applies to the user, not the process group. (setrlimit RLIMIT_NPROC)"}) + limitPhysicalMemoryExportFlag := exportCmd.String("", "limit-physical-memory", &argparse.Options{Help: "Maximum resident set size (in bytes); the amount of physical memory used by a process. (setrlimit RLIMIT_RSS)"}) + limitStackSizeExportFlag := exportCmd.String("", "limit-stack-size", &argparse.Options{Help: "Maximum size (in bytes) of a stack segment (setrlimit RLIMIT_STACK)"}) locationExportFlag := exportCmd.String("", "location", &argparse.Options{Help: "location to output to"}) logPathExportFlag := exportCmd.String("", "log-path", &argparse.Options{Default: "/var/log", Help: "log directory"}) niceExportFlag := exportCmd.String("", "nice", &argparse.Options{Help: "nice level to add to this program before running"}) + prestartExportFlag := exportCmd.String("", "prestart", &argparse.Options{Help: "A command to execute before starting and restarting. A failure of this command will cause the start/restart to abort. This is useful for health checks, config tests, or similar operations."}) workingDirectoryPathExportFlag := exportCmd.String("", "working-directory-path", &argparse.Options{Default: workingDirectoryPath, Help: "working directory path for app"}) runExportFlag := exportCmd.String("", "run", &argparse.Options{Help: "run pid file directory, defaults to /var/run/"}) timeoutExportFlag := exportCmd.Int("", "timeout", &argparse.Options{Default: 5, Help: "amount of time (in seconds) processes have to shutdown gracefully before receiving a SIGKILL"}) @@ -554,7 +620,7 @@ func main() { } else if expandCmd.Happened() { success = expandCommand(entries, *envPathExpandFlag, *allowGetenvExpandFlag, *processTypeExpandFlag, *defaultPortFlag, *delimiterFlag) } else if exportCmd.Happened() { - success = exportCommand(entries, *appExportFlag, *descriptionExportFlag, *envPathExportFlag, *formatExportFlag, *formationExportFlag, *groupExportFlag, *homeExportFlag, *limitOpenFilesExportFlag, *locationExportFlag, *logPathExportFlag, *niceExportFlag, *workingDirectoryPathExportFlag, *runExportFlag, *timeoutExportFlag, *userExportFlag, *defaultPortFlag) + success = exportCommand(entries, *appExportFlag, *descriptionExportFlag, *envPathExportFlag, *formatExportFlag, *formationExportFlag, *groupExportFlag, *homeExportFlag, *limitCoredumpExportFlag, *limitCputimeExportFlag, *limitDataExportFlag, *limitFileSizeExportFlag, *limitLockedMemoryExportFlag, *limitOpenFilesExportFlag, *limitUserProcessesExportFlag, *limitPhysicalMemoryExportFlag, *limitStackSizeExportFlag, *locationExportFlag, *logPathExportFlag, *niceExportFlag, *prestartExportFlag, *workingDirectoryPathExportFlag, *runExportFlag, *timeoutExportFlag, *userExportFlag, *defaultPortFlag) } else if listCmd.Happened() { success = listCommand(entries) } else if setCmd.Happened() { diff --git a/templates/sysv/default/init.sh.tmpl b/templates/sysv/default/init.sh.tmpl new file mode 100644 index 0000000..6715877 --- /dev/null +++ b/templates/sysv/default/init.sh.tmpl @@ -0,0 +1,224 @@ +#!/bin/sh +# Init script for {{ .app }}-{{ .process_type }}-{{ .num }} +# Maintained by {{ if .author }}{{ .author }}{{ end }} +# Generated by pleaserun. +# Implemented based on LSB Core 3.1: +# * Sections: 20.2, 20.3 +# +### BEGIN INIT INFO +# Provides: {{ .app }}-{{ .process_type }}-{{ .num }} +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: {{ if .one_line_description }}{{ .one_line_description }}{{ end }} +# Description: {{ .description }} +### END INIT INFO + +PATH=/sbin:/usr/sbin:/bin:/usr/bin +export PATH + +name={{ .app }}-{{ .process_type }}-{{ .num }} +program={{ .program}} +args={{ .args }} +pidfile="/var/run/$name.pid" +user="{{ .user }}" +group="{{ .group }}" +chroot="{{ .working_directory }}" +chdir="{{ .working_directory }}" +nice="{{ .nice}}" +{{- if .limit_coredump }} +limit_coredump="{{ .limit_coredump }}"{{ end }} +{{- if .limit_cputime }} +limit_cputime="{{ .limit_cputime }}"{{ end }} +{{- if .limit_data }} +limit_data="{{ .limit_data }}"{{ end }} +{{- if .limit_file_size }} +limit_file_size="{{ .limit_file_size }}"{{ end }} +{{- if .limit_locked_memory }} +limit_locked_memory="{{ .limit_locked_memory }}"{{ end }} +{{- if .limit_open_files }} +limit_open_files="{{ .limit_open_files }}"{{ end }} +{{- if .limit_user_processes }} +limit_user_processes="{{ .limit_user_processes }}"{{ end }} +{{- if .limit_physical_memory }} +limit_physical_memory="{{ .limit_physical_memory }}"{{ end }} +{{- if .limit_stack_size }} +limit_stack_size="{{ .limit_stack_size }}"{{ end }} + +# If this is set to 1, then when `stop` is called, if the process has +# not exited within a reasonable time, SIGKILL will be sent next. +# The default behavior is to simply log a message "program stop failed; still running" +KILL_ON_STOP_TIMEOUT=0 + +# When loading default and sysconfig files, we use `set -a` to make +# all variables automatically into environment variables. +set -a +[ -r /etc/default/{{ .app }} ] && . /etc/default/{{ .app }} +[ -r /etc/sysconfig/{{ .app }} ] && . /etc/sysconfig/{{ .app }} +set +a +export PORT={{ .port }} +export PS={{ .ps }} + +[ -z "$nice" ] && nice=0 + +trace() { + logger -t "/etc/init.d/{{ .app }}-{{ .process_type }}-{{ .num }}" "$@" +} + +emit() { + trace "$@" + echo "$@" +} + +start() { + {{/* I do not use 'su' here to run as a different user because the process 'su' + stays as the parent, causing our pidfile to contain the pid of 'su' not the + program we intended to run. Luckily, the 'chroot' program on OSX, FreeBSD, and Linux + all support switching users and it invokes execve immediately after chrooting. */}} + + # Ensure the log directory is setup correctly. + if [ ! -d "{{ .log }}" ]; then + mkdir "{{ .log }}" + chown "$user":"$group" "{{ .log }}" + chmod 755 "{{ .log }}" + fi + + {{- if .prestart }} + if [ "$PRESTART" != "no" ] ; then + # If prestart fails, abort start. + prestart || return $? + fi + {{ end }} + + # Setup any environmental stuff beforehand + {{- if .ulimit_shell }}{{ .ulimit_shell }}{{ end }} + + # Run the program! + {{- if .nice }}nice -n "$nice"{{ end }} + chroot --userspec "$user":"$group" "$chroot" sh -c " + {{ if .ulimit_shell }}{{ .ulimit_shell }}{{ end }} + cd \"$chdir\" + exec \"$program\" $args + " >> {{ .log }}/{{ .app }}/{{ .process_type }}-stdout.log 2>> {{ .log }}/{{ .app }}/{{ .process_type }}-stderr.log & + + # Generate the pidfile from here. If we instead made the forked process + # generate it there will be a race condition between the pidfile writing + # and a process possibly asking for status. + echo $! > $pidfile + + emit "$name started" + return 0 +} + +stop() { + # Try a few times to kill TERM the program + if status ; then + pid=$(cat "$pidfile") + trace "Killing $name (pid $pid) with SIGTERM" + kill -TERM $pid + # Wait for it to exit. + for i in 1 2 3 4 5 ; do + trace "Waiting $name (pid $pid) to die..." + status || break + sleep 1 + done + if status ; then + if [ "$KILL_ON_STOP_TIMEOUT" -eq 1 ] ; then + trace "Timeout reached. Killing $name (pid $pid) with SIGKILL. This may result in data loss." + kill -KILL $pid + emit "$name killed with SIGKILL." + else + emit "$name stop failed; still running." + fi + else + emit "$name stopped." + fi + fi +} + +status() { + if [ -f "$pidfile" ] ; then + pid=$(cat "$pidfile") + if ps -p $pid > /dev/null 2> /dev/null ; then + # process by this pid is running. + # It may not be our pid, but that's what you get with just pidfiles. + # TODO(sissel): Check if this process seems to be the same as the one we + # expect. It'd be nice to use flock here, but flock uses fork, not exec, + # so it makes it quite awkward to use in this case. + return 0 + else + return 2 # program is dead but pid file exists + fi + else + return 3 # program is not running + fi +} + +force_stop() { + if status ; then + stop + status && kill -KILL $(cat "$pidfile") + fi +} + +{{- if .prestart }} +prestart() { + {{ .prestart }} + + status=$? + + if [ $status -gt 0 ] ; then + emit "Prestart command failed with code $status. If you wish to skip the prestart command, set PRESTART=no in your environment." + fi + return $status +} +{{ end }} + +case "$1" in + force-start|start|stop|force-stop|restart) + trace "Attempting '$1' on {{ .app }}-{{ .process_type }}-{{ .num }}" + ;; +esac + +case "$1" in + force-start) + PRESTART=no + exec "$0" start + ;; + start) + status + code=$? + if [ $code -eq 0 ]; then + emit "$name is already running" + exit $code + else + start + exit $? + fi + ;; + stop) stop ;; + force-stop) force_stop ;; + status) + status + code=$? + if [ $code -eq 0 ] ; then + emit "$name is running" + else + emit "$name is not running" + fi + exit $code + ;; + restart) + {{- if .prestart}}if [ "$PRESTART" != "no" ] ; then + prestart || exit $? + fi{{ end }} + stop && start + ;; + *) + echo "Usage: $SCRIPTNAME {start|force-start|stop|force-start|force-stop|status|restart}" >&2 + exit 3 + ;; +esac + +exit $? From 98d23a340a87456ce8c805dd680369128c35d0c9 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 15:04:58 -0400 Subject: [PATCH 21/48] feat: always write logs to the same general location --- templates/launchd/launchd.plist.tmpl | 4 ++-- templates/systemd-user/default/program.service.tmpl | 8 ++++++-- templates/systemd/default/program.service.tmpl | 4 ++-- templates/sysv/default/init.sh.tmpl | 2 +- templates/upstart/default/program.conf.tmpl | 4 ++-- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/templates/launchd/launchd.plist.tmpl b/templates/launchd/launchd.plist.tmpl index 0139d81..86ff8fe 100644 --- a/templates/launchd/launchd.plist.tmpl +++ b/templates/launchd/launchd.plist.tmpl @@ -24,9 +24,9 @@ RunAtLoad StandardOutPath - {{ .log }}/{{ .app }}/{{ .app }}-{{ .process_type }}-{{ .num }}.log + {{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stdout.log StandardErrorPath - {{ .log }}/{{ .app }}/{{ .app }}-{{ .process_type }}-{{ .num }}.log + {{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stderr.log UserName {{ .user }} WorkingDirectory diff --git a/templates/systemd-user/default/program.service.tmpl b/templates/systemd-user/default/program.service.tmpl index 415722f..8a2b21c 100644 --- a/templates/systemd-user/default/program.service.tmpl +++ b/templates/systemd-user/default/program.service.tmpl @@ -3,14 +3,18 @@ Description={{ .description }}{{ end }} [Service] +WorkingDirectory={{ .working_directory }} Type=simple Environment=PORT={{ .port }} Environment=PS={{ .ps }} EnvironmentFile=-{{ .home }}/.config/systemd/user/{{ .ps }}.environment ExecStart={{ .command }} Restart=always -WorkingDirectory={{ .working_directory }} -StandardOutput=journal +RestartSec=14s +StandardInput=null +StandardOutput={{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stdout.log +StandardError={{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stderr.log +SyslogIdentifier=%n [Install] WantedBy=multi-user.target diff --git a/templates/systemd/default/program.service.tmpl b/templates/systemd/default/program.service.tmpl index 9fd44b0..fcb126d 100644 --- a/templates/systemd/default/program.service.tmpl +++ b/templates/systemd/default/program.service.tmpl @@ -19,8 +19,8 @@ ExecStart=/bin/bash -lc 'exec -a "{{ .ps }}" {{ .command }}' Restart=always RestartSec=14s StandardInput=null -StandardOutput=syslog -StandardError=syslog +StandardOutput={{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stdout.log +StandardError={{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stderr.log SyslogIdentifier=%n KillMode=mixed TimeoutStopSec={{ .timeout }} diff --git a/templates/sysv/default/init.sh.tmpl b/templates/sysv/default/init.sh.tmpl index 6715877..049450b 100644 --- a/templates/sysv/default/init.sh.tmpl +++ b/templates/sysv/default/init.sh.tmpl @@ -100,7 +100,7 @@ start() { {{ if .ulimit_shell }}{{ .ulimit_shell }}{{ end }} cd \"$chdir\" exec \"$program\" $args - " >> {{ .log }}/{{ .app }}/{{ .process_type }}-stdout.log 2>> {{ .log }}/{{ .app }}/{{ .process_type }}-stderr.log & + " >> {{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stdout.log 2>> {{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stderr.log & # Generate the pidfile from here. If we instead made the forked process # generate it there will be a race condition between the pidfile writing diff --git a/templates/upstart/default/program.conf.tmpl b/templates/upstart/default/program.conf.tmpl index 7c58923..67975be 100644 --- a/templates/upstart/default/program.conf.tmpl +++ b/templates/upstart/default/program.conf.tmpl @@ -15,8 +15,8 @@ script [ -r /etc/sysconfig/{{ .app }} ] && . /etc/sysconfig/{{ .app }} cd {{ .working_directory }} exec {{ .command }} \ - >> {{ .log }}/{{ .app }}/{{ .process_type }}-stdout.log \ - 2>> {{ .log }}/{{ .app }}/{{ .process_type }}-stderr.log + >> {{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stdout.log \ + 2>> {{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stderr.log end script post-start script From f7682924a4a98860a0db3ff987eb343a20e3ae19 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 15:15:15 -0400 Subject: [PATCH 22/48] chore: drop old OS versions --- Makefile | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Makefile b/Makefile index 1935bc7..13b1cc9 100644 --- a/Makefile +++ b/Makefile @@ -144,16 +144,8 @@ release-packagecloud: release-packagecloud-deb: build/deb/$(NAME)_$(VERSION)_amd64.deb package_cloud push $(PACKAGECLOUD_REPOSITORY)/ubuntu/trusty build/deb/$(NAME)_$(VERSION)_amd64.deb - package_cloud push $(PACKAGECLOUD_REPOSITORY)/ubuntu/utopic build/deb/$(NAME)_$(VERSION)_amd64.deb - package_cloud push $(PACKAGECLOUD_REPOSITORY)/ubuntu/vivid build/deb/$(NAME)_$(VERSION)_amd64.deb - package_cloud push $(PACKAGECLOUD_REPOSITORY)/ubuntu/wily build/deb/$(NAME)_$(VERSION)_amd64.deb package_cloud push $(PACKAGECLOUD_REPOSITORY)/ubuntu/xenial build/deb/$(NAME)_$(VERSION)_amd64.deb - package_cloud push $(PACKAGECLOUD_REPOSITORY)/ubuntu/yakkety build/deb/$(NAME)_$(VERSION)_amd64.deb - package_cloud push $(PACKAGECLOUD_REPOSITORY)/ubuntu/zesty build/deb/$(NAME)_$(VERSION)_amd64.deb - package_cloud push $(PACKAGECLOUD_REPOSITORY)/ubuntu/artful build/deb/$(NAME)_$(VERSION)_amd64.deb package_cloud push $(PACKAGECLOUD_REPOSITORY)/ubuntu/bionic build/deb/$(NAME)_$(VERSION)_amd64.deb - package_cloud push $(PACKAGECLOUD_REPOSITORY)/debian/wheezy build/deb/$(NAME)_$(VERSION)_amd64.deb - package_cloud push $(PACKAGECLOUD_REPOSITORY)/debian/jessie build/deb/$(NAME)_$(VERSION)_amd64.deb package_cloud push $(PACKAGECLOUD_REPOSITORY)/debian/stretch build/deb/$(NAME)_$(VERSION)_amd64.deb package_cloud push $(PACKAGECLOUD_REPOSITORY)/debian/buster build/deb/$(NAME)_$(VERSION)_amd64.deb From e8a48d4ad37ed4dcf5a99fe1f492ed29c646506a Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 15:17:50 -0400 Subject: [PATCH 23/48] docs: add sysv to readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 91fb803..5d8c1a4 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ In addition, not all formats support all arguments, and not all arguments have e ```shell # export systemd init files to the `tmp` directory -# support formats include: [launchd, runit, systemd, systemd-user, upstart] +# support formats include: [launchd, runit, systemd, systemd-user, sysv, upstart] # the default format is: systemd procfile-util export --format systemd --location tmpp From 3d3f2bd7c2d4c26b7488500a97f16f31f62f522e Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 20:13:15 -0400 Subject: [PATCH 24/48] refactor: simplify format adding --- main.go | 41 ++++++++++++----------------------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/main.go b/main.go index e898a02..bd1a231 100644 --- a/main.go +++ b/main.go @@ -26,6 +26,8 @@ type formationEntry struct { Count int } +type exportFunc func(string, []procfileEntry, map[string]formationEntry, string, int, map[string]interface{}) bool + func (p *procfileEntry) commandList() []string { return strings.Fields(p.Command) } @@ -311,13 +313,14 @@ func exportCommand(entries []procfileEntry, app string, description string, envP fmt.Fprintf(os.Stderr, "no output location specified\n") return false } - formats := map[string]bool{ - "launchd": true, - "runit": true, - "systemd": true, - "systemd-user": true, - "sysv": true, - "upstart": true, + + formats := map[string]exportFunc{ + "launchd": exportLaunchd, + "runt": exportRunit, + "systemd": exportSystemd, + "systemd-user": exportSystemdUser, + "sysv": exportSysv, + "upstart": exportUpstart, } if _, ok := formats[format]; !ok { @@ -383,28 +386,8 @@ func exportCommand(entries []procfileEntry, app string, description string, envP vars["ulimit_shell"] = ulimitShell(limitCoredump, limitCputime, limitData, limitFileSize, limitLockedMemory, limitOpenFiles, limitUserProcesses, limitPhysicalMemory, limitStackSize) vars["user"] = user - if format == "launchd" { - return exportLaunchd(app, entries, formations, location, defaultPort, vars) - } - - if format == "runit" { - return exportRunit(app, entries, formations, location, defaultPort, vars) - } - - if format == "systemd" { - return exportSystemd(app, entries, formations, location, defaultPort, vars) - } - - if format == "systemd-user" { - return exportSystemdUser(app, entries, formations, location, defaultPort, vars) - } - - if format == "sysv" { - return exportSysv(app, entries, formations, location, defaultPort, vars) - } - - if format == "upstart" { - return exportUpstart(app, entries, formations, location, defaultPort, vars) + if fn, ok := formats[format]; ok { + return fn(app, entries, formations, location, defaultPort, vars) } return false From bf21589ea80388efc1f30b661ef94eb9ce4d9a8e Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 20:13:30 -0400 Subject: [PATCH 25/48] feat: add nice to launchd --- templates/launchd/launchd.plist.tmpl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/launchd/launchd.plist.tmpl b/templates/launchd/launchd.plist.tmpl index 86ff8fe..b0e0845 100644 --- a/templates/launchd/launchd.plist.tmpl +++ b/templates/launchd/launchd.plist.tmpl @@ -31,5 +31,7 @@ {{ .user }} WorkingDirectory {{ .working_directory }} + {{- if .nice }} + Nice{{ .nice }}{{ end }} From bb74d4a9e2c2e46a09c106dd42f3d1c438c0c4c4 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 20:13:47 -0400 Subject: [PATCH 26/48] fix: unify the log output (again) --- templates/launchd/launchd.plist.tmpl | 4 ++-- templates/runit/log/run.tmpl | 2 +- templates/systemd-user/default/program.service.tmpl | 4 ++-- templates/systemd/default/program.service.tmpl | 4 ++-- templates/sysv/default/init.sh.tmpl | 2 +- templates/upstart/default/program.conf.tmpl | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/templates/launchd/launchd.plist.tmpl b/templates/launchd/launchd.plist.tmpl index b0e0845..f3d652d 100644 --- a/templates/launchd/launchd.plist.tmpl +++ b/templates/launchd/launchd.plist.tmpl @@ -24,9 +24,9 @@ RunAtLoad StandardOutPath - {{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stdout.log + {{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stdout.log StandardErrorPath - {{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stderr.log + {{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stderr.log UserName {{ .user }} WorkingDirectory diff --git a/templates/runit/log/run.tmpl b/templates/runit/log/run.tmpl index 730a502..129cb81 100644 --- a/templates/runit/log/run.tmpl +++ b/templates/runit/log/run.tmpl @@ -1,7 +1,7 @@ #!/bin/sh set -e -LOG={{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }} +LOG={{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }} test -d "$LOG" || mkdir -p -m 2750 "$LOG" && chown {{ .user }} "$LOG" exec chpst -u {{ .user }} svlogd "$LOG" diff --git a/templates/systemd-user/default/program.service.tmpl b/templates/systemd-user/default/program.service.tmpl index 8a2b21c..10facb1 100644 --- a/templates/systemd-user/default/program.service.tmpl +++ b/templates/systemd-user/default/program.service.tmpl @@ -12,8 +12,8 @@ ExecStart={{ .command }} Restart=always RestartSec=14s StandardInput=null -StandardOutput={{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stdout.log -StandardError={{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stderr.log +StandardOutput={{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stdout.log +StandardError={{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stderr.log SyslogIdentifier=%n [Install] diff --git a/templates/systemd/default/program.service.tmpl b/templates/systemd/default/program.service.tmpl index fcb126d..873ff1d 100644 --- a/templates/systemd/default/program.service.tmpl +++ b/templates/systemd/default/program.service.tmpl @@ -19,8 +19,8 @@ ExecStart=/bin/bash -lc 'exec -a "{{ .ps }}" {{ .command }}' Restart=always RestartSec=14s StandardInput=null -StandardOutput={{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stdout.log -StandardError={{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stderr.log +StandardOutput={{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stdout.log +StandardError={{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stderr.log SyslogIdentifier=%n KillMode=mixed TimeoutStopSec={{ .timeout }} diff --git a/templates/sysv/default/init.sh.tmpl b/templates/sysv/default/init.sh.tmpl index 049450b..652e761 100644 --- a/templates/sysv/default/init.sh.tmpl +++ b/templates/sysv/default/init.sh.tmpl @@ -100,7 +100,7 @@ start() { {{ if .ulimit_shell }}{{ .ulimit_shell }}{{ end }} cd \"$chdir\" exec \"$program\" $args - " >> {{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stdout.log 2>> {{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stderr.log & + " >> {{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stdout.log 2>> {{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stderr.log & # Generate the pidfile from here. If we instead made the forked process # generate it there will be a race condition between the pidfile writing diff --git a/templates/upstart/default/program.conf.tmpl b/templates/upstart/default/program.conf.tmpl index 67975be..f4bdfae 100644 --- a/templates/upstart/default/program.conf.tmpl +++ b/templates/upstart/default/program.conf.tmpl @@ -15,8 +15,8 @@ script [ -r /etc/sysconfig/{{ .app }} ] && . /etc/sysconfig/{{ .app }} cd {{ .working_directory }} exec {{ .command }} \ - >> {{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stdout.log \ - 2>> {{ .log }}/{{ .app }}/{{ .process_type }}-{{ .num }}-stderr.log + >> {{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stdout.log \ + 2>> {{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stderr.log end script post-start script From caba5c8d71fc29cdf4f96f98b1f9f6deafeaa352 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 20:14:08 -0400 Subject: [PATCH 27/48] feat: add specific setup for escaped args --- export.go | 1 + main.go | 6 +++++- templates/sysv/default/init.sh.tmpl | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/export.go b/export.go index c151e43..66f35a9 100644 --- a/export.go +++ b/export.go @@ -300,6 +300,7 @@ func portFor(processIndex int, instance int, base int) int { func templateVars(app string, entry procfileEntry, processName string, num int, port int, vars map[string]interface{}) map[string]interface{} { config := vars config["args"] = entry.args() + config["args_escaped"] = entry.argsEscaped() config["command"] = entry.Command config["command_list"] = entry.commandList() config["num"] = num diff --git a/main.go b/main.go index bd1a231..7f87a6a 100644 --- a/main.go +++ b/main.go @@ -37,7 +37,11 @@ func (p *procfileEntry) program() string { } func (p *procfileEntry) args() string { - return shellescape.Quote(strings.Join(strings.Fields(p.Command)[1:], " ")) + return strings.Join(strings.Fields(p.Command)[1:], " ") +} + +func (p *procfileEntry) argsEscaped() string { + return shellescape.Quote(p.args()) } const portEnvVar = "PORT" diff --git a/templates/sysv/default/init.sh.tmpl b/templates/sysv/default/init.sh.tmpl index 652e761..ade9823 100644 --- a/templates/sysv/default/init.sh.tmpl +++ b/templates/sysv/default/init.sh.tmpl @@ -20,7 +20,7 @@ export PATH name={{ .app }}-{{ .process_type }}-{{ .num }} program={{ .program}} -args={{ .args }} +args={{ .args_escaped }} pidfile="/var/run/$name.pid" user="{{ .user }}" group="{{ .group }}" From cf9e9f1a9726920304a342075ab1b9e4860fc280 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 20:14:22 -0400 Subject: [PATCH 28/48] fix: add missing newline to ulimit_shell inclusion --- templates/sysv/default/init.sh.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/sysv/default/init.sh.tmpl b/templates/sysv/default/init.sh.tmpl index ade9823..d6c161e 100644 --- a/templates/sysv/default/init.sh.tmpl +++ b/templates/sysv/default/init.sh.tmpl @@ -92,7 +92,7 @@ start() { {{ end }} # Setup any environmental stuff beforehand - {{- if .ulimit_shell }}{{ .ulimit_shell }}{{ end }} + {{ if .ulimit_shell }}{{ .ulimit_shell }}{{ end }} # Run the program! {{- if .nice }}nice -n "$nice"{{ end }} From e5c48b5a18180a2eda9a05a397fb96de7e8cfc94 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 20:14:43 -0400 Subject: [PATCH 29/48] fix: re-vendor bindata --- bindata.go | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/bindata.go b/bindata.go index b497af8..5cf0840 100644 --- a/bindata.go +++ b/bindata.go @@ -86,7 +86,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _templatesLaunchdLaunchdPlistTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x54\x5f\x6f\xda\x30\x10\x7f\xe7\x53\xdc\xa2\x3e\x8e\x18\xde\xa6\x2a\xa4\x62\x85\x49\xd5\x50\x89\x0a\x6c\xda\x13\x72\x93\x5b\x6a\x91\xd8\xd9\xd9\x81\x45\x91\xbf\xfb\xe4\x40\x96\x50\x4a\xb5\xa7\xbd\x9d\x4e\xbf\x7f\x77\xb9\x38\xb8\xfb\x9d\x67\xb0\x47\xd2\x42\xc9\x89\x37\xf6\x47\x1e\xa0\x8c\x55\x22\x64\x3a\xf1\x36\xeb\x2f\xc3\x4f\xde\x5d\x38\x08\x3e\xcc\x96\xf7\xeb\x1f\xd1\x1c\x8a\x4c\x68\x03\xd1\xe6\xf3\xe2\xe1\x1e\xbc\x21\x63\xd3\xa2\xc8\x90\xb1\xd9\x7a\x06\xd1\xe2\x61\xb5\x86\xb1\x3f\x62\x6c\xfe\xe8\x81\xf7\x62\x4c\x71\xcb\xd8\xe1\x70\xf0\xb9\x43\xf9\xb1\xca\x1d\x50\xb3\x88\x54\x81\x64\xaa\x85\xd0\x66\x38\xf6\x47\x7e\x62\x12\x2f\x1c\x04\x47\xf5\xb3\x38\xe1\x20\x48\x44\x6c\xc2\x01\x00\x40\xb0\xc3\x2a\x5c\xf0\x67\xcc\x02\xe6\xca\x63\x53\x1b\x12\x32\x0d\xeb\x1a\x9c\x0f\x58\x3b\x74\x65\x41\x2a\x46\xad\xb7\xa6\x2a\xb0\xed\xc9\x32\x07\x6b\x03\x76\x62\x74\x9a\x73\xb9\x17\xa4\x64\x8e\xd2\x7c\xe3\x24\xf8\x73\x86\xba\x6f\xd1\x45\xf8\x4b\x89\x96\x4f\xeb\x1e\xe4\x75\x92\x42\x91\xb9\xf0\xea\xc8\xab\xf7\xa8\xfa\x82\x58\xd7\x43\x20\x2e\x53\x84\x9b\x1d\x56\x1f\xe1\x66\xcf\xb3\x12\xe1\x76\x02\x3e\xca\x3d\x58\x7b\x2e\x5f\xd7\x0d\xae\x91\xb9\x66\x73\x92\xe8\x39\xd5\x35\xa0\x4c\x5a\xb1\x80\xbd\xda\x7b\x44\x2a\x25\x9e\x4f\x29\x2d\xdd\x9e\xce\xf6\xc3\x89\x78\x75\x11\x35\x56\x79\xce\x65\xd2\xc4\x3c\xd5\xdb\xe6\x0b\xf7\xf3\x76\xe6\xe2\x27\xe0\xaf\x8e\xe5\xdd\xb8\x15\x7b\x60\xad\x4b\xdb\x2e\xd4\x85\xcc\x34\x9e\xba\x2d\xf6\xd8\x6f\x8a\xab\xe3\xf4\x32\x36\xf3\x7c\x45\x2c\xa6\x99\xd8\x63\x7f\x10\x43\x25\xb2\x1e\xe8\xa9\x94\x53\xb3\x50\x3c\x79\x0f\xb4\x32\x5c\x26\x9c\x92\x65\x69\x22\x6e\x5e\xae\xdc\x66\xa6\x52\xb0\x96\x75\x67\xca\xfe\xf9\x62\x1d\xf7\x8d\xab\x6d\x7d\xe7\x44\x8a\xfe\xab\xf3\x46\x23\x3d\xf2\x1c\xaf\x18\x96\x1a\xe9\xed\x1f\xed\xbb\xa2\x9d\x90\xe9\x4c\x10\xc6\x46\x51\x75\x45\xe0\x70\x84\x6d\x93\x16\x77\xa6\xd6\x9e\x66\xc0\x9a\x07\x23\x1c\xfc\x09\x00\x00\xff\xff\x04\x77\x46\x4f\xc7\x04\x00\x00") +var _templatesLaunchdLaunchdPlistTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x54\x5f\x8f\x9a\x40\x10\x7f\xf7\x53\x4c\x89\x8f\x85\xd5\xb7\xe6\x82\x5c\xec\x69\x93\x4b\x8d\x92\x53\xdb\xf4\xc9\xec\xc1\x1c\xb7\x11\x76\xe9\xec\xa2\x25\x84\xef\xde\x80\x70\xe2\x29\x97\x3e\xf4\x6d\x32\xf9\xfd\x9b\x61\x16\xf7\xfe\x4f\x12\xc3\x01\x49\x0b\x25\x27\xd6\xd8\x19\x59\x80\x32\x50\xa1\x90\xd1\xc4\xda\x6e\xbe\xd9\x5f\xac\x7b\x6f\xe0\x7e\x9a\xad\x1e\x36\xbf\xfc\x39\xa4\xb1\xd0\x06\xfc\xed\xd7\xc5\xe3\x03\x58\x36\x63\xd3\x34\x8d\x91\xb1\xd9\x66\x06\xfe\xe2\x71\xbd\x81\xb1\x33\x62\x6c\xbe\xb4\xc0\x7a\x35\x26\xbd\x63\xec\x78\x3c\x3a\xbc\x42\x39\x81\x4a\x2a\xa0\x66\x3e\xa9\x14\xc9\xe4\x0b\xa1\x8d\x3d\x76\x46\x4e\x68\x42\xcb\x1b\xb8\x27\xf5\x8b\x38\xde\xc0\x0d\x45\x60\xbc\x01\x00\x80\xbb\xc7\xdc\x5b\xf0\x67\x8c\x5d\x56\x95\xa7\xa6\x36\x24\x64\xe4\x15\x05\x54\x3e\x50\x96\x76\x55\xa6\xa4\x02\xd4\x7a\x67\xf2\x14\xdb\x9e\xcc\x12\x28\x4b\x97\x35\x8c\xb3\xe6\x5c\x1e\x04\x29\x99\xa0\x34\x3f\x38\x09\xfe\x1c\xa3\xee\x5a\x9c\x23\xbc\x51\xfc\xd5\xd3\xa6\x03\x79\x9f\x24\x55\x64\xae\xbc\xce\xe4\xf5\x47\x54\x7d\x45\x2c\x0a\x1b\x88\xcb\x08\x61\xb8\xc7\xfc\x33\x0c\x0f\x3c\xce\x10\xee\x26\xe0\xa0\x3c\x40\x59\x5e\xca\x17\x45\x8d\xab\x65\xfa\x6c\x1a\x89\x8e\x53\x51\x00\xca\xb0\x15\x73\xd9\xbb\xbd\xfb\xa4\x22\xe2\xc9\x94\xa2\xac\xda\xd3\xc5\x7e\x38\x11\xcf\xaf\xa2\x06\x2a\x49\xb8\x0c\xeb\x98\x4d\xbd\xab\xbf\x70\x37\xef\xd9\x5c\xbc\x00\xfe\x3e\xb3\xac\x61\xb5\x62\x0b\xca\xb2\x4a\xdb\x2e\xb4\x0a\x19\x6b\x6c\xba\x2d\xf6\xd4\xaf\x8b\xde\x71\x3a\x19\xeb\x79\xbe\x23\xa6\xd3\x58\x1c\xb0\x3b\x88\xa1\x0c\x59\x07\xf4\x94\xc9\xa9\x59\x28\x1e\x7e\x04\x5a\x1b\x2e\x43\x4e\xe1\x2a\x33\x3e\x37\xaf\x3d\xb7\x19\xab\xa8\xbd\xc3\x7f\x3a\x53\x5b\x9b\x50\x65\xa6\xe2\xdd\xb8\xd8\xd6\x73\x4e\xa4\xe8\x3f\xbb\x22\x51\x8f\xeb\x56\x23\x2d\x79\x82\x3d\x66\x99\x46\xba\xfd\xc0\x7e\x2a\xda\x0b\x19\xcd\x04\x61\x60\x14\xe5\x3d\x02\xc7\x13\x6c\x17\xb6\xb8\x9b\x2f\x41\xbc\x80\x23\x45\x80\x6f\xdf\xb6\xd2\x5a\x8a\xa0\x89\xe5\x0a\x69\x30\x42\xaa\x15\x1b\x9c\xcb\x3a\xcd\xe6\x2c\xda\x0b\x77\x59\xfd\xdf\xf1\x06\x7f\x03\x00\x00\xff\xff\xff\x8f\x04\x0b\x0e\x05\x00\x00") func templatesLaunchdLaunchdPlistTmplBytes() ([]byte, error) { return bindataRead( @@ -101,12 +101,12 @@ func templatesLaunchdLaunchdPlistTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/launchd/launchd.plist.tmpl", size: 1223, mode: os.FileMode(420), modTime: time.Unix(1584467755, 0)} + info := bindataFileInfo{name: "templates/launchd/launchd.plist.tmpl", size: 1294, mode: os.FileMode(420), modTime: time.Unix(1584486757, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templatesRunitLogRunTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x8c\xcf\x0a\x82\x40\x10\x87\xef\xf3\x14\xbf\x2c\xbc\x6d\x46\x10\x9d\x3a\x7b\x11\x7c\x84\xa8\x75\x50\x49\xdd\xc5\x59\xfb\x83\xce\xbb\xc7\x42\x1e\xba\x7d\xcc\x37\xbf\x6f\xbb\xc9\xee\xed\x90\x49\x43\xc2\x01\x86\x89\x8a\x32\xbf\xcc\x33\xf6\x9d\xab\xa1\x9a\x45\xbc\x79\xbf\xa2\x1f\x9d\x65\x91\x6b\xf8\x78\x86\xaa\x89\xb7\x61\xea\xa1\x4a\x14\x58\x02\x4c\x85\x64\x57\x94\x79\x82\x65\x41\xff\xa8\xda\x11\xc6\xc3\xf4\x38\x9e\x4f\x87\x55\xa5\x29\x6c\xe3\x5e\x03\xe2\x7c\x12\x1e\xa1\xfa\x73\xc4\x6f\xb6\xb0\x8d\x8f\xad\xe9\xef\x41\x9e\x9d\xab\xd7\x3c\x7d\x03\x00\x00\xff\xff\x0a\xaa\x1d\x31\xba\x00\x00\x00") +var _templatesRunitLogRunTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x8c\xcf\x0a\x82\x40\x10\x87\xef\xf3\x14\xbf\x2c\xbc\x6d\x46\x10\x9d\x3a\x7b\x11\x7c\x84\xa8\x75\x50\x49\xdd\xc5\x59\xfb\x83\xce\xbb\x87\xd0\x1e\xba\x7d\xcc\x37\xbf\x6f\xbb\xc9\xee\xed\x90\x49\x43\xc2\x01\x86\x89\x8a\x32\xbf\xcc\x33\xf6\x9d\xab\xa1\x6a\x56\xbc\x79\x1f\xd1\x8f\xce\xb2\xc8\x35\x7c\x3c\xc7\xdb\x30\xf5\x50\x25\x0a\x2c\x01\xa6\x42\xb2\x2b\xca\x3c\xc1\xb2\xa0\x7f\x54\xed\x08\xe3\x61\x7a\x1c\xcf\xa7\x43\x54\x69\x0a\xdb\xb8\xd7\x80\x75\x3e\x09\x8f\x50\xfd\x39\xe2\x37\x5b\xd8\xc6\xaf\xad\xe9\xef\x41\x9e\x9d\xab\x63\x9e\xbe\x01\x00\x00\xff\xff\x62\xdb\xaa\xfb\xba\x00\x00\x00") func templatesRunitLogRunTmplBytes() ([]byte, error) { return bindataRead( @@ -121,7 +121,7 @@ func templatesRunitLogRunTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/runit/log/run.tmpl", size: 186, mode: os.FileMode(420), modTime: time.Unix(1584456288, 0)} + info := bindataFileInfo{name: "templates/runit/log/run.tmpl", size: 186, mode: os.FileMode(420), modTime: time.Unix(1584486167, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -141,7 +141,7 @@ func templatesRunitRunTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/runit/run.tmpl", size: 154, mode: os.FileMode(420), modTime: time.Unix(1584458764, 0)} + info := bindataFileInfo{name: "templates/runit/run.tmpl", size: 154, mode: os.FileMode(420), modTime: time.Unix(1584472497, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -161,12 +161,12 @@ func templatesSystemdDefaultControlTargetTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/systemd/default/control.target.tmpl", size: 106, mode: os.FileMode(420), modTime: time.Unix(1584336786, 0)} + info := bindataFileInfo{name: "templates/systemd/default/control.target.tmpl", size: 106, mode: os.FileMode(420), modTime: time.Unix(1584472497, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templatesSystemdDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x92\xc1\x6a\xe3\x3c\x10\x80\xef\x7a\x0a\x11\xfa\xd3\xcb\x9f\x98\x85\x3d\x2d\xe8\xd6\x74\x09\xdb\x6d\x4a\xdd\xd0\x43\x29\x41\x95\xc6\xee\x50\x79\x64\xa4\x71\x1a\x63\xfc\xee\x8b\x94\x8d\x0d\xd9\xdd\x93\xa5\x6f\xbe\x91\x67\x46\x7a\xd9\x11\xf2\xab\x18\x86\xa5\xc4\x4a\xae\x2c\x44\x13\xb0\x65\xf4\x24\xc7\x51\xdc\xcc\x5b\x35\x0c\x97\xe1\x61\x90\x40\x36\x79\x0f\x3a\xf0\xb6\xca\x8a\x6e\x5b\x39\x8e\x2b\xd6\xa1\x06\x16\x25\xfb\xf6\xf9\x1d\x68\x47\x04\x60\xc1\xaa\x1e\xa2\x10\x2f\x25\x84\x03\x1a\x78\x15\xbb\x08\x21\xa7\x75\x11\x42\x3a\xe9\x7b\xf0\x5d\x9b\x49\x9d\x56\x09\x3d\xfb\xf0\x81\x54\xdf\x60\x00\xc3\x3e\xf4\x39\xfa\x79\x82\x7b\x7b\xa6\xc9\x5c\xd3\x01\x83\xa7\x06\x88\xd5\xc3\xf6\xf1\x29\x9b\xad\x0f\xfc\x47\xb0\x3c\x85\xe2\x45\xe0\x16\x1d\xa8\x65\x01\x6c\x0a\x0b\x95\xee\x1c\x17\xe7\x9e\xfe\x6d\xc6\x3e\x1a\x4f\x15\xd6\xc5\xdc\x7f\x1e\x68\xd0\x54\x83\xbc\xfa\x80\xfe\x7f\x79\x75\xd0\xae\x03\xf9\x4d\xc9\x15\xd0\xe1\xb2\x9e\xc5\x30\x64\x4f\x8e\x63\x2a\xec\xb7\x3c\x8e\x0b\x31\xcf\x78\x7d\x04\x53\xb2\x0e\xac\x8a\x37\xa4\xe2\x4d\xc7\x77\xb9\x74\x46\x5e\xc3\x11\x8c\x5c\x6a\xb9\x98\x5a\x5a\xc8\xb4\x34\xbe\x69\x74\xce\xbd\x16\x8f\x10\x73\xaa\x76\x9f\xba\x8f\xe7\x6d\x09\x46\x7d\xf9\x1a\x45\xc9\x9a\xac\x0e\x76\x43\x6d\xc7\x8a\x3a\xe7\x26\xb4\xed\x38\xb1\xd8\x47\xe7\xeb\x89\xae\x43\xf0\x61\x82\xf9\xb3\xb1\x40\x8c\x15\x42\x50\xff\x91\xf8\x81\xce\xfd\xf4\x16\x54\x83\x47\xb0\xe2\x09\x1b\xf0\x1d\xa7\xd7\x90\xfe\x99\xaa\xe3\x13\x4a\x9d\x4d\xaf\x8f\xd0\xa4\xae\xc5\x3d\x1a\xc8\xd2\x19\xcc\x53\x38\xab\x0e\x1b\xe4\xbd\x6f\x81\xf6\x15\x3a\xc8\x17\x79\x97\xd8\xfd\xf6\x76\x73\xb7\xce\xd9\x7f\x73\xe6\x93\x7e\x05\x00\x00\xff\xff\x88\x3d\x27\x0c\xfa\x02\x00\x00") +var _templatesSystemdDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x92\x41\x6b\xdc\x30\x10\x85\xef\xfa\x15\x62\x49\xc9\xa5\x1b\x53\xe8\xa9\xe0\x5b\x36\x65\x69\x9a\x0d\x71\x96\x1c\x42\x58\x14\x69\xec\x88\xc8\x23\x33\x1a\x6f\xd6\x18\xfd\xf7\x22\x6d\xbd\x86\x6d\x7b\xe9\x6d\xfc\xe6\x9b\x67\xbd\x61\x9e\xb7\x68\xf9\x45\x8c\xe3\x52\xda\x5a\x5e\x19\x08\x9a\x6c\xc7\xd6\xa3\x8c\x51\x5c\xcf\x9f\xe5\x38\x9e\xb7\xc7\x51\x02\x9a\xc4\xdd\x2b\xe2\x4d\x9d\x11\xd5\x75\x32\xc6\x2b\x56\xd4\x00\x8b\x8a\x7d\xf7\xf4\x06\xb8\x45\x04\x30\x60\xca\x01\x82\x10\xcf\x15\xd0\xde\x6a\x78\x11\xdb\x00\x94\xc7\xfa\x00\x94\x9c\xbe\x93\xef\xbb\xac\x34\xa9\x4a\xd2\x93\xa7\x77\x8b\xcd\xb5\x25\xd0\xec\x69\xc8\xdd\x8f\xa3\xb8\x33\x93\x9a\xc8\x15\xee\x2d\x79\x6c\x01\xb9\xbc\xdf\x3c\x3c\x66\xb2\xf3\xc4\x7f\x34\xab\x63\x2b\x9c\x35\x6e\xac\x83\x72\x59\x00\xeb\xc2\x40\xad\x7a\xc7\xc5\x94\xe9\xdf\x64\x18\x82\xf6\x58\xdb\xa6\x98\xf3\xe7\x85\x92\xc2\x06\xe4\xc5\x3b\x0c\x9f\xe5\xc5\x5e\xb9\x1e\xe4\xb7\x52\x5e\x01\xee\xcf\xdf\xb3\x18\xc7\xcc\xc9\x18\xd3\xc3\x7e\xc3\x31\x2e\xc4\xbc\xe3\xd5\x01\x74\xc5\x8a\xb8\x2c\x5e\x2d\x16\xaf\x2a\xbc\xc9\xa5\xd3\xf2\x12\x0e\xa0\xe5\x52\xc9\xc5\x29\xd2\x42\xa6\x52\xfb\xb6\x55\x79\xf6\x52\x3c\x40\xc8\xa3\xca\x7d\xa8\x21\x4c\x9f\x15\xe8\xf2\xcb\xd7\x20\x2a\x56\x68\x14\x99\x35\x76\x3d\x97\xd8\x3b\x77\x92\x36\x3d\x27\x2d\xf9\x39\xdf\xc8\x18\x97\x73\xc8\x5c\x76\xe4\x35\x84\xb0\xe3\xa1\x83\x49\xc3\xbe\x4d\x65\x60\xe3\x7b\x4e\x73\x27\xbb\x15\x91\xa7\xff\x76\x03\xa2\xa3\xdb\x10\x9c\x6f\xd6\x06\x90\x6d\x6d\x81\xca\x4f\x28\x7e\x58\xe7\x7e\x7a\x03\x65\x6b\x0f\x60\xc4\xa3\x6d\xc1\xf7\x9c\xee\x2f\xa5\x4c\x3e\x7c\x94\xd2\x2e\x4f\xf7\x8e\x56\xa7\xff\x88\x3b\xab\x21\x43\x93\x30\xef\x7d\x42\x9d\x6d\x2d\xef\x7c\x07\xb8\xab\xad\x83\x7c\x3a\xb7\x49\xbb\xdb\xdc\xac\x6f\x57\xc7\x50\x7f\x61\x66\xa7\x5f\x01\x00\x00\xff\xff\x0e\xe4\xbe\x09\x6c\x03\x00\x00") func templatesSystemdDefaultProgramServiceTmplBytes() ([]byte, error) { return bindataRead( @@ -181,12 +181,12 @@ func templatesSystemdDefaultProgramServiceTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/systemd/default/program.service.tmpl", size: 762, mode: os.FileMode(420), modTime: time.Unix(1584464031, 0)} + info := bindataFileInfo{name: "templates/systemd/default/program.service.tmpl", size: 876, mode: os.FileMode(420), modTime: time.Unix(1584486168, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templatesSystemdUserDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x5c\x8e\x41\x6a\xc3\x30\x10\x45\xf7\x3a\x85\x2e\x10\xfb\x04\xda\x94\xa4\xd0\x55\x4a\x9c\x92\x45\x30\x45\x48\x13\x77\x5a\x69\x64\x46\xe3\xa4\x46\xf8\xee\xc5\x36\x6d\x68\x96\xf3\xdf\xbc\xcf\x3f\xbf\x11\x4a\xab\x4a\xd9\x68\xbc\xe8\xca\x43\x76\x8c\xbd\x60\x22\x3d\x4d\x6a\x7b\x3f\x4d\x29\x8f\xb8\x14\x0d\xe4\xe7\x3f\xad\xce\x0d\xf0\x15\x1d\xb4\xea\x38\xf6\x60\x32\xc6\x3e\x80\xda\xd1\x15\x39\x51\x04\x12\xf3\xba\x3f\x1c\x97\x92\x3e\xb1\xcc\xd2\x3f\xd8\xac\x28\x3f\x80\x67\x0c\x60\x36\x33\xfa\x48\x11\xf4\x34\xd5\x95\x4b\x74\xc1\xae\xce\x63\x16\x88\xbe\x1e\x32\x70\xfd\xe7\x56\x70\x77\xd5\xee\x1b\x5c\x23\x96\x65\xe9\x76\x29\x46\xbb\xce\x3d\x40\x5e\x62\x1b\x6e\x76\xcc\xea\x94\xf8\x0b\xa9\xdb\x22\x83\x93\xc4\xe3\xf2\x7e\x5b\xc3\x77\xff\x9b\xce\x62\x23\x96\xbc\x65\xbf\x1f\xa4\x1f\xc4\x7c\xa6\x81\xc9\x06\xa5\xce\x2f\x94\xc5\x86\xd0\xaa\x93\x25\x01\xff\x34\x9a\x38\x04\xc1\xcd\xbc\xae\x12\xcb\x1d\x88\xfa\x09\x00\x00\xff\xff\xd3\x11\x0c\x91\x6b\x01\x00\x00") +var _templatesSystemdUserDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x90\xb1\x8a\xe3\x30\x10\x86\x7b\x3d\x85\x9b\x2b\x63\x73\x70\xad\x9a\x23\x39\x48\x95\x23\xce\x92\x22\x84\x20\xa4\x89\x57\xac\x34\x12\xa3\x71\xb2\xc2\xf8\xdd\x17\xd9\x38\x61\x53\x6e\x37\xf3\xfd\xf3\xfd\xd8\x3a\xbd\xa1\xe5\xb3\x18\x86\x55\x65\xaf\x55\x6d\x20\x69\xb2\x91\x6d\xc0\x6a\x1c\xc5\xfa\xb9\xca\x61\x78\x8d\x87\xa1\x02\x34\xe5\xae\x12\xa7\x16\xe8\x66\x35\x9c\xc5\x31\xd0\x87\xc5\x6e\x6d\x09\x34\x07\xca\x93\x78\x9f\xe1\xc5\x2c\xb4\x58\x87\x1c\x41\x26\xeb\xa3\x03\xb1\xc1\x9b\xa5\x80\x1e\x90\xe5\xff\xdd\xfe\x30\x59\x31\x10\x97\xc3\x6f\x61\x3b\x47\xe9\x25\xf8\x67\x1d\xc8\x55\x89\xde\x83\x87\x6a\x1c\x9b\x5a\x07\xbc\xda\xae\x49\x39\x31\x78\xd3\xf4\x09\xa8\x79\xb8\x35\x3c\x5d\xb1\xf9\x04\xdd\xb2\x22\x9e\xba\x75\xf0\x5e\xcd\x3f\xb6\x87\x34\x61\xe5\xee\x2a\xa7\x65\x6d\x41\xcb\xdf\x7f\x92\x68\x59\xa1\x51\x64\xb6\x18\x7b\x96\xd8\x3b\xf7\x40\xbb\x9e\x0b\x2b\x75\x2e\x74\xd5\x38\x4e\x9f\xa6\x62\x5c\xc6\x48\x41\x43\x4a\x17\xce\x11\x16\x86\xbd\x2f\x63\x62\x13\x7a\x2e\xde\xa3\x6e\x43\x14\xe8\xc7\x6d\x40\x34\xb7\xe5\xe4\x42\xb7\x35\x80\x6c\xaf\x16\x48\xfe\x42\x21\x4e\x5b\x4c\xac\x9c\x3b\x8b\xa3\x42\x06\xf3\x37\x4b\xdf\x3b\xb6\xab\xf2\x5e\x35\x2b\xea\x80\xc5\x57\x00\x00\x00\xff\xff\xca\xbc\xfd\x10\x27\x02\x00\x00") func templatesSystemdUserDefaultProgramServiceTmplBytes() ([]byte, error) { return bindataRead( @@ -201,12 +201,12 @@ func templatesSystemdUserDefaultProgramServiceTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/systemd-user/default/program.service.tmpl", size: 363, mode: os.FileMode(420), modTime: time.Unix(1584464041, 0)} + info := bindataFileInfo{name: "templates/systemd-user/default/program.service.tmpl", size: 551, mode: os.FileMode(420), modTime: time.Unix(1584489411, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templatesSysvDefaultInitShTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x57\x6d\x73\xdb\x36\x12\xfe\xce\x5f\xb1\xa1\x34\x76\x92\xd3\x8b\xed\x5c\xef\x66\x9c\x71\x7a\x69\xe3\xf6\x34\x4d\x6c\x8f\xa5\x4e\x6f\xa6\xed\x28\x10\xb1\x14\x71\x22\x01\x16\x00\x2d\xab\xb6\xfe\xfb\xcd\x02\x20\x45\xda\x52\x2f\xc9\x07\x47\x04\x76\x9f\x5d\xec\xcb\x83\x45\xef\xc5\x78\x21\xe4\xd8\x64\x51\x0f\x26\x52\x58\x30\x89\x16\xa5\x85\x54\x69\x78\x78\x80\x11\x2b\x4b\xd8\x6e\x87\xf4\xb3\xd4\x2a\x41\x63\xe6\x76\x53\x62\xbd\x26\xab\x02\xb6\xdb\xa8\x07\x9f\x98\x90\x96\x09\x89\x1c\x16\x1b\xd2\x14\x29\x8c\x58\x65\x33\xa5\x61\xbb\x75\x48\xad\x0f\x94\xdc\xab\xfd\x88\x12\x35\xb3\x5e\xab\xcc\x91\x19\xd4\x95\x1c\x91\x33\x45\x99\x63\x81\xd2\xed\x31\x83\x1c\x94\x84\x8f\xd3\xef\xe0\x7b\xa5\x11\xde\x8c\x4e\xcf\xa3\x1e\x00\xbc\x86\x29\x26\x56\x28\x69\xce\xe1\xec\x64\x74\x36\xa0\xbf\x6f\xa2\x5e\xd4\xeb\xf5\xe0\xbb\xcb\x1f\x27\x57\x30\xb9\x9a\xcc\x60\x72\xf5\xc3\x75\xd4\x83\x1b\xad\xee\x04\x47\x73\x0e\xcd\xbf\xaf\x39\xe5\x2d\xfe\x51\x09\x8d\x7c\x38\xb5\x4c\x5b\x07\xd2\xd7\x58\x28\x8b\xf3\xd4\x40\xdf\x6c\x4c\xae\x96\x5d\x39\x55\x7a\x5b\x7b\xe5\x3e\x60\xca\xaa\xdc\xb6\xe0\xe0\x0c\xde\xc0\xdf\xe1\x9b\xce\x66\x8d\x01\x27\x70\x0a\xff\x88\x7a\x30\xcd\x94\xb6\xc3\x0f\xe8\x93\x25\x94\x3c\xaf\x43\xae\x24\xce\x73\x21\x71\xce\x77\x9b\x21\x01\x87\xb7\x9a\x74\x74\x10\x77\xe1\xe9\x2a\xb8\xd0\x5e\x5e\x7d\x68\x05\x36\xba\x79\x3f\xfb\xf7\xc5\xd8\x2c\x84\x3c\x1f\x57\x46\x87\x5f\xcd\xe7\x42\xc8\x08\xef\x4b\xa5\x2d\x90\x64\x14\x49\x56\xe0\xc5\x97\x47\xbe\xd4\x6a\xa9\x59\x71\x11\xc4\xe8\xf7\x76\x1b\x31\xbd\x34\x1e\x44\x2f\x8d\x13\x13\x3c\x15\x39\x5e\xc4\xe3\x3b\xa6\xc7\xba\x92\xe3\x3e\x19\x1a\x95\x82\xc7\x51\x65\x50\x5f\xc4\x24\x4e\xbf\x60\xbb\x8d\xa3\xa5\x56\x55\xe9\xd7\xdc\x4f\xb7\x98\x64\x5a\x29\xeb\x57\xd7\x4a\xaf\x84\x5c\xce\xb9\xd0\x98\x58\xa5\x37\x41\x82\x0b\xfd\x57\x02\x52\x24\xe8\xf7\xe9\x17\xad\x3c\x3c\x0c\x5d\x7a\x72\x51\x08\x3b\x4f\x94\x46\x5e\x15\x64\x2f\xea\xae\x78\xad\x67\x52\xf1\x2e\x49\x4f\x90\xca\xca\x8a\x02\x5b\x40\x7e\xa1\x83\xd3\xc8\x1c\x84\xe1\xcc\xb2\x1d\x06\x7d\xb5\x01\xc2\xee\x41\x6d\x8a\xf9\xdc\x88\x3f\x5b\x6e\x34\x4b\x6d\x9c\xb6\xdc\x41\xb0\x5c\x25\x2b\xe4\xf3\x02\x0b\x1f\xcd\x68\xcf\x72\x1b\xf4\xa9\xfc\x41\x60\x55\xa2\x74\x2e\x98\x1d\xea\x6e\xad\x0d\xd9\x91\x3c\x88\x47\x55\x34\x0f\x35\xdb\xc6\xec\xae\xb7\x71\x9f\x69\x1c\xc4\x2e\xb3\x8d\x11\x09\xcb\x9f\x85\xe1\xc9\x46\x1b\xfd\xb9\xce\x41\x78\x63\x59\xb2\x7a\x92\xb1\xdd\x5a\x1b\xb4\x23\xd9\xc2\x23\x82\x4e\xc1\x66\xc2\x80\x30\x60\xd0\x82\x55\x70\x3a\x00\x9b\xa1\x84\x35\xfd\xf9\x6c\xac\x2a\x3f\xd3\x6e\xc2\xf2\x1c\xf9\x80\xec\xdb\x0c\x21\x04\x00\x32\x66\xa2\x1e\x48\x65\x01\xef\x05\xb1\xfc\x5a\xd8\x4c\x48\x60\xa0\x91\x19\x25\xd9\x22\x47\xa0\xc2\x1d\xc0\x74\xf2\xe3\x4f\x93\x8f\x1f\x61\x2d\xf2\x1c\x16\x08\x06\xa5\x05\x89\xf7\x96\x2e\x8a\x59\x86\xc0\x3d\x55\xc2\x02\x33\x76\x27\x94\x26\xb3\x56\x81\x11\x45\x99\x6f\x20\x57\x4b\x60\x50\xa0\x31\x6c\x89\x10\x07\x02\x01\x72\x10\x52\x26\x72\xe4\x6f\xc1\x58\xc2\xd6\x95\x94\x42\x2e\xe3\x88\xcc\xcd\xaf\xaf\xe6\xd3\xd9\xf5\xcd\x7c\x36\xf9\x74\x79\xfd\xf3\xec\xe2\x84\x8e\xfd\x0b\x1d\x2e\x57\x8c\x0b\xb9\x6c\xec\x32\xc9\xc1\x6c\x4c\xa2\x64\x2a\x96\xe0\x4a\x67\x00\x6b\x84\xca\x20\x7c\xa6\xe8\x0c\xd9\x67\x72\xa8\x60\x2b\x8c\x7a\xc0\xf2\x1c\xee\x98\x16\x74\x44\x03\xac\xb2\xaa\x60\x96\x72\x97\x6f\x40\x48\xab\x00\xe5\x9d\xd0\x4a\xd2\xf5\xb7\x13\x1c\x45\x1e\x29\xfa\x15\x86\x1a\xc6\x68\x93\x71\xb0\x3f\xae\x99\x14\xb6\x5b\xf8\x1d\x8e\x8e\x60\x74\x70\xbf\xa5\xdd\x78\x3c\xde\x31\x71\x47\x7d\x9f\x80\x73\xe2\x6f\xac\xa1\xf3\xeb\xdb\x99\xa7\x65\xfa\xda\x6e\x9b\xf5\xa9\x5f\x75\x8d\x41\x36\xff\x84\xb8\x4f\x6c\x18\x7b\x0b\x8e\x22\x4f\xa2\xc8\x6a\x96\xe0\xcb\x57\xf0\x10\x01\xe5\x69\x89\x1a\x86\x16\x62\x67\x5e\x48\x61\x47\x7c\xfc\xc5\xd7\x44\x0c\x71\xff\x5f\x71\xb4\x8d\x22\x2c\x84\x0d\xa0\xce\x80\xdf\x00\xc0\x24\x53\x8d\x90\xa1\x4b\x37\x48\x3d\x3c\x8c\x5f\xc3\x04\xb8\x72\x05\x49\x69\x3b\x36\xd5\x31\x64\xa8\x91\xf2\xa6\x2b\x09\xcc\x00\x03\x2e\xd2\x14\x35\xa5\xc5\x5d\x22\x0b\x4c\x18\x09\xb7\xeb\x9a\x14\x23\x7f\x77\x1a\xcb\x36\x86\x14\xdd\x3e\x23\xbd\x01\x90\x06\xd5\x8e\xaa\x34\x84\x0b\x8b\x4c\x24\xca\xcd\x4f\x5e\x54\x70\x50\xa9\x77\x81\xfc\xb1\x19\x06\xc4\xba\x76\xd7\x48\x85\x82\x92\x23\x0f\xfe\x8d\xe0\x63\x95\xac\x44\xbe\x71\x4d\x08\xc7\xfe\x1a\x3b\x6e\x34\x94\x84\xeb\xe9\x7f\x06\xf0\x83\x46\xfc\x6e\xfa\x61\xe0\x6a\xf6\xa3\x90\xd5\x7d\x80\xa6\xa2\x34\x55\xe9\xb2\x67\xd6\xc2\x26\x19\x79\x49\xc7\x34\x4e\x56\x58\x10\xf2\x4e\xad\xd0\x00\xde\x63\x72\x87\x20\x8a\x02\xb9\x60\x16\xf3\x0d\xb0\xd4\xa2\x06\x6f\x54\xc8\xe5\x08\x5e\x8f\x29\xf1\x00\x3d\xb8\x94\xa6\xd2\x3e\x46\xd4\x89\xbb\xab\xd2\x33\x47\x55\x42\xa2\x34\xad\xe5\x9b\x51\x04\x44\x13\xbf\xc2\x0b\x18\x72\xf0\x3c\xa4\x96\xe0\x72\xfb\xfb\x5b\xcf\x2e\xce\xdd\x62\xc5\x85\xee\x0a\xb8\xf5\x24\x53\x6b\x09\x71\x9f\xdc\x8e\xcf\xe3\xbe\xbb\xd6\xe3\xbd\x82\x85\xe2\xf0\xcf\x6f\xbe\x79\xb6\x97\x8a\xc8\x15\x84\x27\xcc\x52\xa3\xab\x13\x2a\xe3\xe0\x5b\xdc\xbf\xb9\xbd\x9c\xce\xde\xdf\xce\x62\x78\x71\x01\xb1\x54\x54\xd3\xde\x3b\x87\xed\xb8\xb1\x51\x24\x86\x31\x03\x60\x0b\x17\x58\x5a\x1a\x45\x3e\x95\x41\xe0\xf1\x11\x34\xda\x4a\x4b\xe8\x7f\xeb\xed\xbb\xa9\xab\x66\x5a\xc2\x9b\xba\x30\x31\xb9\x69\x33\x03\xcb\xc1\xd8\x2a\x4d\x61\x81\xa9\xd2\x98\x31\xc9\x5b\x8e\x57\x81\xc0\x33\xcc\xf3\x30\x00\x3e\x5f\x6a\xdb\xb8\xad\x64\x5d\xc7\x54\x30\x2f\x5a\x58\xd4\xac\xb0\xdd\xba\xff\x86\xb2\x6e\xe4\x9d\x3e\x84\xc4\xc3\x70\xe8\xea\xa5\xc4\x64\x4f\x0e\xfa\x5e\x28\x06\x93\xc1\x30\x01\x9f\x87\x30\xb6\x7e\x8d\xb7\x2e\x7d\x1c\x7e\x23\x40\x2e\xf4\x6f\x1e\x88\x6a\x92\xd6\x82\xfb\xbf\xc5\xd0\xa7\xb1\x30\x02\x88\xe1\xdd\x3b\xa8\x93\xbc\xdd\xb6\xf8\x64\xbc\x8f\x4f\x8c\xe5\xaa\xb2\x4e\xf8\xec\x6b\x15\x51\x6b\x27\x7c\xe4\x43\x5a\xbf\x6e\xea\xa6\x76\xbd\x9e\x6a\x55\x38\x62\x19\x51\x99\xb8\x46\x36\x16\x19\x87\x82\x71\x2f\x99\x2a\xbd\x42\x5e\x13\x8a\x43\x5a\xd6\x48\xc2\xb1\x81\xc6\xe6\x2e\x64\xe0\x08\x2e\x51\x92\x0b\x37\xa0\x2f\xd0\xae\x11\x65\xc7\xe6\x5a\x0b\xea\x4a\x07\x45\xbd\xcc\x1a\xb6\x2a\x95\x31\x62\x41\x0d\x6c\x68\x90\x75\xef\x3e\x63\x99\xad\xcc\xa8\xe6\xcb\xfe\x0b\x78\x07\xfd\x00\x45\x07\x23\x76\xa5\x22\x60\x05\xfa\x82\x46\x4e\x39\x08\x45\x7c\xe2\xb9\x55\x95\x81\x5a\x7b\x30\xd3\x1b\x60\x90\xe2\xda\x5d\xe7\xee\x66\x5e\x91\xf7\xb3\xcb\xdb\x4f\xed\x92\xf3\x0d\xe6\xad\xb7\xfb\xa9\x14\xfc\xa2\xff\x32\x61\x64\x34\xb8\x11\xbf\x72\x3b\x81\xdc\x7f\x12\x79\x4e\xce\x7b\x97\x5e\x12\x7d\x92\xe0\x2b\x37\x52\xd0\xf4\x40\x96\x7c\x99\x38\xc3\x43\x67\x99\x44\x42\xbf\xfe\xc2\x84\x7f\xf2\x0a\x37\xc8\xd0\x40\xe2\x9b\xd4\xad\x81\x90\x70\x5a\x3f\xcc\xe0\x2d\x70\x15\x28\x33\x98\x27\xed\xbd\xe6\xad\x02\x2e\x70\x34\x1a\xc5\xbb\x0b\x81\xce\xf6\xf8\x08\x0b\x8d\x6c\x55\xaf\xe6\x88\x25\x9c\xba\x2f\xae\xa4\xe7\xfa\xbd\x91\x68\x18\x68\xdf\x7c\x12\xc3\x10\xff\x80\xd3\x2e\x17\xb5\xdc\x9c\x89\x02\x55\x65\x69\xbc\x4a\x32\xe4\x23\xf8\xbf\x61\x23\x2b\x23\x80\x19\x8d\x79\x05\xdb\x80\x46\x43\xd3\x8e\x90\xe0\x9e\x04\xb9\x32\xa6\x39\x5a\x1d\x5a\x37\xa8\x35\xa1\x75\x9d\xd9\x2a\x17\x92\x09\xa3\x5e\x63\xa0\x46\xc0\xdc\xe0\x5e\xa5\xc3\x83\x5a\xa3\xeb\x48\xb3\x03\xf1\x14\xa0\x44\x1e\xa4\x9d\x6c\x2a\xc2\x08\x60\x2b\x13\x0a\xd5\x85\x76\x98\xb6\x8a\xac\x1b\xca\xc3\x65\x28\x52\x28\x0d\x0c\x4b\x77\x6e\x78\x07\x63\x8e\x77\x63\x59\xe5\x39\x9c\xb5\x3f\x3a\x69\xe9\x35\x2d\xb8\xd8\xf8\x41\x9a\x74\x85\x69\x8e\xd6\xc8\x4d\xac\x0b\x3e\x0d\x02\x0b\xac\xc7\x86\x01\x2c\x2a\xa2\x02\x66\x8f\x0d\xac\x33\x66\x61\xa3\x2a\x58\xa2\xf5\xb1\xfd\x6f\x65\x6c\xdd\xfd\x66\x07\x35\xbb\xfe\x70\xfd\xd2\x08\x63\x30\x7f\x75\x0e\xdf\x67\x98\xac\xfc\x58\x4e\xe6\x83\x3b\x06\xb1\x70\x3d\xba\xf0\x6c\x64\x28\x82\x61\x86\x51\x12\x61\x8d\x0d\x1c\xde\x97\x98\xd8\x11\x4c\xec\x31\x27\x71\x77\x41\x58\xe5\xe6\xa7\x94\x1e\x66\x8e\xe7\xbc\xab\xfe\xbb\xa2\x87\x0f\xf1\xdb\x20\x4c\xfe\x98\x0c\x1a\x38\xa3\xa8\xff\x68\x46\x36\xf4\xe3\x8f\x4a\x58\x04\xb6\x5e\xad\x99\xe6\x35\xac\x9b\x90\xdc\xa3\xc2\x60\x7d\xae\x86\x78\x9e\x94\x40\x58\x3f\xf3\xb1\x76\x53\x90\x30\xc0\x89\x6b\xc9\x23\x8a\xb7\x63\x47\xbc\x17\xc6\x9a\x5d\x6d\x34\x10\x01\xe0\x4d\x17\x80\x1c\x0f\x49\x6a\x0a\x29\x55\x3a\xc1\x79\x8b\xf5\xf6\xb6\x2f\xed\x47\x2d\x1e\x38\x3a\xea\x34\xcd\x9e\xda\xf2\xe8\xfb\x86\x91\xfa\x77\x33\xc0\x76\xb7\xa3\xda\xc8\x45\xff\xdb\xa8\x2e\xee\x7e\xb0\x3b\x5c\x5a\x38\xe9\x16\xb7\x6f\x97\x9b\x1a\x21\x51\x45\x41\x17\x85\xef\x3a\x5f\x53\x89\xe2\x58\x43\xb8\xbb\x8b\x2a\x6e\x2d\x4c\xe6\x9e\x5a\x2b\x51\x06\x2e\xef\x42\x0c\xdc\xeb\xb0\x9e\x98\x2e\xa4\xa2\x14\x6e\xa8\x8a\x5b\xa3\xcc\x28\xae\x07\x9f\x7a\x12\xf2\x66\x22\x7a\xb9\x36\x53\x0a\xe5\x1c\xe2\xfe\x69\x0c\x82\x9c\x76\x31\x1f\x3a\x63\x8f\xf5\x5f\x55\x3e\xd6\xcb\xaa\x7c\x0c\xae\x74\xee\x8a\xf7\xd6\x62\x51\x3a\xbe\x3e\xee\x9f\x1e\xd3\x5c\xfc\xe5\x0f\x0c\x07\xf4\xf6\x6d\x84\x86\x25\x7f\xe5\x8f\xb7\xd8\x3a\xf4\x6e\x44\x89\xfb\x27\xb1\xbf\x35\x6b\x30\x80\x96\x4e\x38\xb7\x9b\x71\x14\xc7\x0b\x37\x12\xd6\xe9\x73\x19\x20\x92\x3f\xa9\xa7\xe1\x3d\x64\x27\x0c\xb0\x5c\x23\xe3\x9b\xdd\x73\x36\x48\xdd\x0b\xeb\x41\x9e\x76\xca\xce\x9f\x5a\xea\xdb\xa8\x45\xab\xc1\x49\x55\xbe\xf2\x5c\xec\xbe\x77\x71\x7e\x05\xbb\xf2\x6f\x0e\x64\x2b\xf3\x95\x27\x82\xbf\x3a\x52\xe7\x28\x07\x68\xbe\xdb\x9b\x71\xfb\x04\x4f\x8e\xee\x9c\xec\x54\xc7\xd3\x16\xdb\x6e\xbf\x6c\xd6\xef\xce\xf1\xdd\xd8\x75\x47\x56\x17\x9d\xa3\xa3\xa7\xb9\x7f\xed\xed\xfb\x97\xe9\xcf\x86\x2d\xf1\x1c\xfa\xd3\xef\x6f\x27\x37\xb3\xab\xf7\x9f\x2e\xe1\xc1\x97\x76\xb7\xd8\x5b\x65\xde\xde\x54\xe5\xa3\x8f\x76\x5d\xf9\xdb\x18\xde\x1d\x9d\xed\x22\xf0\x26\x6a\x95\x6f\xed\xec\xff\x02\x00\x00\xff\xff\xd3\x72\x03\xe2\x03\x18\x00\x00") +var _templatesSysvDefaultInitShTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x57\x6d\x73\xdb\x36\x12\xfe\xce\x5f\xb1\xa1\x34\x76\x92\xd3\x8b\xed\x5c\xef\x66\x9c\x71\x7a\x69\xe3\xf6\x34\x4d\x6c\x8f\xa5\x4e\x6f\xa6\xed\x28\x10\xb1\x14\x71\x22\x01\x16\x00\x2d\xab\xb6\xfe\xfb\xcd\x02\x20\x45\xda\x52\x2f\xbd\xcb\x07\x47\x04\x76\x9f\x5d\xec\xcb\x83\x45\xef\xc5\x78\x21\xe4\xd8\x64\x51\x0f\x26\x52\x58\x30\x89\x16\xa5\x85\x54\x69\x78\x78\x80\x11\x2b\x4b\xd8\x6e\x87\xf4\xb3\xd4\x2a\x41\x63\xe6\x76\x53\x62\xbd\x26\xab\x02\xb6\xdb\xa8\x07\x9f\x98\x90\x96\x09\x89\x1c\x16\x1b\xd2\x14\x29\x8c\x58\x65\x33\xa5\x61\xbb\x75\x48\xad\x0f\x94\xdc\xab\x7d\x8f\x12\x35\xb3\x5e\xab\xcc\x91\x19\xd4\x95\x1c\x91\x33\x45\x99\x63\x81\xd2\xed\x31\x83\x1c\x94\x84\x8f\xd3\x6f\xe0\x5b\xa5\x11\xde\x8c\x4e\xcf\xa3\x1e\x00\xbc\x86\x29\x26\x56\x28\x69\xce\xe1\xec\x64\x74\x36\xa0\xbf\x6f\xa2\x5e\xd4\xeb\xf5\xe0\x9b\xcb\xef\x27\x57\x30\xb9\x9a\xcc\x60\x72\xf5\xdd\x75\xd4\x83\x1b\xad\xee\x04\x47\x73\x0e\xcd\xbf\x3f\x73\xca\x5b\xfc\xad\x12\x1a\xf9\x70\x6a\x99\xb6\x0e\xa4\xaf\xb1\x50\x16\xe7\xa9\x81\xbe\xd9\x98\x5c\x2d\xbb\x72\xaa\xf4\xb6\xf6\xca\x7d\xc0\x94\x55\xb9\x6d\xc1\xc1\x19\xbc\x81\xbf\xc2\x57\x9d\xcd\x1a\x03\x4e\xe0\x14\xfe\x16\xf5\x60\x9a\x29\x6d\x87\x1f\xd0\x27\x4b\x28\x79\x5e\x87\x5c\x49\x9c\xe7\x42\xe2\x9c\xef\x36\x43\x02\x0e\x6f\x35\xe9\xe8\x20\xee\xc2\xd3\x55\x70\xa1\xbd\xbc\xfa\xd0\x0a\x6c\x74\xf3\x7e\xf6\xcf\x8b\xb1\x59\x08\x79\x3e\xae\x8c\x0e\xbf\x9a\xcf\x85\x90\x11\xde\x97\x4a\x5b\x20\xc9\x28\x92\xac\xc0\x8b\x2f\x8f\x7c\xa9\xd5\x52\xb3\xe2\x22\x88\xd1\xef\xed\x36\x62\x7a\x69\x3c\x88\x5e\x9a\x39\x9a\x84\x95\xe8\x0e\x52\x0a\x9e\x8a\x1c\x2f\xe2\xf1\x1d\xd3\x63\x5d\xc9\x71\x9f\x0c\x8e\x4a\xc1\xe3\xa8\x32\xa8\x2f\x62\x52\xa3\x5f\xb0\xdd\xc6\xd1\x52\xab\xaa\xf4\x6b\xee\xa7\x5b\x4c\x32\xad\x94\xf5\xab\x6b\xa5\x57\x42\x2e\xe7\x5c\x68\x4c\xac\xd2\x9b\x20\xc1\x85\xfe\x23\x01\x29\x12\xf4\xfb\xf4\x8b\x56\x1e\x1e\x86\x2e\x4d\xb9\x28\x84\x9d\x27\x4a\x23\xaf\x0a\xb2\x17\x75\x57\xbc\xd6\x33\xa9\x78\x97\xac\x27\x48\x65\x65\x45\x81\x2d\x20\xbf\xd0\xc1\x69\x64\x0e\xc2\x70\x66\xd9\x0e\x83\xbe\xda\x00\x61\xf7\xa0\x36\xc5\x7c\x6e\xc4\xef\x2d\x37\x9a\xa5\x36\x4e\x5b\xee\x20\x58\xae\x92\x15\xf2\x79\x81\x85\x8f\x66\xb4\x67\xb9\x0d\xfa\x54\xfe\x20\xb0\x2a\x51\x3a\x17\xcc\x0e\x75\xb7\xd6\x86\xec\x48\x1e\xc4\xa3\x2a\x9a\x87\xda\x6d\x63\x76\xd7\xdb\xb8\xcf\x34\x0e\x62\x97\xd9\xc6\x88\x84\xe5\xcf\xc2\xf0\x64\xa3\x8d\xfe\x5c\xe7\x20\xbc\xb1\x2c\x59\x3d\xc9\xd8\x6e\xad\x0d\xda\x91\x6c\xe1\x11\x51\xa7\x60\x33\x61\x40\x18\x30\x68\xc1\x2a\x38\x1d\x80\xcd\x50\xc2\x9a\xfe\x7c\x36\x56\x95\x9f\x69\x37\x61\x79\x8e\x7c\x40\xf6\x6d\x86\x10\x02\x00\x19\x33\x51\x0f\xa4\xb2\x80\xf7\x82\xd8\x7e\x2d\x6c\x26\x24\x30\xd0\xc8\x8c\x92\x6c\x91\x23\x50\xe1\x0e\x60\x3a\xf9\xfe\x87\xc9\xc7\x8f\xb0\x16\x79\x0e\x0b\x04\x83\xd2\x82\xc4\x7b\x4b\x17\xc6\x2c\x43\xe0\x9e\x32\x61\x81\x19\xbb\x13\x4a\x93\x59\xab\xc0\x88\xa2\xcc\x37\x90\xab\x25\x30\x28\xd0\x18\xb6\x44\x88\x03\x91\x00\x39\x08\x29\x13\x39\xf2\xb7\x60\x2c\x61\xeb\x4a\x4a\x21\x97\x71\x44\xe6\xe6\xd7\x57\xf3\xe9\xec\xfa\x66\x3e\x9b\x7c\xba\xbc\xfe\x71\x76\x71\x42\xc7\xfe\x89\x0e\x97\x2b\xc6\x85\x5c\x36\x76\x99\xe4\x60\x36\x26\x51\x32\x15\x4b\x70\xa5\x33\x80\x35\x42\x65\x10\x3e\x53\x74\x86\xec\x33\x39\x54\xb0\x15\x46\x3d\x60\x79\x0e\x77\x4c\x0b\x3a\xa2\x01\x56\x59\x55\x30\x4b\xb9\xcb\x37\x20\xa4\x55\x80\xf2\x4e\x68\x25\xe9\x1a\xdc\x09\x8e\x22\x8f\x14\xfd\x0c\x43\x0d\x63\xb4\xc9\x38\xd8\x1f\xd7\x8c\x0a\xdb\x2d\xfc\x0a\x47\x47\x30\x3a\xb8\xdf\xd2\x6e\x3c\x1e\xef\x18\xb9\xa3\xbe\x4f\xc0\x39\xf1\x17\xd6\xd0\xfa\xf5\xed\xcc\xd3\x33\x7d\x6d\xb7\xcd\xfa\xd4\xaf\xba\xc6\x20\x9b\xbf\x43\xdc\x27\x36\x8c\xbd\x05\x47\x91\x27\x51\x64\x35\x4b\xf0\xe5\x2b\x78\x88\x80\xf2\xb4\x44\x0d\x43\x0b\xb1\x33\x2f\xa4\xb0\x23\x3e\xfe\xe2\xeb\x22\x86\xb8\xff\x8f\x38\xda\x46\x11\x16\xc2\x06\x50\x67\xc0\x6f\x00\x60\x92\xa9\x46\xc8\xd0\xe5\x1b\xa4\x1e\x1e\xc6\xaf\x61\x02\x5c\xb9\x82\xa4\xb4\x1d\x9b\xea\x18\x32\xd4\x48\x79\xd3\x95\x04\x66\x80\x01\x17\x69\x8a\x9a\xd2\xe2\x2e\x91\x05\x26\x8c\x84\xdb\x75\x4d\x8a\x91\xbf\x43\x8d\x65\x1b\x43\x8a\x6e\x9f\x91\xde\x00\x48\x83\x6a\x47\x55\x1a\xc2\x85\x45\x26\x12\xe5\xe6\x28\x2f\x2a\x38\xa8\xd4\xbb\x40\xfe\xd8\x0c\x03\x62\x5d\xbb\x6b\xa4\x42\x41\xc9\x91\x07\xff\x46\xf0\xb1\x4a\x56\x22\xdf\xb8\x26\x84\x63\x7f\x8d\x1d\x37\x1a\x4a\xc2\xf5\xf4\x5f\x03\xf8\x4e\x23\x7e\x33\xfd\x30\x70\x35\xfb\x51\xc8\xea\x3e\x40\x53\x51\x9a\xaa\x74\xd9\x33\x6b\x61\x93\x8c\xbc\xa4\x63\x1a\x27\x2b\x2c\x08\x79\xa7\x56\x68\x00\xef\x31\xb9\x43\x10\x45\x81\x5c\x30\x8b\xf9\x06\x58\x6a\x51\x83\x37\x2a\xe4\x72\x04\xaf\xc7\x94\x78\x80\x1e\x5c\x4a\x53\x69\x1f\x23\xea\xc4\xdd\x55\xe9\x99\xa3\x2a\x21\x51\x9a\xd6\xf2\xcd\x28\x02\xa2\x89\x9f\xe1\x05\x0c\x39\x78\x1e\x52\x4b\x70\xb9\xfd\xf5\xad\x67\x17\xe7\x6e\xb1\xe2\x42\x77\x05\xdc\x7a\x92\xa9\xb5\x84\xb8\x4f\x6e\xc7\xe7\x71\xdf\x5d\xeb\xf1\x5e\xc1\x42\x71\xf8\xfb\x57\x5f\x3d\xdb\x4b\x45\xe4\x0a\xc2\x13\x66\xa9\xd1\xd5\x09\x95\x71\xf0\x2d\xee\xdf\xdc\x5e\x4e\x67\xef\x6f\x67\x31\xbc\xb8\x80\x58\x2a\xaa\x69\xef\x9d\xc3\x76\xdc\xd8\x28\x12\xc3\x98\x01\xb0\x85\x0b\x2c\x2d\x8d\x22\x9f\xca\x20\xf0\xf8\x08\x1a\x6d\xa5\x25\xf4\xbf\xf6\xf6\xdd\xf4\x55\x33\x2d\xe1\x4d\x5d\x98\x98\xdc\xb4\x99\x81\xe5\x60\x6c\x95\xa6\xb0\xc0\x54\x69\xcc\x98\xe4\x5e\x93\xfc\xae\x02\x7f\x67\x98\xe7\x61\x0e\x7c\xbe\xd4\x36\x71\x5b\xc9\xba\x8c\xa9\x5e\x5e\xb4\x62\x40\xbd\x0a\xdb\xad\xfb\x6f\x28\xeb\x3e\xde\xe9\x43\xc8\x3b\x0c\x87\xae\x5c\x4a\x4c\xf6\xa4\xa0\xef\x85\x62\x30\x19\x0c\x13\xf0\x69\xf8\x1f\xbc\x75\xd9\xe3\xf0\x0b\x01\x72\xa1\x7f\xf1\x40\x54\x92\xb4\x16\xdc\xff\x25\x86\x3e\x4d\x87\x11\x40\x0c\xef\xde\x41\x9d\xe3\xc0\x17\x5f\x44\x27\x43\x63\xb9\xaa\xac\xd3\x3b\xfb\x3f\x30\x50\x6b\xa7\x77\xe4\x03\x5d\x3f\x7d\xea\x4e\x77\x04\x90\x6a\x55\x38\xb6\x19\x51\xed\xb8\xee\x36\x16\x19\x87\x82\x71\x2f\x99\x2a\xbd\x42\x5e\xb3\x8c\x43\x5a\xd6\x48\xc2\x51\x84\xc6\xe6\x82\x64\xe0\x58\x2f\x51\x92\x0b\x37\xbd\x2f\xd0\xae\x11\x65\xc7\xe6\x5a\x0b\x6a\x55\x07\x45\x0d\xce\x1a\x0a\x2b\x95\x31\x62\x41\x5d\x6d\x68\xba\x75\x8f\x42\x63\x99\xad\xcc\xa8\x26\xd1\xfe\x0b\x78\x07\xfd\x00\x45\x07\x23\xca\xa5\xd2\x60\x05\xfa\x2a\x47\x4e\x99\x09\x95\x7d\xe2\x09\x57\x95\x81\x6f\x7b\x30\xd3\x1b\x60\x90\xe2\xda\xdd\xf1\xee\xba\x5e\x91\xf7\xb3\xcb\xdb\x4f\xed\x42\xf4\x5d\xe7\xad\xb7\x9b\xac\x14\xfc\xa2\xff\x32\x61\x64\x34\xb8\x11\xbf\x72\x3b\x81\xf1\x7f\x10\x79\x4e\xce\x7b\x97\x5e\x12\xa7\x92\xe0\x2b\x37\x67\xd0\x48\x41\x96\x7c\xf1\x38\xc3\x43\x67\x99\x44\x42\x13\xff\xc4\x84\x7f\x0f\x0b\x37\xdd\xd0\x94\xe2\x3b\xd7\xad\x81\x90\x70\x5a\xbf\xda\xe0\x2d\x70\x15\x78\x34\x98\x27\xed\xbd\xe6\xad\x02\x2e\x70\x34\x1a\xc5\xbb\x5b\x82\xce\xf6\xf8\x08\x0b\x8d\x6c\x55\xaf\xe6\x88\x25\x9c\xba\x2f\xae\xa4\xbf\x00\xf6\x46\xa2\xa1\xa5\x7d\x43\x4b\x0c\x43\xfc\x0d\x4e\xbb\x04\xd5\x72\x73\x26\x0a\x54\x95\xa5\x99\x2b\xc9\x90\x8f\xe0\xbf\x86\x8d\xac\x8c\x00\x66\x34\xfb\x15\x6c\x03\x1a\x0d\x8d\x40\x42\x82\x7b\x27\xe4\xca\x98\xe6\x68\x75\x68\xdd\xf4\xd6\x84\xd6\xf5\x6b\xab\x5c\x48\x26\xcc\x7f\x8d\x81\x1a\x01\x73\x83\x7b\x95\x0e\x4f\x6f\x8d\xae\x63\xd2\x0e\xc4\x53\x80\x12\x79\x90\x76\xb2\xa9\x08\x73\x81\xad\x4c\x28\x54\x17\xda\x61\xda\x2a\xb2\x6e\x28\x0f\x97\xa1\x48\xa1\x34\x30\x2c\xdd\xb9\xe1\x1d\x8c\x39\xde\x8d\x65\x95\xe7\x70\xd6\xfe\xe8\xa4\xa5\xd7\xb4\xe0\x62\xe3\xa7\x6b\xd2\x15\xa6\x39\x5a\x23\x37\xb1\x2e\xf8\x34\x1d\x2c\xb0\x9e\x25\x06\xb0\xa8\x88\x0a\x98\x3d\x36\xb0\xce\x98\x85\x8d\xaa\x60\x89\xd6\xc7\xf6\xdf\x95\xb1\x75\xf7\x9b\x1d\xd4\xec\xfa\xc3\xf5\x4b\x23\x8c\xc1\xfc\xd5\x39\x7c\x9b\x61\xb2\xf2\xb3\x3a\x99\x0f\xee\x18\xc4\xc2\xf5\xe8\xc2\xb3\x91\xa1\x08\x86\xc1\x46\x49\x84\x35\x36\x70\x78\x5f\x62\x62\x47\x30\xb1\xc7\x9c\xc4\xdd\xb5\x61\x95\x1b\xaa\x52\x7a\xad\x39\x9e\xf3\xae\xfa\xef\x8a\x5e\x43\xc4\x6f\x83\xf0\x1c\xc0\x64\xd0\xc0\x19\x45\xfd\x47\x83\xb3\xa1\x1f\xbf\x55\xc2\x22\xb0\xf5\x6a\xcd\x34\xaf\x61\xdd\xd8\xe4\x5e\x1a\x06\xeb\x73\x35\xc4\xf3\xa4\x04\xc2\xfa\x99\x8f\xb5\x1b\x8d\x84\x01\x4e\x5c\x4b\x1e\x51\xbc\x1d\x3b\xe2\xbd\x30\xd6\xec\x6a\xa3\x81\x08\x00\x6f\xba\x00\xe4\x78\x48\x52\x53\x48\xa9\xd2\x09\xce\x5b\xac\xb7\xb7\x7d\x69\x3f\x6a\xf1\xc0\xd1\x51\xa7\x69\xf6\xd4\x96\x47\xdf\x37\xa1\xd4\xbf\x9b\xa9\xb6\xbb\x1d\xd5\x46\x2e\xfa\x5f\x47\x75\x71\xf7\x83\xdd\xe1\xd2\xc2\x49\xb7\xb8\x7d\xbb\xdc\xd4\x08\x89\x2a\x0a\xba\x28\x7c\xd7\xf9\x9a\x4a\x14\xc7\x1a\xc2\xdd\x5d\x54\x71\x6b\x61\x32\xf7\xfe\x5a\x89\x32\x70\x79\x17\x62\xe0\x9e\x8c\xf5\x18\x75\x21\x15\xa5\x70\x43\x55\xdc\x9a\x6f\x46\x71\x3d\x0d\xd5\xe3\x91\x37\x13\xd1\x73\xb6\x99\x5d\x28\xe7\x10\xf7\x4f\x63\x10\xe4\xb4\x8b\xf9\xd0\x19\x7b\xac\xff\xaa\xf2\xb1\x5e\x56\xe5\x63\x70\xa5\x73\x57\xbc\xb7\x16\x8b\xd2\xf1\xf5\x71\xff\xf4\x98\x86\xe5\x2f\x7f\x75\x38\xa0\xb7\x6f\x23\x34\x2c\xf9\x23\x7f\xbc\xc5\xd6\xa1\x77\x83\x4b\xdc\x3f\x89\xfd\xad\x59\x83\x01\xb4\x74\xc2\xb9\xdd\xe4\xa3\x38\x5e\xb8\x39\xb1\x4e\x9f\xcb\x00\x91\xfc\x49\x3d\x22\xef\x21\x3b\x61\x80\xe5\x1a\x19\xdf\xec\xde\xb8\x41\xea\x5e\x58\x0f\xf2\xb4\x53\x76\xfe\xd4\x52\x5f\x47\x2d\x5a\x0d\x4e\xaa\xf2\x95\xe7\x62\xf7\xbd\x8b\xf3\x2b\xd8\x95\x7f\x73\x20\x5b\x99\x3f\x79\x22\xf8\xa3\x23\x75\x8e\x72\x80\xe6\xbb\xbd\x19\xb7\x4f\xf0\xe4\xe8\xce\xc9\x4e\x75\x3c\x6d\xb1\xed\xf6\xcb\x1e\x00\xdd\xe1\xbe\x1b\xbb\xee\x20\xeb\xa2\x73\x74\xf4\x34\xf7\xaf\xbd\x7d\xff\x5c\xfd\xd1\xb0\x25\x9e\x43\x7f\xfa\xed\xed\xe4\x66\x76\xf5\xfe\xd3\x25\x3c\xf8\xd2\xee\x16\x7b\xab\xcc\xdb\x9b\xaa\x7c\xf4\xd1\xae\x2b\x7f\x1b\xc3\xbb\xa3\xb3\x5d\x04\xde\x44\xad\xf2\xad\x9d\xfd\x4f\x00\x00\x00\xff\xff\x93\x92\x86\x60\x20\x18\x00\x00") func templatesSysvDefaultInitShTmplBytes() ([]byte, error) { return bindataRead( @@ -221,7 +221,7 @@ func templatesSysvDefaultInitShTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/sysv/default/init.sh.tmpl", size: 6147, mode: os.FileMode(420), modTime: time.Unix(1584470819, 0)} + info := bindataFileInfo{name: "templates/sysv/default/init.sh.tmpl", size: 6176, mode: os.FileMode(420), modTime: time.Unix(1584486952, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -241,7 +241,7 @@ func templatesUpstartDefaultControlConfTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/upstart/default/control.conf.tmpl", size: 76, mode: os.FileMode(420), modTime: time.Unix(1584463645, 0)} + info := bindataFileInfo{name: "templates/upstart/default/control.conf.tmpl", size: 76, mode: os.FileMode(420), modTime: time.Unix(1584472497, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -261,12 +261,12 @@ func templatesUpstartDefaultProcessTypeConfTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/upstart/default/process-type.conf.tmpl", size: 120, mode: os.FileMode(420), modTime: time.Unix(1584463645, 0)} + info := bindataFileInfo{name: "templates/upstart/default/process-type.conf.tmpl", size: 120, mode: os.FileMode(420), modTime: time.Unix(1584472497, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templatesUpstartDefaultProgramConfTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x52\xc1\x6e\x13\x41\x0c\xbd\xcf\x57\xbc\x43\xd5\x36\x42\x9b\x05\x6e\x1c\x9a\x53\x2f\x3d\x11\x01\xb7\x52\xb5\xab\x19\x67\x33\xa2\x19\x8f\x6c\x2f\x25\x6a\xe7\xdf\xd1\xec\xa6\xb4\x85\x54\x04\x89\xdb\xec\xf3\xf3\xf3\x7b\x5e\x07\x52\x2f\x31\x5b\xe4\x84\xfb\x7b\xcc\xbb\x9c\x51\x4a\x53\x9f\x59\xd8\x93\xea\xb5\x6d\x33\x3d\x62\x69\xd8\xa0\x14\xe7\xd4\x3a\x31\x70\xc2\xe9\xf8\x8a\xa9\xff\x4b\x37\x58\xb0\x87\x3a\x73\x6a\x9c\x77\x42\x9c\xf3\xa1\x42\x7f\x50\x67\xce\x29\xd9\x10\xc3\x88\x0d\x4a\x52\x7d\x2a\x59\xbf\x83\x7a\xe1\xa1\x12\x9d\x5f\x87\x28\x18\xb1\x3b\x96\x6f\x31\xf5\xd7\x21\x0a\x79\x63\xd9\xd6\xba\x90\xe6\xee\x2e\x39\x37\x2d\xc6\x01\xf4\x23\xb3\x18\x96\x1f\x3f\x7d\x39\x1b\x1d\xd5\xaf\x52\x9e\x55\x3e\x4f\xb8\x4e\xe8\x25\x1a\x41\x4b\xe6\xdb\x40\xab\x6e\xb8\xb5\xf6\xd1\x67\xf5\x7f\x85\xe3\x63\xcc\x5f\xad\xbf\xe8\xd7\xad\x7a\x4e\xab\xd8\xb7\x4f\x49\x5f\x08\xec\x23\x38\xc0\x87\xd7\xf3\x55\xd7\xe4\xc7\xba\xe7\xcd\xa6\x4b\xa1\x8a\x7e\x75\x00\xb0\x58\x8c\xf8\x2d\xf7\x28\xe5\x99\x64\xbb\xef\x1e\xd4\x02\x0f\x36\x92\xa7\xee\xf7\xff\xda\x4e\x22\x95\xec\x28\x05\xec\xb6\xed\x32\xab\x35\xd3\x79\xfd\xfa\x01\xcb\x8b\xf3\xb3\x1b\xb5\xce\x06\x3d\xfc\x48\xf1\x00\xea\x85\x32\x1a\x8e\x38\x39\xbd\x7c\xdb\x7c\xb8\x7a\x33\x3b\x3a\xc1\x03\xd6\xd4\x05\x34\xe9\xdd\x4d\x5d\x86\x5f\x33\x8e\x96\x17\xe7\x58\xa0\xfd\xde\x49\x2b\x43\xfa\xdd\xfa\x41\xf3\xe6\x39\x86\x7d\x49\x38\x3f\x05\x91\x0d\x9a\xd5\xff\x1d\xf3\x33\x00\x00\xff\xff\x99\xdb\x24\x5f\xc1\x03\x00\x00") +var _templatesUpstartDefaultProgramConfTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x52\xc1\x4e\x1b\x31\x10\xbd\xfb\x2b\xde\x01\x01\x51\xb5\xd9\xb6\xb7\x1e\xc8\x89\x0b\xa7\x46\x6d\x6f\x14\xc1\xca\x9e\x6c\xac\x12\x8f\x35\x33\x5b\x1a\xc1\xfe\x7b\xe5\xdd\xa4\x80\x9a\xa8\x2b\x95\x9b\xfd\x66\xe6\xf9\xbd\xe7\x09\xa4\x5e\x62\xb6\xc8\x09\x8f\x8f\x98\x37\x39\xa3\xef\xab\x72\xcc\xc2\x9e\x54\x6f\x6d\x9b\x69\x8f\xa5\x6e\x83\xbe\x77\x4e\xad\x11\x03\x27\x9c\x0f\xa7\x98\xda\x7f\x4c\x83\x05\x07\x5a\x67\x4e\x8d\xf3\x8e\x88\x73\x9e\x4a\xf4\x57\xeb\xcc\x39\x25\xeb\x62\x18\xb0\x4e\x49\x8a\x4e\x25\x6b\x77\x50\x2b\xdc\x95\x46\xe7\xd7\x21\x0a\x06\xec\x81\xe5\x47\x4c\xed\x6d\x88\x42\xde\x58\xb6\xa5\x2e\xa4\xb9\x79\x48\xce\x8d\xc1\x38\x80\x7e\x65\x16\xc3\xf2\xf3\x97\x6f\x17\x83\xa2\x72\xeb\xfb\x17\x95\xaf\x23\xae\x23\x7a\x8d\x4a\x50\x93\xf9\x3a\xd0\xaa\xe9\xee\xad\xde\xeb\x2c\xfa\x6f\x70\x7a\x8a\xf9\xd1\xfa\xab\x79\xdd\xaa\xe7\xb4\x8a\x6d\xfd\xec\xf4\x15\xc1\xa1\x06\x07\xf8\x70\xdc\x5f\x51\x4d\x7e\xa8\x7b\xde\x6c\x9a\x14\x0a\xe9\x77\x07\x00\x8b\xc5\x80\xdf\x73\xbb\x4f\x7f\xd2\x3e\x54\x6a\x81\x3b\x1b\xe6\x46\xa2\x8f\xff\xc1\x44\x22\x65\xce\x51\x0a\xd8\xfd\x81\xcb\xac\x56\x8d\x4b\xf7\xe7\x5b\x96\x57\x97\x17\x77\x6a\x8d\x75\x3a\x7d\x75\xf1\x04\x6a\x85\x32\x2a\x8e\x38\x3b\xbf\x7e\x5f\x7d\xba\x79\x37\x3b\x39\xc3\x13\xd6\xd4\x04\x54\xe9\xc3\x5d\x89\xc8\xaf\x19\x27\xcb\xab\x4b\x2c\x50\xff\x6c\xa4\x96\x2e\xbd\x88\xb8\x9e\xfc\xde\x3c\xc7\x70\xc8\x09\xe7\x67\x23\xb2\x41\xb5\x7a\xdb\x67\x7e\x07\x00\x00\xff\xff\xc2\x40\xab\xd2\xd7\x03\x00\x00") func templatesUpstartDefaultProgramConfTmplBytes() ([]byte, error) { return bindataRead( @@ -281,7 +281,7 @@ func templatesUpstartDefaultProgramConfTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/upstart/default/program.conf.tmpl", size: 961, mode: os.FileMode(420), modTime: time.Unix(1584468680, 0)} + info := bindataFileInfo{name: "templates/upstart/default/program.conf.tmpl", size: 983, mode: os.FileMode(420), modTime: time.Unix(1584486170, 0)} a := &asset{bytes: bytes, info: info} return a, nil } From 0912591d622e39105d073b75d6c20436852fdd1e Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 20:16:15 -0400 Subject: [PATCH 30/48] feat: add log message stating to reload systemctl when adding the services --- export.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/export.go b/export.go index 66f35a9..90e1a02 100644 --- a/export.go +++ b/export.go @@ -163,7 +163,12 @@ func exportSystemd(app string, entries []procfileEntry, formations map[string]fo config := vars config["processes"] = processes fmt.Println("writing:", app+".target") - return writeOutput(t, location+"/"+app+".target", config) + if writeOutput(t, location+"/"+app+".target", config) { + fmt.Println("You will want to run 'systemctl --system daemon-reload' to activate the service on the target host") + return true + } + + return true } func exportSystemdUser(app string, entries []procfileEntry, formations map[string]formationEntry, location string, defaultPort int, vars map[string]interface{}) bool { @@ -195,6 +200,7 @@ func exportSystemdUser(app string, entries []procfileEntry, formations map[strin } } + fmt.Println("You will want to run 'systemctl --user daemon-reload' to activate the service on the target host") return true } From f6001828c28a5ee8c9f1b00b0f0b33967194bd51 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 20:17:22 -0400 Subject: [PATCH 31/48] refactor: move print message to single locationn --- export.go | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/export.go b/export.go index 90e1a02..ee24e36 100644 --- a/export.go +++ b/export.go @@ -24,8 +24,6 @@ func exportLaunchd(app string, entries []procfileEntry, formations map[string]fo for num <= count { processName := fmt.Sprintf("%s-%d", entry.Name, num) - fmt.Println("writing:", app+"-"+processName+".plist") - port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) if !writeOutput(l, location+"/"+app+"-"+processName+".plist", config) { @@ -76,7 +74,6 @@ func exportRunit(app string, entries []procfileEntry, formations map[string]form port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) - fmt.Println("writing:", app+"-"+processName+"/run") if !writeOutput(r, folderPath+"/run", config) { return false } @@ -110,7 +107,6 @@ func exportRunit(app string, entries []procfileEntry, formations map[string]form } } - fmt.Println("writing:", app+"-"+processName+"/log/run") if !writeOutput(l, folderPath+"/log/run", config) { return false } @@ -148,7 +144,6 @@ func exportSystemd(app string, entries []procfileEntry, formations map[string]fo processName := fmt.Sprintf("%s-%d", entry.Name, num) fileName := fmt.Sprintf("%s.%d", entry.Name, num) processes = append(processes, fmt.Sprintf(app+"-%s.service", fileName)) - fmt.Println("writing:", app+"-"+fileName+".service") port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) @@ -162,7 +157,6 @@ func exportSystemd(app string, entries []procfileEntry, formations map[string]fo config := vars config["processes"] = processes - fmt.Println("writing:", app+".target") if writeOutput(t, location+"/"+app+".target", config) { fmt.Println("You will want to run 'systemctl --system daemon-reload' to activate the service on the target host") return true @@ -188,8 +182,6 @@ func exportSystemdUser(app string, entries []procfileEntry, formations map[strin for num <= count { processName := fmt.Sprintf("%s-%d", entry.Name, num) - fmt.Println("writing:", app+"-"+processName+".service") - port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) if !writeOutput(s, location+"/"+app+"-"+processName+".service", config) { @@ -221,8 +213,6 @@ func exportSysv(app string, entries []procfileEntry, formations map[string]forma for num <= count { processName := fmt.Sprintf("%s-%d", entry.Name, num) - fmt.Println("writing:", app+"-"+processName) - port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) if !writeOutput(l, location+"/"+app+"-"+processName, config) { @@ -264,7 +254,6 @@ func exportUpstart(app string, entries []procfileEntry, formations map[string]fo variables := vars variables["process_type"] = entry.Name - fmt.Println("writing:", app+"-"+entry.Name+".conf") if !writeOutput(t, location+"/"+app+"-"+entry.Name+".conf", variables) { return false } @@ -272,8 +261,6 @@ func exportUpstart(app string, entries []procfileEntry, formations map[string]fo for num <= count { processName := fmt.Sprintf("%s-%d", entry.Name, num) fileName := fmt.Sprintf("%s-%d", entry.Name, num) - fmt.Println("writing:", app+"-"+fileName+".conf") - port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) if !writeOutput(p, location+"/"+app+"-"+fileName+".conf", config) { @@ -285,7 +272,6 @@ func exportUpstart(app string, entries []procfileEntry, formations map[string]fo } config := vars - fmt.Println("writing:", app+".conf") return writeOutput(c, location+"/"+app+".conf", config) } func processCount(entry procfileEntry, formations map[string]formationEntry) int { @@ -323,6 +309,7 @@ func templateVars(app string, entry procfileEntry, processName string, num int, } func writeOutput(t *template.Template, outputPath string, variables map[string]interface{}) bool { + fmt.Println("writing:", outputPath) f, err := os.Create(outputPath) if err != nil { fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) From f610f78b13dc317a8d90363d199cd9a64c55fc57 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 20:18:43 -0400 Subject: [PATCH 32/48] feat: write files into paths that mimic the installed paths --- export.go | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/export.go b/export.go index ee24e36..c888266 100644 --- a/export.go +++ b/export.go @@ -14,8 +14,8 @@ func exportLaunchd(app string, entries []procfileEntry, formations map[string]fo return false } - if _, err := os.Stat(location); os.IsNotExist(err) { - os.MkdirAll(location, os.ModePerm) + if _, err := os.Stat(location + "/Library/LaunchDaemons/"); os.IsNotExist(err) { + os.MkdirAll(location+"/Library/LaunchDaemons/", os.ModePerm) } for i, entry := range entries { @@ -26,7 +26,7 @@ func exportLaunchd(app string, entries []procfileEntry, formations map[string]fo processName := fmt.Sprintf("%s-%d", entry.Name, num) port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) - if !writeOutput(l, location+"/"+app+"-"+processName+".plist", config) { + if !writeOutput(l, location+"/Library/LaunchDaemons/"+app+"-"+processName+".plist", config) { return false } @@ -131,8 +131,8 @@ func exportSystemd(app string, entries []procfileEntry, formations map[string]fo return false } - if _, err := os.Stat(location); os.IsNotExist(err) { - os.MkdirAll(location, os.ModePerm) + if _, err := os.Stat(location + "/etc/systemd/system/"); os.IsNotExist(err) { + os.MkdirAll(location+"/etc/systemd/system/", os.ModePerm) } processes := []string{} @@ -147,7 +147,7 @@ func exportSystemd(app string, entries []procfileEntry, formations map[string]fo port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) - if !writeOutput(s, location+"/"+app+"-"+fileName+".service", config) { + if !writeOutput(s, location+"/etc/systemd/system/"+app+"-"+fileName+".service", config) { return false } @@ -157,7 +157,7 @@ func exportSystemd(app string, entries []procfileEntry, formations map[string]fo config := vars config["processes"] = processes - if writeOutput(t, location+"/"+app+".target", config) { + if writeOutput(t, location+"/etc/systemd/system/"+app+".target", config) { fmt.Println("You will want to run 'systemctl --system daemon-reload' to activate the service on the target host") return true } @@ -172,8 +172,9 @@ func exportSystemdUser(app string, entries []procfileEntry, formations map[strin return false } - if _, err := os.Stat(location); os.IsNotExist(err) { - os.MkdirAll(location, os.ModePerm) + path := vars["home"].(string) + "/.config/systemd/user/" + if _, err := os.Stat(location + path); os.IsNotExist(err) { + os.MkdirAll(location+path, os.ModePerm) } for i, entry := range entries { @@ -184,7 +185,7 @@ func exportSystemdUser(app string, entries []procfileEntry, formations map[strin processName := fmt.Sprintf("%s-%d", entry.Name, num) port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) - if !writeOutput(s, location+"/"+app+"-"+processName+".service", config) { + if !writeOutput(s, fmt.Sprintf("%s%s%s-%s.service", location, path, app, processName), config) { return false } @@ -203,8 +204,8 @@ func exportSysv(app string, entries []procfileEntry, formations map[string]forma return false } - if _, err := os.Stat(location); os.IsNotExist(err) { - os.MkdirAll(location, os.ModePerm) + if _, err := os.Stat(location + "/etc/init.d/"); os.IsNotExist(err) { + os.MkdirAll(location+"/etc/init.d/", os.ModePerm) } for i, entry := range entries { @@ -215,7 +216,7 @@ func exportSysv(app string, entries []procfileEntry, formations map[string]forma processName := fmt.Sprintf("%s-%d", entry.Name, num) port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) - if !writeOutput(l, location+"/"+app+"-"+processName, config) { + if !writeOutput(l, fmt.Sprintf("%s/etc/init.d/%s-%s", location, app, processName), config) { return false } @@ -244,8 +245,8 @@ func exportUpstart(app string, entries []procfileEntry, formations map[string]fo return false } - if _, err := os.Stat(location); os.IsNotExist(err) { - os.MkdirAll(location, os.ModePerm) + if _, err := os.Stat(location + "/etc/init/"); os.IsNotExist(err) { + os.MkdirAll(location+"/etc/init/", os.ModePerm) } for i, entry := range entries { @@ -254,7 +255,7 @@ func exportUpstart(app string, entries []procfileEntry, formations map[string]fo variables := vars variables["process_type"] = entry.Name - if !writeOutput(t, location+"/"+app+"-"+entry.Name+".conf", variables) { + if !writeOutput(t, fmt.Sprintf("%s/etc/init/%s-%s.conf", location, app, entry.Name), variables) { return false } @@ -263,7 +264,7 @@ func exportUpstart(app string, entries []procfileEntry, formations map[string]fo fileName := fmt.Sprintf("%s-%d", entry.Name, num) port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) - if !writeOutput(p, location+"/"+app+"-"+fileName+".conf", config) { + if !writeOutput(p, fmt.Sprintf("%s/etc/init/%s-%s.conf", location, app, fileName), config) { return false } @@ -272,7 +273,7 @@ func exportUpstart(app string, entries []procfileEntry, formations map[string]fo } config := vars - return writeOutput(c, location+"/"+app+".conf", config) + return writeOutput(c, fmt.Sprintf("%s/etc/init/%s.conf", location, app), config) } func processCount(entry procfileEntry, formations map[string]formationEntry) int { count := 0 From d33cfe1d33a559757e423140c06522bd18831f6c Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 20:19:01 -0400 Subject: [PATCH 33/48] fix: do not prinnt out process-level init if not necessary --- export.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/export.go b/export.go index c888266..40ce92e 100644 --- a/export.go +++ b/export.go @@ -253,10 +253,12 @@ func exportUpstart(app string, entries []procfileEntry, formations map[string]fo num := 1 count := processCount(entry, formations) - variables := vars - variables["process_type"] = entry.Name - if !writeOutput(t, fmt.Sprintf("%s/etc/init/%s-%s.conf", location, app, entry.Name), variables) { - return false + if count > 0 { + config := vars + config["process_type"] = entry.Name + if !writeOutput(t, fmt.Sprintf("%s/etc/init/%s-%s.conf", location, app, entry.Name), config) { + return false + } } for num <= count { From 9ec5b6df81cca29ffeb96c15d16da39e4e2a0a79 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 20:19:42 -0400 Subject: [PATCH 34/48] feat: interpolate home path based on logged in user --- main.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/main.go b/main.go index 7f87a6a..d502d8d 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "fmt" "io/ioutil" "os" + "os/user" "regexp" "sort" "strconv" @@ -308,7 +309,7 @@ func expandCommand(entries []procfileEntry, envPath string, allowGetenv bool, pr return true } -func exportCommand(entries []procfileEntry, app string, description string, envPath string, format string, formation string, group string, home string, limitCoredump string, limitCputime string, limitData string, limitFileSize string, limitLockedMemory string, limitOpenFiles string, limitUserProcesses string, limitPhysicalMemory string, limitStackSize string, location string, logPath string, nice string, prestart string, workingDirectoryPath string, runPath string, timeout int, user string, defaultPort int) bool { +func exportCommand(entries []procfileEntry, app string, description string, envPath string, format string, formation string, group string, home string, limitCoredump string, limitCputime string, limitData string, limitFileSize string, limitLockedMemory string, limitOpenFiles string, limitUserProcesses string, limitPhysicalMemory string, limitStackSize string, location string, logPath string, nice string, prestart string, workingDirectoryPath string, runPath string, timeout int, processUser string, defaultPort int) bool { if format == "" { fmt.Fprintf(os.Stderr, "no format specified\n") return false @@ -338,16 +339,22 @@ func exportCommand(entries []procfileEntry, app string, description string, envP return false } - if user == "" { - user = app + if processUser == "" { + processUser = app } if group == "" { group = app } + u, err := user.Current() + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + return false + } + if home == "" { - home = "/home/" + app + home = "/home/" + u.Username } env := make(map[string]string) @@ -388,7 +395,7 @@ func exportCommand(entries []procfileEntry, app string, description string, envP vars["working_directory"] = workingDirectoryPath vars["timeout"] = strconv.Itoa(timeout) vars["ulimit_shell"] = ulimitShell(limitCoredump, limitCputime, limitData, limitFileSize, limitLockedMemory, limitOpenFiles, limitUserProcesses, limitPhysicalMemory, limitStackSize) - vars["user"] = user + vars["user"] = processUser if fn, ok := formats[format]; ok { return fn(app, entries, formations, location, defaultPort, vars) From ab8aa2dbf08fe2a9a770d1a4c8b3fc11a1bf91ae Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 20:19:53 -0400 Subject: [PATCH 35/48] fix: set correct flag for home --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index d502d8d..ee11d45 100644 --- a/main.go +++ b/main.go @@ -551,7 +551,7 @@ func main() { formatExportFlag := exportCmd.String("", "format", &argparse.Options{Help: "format to export"}) formationExportFlag := exportCmd.String("", "formation", &argparse.Options{Default: "all=1", Help: "specify what processes will run and how many"}) groupExportFlag := exportCmd.String("", "group", &argparse.Options{Help: "group to run the command as"}) - homeExportFlag := exportCmd.String("", "group", &argparse.Options{Help: "home directory for program"}) + homeExportFlag := exportCmd.String("", "home", &argparse.Options{Help: "home directory for program"}) limitCoredumpExportFlag := exportCmd.String("", "limit-coredump", &argparse.Options{Help: "Largest size (in blocks) of a core file that can be created. (setrlimit RLIMIT_CORE)"}) limitCputimeExportFlag := exportCmd.String("", "limit-cputime", &argparse.Options{Help: "Maximum amount of cpu time (in seconds) a program may use. (setrlimit RLIMIT_CPU)"}) limitDataExportFlag := exportCmd.String("", "limit-data", &argparse.Options{Help: "Maximum data segment size (setrlimit RLIMIT_DATA)"}) From 7a5eba8379388702a775dc5cc4af0b625f4953c4 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 20:20:16 -0400 Subject: [PATCH 36/48] feat: set working directory to / by default --- main.go | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/main.go b/main.go index ee11d45..a6cdf83 100644 --- a/main.go +++ b/main.go @@ -516,12 +516,6 @@ func showCommand(entries []procfileEntry, envPath string, allowGetenv bool, proc } func main() { - workingDirectoryPath, err := os.Getwd() - if err != nil { - fmt.Fprintf(os.Stderr, "%s\n", err) - os.Exit(1) - } - parser := argparse.NewParser("procfile-util", "A procfile parsing tool") loglevelFlag := parser.Selector("l", "loglevel", []string{"info", "debug"}, &argparse.Options{Default: "info", Help: "loglevel to use"}) procfileFlag := parser.String("P", "procfile", &argparse.Options{Default: "Procfile", Help: "path to a procfile"}) @@ -565,7 +559,7 @@ func main() { logPathExportFlag := exportCmd.String("", "log-path", &argparse.Options{Default: "/var/log", Help: "log directory"}) niceExportFlag := exportCmd.String("", "nice", &argparse.Options{Help: "nice level to add to this program before running"}) prestartExportFlag := exportCmd.String("", "prestart", &argparse.Options{Help: "A command to execute before starting and restarting. A failure of this command will cause the start/restart to abort. This is useful for health checks, config tests, or similar operations."}) - workingDirectoryPathExportFlag := exportCmd.String("", "working-directory-path", &argparse.Options{Default: workingDirectoryPath, Help: "working directory path for app"}) + workingDirectoryPathExportFlag := exportCmd.String("", "working-directory-path", &argparse.Options{Default: "/", Help: "working directory path for app"}) runExportFlag := exportCmd.String("", "run", &argparse.Options{Help: "run pid file directory, defaults to /var/run/"}) timeoutExportFlag := exportCmd.Int("", "timeout", &argparse.Options{Default: 5, Help: "amount of time (in seconds) processes have to shutdown gracefully before receiving a SIGKILL"}) userExportFlag := exportCmd.String("", "user", &argparse.Options{Help: "user to run the command as"}) @@ -583,7 +577,7 @@ func main() { envPathShowFlag := showCmd.String("e", "env-file", &argparse.Options{Help: "path to a dotenv file"}) processTypeShowFlag := showCmd.String("p", "process-type", &argparse.Options{Help: "name of process to show", Required: true}) - if err = parser.Parse(os.Args); err != nil { + if err := parser.Parse(os.Args); err != nil { fmt.Fprintf(os.Stderr, "%s\n", parser.Usage(err)) os.Exit(1) return From 1754ce601b3abeeb948ca6bee318ee514aa9a857 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 20:37:39 -0400 Subject: [PATCH 37/48] fix: hyphen should be slash --- bindata.go | 24 +++++++++---------- templates/launchd/launchd.plist.tmpl | 4 ++-- templates/runit/log/run.tmpl | 2 +- .../systemd-user/default/program.service.tmpl | 4 ++-- .../systemd/default/program.service.tmpl | 4 ++-- templates/sysv/default/init.sh.tmpl | 2 +- templates/upstart/default/program.conf.tmpl | 4 ++-- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/bindata.go b/bindata.go index 5cf0840..328249c 100644 --- a/bindata.go +++ b/bindata.go @@ -86,7 +86,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _templatesLaunchdLaunchdPlistTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x54\x5f\x8f\x9a\x40\x10\x7f\xf7\x53\x4c\x89\x8f\x85\xd5\xb7\xe6\x82\x5c\xec\x69\x93\x4b\x8d\x92\x53\xdb\xf4\xc9\xec\xc1\x1c\xb7\x11\x76\xe9\xec\xa2\x25\x84\xef\xde\x80\x70\xe2\x29\x97\x3e\xf4\x6d\x32\xf9\xfd\x9b\x61\x16\xf7\xfe\x4f\x12\xc3\x01\x49\x0b\x25\x27\xd6\xd8\x19\x59\x80\x32\x50\xa1\x90\xd1\xc4\xda\x6e\xbe\xd9\x5f\xac\x7b\x6f\xe0\x7e\x9a\xad\x1e\x36\xbf\xfc\x39\xa4\xb1\xd0\x06\xfc\xed\xd7\xc5\xe3\x03\x58\x36\x63\xd3\x34\x8d\x91\xb1\xd9\x66\x06\xfe\xe2\x71\xbd\x81\xb1\x33\x62\x6c\xbe\xb4\xc0\x7a\x35\x26\xbd\x63\xec\x78\x3c\x3a\xbc\x42\x39\x81\x4a\x2a\xa0\x66\x3e\xa9\x14\xc9\xe4\x0b\xa1\x8d\x3d\x76\x46\x4e\x68\x42\xcb\x1b\xb8\x27\xf5\x8b\x38\xde\xc0\x0d\x45\x60\xbc\x01\x00\x80\xbb\xc7\xdc\x5b\xf0\x67\x8c\x5d\x56\x95\xa7\xa6\x36\x24\x64\xe4\x15\x05\x54\x3e\x50\x96\x76\x55\xa6\xa4\x02\xd4\x7a\x67\xf2\x14\xdb\x9e\xcc\x12\x28\x4b\x97\x35\x8c\xb3\xe6\x5c\x1e\x04\x29\x99\xa0\x34\x3f\x38\x09\xfe\x1c\xa3\xee\x5a\x9c\x23\xbc\x51\xfc\xd5\xd3\xa6\x03\x79\x9f\x24\x55\x64\xae\xbc\xce\xe4\xf5\x47\x54\x7d\x45\x2c\x0a\x1b\x88\xcb\x08\x61\xb8\xc7\xfc\x33\x0c\x0f\x3c\xce\x10\xee\x26\xe0\xa0\x3c\x40\x59\x5e\xca\x17\x45\x8d\xab\x65\xfa\x6c\x1a\x89\x8e\x53\x51\x00\xca\xb0\x15\x73\xd9\xbb\xbd\xfb\xa4\x22\xe2\xc9\x94\xa2\xac\xda\xd3\xc5\x7e\x38\x11\xcf\xaf\xa2\x06\x2a\x49\xb8\x0c\xeb\x98\x4d\xbd\xab\xbf\x70\x37\xef\xd9\x5c\xbc\x00\xfe\x3e\xb3\xac\x61\xb5\x62\x0b\xca\xb2\x4a\xdb\x2e\xb4\x0a\x19\x6b\x6c\xba\x2d\xf6\xd4\xaf\x8b\xde\x71\x3a\x19\xeb\x79\xbe\x23\xa6\xd3\x58\x1c\xb0\x3b\x88\xa1\x0c\x59\x07\xf4\x94\xc9\xa9\x59\x28\x1e\x7e\x04\x5a\x1b\x2e\x43\x4e\xe1\x2a\x33\x3e\x37\xaf\x3d\xb7\x19\xab\xa8\xbd\xc3\x7f\x3a\x53\x5b\x9b\x50\x65\xa6\xe2\xdd\xb8\xd8\xd6\x73\x4e\xa4\xe8\x3f\xbb\x22\x51\x8f\xeb\x56\x23\x2d\x79\x82\x3d\x66\x99\x46\xba\xfd\xc0\x7e\x2a\xda\x0b\x19\xcd\x04\x61\x60\x14\xe5\x3d\x02\xc7\x13\x6c\x17\xb6\xb8\x9b\x2f\x41\xbc\x80\x23\x45\x80\x6f\xdf\xb6\xd2\x5a\x8a\xa0\x89\xe5\x0a\x69\x30\x42\xaa\x15\x1b\x9c\xcb\x3a\xcd\xe6\x2c\xda\x0b\x77\x59\xfd\xdf\xf1\x06\x7f\x03\x00\x00\xff\xff\xff\x8f\x04\x0b\x0e\x05\x00\x00") +var _templatesLaunchdLaunchdPlistTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x54\x5f\x8f\x9a\x40\x10\x7f\xf7\x53\x4c\x89\x8f\x85\xd5\xb7\xe6\x82\x5c\xec\x69\x93\x4b\x8d\x92\x53\xdb\xf4\xc9\xec\xc1\x1c\xb7\x11\x76\xe9\xec\xa2\x25\x84\xef\xde\x80\x70\xe2\x29\x97\x3e\xf4\x6d\x32\xf9\xfd\x9b\x61\x16\xf7\xfe\x4f\x12\xc3\x01\x49\x0b\x25\x27\xd6\xd8\x19\x59\x80\x32\x50\xa1\x90\xd1\xc4\xda\x6e\xbe\xd9\x5f\xac\x7b\x6f\xe0\x7e\x9a\xad\x1e\x36\xbf\xfc\x39\xa4\xb1\xd0\x06\xfc\xed\xd7\xc5\xe3\x03\x58\x36\x63\xd3\x34\x8d\x91\xb1\xd9\x66\x06\xfe\xe2\x71\xbd\x81\xb1\x33\x62\x6c\xbe\xb4\xc0\x7a\x35\x26\xbd\x63\xec\x78\x3c\x3a\xbc\x42\x39\x81\x4a\x2a\xa0\x66\x3e\xa9\x14\xc9\xe4\x0b\xa1\x8d\x3d\x76\x46\x4e\x68\x42\xcb\x1b\xb8\x27\xf5\x8b\x38\xde\xc0\x0d\x45\x60\xbc\x01\x00\x80\xbb\xc7\xdc\x5b\xf0\x67\x8c\x5d\x56\x95\xa7\xa6\x36\x24\x64\xe4\x15\x05\x54\x3e\x50\x96\x76\x55\xa6\xa4\x02\xd4\x7a\x67\xf2\x14\xdb\x9e\xcc\x12\x28\x4b\x97\x35\x8c\xb3\xe6\x5c\x1e\x04\x29\x99\xa0\x34\x3f\x38\x09\xfe\x1c\xa3\xee\x5a\x9c\x23\xbc\x51\xfc\xd5\xd3\xa6\x03\x79\x9f\x24\x55\x64\xae\xbc\xce\xe4\xf5\x47\x54\x7d\x45\x2c\x0a\x1b\x88\xcb\x08\x61\xb8\xc7\xfc\x33\x0c\x0f\x3c\xce\x10\xee\x26\xe0\xa0\x3c\x40\x59\x5e\xca\x17\x45\x8d\xab\x65\xfa\x6c\x1a\x89\x8e\x53\x51\x00\xca\xb0\x15\x73\xd9\xbb\xbd\xfb\xa4\x22\xe2\xc9\x94\xa2\xac\xda\xd3\xc5\x7e\x38\x11\xcf\xaf\xa2\x06\x2a\x49\xb8\x0c\xeb\x98\x4d\xbd\xab\xbf\x70\x37\xef\xd9\x5c\xbc\x00\xfe\x3e\xb3\xac\x61\xb5\x62\x0b\xca\xb2\x4a\xdb\x2e\xb4\x0a\x19\x6b\x6c\xba\x2d\xf6\xd4\xaf\x8b\xde\x71\x3a\x19\xeb\x79\xbe\x23\xa6\xd3\x58\x1c\xb0\x3b\x88\xa1\x0c\x59\x07\xf4\x94\xc9\xa9\x59\x28\x1e\x7e\x04\x5a\x1b\x2e\x43\x4e\xe1\x2a\x33\x3e\x37\xaf\x3d\xb7\x19\xab\x08\xca\x92\xfd\xf3\x99\xda\xda\x84\x2a\x33\x15\xef\xc6\xc5\xb6\x9e\x73\x22\x45\xff\xd9\x15\x89\x7a\x5c\xb7\x1a\x69\xc9\x13\xec\x31\xcb\x34\xd2\xed\x07\xf6\x53\xd1\x5e\xc8\x68\x26\x08\x03\xa3\x28\xef\x11\x38\x9e\x60\xbb\xb0\xc5\xdd\x7c\x09\xe2\x05\x1c\x29\x02\x7c\xfb\xb6\x95\xd6\x52\x04\x4d\x2c\x57\x48\x83\x11\x52\xad\xd8\xe0\x5c\xd6\x69\x36\x67\xd1\x5e\xb8\xcb\xea\xff\x8e\x37\xf8\x1b\x00\x00\xff\xff\xff\xd0\xa2\x61\x0e\x05\x00\x00") func templatesLaunchdLaunchdPlistTmplBytes() ([]byte, error) { return bindataRead( @@ -101,12 +101,12 @@ func templatesLaunchdLaunchdPlistTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/launchd/launchd.plist.tmpl", size: 1294, mode: os.FileMode(420), modTime: time.Unix(1584486757, 0)} + info := bindataFileInfo{name: "templates/launchd/launchd.plist.tmpl", size: 1294, mode: os.FileMode(420), modTime: time.Unix(1584491772, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templatesRunitLogRunTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x8c\xcf\x0a\x82\x40\x10\x87\xef\xf3\x14\xbf\x2c\xbc\x6d\x46\x10\x9d\x3a\x7b\x11\x7c\x84\xa8\x75\x50\x49\xdd\xc5\x59\xfb\x83\xce\xbb\x87\xd0\x1e\xba\x7d\xcc\x37\xbf\x6f\xbb\xc9\xee\xed\x90\x49\x43\xc2\x01\x86\x89\x8a\x32\xbf\xcc\x33\xf6\x9d\xab\xa1\x6a\x56\xbc\x79\x1f\xd1\x8f\xce\xb2\xc8\x35\x7c\x3c\xc7\xdb\x30\xf5\x50\x25\x0a\x2c\x01\xa6\x42\xb2\x2b\xca\x3c\xc1\xb2\xa0\x7f\x54\xed\x08\xe3\x61\x7a\x1c\xcf\xa7\x43\x54\x69\x0a\xdb\xb8\xd7\x80\x75\x3e\x09\x8f\x50\xfd\x39\xe2\x37\x5b\xd8\xc6\xaf\xad\xe9\xef\x41\x9e\x9d\xab\x63\x9e\xbe\x01\x00\x00\xff\xff\x62\xdb\xaa\xfb\xba\x00\x00\x00") +var _templatesRunitLogRunTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x8c\xcf\x0a\x82\x40\x10\x87\xef\xf3\x14\xbf\x2c\xbc\x6d\x46\x10\x9d\x3a\x7b\x11\x7c\x84\xa8\x75\x50\x49\xdd\xc5\x59\xfb\x83\xce\xbb\xc7\x42\x1e\xba\x7d\xcc\x37\xbf\x6f\xbb\xc9\xee\xed\x90\x49\x43\xc2\x01\x86\x89\x8a\x32\xbf\xcc\x33\xf6\x9d\xab\xa1\x9a\x45\xbc\x79\x0f\x55\x13\xd1\x8f\xce\xb2\xc8\x35\x7c\x3c\xaf\xb7\x61\xea\xa1\x4a\x14\x58\x02\x4c\x85\x64\x57\x94\x79\x82\x65\x41\xff\xa8\xda\x11\xc6\xc3\xf4\x38\x9e\x4f\x87\x55\xa5\x29\x6c\xe3\x5e\x03\xe2\x7c\x12\x1e\xa1\xfa\x73\xc4\x6f\xb6\xb0\x8d\x8f\xad\xe9\xef\x41\x9e\x9d\xab\xd7\x3c\x7d\x03\x00\x00\xff\xff\x6a\x88\x64\xed\xba\x00\x00\x00") func templatesRunitLogRunTmplBytes() ([]byte, error) { return bindataRead( @@ -121,7 +121,7 @@ func templatesRunitLogRunTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/runit/log/run.tmpl", size: 186, mode: os.FileMode(420), modTime: time.Unix(1584486167, 0)} + info := bindataFileInfo{name: "templates/runit/log/run.tmpl", size: 186, mode: os.FileMode(420), modTime: time.Unix(1584491772, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -166,7 +166,7 @@ func templatesSystemdDefaultControlTargetTmpl() (*asset, error) { return a, nil } -var _templatesSystemdDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x92\x41\x6b\xdc\x30\x10\x85\xef\xfa\x15\x62\x49\xc9\xa5\x1b\x53\xe8\xa9\xe0\x5b\x36\x65\x69\x9a\x0d\x71\x96\x1c\x42\x58\x14\x69\xec\x88\xc8\x23\x33\x1a\x6f\xd6\x18\xfd\xf7\x22\x6d\xbd\x86\x6d\x7b\xe9\x6d\xfc\xe6\x9b\x67\xbd\x61\x9e\xb7\x68\xf9\x45\x8c\xe3\x52\xda\x5a\x5e\x19\x08\x9a\x6c\xc7\xd6\xa3\x8c\x51\x5c\xcf\x9f\xe5\x38\x9e\xb7\xc7\x51\x02\x9a\xc4\xdd\x2b\xe2\x4d\x9d\x11\xd5\x75\x32\xc6\x2b\x56\xd4\x00\x8b\x8a\x7d\xf7\xf4\x06\xb8\x45\x04\x30\x60\xca\x01\x82\x10\xcf\x15\xd0\xde\x6a\x78\x11\xdb\x00\x94\xc7\xfa\x00\x94\x9c\xbe\x93\xef\xbb\xac\x34\xa9\x4a\xd2\x93\xa7\x77\x8b\xcd\xb5\x25\xd0\xec\x69\xc8\xdd\x8f\xa3\xb8\x33\x93\x9a\xc8\x15\xee\x2d\x79\x6c\x01\xb9\xbc\xdf\x3c\x3c\x66\xb2\xf3\xc4\x7f\x34\xab\x63\x2b\x9c\x35\x6e\xac\x83\x72\x59\x00\xeb\xc2\x40\xad\x7a\xc7\xc5\x94\xe9\xdf\x64\x18\x82\xf6\x58\xdb\xa6\x98\xf3\xe7\x85\x92\xc2\x06\xe4\xc5\x3b\x0c\x9f\xe5\xc5\x5e\xb9\x1e\xe4\xb7\x52\x5e\x01\xee\xcf\xdf\xb3\x18\xc7\xcc\xc9\x18\xd3\xc3\x7e\xc3\x31\x2e\xc4\xbc\xe3\xd5\x01\x74\xc5\x8a\xb8\x2c\x5e\x2d\x16\xaf\x2a\xbc\xc9\xa5\xd3\xf2\x12\x0e\xa0\xe5\x52\xc9\xc5\x29\xd2\x42\xa6\x52\xfb\xb6\x55\x79\xf6\x52\x3c\x40\xc8\xa3\xca\x7d\xa8\x21\x4c\x9f\x15\xe8\xf2\xcb\xd7\x20\x2a\x56\x68\x14\x99\x35\x76\x3d\x97\xd8\x3b\x77\x92\x36\x3d\x27\x2d\xf9\x39\xdf\xc8\x18\x97\x73\xc8\x5c\x76\xe4\x35\x84\xb0\xe3\xa1\x83\x49\xc3\xbe\x4d\x65\x60\xe3\x7b\x4e\x73\x27\xbb\x15\x91\xa7\xff\x76\x03\xa2\xa3\xdb\x10\x9c\x6f\xd6\x06\x90\x6d\x6d\x81\xca\x4f\x28\x7e\x58\xe7\x7e\x7a\x03\x65\x6b\x0f\x60\xc4\xa3\x6d\xc1\xf7\x9c\xee\x2f\xa5\x4c\x3e\x7c\x94\xd2\x2e\x4f\xf7\x8e\x56\xa7\xff\x88\x3b\xab\x21\x43\x93\x30\xef\x7d\x42\x9d\x6d\x2d\xef\x7c\x07\xb8\xab\xad\x83\x7c\x3a\xb7\x49\xbb\xdb\xdc\xac\x6f\x57\xc7\x50\x7f\x61\x66\xa7\x5f\x01\x00\x00\xff\xff\x0e\xe4\xbe\x09\x6c\x03\x00\x00") +var _templatesSystemdDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x92\x41\x6b\x1b\x31\x10\x85\xef\xfa\x15\xc2\xa4\xe4\x52\x7b\x29\xf4\x54\xd8\x5b\x9c\x62\x9a\xc6\x21\x1b\x93\x43\x08\x46\x91\x66\x37\x22\xda\xd1\x32\x9a\x75\xbc\x2c\xfa\xef\x45\x72\xd7\x2e\x6e\x7b\xc9\x4d\x7a\xf3\xcd\x93\xde\x30\x4f\x1b\xb4\xfc\x2c\xc6\x71\x2e\x6d\x2d\x17\x06\x82\x26\xdb\xb1\xf5\x28\x63\x14\x57\xa7\x6b\x39\x8e\xe7\xe5\x71\x94\x80\x26\x71\x77\x8a\x78\x5d\x67\x44\x75\x9d\x8c\x71\xc1\x8a\x1a\x60\x51\xb1\xef\x1e\x5f\x01\x37\x88\x00\x06\x4c\x39\x40\x10\xe2\xa9\x02\xda\x59\x0d\xcf\x62\x13\x80\x72\x5b\x1f\x80\x92\xd3\x77\xf2\x7d\x97\x95\x26\x9d\x92\xf4\xe8\xe9\xcd\x62\x73\x65\x09\x34\x7b\x1a\x72\xf5\xfd\x20\x6e\xcd\xa4\x26\x72\x89\x3b\x4b\x1e\x5b\x40\x2e\xef\xd6\xf7\x0f\x99\xec\x3c\xf1\x5f\xc5\xea\x50\x0a\x67\x85\x6b\xeb\xa0\x9c\x17\xc0\xba\x30\x50\xab\xde\x71\x31\x65\xfa\x3f\x19\x86\xa0\x3d\xd6\xb6\x29\x4e\xf9\xf3\x40\x49\x61\x03\xf2\xe2\x0d\x86\xcf\xf2\x62\xa7\x5c\x0f\xf2\x5b\x29\x17\x80\xbb\xf3\xff\xcc\xc6\x31\x73\x32\xc6\xf4\xb1\xdf\x70\x8c\x33\x71\x9a\xf1\x72\x0f\xba\x62\x45\x5c\x16\x2f\x16\x8b\x17\x15\x5e\xe5\xdc\x69\x79\x09\x7b\xd0\x72\xae\xe4\xec\x18\x69\x26\xd3\x51\xfb\xb6\x55\xb9\xf7\x52\xdc\x43\xc8\xad\xca\xbd\xab\x21\x4c\xd7\x0a\x74\xf9\xe5\x6b\x10\x15\x2b\x34\x8a\xcc\x0a\xbb\x9e\x4b\xec\x9d\x3b\x4a\xeb\x9e\x93\x96\xfc\x9c\x6f\x64\x8c\x7f\x84\x9c\xe7\x07\xc9\x6b\x08\x61\xcb\x43\x07\x93\x86\x7d\x9b\x8e\x81\x8d\xef\x39\xf5\x1d\xed\x96\x44\x9e\x3e\xec\x06\x44\x07\xb7\x21\x38\xdf\xac\x0c\x20\xdb\xda\x02\x95\x9f\x50\xfc\xb0\xce\xfd\xf4\x06\xca\xd6\xee\xc1\x88\x07\xdb\x82\xef\x39\xed\x5f\x4a\x99\x7c\xf8\x20\xa5\x59\x1e\xf7\x1d\xad\x4e\xef\x88\x5b\xab\x21\x43\x93\x70\x9a\xfb\x84\x3a\xdb\x5a\xde\xfa\x0e\x70\x5b\x5b\x07\x79\x75\x6e\x92\x76\xbb\xbe\x5e\xdd\x2c\x0f\xa1\xfe\xc1\x9c\x9c\x7e\x05\x00\x00\xff\xff\xdd\xbc\x49\x0c\x6c\x03\x00\x00") func templatesSystemdDefaultProgramServiceTmplBytes() ([]byte, error) { return bindataRead( @@ -181,12 +181,12 @@ func templatesSystemdDefaultProgramServiceTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/systemd/default/program.service.tmpl", size: 876, mode: os.FileMode(420), modTime: time.Unix(1584486168, 0)} + info := bindataFileInfo{name: "templates/systemd/default/program.service.tmpl", size: 876, mode: os.FileMode(420), modTime: time.Unix(1584491772, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templatesSystemdUserDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x90\xb1\x8a\xe3\x30\x10\x86\x7b\x3d\x85\x9b\x2b\x63\x73\x70\xad\x9a\x23\x39\x48\x95\x23\xce\x92\x22\x84\x20\xa4\x89\x57\xac\x34\x12\xa3\x71\xb2\xc2\xf8\xdd\x17\xd9\x38\x61\x53\x6e\x37\xf3\xfd\xf3\xfd\xd8\x3a\xbd\xa1\xe5\xb3\x18\x86\x55\x65\xaf\x55\x6d\x20\x69\xb2\x91\x6d\xc0\x6a\x1c\xc5\xfa\xb9\xca\x61\x78\x8d\x87\xa1\x02\x34\xe5\xae\x12\xa7\x16\xe8\x66\x35\x9c\xc5\x31\xd0\x87\xc5\x6e\x6d\x09\x34\x07\xca\x93\x78\x9f\xe1\xc5\x2c\xb4\x58\x87\x1c\x41\x26\xeb\xa3\x03\xb1\xc1\x9b\xa5\x80\x1e\x90\xe5\xff\xdd\xfe\x30\x59\x31\x10\x97\xc3\x6f\x61\x3b\x47\xe9\x25\xf8\x67\x1d\xc8\x55\x89\xde\x83\x87\x6a\x1c\x9b\x5a\x07\xbc\xda\xae\x49\x39\x31\x78\xd3\xf4\x09\xa8\x79\xb8\x35\x3c\x5d\xb1\xf9\x04\xdd\xb2\x22\x9e\xba\x75\xf0\x5e\xcd\x3f\xb6\x87\x34\x61\xe5\xee\x2a\xa7\x65\x6d\x41\xcb\xdf\x7f\x92\x68\x59\xa1\x51\x64\xb6\x18\x7b\x96\xd8\x3b\xf7\x40\xbb\x9e\x0b\x2b\x75\x2e\x74\xd5\x38\x4e\x9f\xa6\x62\x5c\xc6\x48\x41\x43\x4a\x17\xce\x11\x16\x86\xbd\x2f\x63\x62\x13\x7a\x2e\xde\xa3\x6e\x43\x14\xe8\xc7\x6d\x40\x34\xb7\xe5\xe4\x42\xb7\x35\x80\x6c\xaf\x16\x48\xfe\x42\x21\x4e\x5b\x4c\xac\x9c\x3b\x8b\xa3\x42\x06\xf3\x37\x4b\xdf\x3b\xb6\xab\xf2\x5e\x35\x2b\xea\x80\xc5\x57\x00\x00\x00\xff\xff\xca\xbc\xfd\x10\x27\x02\x00\x00") +var _templatesSystemdUserDefaultProgramServiceTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x90\x31\x6b\xf3\x30\x10\x86\x77\xfd\x0a\x2f\xdf\x18\x9b\x0f\xba\x6a\x29\x49\x21\x53\x4a\x9c\x92\x21\x84\x20\xa4\x8b\x2b\x2a\x9d\xc4\xe9\x9c\x54\x18\xff\xf7\x22\x9b\x24\x34\x63\x37\xdd\xf3\xde\xf3\x72\xf6\xe1\x03\x2d\x1f\xc5\x30\x2c\x2a\x7b\xae\x6a\x03\x49\x93\x8d\x6c\x03\x56\xe3\x28\x96\x8f\x51\x0e\xc3\x73\x3c\x0c\x15\xa0\x29\x7b\x95\x38\xb4\x40\x17\xab\xe1\x28\xf6\x81\xbe\x2c\x76\x4b\x4b\xa0\x39\x50\x9e\xc4\xeb\x0c\x4f\xe6\x46\x8b\xb5\xcb\x11\x64\xb2\x3e\x3a\x10\x2b\xbc\x58\x0a\xe8\x01\x59\xbe\x6f\xb6\xbb\xc9\x8a\x81\xb8\x2c\xfe\x0a\xdb\x39\x4a\x4f\xc1\x9b\x75\x20\x17\x25\xfa\x0c\x1e\xaa\x71\x6c\x6a\x1d\xf0\x6c\xbb\x26\xe5\xc4\xe0\x4d\xd3\x27\xa0\xe6\xee\xd6\xf0\x70\xc5\xea\x1b\x74\xcb\x8a\x78\xea\xd6\xc1\x7b\x35\x7f\xd8\x16\xd2\x84\x95\xbb\xaa\x9c\x6e\x63\x0b\x5a\xfe\x7f\x49\xa2\x65\x85\x46\x91\x59\x63\xec\x59\x62\xef\xdc\x1d\x6d\x7a\x2e\xac\xd4\xb9\xd0\x95\x73\xca\x53\xc5\x58\x8d\xe3\x74\x65\xa4\xa0\x21\xa5\x13\xe7\x08\x37\x86\xbd\x2f\xcf\xc4\x26\xf4\x5c\xbc\x7b\xdd\x8a\x28\xd0\x9f\xdb\x80\x68\x6e\xcb\xc9\x85\x6e\x6d\x00\xd9\x9e\x2d\x90\xfc\x87\x42\x1c\xd6\x98\x58\x39\x77\x14\x7b\x85\x0c\xe6\x35\x4b\xdf\x3b\xb6\x8b\xf2\xbf\x6a\x56\xd4\x01\x8b\x9f\x00\x00\x00\xff\xff\xad\xa5\x8f\x08\x27\x02\x00\x00") func templatesSystemdUserDefaultProgramServiceTmplBytes() ([]byte, error) { return bindataRead( @@ -201,12 +201,12 @@ func templatesSystemdUserDefaultProgramServiceTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/systemd-user/default/program.service.tmpl", size: 551, mode: os.FileMode(420), modTime: time.Unix(1584489411, 0)} + info := bindataFileInfo{name: "templates/systemd-user/default/program.service.tmpl", size: 551, mode: os.FileMode(420), modTime: time.Unix(1584491772, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _templatesSysvDefaultInitShTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x57\x6d\x73\xdb\x36\x12\xfe\xce\x5f\xb1\xa1\x34\x76\x92\xd3\x8b\xed\x5c\xef\x66\x9c\x71\x7a\x69\xe3\xf6\x34\x4d\x6c\x8f\xa5\x4e\x6f\xa6\xed\x28\x10\xb1\x14\x71\x22\x01\x16\x00\x2d\xab\xb6\xfe\xfb\xcd\x02\x20\x45\xda\x52\x2f\xbd\xcb\x07\x47\x04\x76\x9f\x5d\xec\xcb\x83\x45\xef\xc5\x78\x21\xe4\xd8\x64\x51\x0f\x26\x52\x58\x30\x89\x16\xa5\x85\x54\x69\x78\x78\x80\x11\x2b\x4b\xd8\x6e\x87\xf4\xb3\xd4\x2a\x41\x63\xe6\x76\x53\x62\xbd\x26\xab\x02\xb6\xdb\xa8\x07\x9f\x98\x90\x96\x09\x89\x1c\x16\x1b\xd2\x14\x29\x8c\x58\x65\x33\xa5\x61\xbb\x75\x48\xad\x0f\x94\xdc\xab\x7d\x8f\x12\x35\xb3\x5e\xab\xcc\x91\x19\xd4\x95\x1c\x91\x33\x45\x99\x63\x81\xd2\xed\x31\x83\x1c\x94\x84\x8f\xd3\x6f\xe0\x5b\xa5\x11\xde\x8c\x4e\xcf\xa3\x1e\x00\xbc\x86\x29\x26\x56\x28\x69\xce\xe1\xec\x64\x74\x36\xa0\xbf\x6f\xa2\x5e\xd4\xeb\xf5\xe0\x9b\xcb\xef\x27\x57\x30\xb9\x9a\xcc\x60\x72\xf5\xdd\x75\xd4\x83\x1b\xad\xee\x04\x47\x73\x0e\xcd\xbf\x3f\x73\xca\x5b\xfc\xad\x12\x1a\xf9\x70\x6a\x99\xb6\x0e\xa4\xaf\xb1\x50\x16\xe7\xa9\x81\xbe\xd9\x98\x5c\x2d\xbb\x72\xaa\xf4\xb6\xf6\xca\x7d\xc0\x94\x55\xb9\x6d\xc1\xc1\x19\xbc\x81\xbf\xc2\x57\x9d\xcd\x1a\x03\x4e\xe0\x14\xfe\x16\xf5\x60\x9a\x29\x6d\x87\x1f\xd0\x27\x4b\x28\x79\x5e\x87\x5c\x49\x9c\xe7\x42\xe2\x9c\xef\x36\x43\x02\x0e\x6f\x35\xe9\xe8\x20\xee\xc2\xd3\x55\x70\xa1\xbd\xbc\xfa\xd0\x0a\x6c\x74\xf3\x7e\xf6\xcf\x8b\xb1\x59\x08\x79\x3e\xae\x8c\x0e\xbf\x9a\xcf\x85\x90\x11\xde\x97\x4a\x5b\x20\xc9\x28\x92\xac\xc0\x8b\x2f\x8f\x7c\xa9\xd5\x52\xb3\xe2\x22\x88\xd1\xef\xed\x36\x62\x7a\x69\x3c\x88\x5e\x9a\x39\x9a\x84\x95\xe8\x0e\x52\x0a\x9e\x8a\x1c\x2f\xe2\xf1\x1d\xd3\x63\x5d\xc9\x71\x9f\x0c\x8e\x4a\xc1\xe3\xa8\x32\xa8\x2f\x62\x52\xa3\x5f\xb0\xdd\xc6\xd1\x52\xab\xaa\xf4\x6b\xee\xa7\x5b\x4c\x32\xad\x94\xf5\xab\x6b\xa5\x57\x42\x2e\xe7\x5c\x68\x4c\xac\xd2\x9b\x20\xc1\x85\xfe\x23\x01\x29\x12\xf4\xfb\xf4\x8b\x56\x1e\x1e\x86\x2e\x4d\xb9\x28\x84\x9d\x27\x4a\x23\xaf\x0a\xb2\x17\x75\x57\xbc\xd6\x33\xa9\x78\x97\xac\x27\x48\x65\x65\x45\x81\x2d\x20\xbf\xd0\xc1\x69\x64\x0e\xc2\x70\x66\xd9\x0e\x83\xbe\xda\x00\x61\xf7\xa0\x36\xc5\x7c\x6e\xc4\xef\x2d\x37\x9a\xa5\x36\x4e\x5b\xee\x20\x58\xae\x92\x15\xf2\x79\x81\x85\x8f\x66\xb4\x67\xb9\x0d\xfa\x54\xfe\x20\xb0\x2a\x51\x3a\x17\xcc\x0e\x75\xb7\xd6\x86\xec\x48\x1e\xc4\xa3\x2a\x9a\x87\xda\x6d\x63\x76\xd7\xdb\xb8\xcf\x34\x0e\x62\x97\xd9\xc6\x88\x84\xe5\xcf\xc2\xf0\x64\xa3\x8d\xfe\x5c\xe7\x20\xbc\xb1\x2c\x59\x3d\xc9\xd8\x6e\xad\x0d\xda\x91\x6c\xe1\x11\x51\xa7\x60\x33\x61\x40\x18\x30\x68\xc1\x2a\x38\x1d\x80\xcd\x50\xc2\x9a\xfe\x7c\x36\x56\x95\x9f\x69\x37\x61\x79\x8e\x7c\x40\xf6\x6d\x86\x10\x02\x00\x19\x33\x51\x0f\xa4\xb2\x80\xf7\x82\xd8\x7e\x2d\x6c\x26\x24\x30\xd0\xc8\x8c\x92\x6c\x91\x23\x50\xe1\x0e\x60\x3a\xf9\xfe\x87\xc9\xc7\x8f\xb0\x16\x79\x0e\x0b\x04\x83\xd2\x82\xc4\x7b\x4b\x17\xc6\x2c\x43\xe0\x9e\x32\x61\x81\x19\xbb\x13\x4a\x93\x59\xab\xc0\x88\xa2\xcc\x37\x90\xab\x25\x30\x28\xd0\x18\xb6\x44\x88\x03\x91\x00\x39\x08\x29\x13\x39\xf2\xb7\x60\x2c\x61\xeb\x4a\x4a\x21\x97\x71\x44\xe6\xe6\xd7\x57\xf3\xe9\xec\xfa\x66\x3e\x9b\x7c\xba\xbc\xfe\x71\x76\x71\x42\xc7\xfe\x89\x0e\x97\x2b\xc6\x85\x5c\x36\x76\x99\xe4\x60\x36\x26\x51\x32\x15\x4b\x70\xa5\x33\x80\x35\x42\x65\x10\x3e\x53\x74\x86\xec\x33\x39\x54\xb0\x15\x46\x3d\x60\x79\x0e\x77\x4c\x0b\x3a\xa2\x01\x56\x59\x55\x30\x4b\xb9\xcb\x37\x20\xa4\x55\x80\xf2\x4e\x68\x25\xe9\x1a\xdc\x09\x8e\x22\x8f\x14\xfd\x0c\x43\x0d\x63\xb4\xc9\x38\xd8\x1f\xd7\x8c\x0a\xdb\x2d\xfc\x0a\x47\x47\x30\x3a\xb8\xdf\xd2\x6e\x3c\x1e\xef\x18\xb9\xa3\xbe\x4f\xc0\x39\xf1\x17\xd6\xd0\xfa\xf5\xed\xcc\xd3\x33\x7d\x6d\xb7\xcd\xfa\xd4\xaf\xba\xc6\x20\x9b\xbf\x43\xdc\x27\x36\x8c\xbd\x05\x47\x91\x27\x51\x64\x35\x4b\xf0\xe5\x2b\x78\x88\x80\xf2\xb4\x44\x0d\x43\x0b\xb1\x33\x2f\xa4\xb0\x23\x3e\xfe\xe2\xeb\x22\x86\xb8\xff\x8f\x38\xda\x46\x11\x16\xc2\x06\x50\x67\xc0\x6f\x00\x60\x92\xa9\x46\xc8\xd0\xe5\x1b\xa4\x1e\x1e\xc6\xaf\x61\x02\x5c\xb9\x82\xa4\xb4\x1d\x9b\xea\x18\x32\xd4\x48\x79\xd3\x95\x04\x66\x80\x01\x17\x69\x8a\x9a\xd2\xe2\x2e\x91\x05\x26\x8c\x84\xdb\x75\x4d\x8a\x91\xbf\x43\x8d\x65\x1b\x43\x8a\x6e\x9f\x91\xde\x00\x48\x83\x6a\x47\x55\x1a\xc2\x85\x45\x26\x12\xe5\xe6\x28\x2f\x2a\x38\xa8\xd4\xbb\x40\xfe\xd8\x0c\x03\x62\x5d\xbb\x6b\xa4\x42\x41\xc9\x91\x07\xff\x46\xf0\xb1\x4a\x56\x22\xdf\xb8\x26\x84\x63\x7f\x8d\x1d\x37\x1a\x4a\xc2\xf5\xf4\x5f\x03\xf8\x4e\x23\x7e\x33\xfd\x30\x70\x35\xfb\x51\xc8\xea\x3e\x40\x53\x51\x9a\xaa\x74\xd9\x33\x6b\x61\x93\x8c\xbc\xa4\x63\x1a\x27\x2b\x2c\x08\x79\xa7\x56\x68\x00\xef\x31\xb9\x43\x10\x45\x81\x5c\x30\x8b\xf9\x06\x58\x6a\x51\x83\x37\x2a\xe4\x72\x04\xaf\xc7\x94\x78\x80\x1e\x5c\x4a\x53\x69\x1f\x23\xea\xc4\xdd\x55\xe9\x99\xa3\x2a\x21\x51\x9a\xd6\xf2\xcd\x28\x02\xa2\x89\x9f\xe1\x05\x0c\x39\x78\x1e\x52\x4b\x70\xb9\xfd\xf5\xad\x67\x17\xe7\x6e\xb1\xe2\x42\x77\x05\xdc\x7a\x92\xa9\xb5\x84\xb8\x4f\x6e\xc7\xe7\x71\xdf\x5d\xeb\xf1\x5e\xc1\x42\x71\xf8\xfb\x57\x5f\x3d\xdb\x4b\x45\xe4\x0a\xc2\x13\x66\xa9\xd1\xd5\x09\x95\x71\xf0\x2d\xee\xdf\xdc\x5e\x4e\x67\xef\x6f\x67\x31\xbc\xb8\x80\x58\x2a\xaa\x69\xef\x9d\xc3\x76\xdc\xd8\x28\x12\xc3\x98\x01\xb0\x85\x0b\x2c\x2d\x8d\x22\x9f\xca\x20\xf0\xf8\x08\x1a\x6d\xa5\x25\xf4\xbf\xf6\xf6\xdd\xf4\x55\x33\x2d\xe1\x4d\x5d\x98\x98\xdc\xb4\x99\x81\xe5\x60\x6c\x95\xa6\xb0\xc0\x54\x69\xcc\x98\xe4\x5e\x93\xfc\xae\x02\x7f\x67\x98\xe7\x61\x0e\x7c\xbe\xd4\x36\x71\x5b\xc9\xba\x8c\xa9\x5e\x5e\xb4\x62\x40\xbd\x0a\xdb\xad\xfb\x6f\x28\xeb\x3e\xde\xe9\x43\xc8\x3b\x0c\x87\xae\x5c\x4a\x4c\xf6\xa4\xa0\xef\x85\x62\x30\x19\x0c\x13\xf0\x69\xf8\x1f\xbc\x75\xd9\xe3\xf0\x0b\x01\x72\xa1\x7f\xf1\x40\x54\x92\xb4\x16\xdc\xff\x25\x86\x3e\x4d\x87\x11\x40\x0c\xef\xde\x41\x9d\xe3\xc0\x17\x5f\x44\x27\x43\x63\xb9\xaa\xac\xd3\x3b\xfb\x3f\x30\x50\x6b\xa7\x77\xe4\x03\x5d\x3f\x7d\xea\x4e\x77\x04\x90\x6a\x55\x38\xb6\x19\x51\xed\xb8\xee\x36\x16\x19\x87\x82\x71\x2f\x99\x2a\xbd\x42\x5e\xb3\x8c\x43\x5a\xd6\x48\xc2\x51\x84\xc6\xe6\x82\x64\xe0\x58\x2f\x51\x92\x0b\x37\xbd\x2f\xd0\xae\x11\x65\xc7\xe6\x5a\x0b\x6a\x55\x07\x45\x0d\xce\x1a\x0a\x2b\x95\x31\x62\x41\x5d\x6d\x68\xba\x75\x8f\x42\x63\x99\xad\xcc\xa8\x26\xd1\xfe\x0b\x78\x07\xfd\x00\x45\x07\x23\xca\xa5\xd2\x60\x05\xfa\x2a\x47\x4e\x99\x09\x95\x7d\xe2\x09\x57\x95\x81\x6f\x7b\x30\xd3\x1b\x60\x90\xe2\xda\xdd\xf1\xee\xba\x5e\x91\xf7\xb3\xcb\xdb\x4f\xed\x42\xf4\x5d\xe7\xad\xb7\x9b\xac\x14\xfc\xa2\xff\x32\x61\x64\x34\xb8\x11\xbf\x72\x3b\x81\xf1\x7f\x10\x79\x4e\xce\x7b\x97\x5e\x12\xa7\x92\xe0\x2b\x37\x67\xd0\x48\x41\x96\x7c\xf1\x38\xc3\x43\x67\x99\x44\x42\x13\xff\xc4\x84\x7f\x0f\x0b\x37\xdd\xd0\x94\xe2\x3b\xd7\xad\x81\x90\x70\x5a\xbf\xda\xe0\x2d\x70\x15\x78\x34\x98\x27\xed\xbd\xe6\xad\x02\x2e\x70\x34\x1a\xc5\xbb\x5b\x82\xce\xf6\xf8\x08\x0b\x8d\x6c\x55\xaf\xe6\x88\x25\x9c\xba\x2f\xae\xa4\xbf\x00\xf6\x46\xa2\xa1\xa5\x7d\x43\x4b\x0c\x43\xfc\x0d\x4e\xbb\x04\xd5\x72\x73\x26\x0a\x54\x95\xa5\x99\x2b\xc9\x90\x8f\xe0\xbf\x86\x8d\xac\x8c\x00\x66\x34\xfb\x15\x6c\x03\x1a\x0d\x8d\x40\x42\x82\x7b\x27\xe4\xca\x98\xe6\x68\x75\x68\xdd\xf4\xd6\x84\xd6\xf5\x6b\xab\x5c\x48\x26\xcc\x7f\x8d\x81\x1a\x01\x73\x83\x7b\x95\x0e\x4f\x6f\x8d\xae\x63\xd2\x0e\xc4\x53\x80\x12\x79\x90\x76\xb2\xa9\x08\x73\x81\xad\x4c\x28\x54\x17\xda\x61\xda\x2a\xb2\x6e\x28\x0f\x97\xa1\x48\xa1\x34\x30\x2c\xdd\xb9\xe1\x1d\x8c\x39\xde\x8d\x65\x95\xe7\x70\xd6\xfe\xe8\xa4\xa5\xd7\xb4\xe0\x62\xe3\xa7\x6b\xd2\x15\xa6\x39\x5a\x23\x37\xb1\x2e\xf8\x34\x1d\x2c\xb0\x9e\x25\x06\xb0\xa8\x88\x0a\x98\x3d\x36\xb0\xce\x98\x85\x8d\xaa\x60\x89\xd6\xc7\xf6\xdf\x95\xb1\x75\xf7\x9b\x1d\xd4\xec\xfa\xc3\xf5\x4b\x23\x8c\xc1\xfc\xd5\x39\x7c\x9b\x61\xb2\xf2\xb3\x3a\x99\x0f\xee\x18\xc4\xc2\xf5\xe8\xc2\xb3\x91\xa1\x08\x86\xc1\x46\x49\x84\x35\x36\x70\x78\x5f\x62\x62\x47\x30\xb1\xc7\x9c\xc4\xdd\xb5\x61\x95\x1b\xaa\x52\x7a\xad\x39\x9e\xf3\xae\xfa\xef\x8a\x5e\x43\xc4\x6f\x83\xf0\x1c\xc0\x64\xd0\xc0\x19\x45\xfd\x47\x83\xb3\xa1\x1f\xbf\x55\xc2\x22\xb0\xf5\x6a\xcd\x34\xaf\x61\xdd\xd8\xe4\x5e\x1a\x06\xeb\x73\x35\xc4\xf3\xa4\x04\xc2\xfa\x99\x8f\xb5\x1b\x8d\x84\x01\x4e\x5c\x4b\x1e\x51\xbc\x1d\x3b\xe2\xbd\x30\xd6\xec\x6a\xa3\x81\x08\x00\x6f\xba\x00\xe4\x78\x48\x52\x53\x48\xa9\xd2\x09\xce\x5b\xac\xb7\xb7\x7d\x69\x3f\x6a\xf1\xc0\xd1\x51\xa7\x69\xf6\xd4\x96\x47\xdf\x37\xa1\xd4\xbf\x9b\xa9\xb6\xbb\x1d\xd5\x46\x2e\xfa\x5f\x47\x75\x71\xf7\x83\xdd\xe1\xd2\xc2\x49\xb7\xb8\x7d\xbb\xdc\xd4\x08\x89\x2a\x0a\xba\x28\x7c\xd7\xf9\x9a\x4a\x14\xc7\x1a\xc2\xdd\x5d\x54\x71\x6b\x61\x32\xf7\xfe\x5a\x89\x32\x70\x79\x17\x62\xe0\x9e\x8c\xf5\x18\x75\x21\x15\xa5\x70\x43\x55\xdc\x9a\x6f\x46\x71\x3d\x0d\xd5\xe3\x91\x37\x13\xd1\x73\xb6\x99\x5d\x28\xe7\x10\xf7\x4f\x63\x10\xe4\xb4\x8b\xf9\xd0\x19\x7b\xac\xff\xaa\xf2\xb1\x5e\x56\xe5\x63\x70\xa5\x73\x57\xbc\xb7\x16\x8b\xd2\xf1\xf5\x71\xff\xf4\x98\x86\xe5\x2f\x7f\x75\x38\xa0\xb7\x6f\x23\x34\x2c\xf9\x23\x7f\xbc\xc5\xd6\xa1\x77\x83\x4b\xdc\x3f\x89\xfd\xad\x59\x83\x01\xb4\x74\xc2\xb9\xdd\xe4\xa3\x38\x5e\xb8\x39\xb1\x4e\x9f\xcb\x00\x91\xfc\x49\x3d\x22\xef\x21\x3b\x61\x80\xe5\x1a\x19\xdf\xec\xde\xb8\x41\xea\x5e\x58\x0f\xf2\xb4\x53\x76\xfe\xd4\x52\x5f\x47\x2d\x5a\x0d\x4e\xaa\xf2\x95\xe7\x62\xf7\xbd\x8b\xf3\x2b\xd8\x95\x7f\x73\x20\x5b\x99\x3f\x79\x22\xf8\xa3\x23\x75\x8e\x72\x80\xe6\xbb\xbd\x19\xb7\x4f\xf0\xe4\xe8\xce\xc9\x4e\x75\x3c\x6d\xb1\xed\xf6\xcb\x1e\x00\xdd\xe1\xbe\x1b\xbb\xee\x20\xeb\xa2\x73\x74\xf4\x34\xf7\xaf\xbd\x7d\xff\x5c\xfd\xd1\xb0\x25\x9e\x43\x7f\xfa\xed\xed\xe4\x66\x76\xf5\xfe\xd3\x25\x3c\xf8\xd2\xee\x16\x7b\xab\xcc\xdb\x9b\xaa\x7c\xf4\xd1\xae\x2b\x7f\x1b\xc3\xbb\xa3\xb3\x5d\x04\xde\x44\xad\xf2\xad\x9d\xfd\x4f\x00\x00\x00\xff\xff\x93\x92\x86\x60\x20\x18\x00\x00") +var _templatesSysvDefaultInitShTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x57\x6d\x73\xdb\xb8\x11\xfe\xce\x5f\xb1\xa1\x34\x76\x9c\xea\xc5\x76\x7a\xed\x8c\x33\xce\x35\x2f\xbe\x54\x73\x89\xed\xb1\x74\x73\x9d\xb9\xdc\x28\x10\xb1\x14\x51\x91\x00\x03\x80\x96\x75\x36\xff\x7b\x67\x01\x92\x22\x6d\x29\xcd\xb5\xf9\xe0\x88\xc0\xee\xb3\x8b\x7d\x79\xb0\xe8\x3d\x1b\x2f\x84\x1c\x9b\x24\xe8\xc1\x44\x0a\x0b\x26\xd2\x22\xb7\x10\x2b\x0d\xf7\xf7\x30\x62\x79\x0e\x65\x39\xa4\x9f\xb9\x56\x11\x1a\x33\xb7\x9b\x1c\xeb\x35\x59\x64\x50\x96\x41\x0f\x3e\x31\x21\x2d\x13\x12\x39\x2c\x36\xa4\x29\x62\x18\xb1\xc2\x26\x4a\x43\x59\x3a\xa4\xd6\x07\x4a\xee\xd5\x3e\xa0\x44\xcd\xac\xd7\xca\x53\x64\x06\x75\x21\x47\xe4\x4c\x96\xa7\x98\xa1\x74\x7b\xcc\x20\x07\x25\xe1\xe3\xf4\x2d\xbc\x53\x1a\xe1\xe5\xe8\xe4\x2c\xe8\x01\xc0\x0b\x98\x62\x64\x85\x92\xe6\x0c\x4e\x8f\x47\xa7\x03\xfa\xfb\x32\xe8\x05\xbd\x5e\x0f\xde\x5e\x7c\x98\x5c\xc2\xe4\x72\x32\x83\xc9\xe5\x4f\x57\x41\x0f\xae\xb5\xba\x15\x1c\xcd\x19\x34\xff\xfe\xcc\x29\x6f\xf0\x6b\x21\x34\xf2\xe1\xd4\x32\x6d\x1d\x48\x5f\x63\xa6\x2c\xce\x63\x03\x7d\xb3\x31\xa9\x5a\x76\xe5\x54\xee\x6d\xed\x94\x7b\x8f\x31\x2b\x52\xdb\x82\x83\x53\x78\x09\x7f\x85\x1f\x3a\x9b\x35\x06\x1c\xc3\x09\xfc\x2d\xe8\xc1\x34\x51\xda\x0e\xdf\xa3\x4f\x96\x50\xf2\xac\x0e\xb9\x92\x38\x4f\x85\xc4\x39\xdf\x6e\x56\x09\xd8\xbf\xd5\xa4\xa3\x83\xb8\x0d\x4f\x57\xc1\x85\xf6\xe2\xf2\x7d\x2b\xb0\xc1\xf5\x9b\xd9\x3f\xcf\xc7\x66\x21\xe4\xd9\xb8\x30\xba\xfa\xd5\x7c\x2e\x84\x0c\xf0\x2e\x57\xda\x02\x49\x06\x81\x64\x19\x9e\x7f\x7f\xe4\x73\xad\x96\x9a\x65\xe7\x95\x18\xfd\x2e\xcb\x80\xe9\xa5\xf1\x20\x7a\x69\xe6\x68\x22\x96\xa3\x3b\x48\x2e\x78\x2c\x52\x3c\x0f\xc7\xb7\x4c\x8f\x75\x21\xc7\x7d\x32\x38\xca\x05\x0f\x83\xc2\xa0\x3e\x0f\x49\x8d\x7e\x41\x59\x86\xc1\x52\xab\x22\xf7\x6b\xee\xa7\x5b\x8c\x12\xad\x94\xf5\xab\x6b\xa5\x57\x42\x2e\xe7\x5c\x68\x8c\xac\xd2\x9b\x4a\x82\x0b\xfd\x2d\x01\x29\x22\xf4\xfb\xf4\x8b\x56\xee\xef\x87\x2e\x4d\xa9\xc8\x84\x9d\x47\x4a\x23\x2f\x32\xb2\x17\x74\x57\xbc\xd6\x13\xa9\x70\x9b\xac\x47\x48\x79\x61\x45\x86\x2d\x20\xbf\xd0\xc1\x69\x64\xf6\xc2\x70\x66\xd9\x16\x83\xbe\xda\x00\xd5\xee\x5e\x6d\x8a\xf9\xdc\x88\x3f\x5a\x6e\x34\x4b\x6d\x9c\xb6\xdc\x5e\xb0\x54\x45\x2b\xe4\xf3\x0c\x33\x1f\xcd\x60\xc7\x72\x1b\xf4\xb1\xfc\x5e\x60\x95\xa3\x74\x2e\x98\x2d\xea\x76\xad\x0d\xd9\x91\xdc\x8b\x47\x55\x34\xaf\x6a\xb7\x8d\xd9\x5d\x6f\xe3\x3e\xd1\xd8\x8b\x9d\x27\x1b\x23\x22\x96\x3e\x09\xc3\xa3\x8d\x36\xfa\x53\x9d\xbd\xf0\xc6\xb2\x68\xf5\x28\x63\xdb\xb5\x36\x68\x47\xb2\x85\x47\x44\x1d\x83\x4d\x84\x01\x61\xc0\xa0\x05\xab\xe0\x64\x00\x36\x41\x09\x6b\xfa\xf3\xc5\x58\x95\x7f\xa1\xdd\x88\xa5\x29\xf2\x01\xd9\xb7\x09\x42\x15\x00\x48\x98\x09\x7a\x20\x95\x05\xbc\x13\xc4\xf6\x6b\x61\x13\x21\x81\x81\x46\x66\x94\x64\x8b\x14\x81\x0a\x77\x00\xd3\xc9\x87\x9f\x27\x1f\x3f\xc2\x5a\xa4\x29\x2c\x10\x0c\x4a\x0b\x12\xef\x2c\x5d\x18\xb3\x04\x81\x7b\xca\x84\x05\x26\xec\x56\x28\x4d\x66\xad\x02\x23\xb2\x3c\xdd\x40\xaa\x96\xc0\x20\x43\x63\xd8\x12\x21\xac\x88\x04\xc8\x41\x88\x99\x48\x91\xbf\x02\x63\x09\x5b\x17\x52\x0a\xb9\x0c\x03\x32\x37\xbf\xba\x9c\x4f\x67\x57\xd7\xf3\xd9\xe4\xd3\xc5\xd5\x2f\xb3\xf3\x63\x3a\xf6\xaf\x74\xb8\x54\x31\x2e\xe4\xb2\xb1\xcb\x24\x07\xb3\x31\x91\x92\xb1\x58\x82\x2b\x9d\x01\xac\x11\x0a\x83\xf0\x85\xa2\x33\x64\x5f\xc8\xa1\x8c\xad\x30\xe8\x01\x4b\x53\xb8\x65\x5a\xd0\x11\x0d\xb0\xc2\xaa\x8c\x59\xca\x5d\xba\x01\x21\xad\x02\x94\xb7\x42\x2b\x49\xd7\xe0\x56\x70\x14\x78\xa4\xe0\x37\x18\x6a\x18\xa3\x8d\xc6\x95\xfd\x71\xcd\xa8\x50\x96\xf0\x3b\x1c\x1c\xc0\x68\xef\x7e\x4b\xbb\xf1\x78\xbc\x65\xe4\x8e\xfa\x2e\x01\xe7\xc4\x5f\x58\x43\xeb\x57\x37\x33\x4f\xcf\xf4\x55\x96\xcd\xfa\xd4\xaf\xba\xc6\x20\x9b\x7f\x40\xd8\x27\x36\x0c\xbd\x05\x47\x91\xc7\x41\x60\x35\x8b\xf0\xf9\x11\xdc\x07\x40\x79\x5a\xa2\x86\xa1\x85\xd0\x99\x17\x52\xd8\x11\x1f\x7f\xf7\x75\x11\x42\xd8\xff\x47\x18\x94\x41\x80\x99\xb0\x15\xa8\x33\xe0\x37\x00\x30\x4a\x54\x23\x64\xe8\xf2\xad\xa4\xee\xef\xc7\x2f\x60\x02\x5c\xb9\x82\xa4\xb4\x1d\x9a\xe2\x10\x12\xd4\x48\x79\xd3\x85\x04\x66\x80\x01\x17\x71\x8c\x9a\xd2\xe2\x2e\x91\x05\x46\x8c\x84\xdb\x75\x4d\x8a\x81\xbf\x43\x8d\x65\x1b\x43\x8a\x6e\x9f\x91\xde\x00\x48\x83\x6a\x47\x15\x1a\xaa\x0b\x8b\x4c\x44\xca\xcd\x51\x5e\x54\x70\x50\xb1\x77\x81\xfc\xb1\x09\x56\x88\x75\xed\xae\x91\x0a\x05\x25\x47\x5e\xf9\x37\x82\x8f\x45\xb4\x12\xe9\xc6\x35\x21\x1c\xfa\x6b\xec\xb0\xd1\x50\x12\xae\xa6\xff\x1a\xc0\x4f\x1a\xf1\xed\xf4\xfd\xc0\xd5\xec\x47\x21\x8b\xbb\x0a\x9a\x8a\xd2\x14\xb9\xcb\x9e\x59\x0b\x1b\x25\xe4\x25\x1d\xd3\x38\x59\x61\x41\xc8\x5b\xb5\x42\x03\x78\x87\xd1\x2d\x82\xc8\x32\xe4\x82\x59\x4c\x37\xc0\x62\x8b\x1a\xbc\x51\x21\x97\x23\x78\x31\xa6\xc4\x03\xf4\xe0\x42\x9a\x42\xfb\x18\x51\x27\x6e\xaf\x4a\xcf\x1c\x45\x0e\x91\xd2\xb4\x96\x6e\x46\x01\x10\x4d\xfc\x06\xcf\x60\xc8\xc1\xf3\x90\x5a\x82\xcb\xed\xef\xaf\x3c\xbb\x38\x77\xb3\x15\x17\xba\x2b\xe0\xd6\xa3\x44\xad\x25\x84\x7d\x72\x3b\x3c\x0b\xfb\xee\x5a\x0f\x77\x0a\x66\x8a\xc3\xdf\x7f\xf8\xe1\xc9\x5e\x2c\x02\x57\x10\x9e\x30\x73\x8d\xae\x4e\xa8\x8c\x2b\xdf\xc2\xfe\xf5\xcd\xc5\x74\xf6\xe6\x66\x16\xc2\xb3\x73\x08\xa5\xa2\x9a\xf6\xde\x39\x6c\xc7\x8d\x8d\x22\x31\x8c\x19\x00\x5b\xb8\xc0\xd2\xd2\x28\xf0\xa9\xac\x04\x1e\x1e\x40\xa3\x2d\xb4\x84\xfe\x8f\xde\xbe\x9b\xbe\x6a\xa6\x25\xbc\xa9\x0b\x13\x93\x9b\x36\x33\xb0\x14\x8c\x2d\xe2\x18\x16\x18\x2b\x8d\x09\x93\xdc\x6b\x92\xdf\x45\xc5\xdf\x09\xa6\x69\x35\x07\x3e\x5d\x6a\x9b\xb8\x29\x64\x5d\xc6\x54\x2f\xcf\x5a\x31\xa0\x5e\x85\xb2\x74\xff\x0d\x65\xdd\xc7\x5b\x7d\xa8\xf2\x0e\xc3\xa1\x2b\x97\x1c\xa3\x1d\x29\xe8\x7b\xa1\x10\x4c\x02\xc3\x08\x7c\x1a\xfe\x07\x6f\x5d\xf6\x38\x7c\x26\x40\x2e\xf4\x67\x0f\x44\x25\x49\x6b\x95\xfb\x9f\x43\xe8\xd3\x74\x18\x00\x84\xf0\xfa\x35\xd4\x39\x2e\xcb\xef\xa7\x93\xa1\xb1\x5c\x15\xd6\xe9\x9d\xfe\x1f\x18\xa8\xb5\xd3\x3b\xf0\x81\xae\x9f\x3e\x75\xa7\x3b\x02\x88\xb5\xca\x1c\xdb\x8c\xa8\x76\x5c\x77\x1b\x8b\x8c\x43\xc6\xb8\x97\x8c\x95\x5e\x21\xaf\x59\xc6\x21\x2d\x6b\x24\xe1\x28\x42\x63\x73\x41\x32\x70\xac\x17\x29\xc9\x85\x9b\xde\x17\x68\xd7\x88\xb2\x63\x73\xad\x05\xb5\xaa\x83\xa2\x06\x67\x0d\x85\xe5\xca\x18\xb1\xa0\xae\x36\x34\xdd\xba\x47\xa1\xb1\xcc\x16\x66\x54\x93\x68\xff\x19\xbc\x86\x7e\x05\x45\x07\x23\xca\xa5\xd2\x60\x19\xfa\x2a\x47\x4e\x99\xa9\x2a\xfb\xd8\x13\xae\xca\x2b\xbe\xed\xc1\x4c\x6f\x80\x41\x8c\x6b\x77\xc7\xbb\xeb\x7a\x45\xde\xcf\x2e\x6e\x3e\xb5\x0b\xd1\x77\x9d\xb7\xde\x6e\xb2\x5c\xf0\xf3\xfe\xf3\x88\x91\xd1\xca\x8d\xf0\xc8\xed\x54\x8c\xff\xb3\x48\x53\x72\xde\xbb\xf4\x9c\x38\x95\x04\x8f\xdc\x9c\x41\x23\x05\x59\xf2\xc5\xe3\x0c\x0f\x9d\x65\x12\xa9\x9a\xf8\x57\x26\xfc\x7b\x58\xb8\xe9\x86\xa6\x14\xdf\xb9\x6e\x0d\x84\x84\x93\xfa\xd5\x06\xaf\x80\xab\x8a\x47\x2b\xf3\xa4\xbd\xd3\xbc\x55\xc0\x05\x8e\x46\xa3\x70\x7b\x4b\xd0\xd9\x1e\x1e\x60\xa1\x91\xad\xea\xd5\x14\x31\x87\x13\xf7\xc5\x95\xf4\x17\xc0\xce\x48\x34\xb4\xb4\x6b\x68\x09\x61\x88\x5f\xe1\xa4\x4b\x50\x2d\x37\x67\x22\x43\x55\x58\x9a\xb9\xa2\x04\xf9\x08\xfe\x6b\xd8\xc8\xca\x08\x60\x46\xb3\x5f\xc6\x36\xa0\xd1\xd0\x08\x24\x24\xb8\x77\x42\xaa\x8c\x69\x8e\x56\x87\xd6\x4d\x6f\x4d\x68\x5d\xbf\xb6\xca\x85\x64\xaa\xf9\xaf\x31\x50\x23\x60\x6a\x70\xa7\xd2\xfe\xe9\xad\xd1\x75\x4c\xda\x81\x78\x0c\x90\x23\xaf\xa4\x9d\x6c\x2c\xaa\xb9\xc0\x16\xa6\x2a\x54\x17\xda\x61\xdc\x2a\xb2\x6e\x28\xf7\x97\xa1\x88\x21\x37\x30\xcc\xdd\xb9\xe1\x35\x8c\x39\xde\x8e\x65\x91\xa6\x70\xda\xfe\xe8\xa4\xa5\xd7\xb4\xe0\x62\xe3\xa7\x6b\xd2\x15\xa6\x39\x5a\x23\x37\xb1\x2e\xf8\x34\x1d\x2c\xb0\x9e\x25\x06\xb0\x28\x88\x0a\x98\x3d\x34\xb0\x4e\x98\x85\x8d\x2a\x60\x89\xd6\xc7\xf6\xdf\x85\xb1\x75\xf7\x9b\x2d\xd4\xec\xea\xfd\xd5\x73\x23\x8c\xc1\xf4\xe8\x0c\xde\x25\x18\xad\xfc\xac\x4e\xe6\x2b\x77\x0c\x62\xe6\x7a\x74\xe1\xd9\xc8\x50\x04\xab\xc1\x46\x49\x84\x35\x36\x70\x78\x97\x63\x64\x47\x30\xb1\x87\x9c\xc4\xdd\xb5\x61\x95\x1b\xaa\x62\x7a\xad\x39\x9e\xf3\xae\xfa\xef\x82\x5e\x43\xc4\x6f\x83\xea\x39\x80\xd1\xa0\x81\x33\x8a\xfa\x8f\x06\x67\x43\x3f\xbe\x16\xc2\x22\xb0\xf5\x6a\xcd\x34\xaf\x61\xdd\xd8\xe4\x5e\x1a\x06\xeb\x73\x35\xc4\xf3\xa8\x04\xaa\xf5\x53\x1f\x6b\x37\x1a\x09\x03\x9c\xb8\x96\x3c\xa2\x78\x3b\x76\xc4\x3b\x61\xac\xd9\xd6\x46\x03\x51\x01\xbc\xec\x02\x90\xe3\x55\x92\x9a\x42\x8a\x95\x8e\x70\xde\x62\xbd\x9d\xed\x4b\xfb\x41\x8b\x07\x0e\x0e\x3a\x4d\xb3\xa3\xb6\x3c\xfa\xae\x09\xa5\xfe\xdd\x4c\xb5\xdd\xed\xa0\x36\x72\xde\xff\x31\xa8\x8b\xbb\x5f\xd9\x1d\x2e\x2d\x1c\x77\x8b\xdb\xb7\xcb\x75\x8d\x10\xa9\x2c\xa3\x8b\xc2\x77\x9d\xaf\xa9\x48\x71\xac\x21\xdc\xdd\x45\x15\xb7\x16\x26\x71\xef\xaf\x95\xc8\x2b\x2e\xef\x42\x0c\xdc\x93\xb1\x1e\xa3\xce\xa5\xa2\x14\x6e\xa8\x8a\x5b\xf3\xcd\x28\xac\xa7\xa1\x7a\x3c\xf2\x66\x02\x7a\xce\x36\xb3\x0b\xe5\x1c\xc2\xfe\x49\x08\x82\x9c\x76\x31\x1f\x3a\x63\x0f\xf5\x5f\x95\x3f\xd4\xcb\x2a\x7f\xa8\x5c\xe9\xdc\x15\x6f\xac\xc5\x2c\x77\x7c\x7d\xd8\x3f\x39\xa4\x61\xf9\xfb\x5f\x1d\x0e\xe8\xd5\xab\x00\x0d\x8b\xbe\xe5\x8f\xb7\xd8\x3a\xf4\x76\x70\x09\xfb\xc7\xa1\xbf\x35\x6b\x30\x80\x96\x4e\x75\x6e\x37\xf9\x28\x8e\xe7\x6e\x4e\xac\xd3\xe7\x32\x40\x24\x7f\x5c\x8f\xc8\x3b\xc8\x4e\x18\x60\xa9\x46\xc6\x37\xdb\x37\x6e\x25\x75\x27\xac\x07\x79\xdc\x29\x5b\x7f\x6a\xa9\x1f\x83\x16\xad\x56\x4e\xaa\xfc\xc8\x73\xb1\xfb\xde\xc6\xf9\x08\xb6\xe5\xdf\x1c\xc8\x16\xe6\x4f\x9e\x08\xbe\x75\xa4\xce\x51\xf6\xd0\x7c\xb7\x37\xc3\xf6\x09\x1e\x1d\xdd\x39\xd9\xa9\x8e\xc7\x2d\x56\x96\xdf\xf7\x00\xe8\x0e\xf7\xdd\xd8\x75\x07\x59\x17\x9d\x83\x83\xc7\xb9\x7f\xe1\xed\xfb\xe7\xea\x2f\x86\x2d\xf1\x0c\xfa\xd3\x77\x37\x93\xeb\xd9\xe5\x9b\x4f\x17\x70\xef\x4b\xbb\x5b\xec\xad\x32\x6f\x6f\xaa\xfc\xc1\x47\xbb\xae\xfc\x32\x84\xd7\x07\xa7\xdb\x08\xbc\x0c\x5a\xe5\x5b\x3b\xfb\x9f\x00\x00\x00\xff\xff\x7f\x40\x9c\x08\x20\x18\x00\x00") func templatesSysvDefaultInitShTmplBytes() ([]byte, error) { return bindataRead( @@ -221,7 +221,7 @@ func templatesSysvDefaultInitShTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/sysv/default/init.sh.tmpl", size: 6176, mode: os.FileMode(420), modTime: time.Unix(1584486952, 0)} + info := bindataFileInfo{name: "templates/sysv/default/init.sh.tmpl", size: 6176, mode: os.FileMode(420), modTime: time.Unix(1584491772, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -266,7 +266,7 @@ func templatesUpstartDefaultProcessTypeConfTmpl() (*asset, error) { return a, nil } -var _templatesUpstartDefaultProgramConfTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x52\xc1\x4e\x1b\x31\x10\xbd\xfb\x2b\xde\x01\x01\x51\xb5\xd9\xb6\xb7\x1e\xc8\x89\x0b\xa7\x46\x6d\x6f\x14\xc1\xca\x9e\x6c\xac\x12\x8f\x35\x33\x5b\x1a\xc1\xfe\x7b\xe5\xdd\xa4\x80\x9a\xa8\x2b\x95\x9b\xfd\x66\xe6\xf9\xbd\xe7\x09\xa4\x5e\x62\xb6\xc8\x09\x8f\x8f\x98\x37\x39\xa3\xef\xab\x72\xcc\xc2\x9e\x54\x6f\x6d\x9b\x69\x8f\xa5\x6e\x83\xbe\x77\x4e\xad\x11\x03\x27\x9c\x0f\xa7\x98\xda\x7f\x4c\x83\x05\x07\x5a\x67\x4e\x8d\xf3\x8e\x88\x73\x9e\x4a\xf4\x57\xeb\xcc\x39\x25\xeb\x62\x18\xb0\x4e\x49\x8a\x4e\x25\x6b\x77\x50\x2b\xdc\x95\x46\xe7\xd7\x21\x0a\x06\xec\x81\xe5\x47\x4c\xed\x6d\x88\x42\xde\x58\xb6\xa5\x2e\xa4\xb9\x79\x48\xce\x8d\xc1\x38\x80\x7e\x65\x16\xc3\xf2\xf3\x97\x6f\x17\x83\xa2\x72\xeb\xfb\x17\x95\xaf\x23\xae\x23\x7a\x8d\x4a\x50\x93\xf9\x3a\xd0\xaa\xe9\xee\xad\xde\xeb\x2c\xfa\x6f\x70\x7a\x8a\xf9\xd1\xfa\xab\x79\xdd\xaa\xe7\xb4\x8a\x6d\xfd\xec\xf4\x15\xc1\xa1\x06\x07\xf8\x70\xdc\x5f\x51\x4d\x7e\xa8\x7b\xde\x6c\x9a\x14\x0a\xe9\x77\x07\x00\x8b\xc5\x80\xdf\x73\xbb\x4f\x7f\xd2\x3e\x54\x6a\x81\x3b\x1b\xe6\x46\xa2\x8f\xff\xc1\x44\x22\x65\xce\x51\x0a\xd8\xfd\x81\xcb\xac\x56\x8d\x4b\xf7\xe7\x5b\x96\x57\x97\x17\x77\x6a\x8d\x75\x3a\x7d\x75\xf1\x04\x6a\x85\x32\x2a\x8e\x38\x3b\xbf\x7e\x5f\x7d\xba\x79\x37\x3b\x39\xc3\x13\xd6\xd4\x04\x54\xe9\xc3\x5d\x89\xc8\xaf\x19\x27\xcb\xab\x4b\x2c\x50\xff\x6c\xa4\x96\x2e\xbd\x88\xb8\x9e\xfc\xde\x3c\xc7\x70\xc8\x09\xe7\x67\x23\xb2\x41\xb5\x7a\xdb\x67\x7e\x07\x00\x00\xff\xff\xc2\x40\xab\xd2\xd7\x03\x00\x00") +var _templatesUpstartDefaultProgramConfTmpl = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x52\xc1\x4e\x1b\x31\x10\xbd\xfb\x2b\xde\x01\x01\x51\xb5\xd9\xb6\xb7\x1e\xc8\x89\x0b\xa7\x46\x6d\x6f\x14\xc1\xca\x9e\x6c\xac\x12\x8f\x35\x33\x5b\x1a\x81\xff\xbd\xf2\x6e\x28\xa0\x06\x35\x52\xb9\x79\xdf\xbc\xf7\xf6\x3d\x7b\x02\xa9\x97\x98\x2d\x72\xc2\xfd\x3d\xe6\x5d\xce\x28\xa5\xa9\xc7\x2c\xec\x49\xf5\xda\xb6\x99\x1e\xb1\x34\x6c\x50\x8a\x73\x6a\x9d\x18\x38\xe1\x74\x3c\xc5\xd4\xff\x43\x0d\x16\xec\xa1\xce\x9c\x1a\xe7\x9d\x11\xe7\x7c\xa8\xd1\x5f\xd4\x99\x73\x4a\x36\xc4\x30\x62\x83\x92\xd4\x9c\x4a\xd6\xef\xa0\x5e\x78\xa8\x44\xe7\xd7\x21\x0a\x46\xec\x8e\xe5\x47\x4c\xfd\x75\x88\x42\xde\x58\xb6\x75\x2e\xa4\xb9\xbb\x4b\xce\x4d\x17\xe3\x00\xfa\x95\x59\x0c\xcb\xcf\x5f\xbe\x9d\x8d\x89\xea\x57\x29\xcf\x26\x5f\x27\x5c\x27\xf4\x12\x8d\xa0\x25\xf3\x6d\xa0\x55\x37\xdc\x5a\xfb\x98\xb3\xe6\xbf\xc2\xf1\x31\xe6\xaf\xce\x5f\xe8\x75\xab\x9e\xd3\x2a\xf6\xed\x53\xd3\x17\x06\xfb\x08\x0e\xf0\xe1\xf5\x7e\x35\x35\xf9\x71\xee\x79\xb3\xe9\x52\xa8\xa6\xdf\x1d\x00\x2c\x16\x23\x7e\xcb\x3d\x4a\x69\x0f\xde\x87\x46\x2d\xf0\x60\xa3\x6e\x32\xfa\xf8\x1f\x4e\x24\x52\x75\x8e\x52\xc0\xee\x0d\x5c\x66\xb5\x66\x5a\xba\x3f\xcf\xb2\xbc\x38\x3f\xbb\x51\xeb\x6c\xd0\xc3\x57\x17\x0f\xa0\x5e\x28\xa3\xe1\x88\x93\xd3\xcb\xf7\xcd\xa7\xab\x77\xb3\xa3\x13\x3c\x60\x4d\x5d\x40\x93\x3e\xdc\xd4\x2b\xf2\x6b\xc6\xd1\xf2\xe2\x1c\x0b\xb4\x3f\x3b\x69\x65\x48\xcf\x5a\x1c\x5e\x68\x9e\x63\xd8\xd7\x84\xf3\x53\x11\xd9\xa0\x59\xbd\xed\x6f\x7e\x07\x00\x00\xff\xff\x75\xdd\xd3\xde\xd7\x03\x00\x00") func templatesUpstartDefaultProgramConfTmplBytes() ([]byte, error) { return bindataRead( @@ -281,7 +281,7 @@ func templatesUpstartDefaultProgramConfTmpl() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "templates/upstart/default/program.conf.tmpl", size: 983, mode: os.FileMode(420), modTime: time.Unix(1584486170, 0)} + info := bindataFileInfo{name: "templates/upstart/default/program.conf.tmpl", size: 983, mode: os.FileMode(420), modTime: time.Unix(1584491772, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/templates/launchd/launchd.plist.tmpl b/templates/launchd/launchd.plist.tmpl index f3d652d..03c6000 100644 --- a/templates/launchd/launchd.plist.tmpl +++ b/templates/launchd/launchd.plist.tmpl @@ -24,9 +24,9 @@ RunAtLoad StandardOutPath - {{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stdout.log + {{ .log }}/{{ .app }}-{{ .process_type }}-{{ .num }}-stdout.log StandardErrorPath - {{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stderr.log + {{ .log }}/{{ .app }}-{{ .process_type }}-{{ .num }}-stderr.log UserName {{ .user }} WorkingDirectory diff --git a/templates/runit/log/run.tmpl b/templates/runit/log/run.tmpl index 129cb81..0e90e4e 100644 --- a/templates/runit/log/run.tmpl +++ b/templates/runit/log/run.tmpl @@ -1,7 +1,7 @@ #!/bin/sh set -e -LOG={{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }} +LOG={{ .log }}/{{ .app }}-{{ .process_type }}-{{ .num }} test -d "$LOG" || mkdir -p -m 2750 "$LOG" && chown {{ .user }} "$LOG" exec chpst -u {{ .user }} svlogd "$LOG" diff --git a/templates/systemd-user/default/program.service.tmpl b/templates/systemd-user/default/program.service.tmpl index 10facb1..34f01e4 100644 --- a/templates/systemd-user/default/program.service.tmpl +++ b/templates/systemd-user/default/program.service.tmpl @@ -12,8 +12,8 @@ ExecStart={{ .command }} Restart=always RestartSec=14s StandardInput=null -StandardOutput={{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stdout.log -StandardError={{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stderr.log +StandardOutput={{ .log }}/{{ .app }}-{{ .process_type }}-{{ .num }}-stdout.log +StandardError={{ .log }}/{{ .app }}-{{ .process_type }}-{{ .num }}-stderr.log SyslogIdentifier=%n [Install] diff --git a/templates/systemd/default/program.service.tmpl b/templates/systemd/default/program.service.tmpl index 873ff1d..7218e82 100644 --- a/templates/systemd/default/program.service.tmpl +++ b/templates/systemd/default/program.service.tmpl @@ -19,8 +19,8 @@ ExecStart=/bin/bash -lc 'exec -a "{{ .ps }}" {{ .command }}' Restart=always RestartSec=14s StandardInput=null -StandardOutput={{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stdout.log -StandardError={{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stderr.log +StandardOutput={{ .log }}/{{ .app }}-{{ .process_type }}-{{ .num }}-stdout.log +StandardError={{ .log }}/{{ .app }}-{{ .process_type }}-{{ .num }}-stderr.log SyslogIdentifier=%n KillMode=mixed TimeoutStopSec={{ .timeout }} diff --git a/templates/sysv/default/init.sh.tmpl b/templates/sysv/default/init.sh.tmpl index d6c161e..21b0c7f 100644 --- a/templates/sysv/default/init.sh.tmpl +++ b/templates/sysv/default/init.sh.tmpl @@ -100,7 +100,7 @@ start() { {{ if .ulimit_shell }}{{ .ulimit_shell }}{{ end }} cd \"$chdir\" exec \"$program\" $args - " >> {{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stdout.log 2>> {{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stderr.log & + " >> {{ .log }}/{{ .app }}-{{ .process_type }}-{{ .num }}-stdout.log 2>> {{ .log }}/{{ .app }}-{{ .process_type }}-{{ .num }}-stderr.log & # Generate the pidfile from here. If we instead made the forked process # generate it there will be a race condition between the pidfile writing diff --git a/templates/upstart/default/program.conf.tmpl b/templates/upstart/default/program.conf.tmpl index f4bdfae..b0e7b8d 100644 --- a/templates/upstart/default/program.conf.tmpl +++ b/templates/upstart/default/program.conf.tmpl @@ -15,8 +15,8 @@ script [ -r /etc/sysconfig/{{ .app }} ] && . /etc/sysconfig/{{ .app }} cd {{ .working_directory }} exec {{ .command }} \ - >> {{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stdout.log \ - 2>> {{ .log }}-{{ .app }}-{{ .process_type }}-{{ .num }}-stderr.log + >> {{ .log }}/{{ .app }}-{{ .process_type }}-{{ .num }}-stdout.log \ + 2>> {{ .log }}/{{ .app }}-{{ .process_type }}-{{ .num }}-stderr.log end script post-start script From 20652211f08515ffb1731b576d90815607c5613b Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 20:37:48 -0400 Subject: [PATCH 38/48] fix: runt => runit --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index a6cdf83..d0718af 100644 --- a/main.go +++ b/main.go @@ -321,7 +321,7 @@ func exportCommand(entries []procfileEntry, app string, description string, envP formats := map[string]exportFunc{ "launchd": exportLaunchd, - "runt": exportRunit, + "runit": exportRunit, "systemd": exportSystemd, "systemd-user": exportSystemdUser, "sysv": exportSysv, From b2839044c65f4f6a765d5da538f2887fe8e58c93 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 20:38:05 -0400 Subject: [PATCH 39/48] refactor: write runit files to correct path --- export.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/export.go b/export.go index 40ce92e..f285e8d 100644 --- a/export.go +++ b/export.go @@ -49,8 +49,8 @@ func exportRunit(app string, entries []procfileEntry, formations map[string]form return false } - if _, err := os.Stat(location); os.IsNotExist(err) { - os.MkdirAll(location, os.ModePerm) + if _, err := os.Stat(location + "/service"); os.IsNotExist(err) { + os.MkdirAll(location+"/service", os.ModePerm) } for i, entry := range entries { @@ -59,16 +59,16 @@ func exportRunit(app string, entries []procfileEntry, formations map[string]form for num <= count { processDirectory := fmt.Sprintf("%s-%s-%d", app, entry.Name, num) - folderPath := location + "/" + processDirectory + folderPath := location + "/service/" + processDirectory processName := fmt.Sprintf("%s-%d", entry.Name, num) - fmt.Println("creating:", app+"-"+processName) + fmt.Println("creating:", folderPath) os.MkdirAll(folderPath, os.ModePerm) - fmt.Println("creating:", app+"-"+processName+"/env") + fmt.Println("creating:", folderPath+"/env") os.MkdirAll(folderPath+"/env", os.ModePerm) - fmt.Println("creating:", app+"-"+processName+"/log") + fmt.Println("creating:", folderPath+"/log") os.MkdirAll(folderPath+"/log", os.ModePerm) port := portFor(i, num, defaultPort) @@ -88,7 +88,7 @@ func exportRunit(app string, entries []procfileEntry, formations map[string]form env["PS"] = app + "-" + processName for key, value := range env { - fmt.Println("writing:", app+"-"+processName+"/env/"+key) + fmt.Println("writing:", folderPath+"/env/"+key) f, err := os.Create(folderPath + "/env/" + key) if err != nil { fmt.Fprintf(os.Stderr, "error creating file: %s\n", err) From 78a0ccf7e08b6b54f6bb083f589dde93457817a5 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Tue, 17 Mar 2020 20:40:26 -0400 Subject: [PATCH 40/48] refactor: use sprintf instead of concatenation --- export.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/export.go b/export.go index f285e8d..0efdb3e 100644 --- a/export.go +++ b/export.go @@ -26,7 +26,7 @@ func exportLaunchd(app string, entries []procfileEntry, formations map[string]fo processName := fmt.Sprintf("%s-%d", entry.Name, num) port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) - if !writeOutput(l, location+"/Library/LaunchDaemons/"+app+"-"+processName+".plist", config) { + if !writeOutput(l, fmt.Sprintf("%s/Library/LaunchDaemons/%s-%s.plist", location, app, processName), config) { return false } @@ -74,7 +74,7 @@ func exportRunit(app string, entries []procfileEntry, formations map[string]form port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) - if !writeOutput(r, folderPath+"/run", config) { + if !writeOutput(r, fmt.Sprintf("%s/run", folderPath), config) { return false } @@ -107,7 +107,7 @@ func exportRunit(app string, entries []procfileEntry, formations map[string]form } } - if !writeOutput(l, folderPath+"/log/run", config) { + if !writeOutput(l, fmt.Sprintf("%s/log/run", folderPath), config) { return false } @@ -147,7 +147,7 @@ func exportSystemd(app string, entries []procfileEntry, formations map[string]fo port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) - if !writeOutput(s, location+"/etc/systemd/system/"+app+"-"+fileName+".service", config) { + if !writeOutput(s, fmt.Sprintf("%s/etc/systemd/system/%s-%s.service", location, app, filename), config) { return false } @@ -157,7 +157,7 @@ func exportSystemd(app string, entries []procfileEntry, formations map[string]fo config := vars config["processes"] = processes - if writeOutput(t, location+"/etc/systemd/system/"+app+".target", config) { + if writeOutput(t, fmt.Sprintf("%s/etc/systemd/system/%s.target", location, app), config) { fmt.Println("You will want to run 'systemctl --system daemon-reload' to activate the service on the target host") return true } From f04de1c94a1ed80bac823fd4f13c47cd94d828de Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 22 Mar 2020 02:40:31 -0400 Subject: [PATCH 41/48] fix: shellescape is not an indirect import --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 6b22373..4a7af8e 100644 --- a/go.mod +++ b/go.mod @@ -7,5 +7,5 @@ require ( github.com/andrew-d/go-termutil v0.0.0-20150726205930-009166a695a2 github.com/go-bindata/go-bindata v3.1.2+incompatible // indirect github.com/joho/godotenv v1.2.0 - gopkg.in/alessio/shellescape.v1 v1.0.0-20170105083845-52074bc9df61 // indirect + gopkg.in/alessio/shellescape.v1 v1.0.0-20170105083845-52074bc9df61 ) From 2fea2a2b45c723a06a5887bf6fc55221f2f085d0 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 22 Mar 2020 02:40:44 -0400 Subject: [PATCH 42/48] fix: correct variable name --- export.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/export.go b/export.go index 0efdb3e..1d5d27b 100644 --- a/export.go +++ b/export.go @@ -147,7 +147,7 @@ func exportSystemd(app string, entries []procfileEntry, formations map[string]fo port := portFor(i, num, defaultPort) config := templateVars(app, entry, processName, num, port, vars) - if !writeOutput(s, fmt.Sprintf("%s/etc/systemd/system/%s-%s.service", location, app, filename), config) { + if !writeOutput(s, fmt.Sprintf("%s/etc/systemd/system/%s-%s.service", location, app, fileName), config) { return false } From 84ecb7973140ca7331ec30f9033ad5a24f3d9082 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 22 Mar 2020 02:46:51 -0400 Subject: [PATCH 43/48] fix: correct description --- export.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/export.go b/export.go index 1d5d27b..4538a4b 100644 --- a/export.go +++ b/export.go @@ -305,7 +305,7 @@ func templateVars(app string, entry procfileEntry, processName string, num int, config["program"] = entry.program() config["ps"] = app + "-" + entry.Name + "." + strconv.Itoa(num) if config["description"] == "" { - config["description"] = fmt.Sprintf("%s process for %s", processName, app) + config["description"] = fmt.Sprintf("%s.%s process for %s", entry.Name, strconv.Itoa(num), app) } return config From 71e8c07473f2dcf9dd5b833e9742abe1108079df Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Sun, 22 Mar 2020 02:46:59 -0400 Subject: [PATCH 44/48] feat: set systemd as default format --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index d0718af..b79a163 100644 --- a/main.go +++ b/main.go @@ -542,7 +542,7 @@ func main() { appExportFlag := exportCmd.String("", "app", &argparse.Options{Default: "app", Help: "name of app"}) descriptionExportFlag := exportCmd.String("", "description", &argparse.Options{Help: "process description"}) envPathExportFlag := exportCmd.String("e", "env-file", &argparse.Options{Help: "path to a dotenv file"}) - formatExportFlag := exportCmd.String("", "format", &argparse.Options{Help: "format to export"}) + formatExportFlag := exportCmd.String("", "format", &argparse.Options{Default: "systemd", Help: "format to export"}) formationExportFlag := exportCmd.String("", "formation", &argparse.Options{Default: "all=1", Help: "specify what processes will run and how many"}) groupExportFlag := exportCmd.String("", "group", &argparse.Options{Help: "group to run the command as"}) homeExportFlag := exportCmd.String("", "home", &argparse.Options{Help: "home directory for program"}) From 1e57a5cdde62512505429402e96441ba8f5e2f39 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Thu, 30 Apr 2020 16:21:50 -0400 Subject: [PATCH 45/48] docs: remove extra p --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5d8c1a4..6f1eb69 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ In addition, not all formats support all arguments, and not all arguments have e # export systemd init files to the `tmp` directory # support formats include: [launchd, runit, systemd, systemd-user, sysv, upstart] # the default format is: systemd -procfile-util export --format systemd --location tmpp +procfile-util export --format systemd --location tmp # override the app name procfile-util export --location tmp --app node-js-app From aab42d57c48c9aa0600bd9b1b55fb4fc388567e7 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 6 May 2020 00:28:50 -0400 Subject: [PATCH 46/48] chore: do not release to beta channel --- .circleci/config.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fa4c93f..d43f4c6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,6 +25,5 @@ jobs: - run: command: | if [[ "$CIRCLE_BRANCH" == "release" ]]; then - make release-in-docker + make release-in-docker release-packagecloud-in-docker fi - make release-packagecloud-in-docker || true From bb0f662182fbf7387314f2d5200879bc61b20204 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 6 May 2020 00:29:40 -0400 Subject: [PATCH 47/48] feat: release packages for focal --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 13b1cc9..6741b1f 100644 --- a/Makefile +++ b/Makefile @@ -143,9 +143,9 @@ release-packagecloud: @$(MAKE) release-packagecloud-rpm release-packagecloud-deb: build/deb/$(NAME)_$(VERSION)_amd64.deb - package_cloud push $(PACKAGECLOUD_REPOSITORY)/ubuntu/trusty build/deb/$(NAME)_$(VERSION)_amd64.deb package_cloud push $(PACKAGECLOUD_REPOSITORY)/ubuntu/xenial build/deb/$(NAME)_$(VERSION)_amd64.deb package_cloud push $(PACKAGECLOUD_REPOSITORY)/ubuntu/bionic build/deb/$(NAME)_$(VERSION)_amd64.deb + package_cloud push $(PACKAGECLOUD_REPOSITORY)/ubuntu/focal build/deb/$(NAME)_$(VERSION)_amd64.deb package_cloud push $(PACKAGECLOUD_REPOSITORY)/debian/stretch build/deb/$(NAME)_$(VERSION)_amd64.deb package_cloud push $(PACKAGECLOUD_REPOSITORY)/debian/buster build/deb/$(NAME)_$(VERSION)_amd64.deb From 3eae4747a272940a53bbc261f97bfe0f4b0871a6 Mon Sep 17 00:00:00 2001 From: Jose Diaz-Gonzalez Date: Wed, 6 May 2020 11:42:44 -0400 Subject: [PATCH 48/48] Release 0.8.0 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6741b1f..da93d6f 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ MAINTAINER_NAME = Jose Diaz-Gonzalez REPOSITORY = go-procfile-util HARDWARE = $(shell uname -m) SYSTEM_NAME = $(shell uname -s | tr '[:upper:]' '[:lower:]') -BASE_VERSION ?= 0.7.0 +BASE_VERSION ?= 0.8.0 IMAGE_NAME ?= $(MAINTAINER)/$(REPOSITORY) PACKAGECLOUD_REPOSITORY ?= dokku/dokku-betafish