Skip to content

Commit

Permalink
Merge pull request #2083 from bauerm97/apps-support-static
Browse files Browse the repository at this point in the history
Add support for apps to Singularity 3.0
  • Loading branch information
yhcote authored Sep 25, 2018
2 parents ebf2f6f + a144f29 commit b9f0876
Show file tree
Hide file tree
Showing 14 changed files with 751 additions and 125 deletions.
4 changes: 4 additions & 0 deletions src/cmd/singularity/cli/action_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (

// actionflags.go contains flag variables for action-like commands to draw from
var (
AppName string
BindPaths []string
HomePath string
OverlayPath []string
Expand Down Expand Up @@ -74,6 +75,9 @@ func init() {

// initPathVars initializes flags that take a string argument
func initPathVars() {
// --app
actionFlags.StringVar(&AppName, "app", "", "Set container app to run")

// -B|--bind
actionFlags.StringSliceVarP(&BindPaths, "bind", "B", []string{}, "A user-bind path specification. spec has the format src[:dest[:opts]], where src and dest are outside and inside paths. If dest is not given, it is set equal to src. Mount options ('opts') may be specified as 'ro' (read-only) or 'rw' (read/write, which is the default). Multiple bind paths can be given by a comma separated list.")
actionFlags.SetAnnotation("bind", "argtag", []string{"<spec>"})
Expand Down
3 changes: 3 additions & 0 deletions src/cmd/singularity/cli/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ func init() {
cmd.Flags().AddFlag(actionFlags.Lookup("no-init"))
cmd.Flags().AddFlag(actionFlags.Lookup("security"))
cmd.Flags().AddFlag(actionFlags.Lookup("apply-cgroups"))
cmd.Flags().AddFlag(actionFlags.Lookup("app"))
cmd.Flags().SetInterspersed(false)
}

Expand Down Expand Up @@ -431,6 +432,8 @@ func execStarter(cobraCmd *cobra.Command, image string, args []string, name stri

Env := []string{sylog.GetEnvVar(), "SRUNTIME=singularity"}

generator.AddProcessEnv("SINGULARITY_APPNAME", AppName)

cfg := &config.Common{
EngineName: singularity.Name,
ContainerID: name,
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/singularity/cli/singularity.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/sylabs/singularity/src/docs"
"github.com/sylabs/singularity/src/pkg/buildcfg"
"github.com/sylabs/singularity/src/pkg/sylog"
"github.com/sylabs/singularity/src/pkg/syplugin"
"github.com/sylabs/singularity/src/pkg/util/auth"
)

Expand Down Expand Up @@ -153,6 +154,7 @@ func handleEnv(flag *pflag.Flag) {
func persistentPreRun(cmd *cobra.Command, args []string) {
setSylogMessageLevel(cmd, args)
updateFlagsFromEnv(cmd)
syplugin.Init()
}

// sylabsToken process the authentication Token
Expand Down
3 changes: 2 additions & 1 deletion src/pkg/build/assemblers/assembler_sif.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/satori/go.uuid"
"github.com/sylabs/sif/pkg/sif"
"github.com/sylabs/singularity/src/pkg/build/types"
"github.com/sylabs/singularity/src/pkg/build/types/parser"
"github.com/sylabs/singularity/src/pkg/sylog"
)

Expand Down Expand Up @@ -87,7 +88,7 @@ func (a *SIFAssembler) Assemble(b *types.Bundle, path string) (err error) {

// convert definition to plain text
var buf bytes.Buffer
b.Recipe.WriteDefinitionFile(&buf)
parser.WriteDefinitionFile(&(b.Recipe), &buf)
def := buf.Bytes()

// make system partition image
Expand Down
59 changes: 31 additions & 28 deletions src/pkg/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import (
"github.com/sylabs/singularity/src/pkg/build/assemblers"
"github.com/sylabs/singularity/src/pkg/build/sources"
"github.com/sylabs/singularity/src/pkg/build/types"
"github.com/sylabs/singularity/src/pkg/build/types/parser"
"github.com/sylabs/singularity/src/pkg/buildcfg"
"github.com/sylabs/singularity/src/pkg/sylog"
"github.com/sylabs/singularity/src/pkg/syplugin"
syexec "github.com/sylabs/singularity/src/pkg/util/exec"
"github.com/sylabs/singularity/src/runtime/engines/config"
"github.com/sylabs/singularity/src/runtime/engines/config/oci"
Expand Down Expand Up @@ -173,6 +175,9 @@ func (b *Build) Full() error {
}
}

syplugin.BuildHandleBundles(b.b)
b.b.Recipe.BuildData.Post += syplugin.BuildHandlePosts()

if hasScripts(b.d) {
if syscall.Getuid() == 0 {
sylog.Debugf("Starting build engine")
Expand Down Expand Up @@ -377,43 +382,41 @@ func getcp(def types.Definition, libraryURL, authToken string) (ConveyorPacker,

// makeDef gets a definition object from a spec
func makeDef(spec string) (types.Definition, error) {
var def types.Definition

if ok, err := IsValidURI(spec); ok && err == nil {
// URI passed as spec
def, err = types.NewDefinitionFromURI(spec)
if err != nil {
return def, fmt.Errorf("unable to parse URI %s: %v", spec, err)
}
} else if _, err := os.Stat(spec); err == nil {
// Non-URI passed as spec
return types.NewDefinitionFromURI(spec)
}

// Non-URI passed as spec
ok, err := parser.IsValidDefinition(spec)
if ok {
sylog.Debugf("Found valid definition: %s\n", spec)
// File exists and contains valid definition
defFile, err := os.Open(spec)
if err != nil {
return def, fmt.Errorf("unable to open file %s: %v", spec, err)
return types.Definition{}, fmt.Errorf("unable to open file %s: %v", spec, err)
}
defer defFile.Close()

if d, err := types.ParseDefinitionFile(defFile); err == nil {
// must be root to build from a definition
if os.Getuid() != 0 {
sylog.Fatalf("You must be the root user to build from a Singularity recipe file")
}
//definition used as input
def = d
} else {
//local image or sandbox, make sure it exists on filesystem
def = types.Definition{
Header: map[string]string{
"bootstrap": "localimage",
"from": spec,
},
}
// must be root to build from a definition
if os.Getuid() != 0 {
sylog.Fatalf("You must be the root user to build from a Singularity recipe file")
}
} else {
return def, fmt.Errorf("unable to build from %s: %v", spec, err)

return parser.ParseDefinitionFile(defFile)
} else if err == nil {
// File exists and does NOT contain a valid definition
// local image or sandbox
return types.Definition{
Header: map[string]string{
"bootstrap": "localimage",
"from": spec,
},
}, nil
}

return def, nil
// File does NOT exist or cannot be opened for another reason
return types.Definition{}, fmt.Errorf("unable to build from %s: %v", spec, err)
}

func (b *Build) addOptions() {
Expand Down Expand Up @@ -545,7 +548,7 @@ func insertDefinition(b *types.Bundle) error {
return err
}

b.Recipe.WriteDefinitionFile(f)
parser.WriteDefinitionFile(&b.Recipe, f)

return nil
}
Expand Down
5 changes: 3 additions & 2 deletions src/pkg/build/sources/conveyorPacker_arch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/sylabs/singularity/src/pkg/build/sources"
"github.com/sylabs/singularity/src/pkg/build/types"
"github.com/sylabs/singularity/src/pkg/build/types/parser"
"github.com/sylabs/singularity/src/pkg/test"
)

Expand Down Expand Up @@ -41,7 +42,7 @@ func TestArchConveyor(t *testing.T) {
return
}

b.Recipe, err = types.ParseDefinitionFile(defFile)
b.Recipe, err = parser.ParseDefinitionFile(defFile)
if err != nil {
t.Fatalf("failed to parse definition file %s: %v\n", archDef, err)
}
Expand Down Expand Up @@ -75,7 +76,7 @@ func TestArchPacker(t *testing.T) {
return
}

b.Recipe, err = types.ParseDefinitionFile(defFile)
b.Recipe, err = parser.ParseDefinitionFile(defFile)
if err != nil {
t.Fatalf("failed to parse definition file %s: %v\n", archDef, err)
}
Expand Down
5 changes: 3 additions & 2 deletions src/pkg/build/sources/conveyorPacker_busybox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/sylabs/singularity/src/pkg/build/sources"
"github.com/sylabs/singularity/src/pkg/build/types"
"github.com/sylabs/singularity/src/pkg/build/types/parser"
"github.com/sylabs/singularity/src/pkg/test"
)

Expand All @@ -36,7 +37,7 @@ func TestBusyBoxConveyor(t *testing.T) {
return
}

b.Recipe, err = types.ParseDefinitionFile(defFile)
b.Recipe, err = parser.ParseDefinitionFile(defFile)
if err != nil {
t.Fatalf("failed to parse definition file %s: %v\n", busyBoxDef, err)
}
Expand Down Expand Up @@ -66,7 +67,7 @@ func TestBusyBoxPacker(t *testing.T) {
return
}

b.Recipe, err = types.ParseDefinitionFile(defFile)
b.Recipe, err = parser.ParseDefinitionFile(defFile)
if err != nil {
t.Fatalf("failed to parse definition file %s: %v\n", busyBoxDef, err)
}
Expand Down
5 changes: 3 additions & 2 deletions src/pkg/build/sources/conveyorPacker_yum_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"testing"

"github.com/sylabs/singularity/src/pkg/build/types"
"github.com/sylabs/singularity/src/pkg/build/types/parser"
"github.com/sylabs/singularity/src/pkg/test"
)

Expand Down Expand Up @@ -41,7 +42,7 @@ func TestYumConveyor(t *testing.T) {
return
}

b.Recipe, err = types.ParseDefinitionFile(defFile)
b.Recipe, err = parser.ParseDefinitionFile(defFile)
if err != nil {
t.Fatalf("failed to parse definition file %s: %v\n", yumDef, err)
}
Expand Down Expand Up @@ -77,7 +78,7 @@ func TestYumPacker(t *testing.T) {
return
}

b.Recipe, err = types.ParseDefinitionFile(defFile)
b.Recipe, err = parser.ParseDefinitionFile(defFile)
if err != nil {
t.Fatalf("failed to parse definition file %s: %v\n", yumDef, err)
}
Expand Down
27 changes: 0 additions & 27 deletions src/pkg/build/types/definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,30 +92,3 @@ func NewDefinitionFromJSON(r io.Reader) (d Definition, err error) {

return d, nil
}

// validSections just contains a list of all the valid sections a definition file
// could contain. If any others are found, an error will generate
var validSections = map[string]bool{
"help": true,
"setup": true,
"files": true,
"labels": true,
"environment": true,
"pre": true,
"post": true,
"runscript": true,
"test": true,
"startscript": true,
}

// validHeaders just contains a list of all the valid headers a definition file
// could contain. If any others are found, an error will generate
var validHeaders = map[string]bool{
"bootstrap": true,
"from": true,
"includecmd": true,
"mirrorurl": true,
"updateurl": true,
"osversion": true,
"include": true,
}
Loading

0 comments on commit b9f0876

Please sign in to comment.