Skip to content

Commit

Permalink
Merge pull request #170 from tgross/gh145_command_env_vars
Browse files Browse the repository at this point in the history
Interpolate variables in command args
  • Loading branch information
tgross committed Jun 1, 2016
2 parents 4f2578e + c93eb97 commit 85596c4
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 5 deletions.
21 changes: 19 additions & 2 deletions core/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ func (a *App) Run() {
if 1 == os.Getpid() {
reapChildren()
}
command, err := utils.ParseCommandArgs(flag.Args())
args := getArgs(flag.Args())
command, err := utils.ParseCommandArgs(args)
if err != nil {
log.Errorf("Unable to parse command arguments: %v", err)
}
Expand All @@ -122,7 +123,7 @@ func (a *App) Run() {
}
a.handlePolling()

if len(flag.Args()) != 0 {
if len(args) != 0 {
// Run our main application and capture its stdout/stderr.
// This will block until the main application exits and then os.Exit
// with the exit code of that application.
Expand All @@ -145,6 +146,22 @@ func (a *App) Run() {
select {}
}

// Render the command line args thru golang templating so we can
// interpolate environment variables
func getArgs(args []string) []string {
var renderedArgs []string
for _, arg := range args {
newArg, err := config.ApplyTemplate([]byte(arg))
if err != nil {
log.Errorf("Unable to render command arguments template: %v", err)
renderedArgs = args // skip rendering on error
break
}
renderedArgs = append(renderedArgs, string(newArg))
}
return renderedArgs
}

// ToggleMaintenanceMode marks all services for maintenance
func (a *App) ToggleMaintenanceMode() {
a.maintModeLock.RLock()
Expand Down
15 changes: 15 additions & 0 deletions core/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,21 @@ func TestParseTrailingComma(t *testing.T) {
}`, "Do you have an extra comma somewhere?")
}

func TestRenderArgs(t *testing.T) {
flags := []string{"-name", "{{ .HOSTNAME }}"}
expected, _ := os.Hostname()
if got := getArgs(flags)[1]; got != expected {
t.Errorf("Expected %v but got %v for rendered hostname", expected, got)
}

// invalid template should just be returned unchanged
flags = []string{"-name", "{{ .HOSTNAME }"}
expected = "{{ .HOSTNAME }"
if got := getArgs(flags)[1]; got != expected {
t.Errorf("Expected %v but got %v for unrendered hostname", expected, got)
}
}

func TestMetricServiceCreation(t *testing.T) {

jsonFragment := `{
Expand Down
16 changes: 14 additions & 2 deletions documentation/12-configuration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,9 @@ All executable fields, including `services/health`, `preStart`, `preStop`, `post

### Template configuration

ContainerPilot configuration has template support. If you have an environment variable such as `FOO=BAR` then you can use `{{.FOO}}` in your configuration file and it will be substituted with `BAR`.
ContainerPilot configuration has template support. If you have an environment variable such as `FOO=BAR` then you can use `{{.FOO}}` in your configuration file or in your command arguments and it will be substituted with `BAR`.

**Example usage**
**Example usage in a config file**

```json
{
Expand All @@ -263,4 +263,16 @@ ContainerPilot configuration has template support. If you have an environment va
}
```

**Example usage in a Dockerfile**

```
ENV APP_PORT=8000
CMD [ "/usr/local/bin/containerpilot", \
"node",\
"/usr/local/bin/http-server",\
"-p",\
"{{ .APP_PORT }}"]
```


**Note**: If you need more than just variable interpolation, check out the [Go text/template Docs](https://golang.org/pkg/text/template/).
6 changes: 5 additions & 1 deletion integration_tests/fixtures/app/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ COPY task.sh /task.sh
# by default use app-consul.json, allows for override in docker-compose
ENV CONTAINERPILOT=file:///app-with-consul.json

# default port, allows us to override in docker-compose and also test
# env var interpolation in the command args
ENV APP_PORT=8000

ENTRYPOINT [ "/bin/containerpilot", \
"/usr/local/bin/node", \
"/usr/local/bin/http-server", "/srv", "-p", "8000"]
"/usr/local/bin/http-server", "/srv", "-p", "{{ .APP_PORT }}"]

0 comments on commit 85596c4

Please sign in to comment.