added scriptEnvFile to command.commandName object
Some checks failed
ci/woodpecker/push/go-lint Pipeline failed

This commit is contained in:
Andrew Woodlee 2023-08-06 22:27:51 -05:00
parent b8a82b2836
commit 6ccb75f4fa
6 changed files with 80 additions and 13 deletions

View File

@ -1,4 +1,9 @@
steps: steps:
build:
image: golang
commands:
- go build
- go test
release: release:
image: golangci/golangci-lint:v1.53.3 image: golangci/golangci-lint:v1.53.3
commands: commands:

View File

@ -7,6 +7,8 @@ The yaml top-level map can be any string.
The top-level name must be unique. The top-level name must be unique.
### Example Config
```yaml ```yaml
commands: commands:
stop-docker-container: stop-docker-container:
@ -29,14 +31,15 @@ commands:
Values available for this section: Values available for this section:
| name | description | type | required | name | notes | type | required
| --- | --- | --- | --- | | --- | --- | --- | --- |
| `cmd` | Defines the command to execute | `string` | yes | | `cmd` | Defines the command to execute | `string` | yes |
| `args` | Defines the arguments to the command | `[]string` | no | | `args` | Defines the arguments to the command | `[]string` | no |
| `environment` | Defines evironment variables for the command | `[]string` | no | | `environment` | Defines evironment variables for the command | `[]string` | no |
| `type` | May be `scriptFile` or `script`. Runs script from local machine on remote | `string` | no | | `type` | May be `scriptFile` or `script`. Runs script from local machine on remote. Only applicable when `host` is defined. | `string` | no |
| `getOutput` | Command(s) output is in the notification(s) | `bool` | no | | `getOutput` | Command(s) output is in the notification(s) | `bool` | no |
| `host` | If not specified, the command will execute locally. | `string` | no | | `host` | If not specified, the command will execute locally. | `string` | no |
| `scriptEnvFile` | When type is `scriptFile`, the script is appended to this file. | `string` | no |
| `shell` | Only applicable when host is not specified | `string` | no | | `shell` | Only applicable when host is not specified | `string` | no |
#### cmd #### cmd
@ -86,13 +89,21 @@ If I assign a value to host as `host: web-prod` and don't specify this value in
If shell is defined and host is NOT defined, the command will run in the specified shell. If shell is defined and host is NOT defined, the command will run in the specified shell.
Make sure to escape any shell input. Make sure to escape any shell input.
### scriptEnvFile
Path to a file.
When type is `scriptFile`, the script is appended to this file.
This is useful for specifiing environment variables or other things so they don't have to be included in the script.
### type ### type
May be `scriptFile` or `script`. Runs script from local machine on remote host. May be `scriptFile` or `script`. Runs script from local machine on remote host passed to the SSH session as standard input.
If `script` is specified, `cmd` is used as the script. If `type` is `script`, `cmd` is used as the script.
Script file is input as stdin to SSH. If `type` is `scriptFile`, cmd must be a file path.
### environment ### environment
@ -100,7 +111,7 @@ The environment variables support expansion:
- using escaped values `$VAR` or `${VAR}` - using escaped values `$VAR` or `${VAR}`
For now the variables have to be defined in an `.env` file in the same directory as the config file. For now, the variables have to be defined in an `.env` file in the same directory as the config file.
If using it with host specified, the SSH server has to be configured to accept those env variables. If using it with host specified, the SSH server has to be configured to accept those env variables.

2
go.mod
View File

@ -1,6 +1,6 @@
module git.andrewnw.xyz/CyberShell/backy module git.andrewnw.xyz/CyberShell/backy
go 1.20 go 1.26
require ( require (
github.com/go-co-op/gocron v1.30.1 github.com/go-co-op/gocron v1.30.1

View File

@ -95,6 +95,13 @@ func (command *Command) RunCmd(log zerolog.Logger, backyConf *ConfigFile, opts *
commandSession.Stderr = cmdOutWriters commandSession.Stderr = cmdOutWriters
if command.Type != "" { if command.Type != "" {
// did the program panic while writing to the buffer?
defer func() {
if err := recover(); err != nil {
log.Info().Msg(fmt.Sprintf("panic occured writing to buffer: %x", err))
}
}()
if command.Type == "script" { if command.Type == "script" {
script := bytes.NewBufferString(cmd + "\n") script := bytes.NewBufferString(cmd + "\n")
@ -130,8 +137,31 @@ func (command *Command) RunCmd(log zerolog.Logger, backyConf *ConfigFile, opts *
return outputArr, nil return outputArr, nil
} }
if command.Type == "scriptFile" { if command.Type == "scriptFile" {
var buffer bytes.Buffer var (
var dirErr error buffer bytes.Buffer
scriptEnvFileBuffer bytes.Buffer
scriptFileBuffer bytes.Buffer
dirErr error
scriptEnvFilePresent bool
)
if command.ScriptEnvFile != "" {
command.ScriptEnvFile, dirErr = resolveDir(command.ScriptEnvFile)
if dirErr != nil {
return nil, dirErr
}
file, err := os.Open(command.ScriptEnvFile)
if err != nil {
return nil, err
}
defer file.Close()
_, err = io.Copy(&scriptEnvFileBuffer, file)
if err != nil {
return nil, err
}
scriptEnvFilePresent = true
}
command.Cmd, dirErr = resolveDir(command.Cmd) command.Cmd, dirErr = resolveDir(command.Cmd)
if dirErr != nil { if dirErr != nil {
return nil, dirErr return nil, dirErr
@ -140,11 +170,31 @@ func (command *Command) RunCmd(log zerolog.Logger, backyConf *ConfigFile, opts *
if err != nil { if err != nil {
return nil, err return nil, err
} }
_, err = io.Copy(&scriptFileBuffer, file)
if err != nil {
return nil, err
}
defer file.Close() defer file.Close()
if scriptEnvFilePresent {
_, err := buffer.WriteString(scriptEnvFileBuffer.String())
if err != nil {
return nil, err
}
// write newline
buffer.WriteByte(0x0A)
_, err = buffer.WriteString(scriptFileBuffer.String())
if err != nil {
return nil, err
}
} else {
_, err = io.Copy(&buffer, file) _, err = io.Copy(&buffer, file)
if err != nil { if err != nil {
return nil, err return nil, err
} }
}
script := &buffer script := &buffer

View File

@ -236,9 +236,8 @@ func ReadConfig(opts *ConfigOpts) *ConfigFile {
} }
} }
var notificationsMap = make(map[string]interface{})
if backyViper.IsSet("notifications") { if backyViper.IsSet("notifications") {
notificationsMap = backyViper.GetStringMap("notifications") notificationsMap := backyViper.GetStringMap("notifications")
for id := range notificationsMap { for id := range notificationsMap {
notifConfig := backyViper.Sub(getNestedConfig("notifications", id)) notifConfig := backyViper.Sub(getNestedConfig("notifications", id))
config := &NotificationsConfig{ config := &NotificationsConfig{

View File

@ -100,6 +100,8 @@ type (
// Output determines if output is requested. // Output determines if output is requested.
// Only works if command is in a list. // Only works if command is in a list.
GetOutput bool `yaml:"getOutput,omitempty"` GetOutput bool `yaml:"getOutput,omitempty"`
ScriptEnvFile string `yaml:"scriptEnvFile"`
} }
BackyOptionFunc func(*ConfigOpts) BackyOptionFunc func(*ConfigOpts)