Skip to content
This repository has been archived by the owner on Aug 14, 2020. It is now read-only.

Commit

Permalink
spec: change executable path in App.Exec to be PATH-dependent.
Browse files Browse the repository at this point in the history
The searching of the executable path duplicates the shell.
The details are described in the manual page of exec(3).
  • Loading branch information
Yifan Gu committed Oct 16, 2015
1 parent 5a7af19 commit 7d3e414
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 65 deletions.
66 changes: 21 additions & 45 deletions schema/types/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,58 +46,34 @@ func TestAppValid(t *testing.T) {
Group: "0",
WorkingDirectory: "/tmp",
},
}
for i, tt := range tests {
if err := tt.assertValid(); err != nil {
t.Errorf("#%d: err == %v, want nil", i, err)
}
}
}

func TestAppExecInvalid(t *testing.T) {
tests := []struct {
app App
valid bool
}{
{
App{
Exec: nil,
User: "0",
Group: "0",
},
true,
App{
Exec: nil,
User: "0",
Group: "0",
WorkingDirectory: "/tmp",
},
{
App{
Exec: []string{},
User: "0",
Group: "0",
},
true,
App{
Exec: []string{},
User: "0",
Group: "0",
WorkingDirectory: "/tmp",
},
{
App{
Exec: []string{"app"},
User: "0",
Group: "0",
},
false,
App{
Exec: []string{"app"},
User: "0",
Group: "0",
WorkingDirectory: "/tmp",
},
{
App{
Exec: []string{"bin/app", "arg1"},
User: "0",
Group: "0",
},
false,
App{
Exec: []string{"bin/app", "arg1"},
User: "0",
Group: "0",
WorkingDirectory: "/tmp",
},
}
for i, tt := range tests {
err := tt.app.assertValid()
if err != nil && tt.valid {
if err := tt.assertValid(); err != nil {
t.Errorf("#%d: err == %v, want nil", i, err)
} else if err == nil && !tt.valid {
t.Errorf("#%d: err == nil, want non-nil", i)
}
}
}
Expand Down
9 changes: 1 addition & 8 deletions schema/types/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,13 @@

package types

import (
"encoding/json"
"errors"
"path/filepath"
)
import "encoding/json"

type Exec []string

type exec Exec

func (e Exec) assertValid() error {
if len(e) > 0 && !filepath.IsAbs(e[0]) {
return errors.New(`exec[0] must be absolute path`)
}
return nil
}

Expand Down
12 changes: 1 addition & 11 deletions schema/types/exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,11 @@ func TestExecValid(t *testing.T) {
Exec{"/bin/httpd"},
Exec{"/app"},
Exec{"/app", "arg1", "arg2"},
Exec{"app"},
}
for i, tt := range tests {
if err := tt.assertValid(); err != nil {
t.Errorf("#%d: err == %v, want nil", i, err)
}
}
}

func TestExecInvalid(t *testing.T) {
tests := []Exec{
Exec{"app"},
}
for i, tt := range tests {
if err := tt.assertValid(); err == nil {
t.Errorf("#%d: err == nil, want non-nil", i)
}
}
}
2 changes: 1 addition & 1 deletion spec/aci.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ JSON Schema for the Image Manifest (app image manifest, ACI manifest), conformin
* **version** when combined with "name", this SHOULD be unique for every build of an app (on a given "os"/"arch" combination).
* **os**, **arch** can together be considered to describe the syscall ABI this image requires. **arch** is meaningful only if **os** is provided. If one or both values are not provided, the image is assumed to be OS- and/or architecture-independent. Currently supported combinations are listed in the [`types.ValidOSArch`](../schema/types/labels.go) variable, which can be updated by an implementation that supports other combinations. The combinations whitelisted by default are (in format `os/arch`): `linux/amd64`, `linux/i386`, `freebsd/amd64`, `freebsd/i386`, `freebsd/arm`, `darwin/x86_64`, `darwin/i386`. See the [Operating System spec](OS-SPEC.md) for the environment apps can expect to run in given a known **os** label.
* **app** (object, optional) if present, defines the default parameters that can be used to execute this image as an application.
* **exec** (list of strings, optional) executable to launch and any flags. The executable MUST be an absolute path within the app rootfs. ACE MAY append or override the list. These strings are not evaluated in any way and environment variables are not substituted.
* **exec** (list of strings, optional) executable to launch and any flags. ACE duplicates the actions of the shell in searching for the executable file. If the specified filename does not contain a slash (`/`) character, the executable is sought according to the `PATH` environment variable. If `PATH` isn't defined, the executable is sought in the current directory followed by the list of directories returned by `confstr(_CS_PATH)`. If the specified filename includes a slash character, then `PATH` is ignored, and the file at the specified pathname is executed. (See `man exec(3)` for more details). ACE MAY append or override the list. These strings are not evaluated in any way and environment variables are not substituted.
* **user**, **group** (string, required) indicates either the username/group name or the UID/GID the app is to be run as (freeform string). The user and group values may be all numbers to indicate a UID/GID, however it is possible on some systems (POSIX) to have usernames that are all numerical. The user and group values will first be resolved using the image's own `/etc/passwd` or `/etc/group`. If no valid matches are found, then if the string is all numerical, it shall be converted to an integer and used as the UID/GID. If the user or group field begins with a "/", the owner and group of the file found at that absolute path inside the rootfs is used as the UID/GID of the process. Example values for the fields include `root`, `1000`, or `/usr/bin/ping`.
* **supplementaryGIDs** (list of unsigned integers, optional) indicates additional (supplementary) group IDs (GIDs) as which the app's processes should run.
* **eventHandlers** (list of objects, optional) allows the app to have several hooks based on lifecycle events. For example, you may want to execute a script before the main process starts up to download a dataset or backup onto the filesystem. An eventHandler is a simple object with two fields - an **exec** (array of strings, ACE can append or override), and a **name** (there may be only one eventHandler of a given name), which must be one of:
Expand Down

0 comments on commit 7d3e414

Please sign in to comment.