Skip to content

Commit b9f0876

Browse files
authored
Merge pull request #2083 from bauerm97/apps-support-static
Add support for apps to Singularity 3.0
2 parents ebf2f6f + a144f29 commit b9f0876

File tree

14 files changed

+751
-125
lines changed

14 files changed

+751
-125
lines changed

src/cmd/singularity/cli/action_flags.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515

1616
// actionflags.go contains flag variables for action-like commands to draw from
1717
var (
18+
AppName string
1819
BindPaths []string
1920
HomePath string
2021
OverlayPath []string
@@ -74,6 +75,9 @@ func init() {
7475

7576
// initPathVars initializes flags that take a string argument
7677
func initPathVars() {
78+
// --app
79+
actionFlags.StringVar(&AppName, "app", "", "Set container app to run")
80+
7781
// -B|--bind
7882
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.")
7983
actionFlags.SetAnnotation("bind", "argtag", []string{"<spec>"})

src/cmd/singularity/cli/actions.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ func init() {
7777
cmd.Flags().AddFlag(actionFlags.Lookup("no-init"))
7878
cmd.Flags().AddFlag(actionFlags.Lookup("security"))
7979
cmd.Flags().AddFlag(actionFlags.Lookup("apply-cgroups"))
80+
cmd.Flags().AddFlag(actionFlags.Lookup("app"))
8081
cmd.Flags().SetInterspersed(false)
8182
}
8283

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

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

435+
generator.AddProcessEnv("SINGULARITY_APPNAME", AppName)
436+
434437
cfg := &config.Common{
435438
EngineName: singularity.Name,
436439
ContainerID: name,

src/cmd/singularity/cli/singularity.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/sylabs/singularity/src/docs"
1818
"github.com/sylabs/singularity/src/pkg/buildcfg"
1919
"github.com/sylabs/singularity/src/pkg/sylog"
20+
"github.com/sylabs/singularity/src/pkg/syplugin"
2021
"github.com/sylabs/singularity/src/pkg/util/auth"
2122
)
2223

@@ -153,6 +154,7 @@ func handleEnv(flag *pflag.Flag) {
153154
func persistentPreRun(cmd *cobra.Command, args []string) {
154155
setSylogMessageLevel(cmd, args)
155156
updateFlagsFromEnv(cmd)
157+
syplugin.Init()
156158
}
157159

158160
// sylabsToken process the authentication Token

src/pkg/build/assemblers/assembler_sif.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/satori/go.uuid"
1818
"github.com/sylabs/sif/pkg/sif"
1919
"github.com/sylabs/singularity/src/pkg/build/types"
20+
"github.com/sylabs/singularity/src/pkg/build/types/parser"
2021
"github.com/sylabs/singularity/src/pkg/sylog"
2122
)
2223

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

8889
// convert definition to plain text
8990
var buf bytes.Buffer
90-
b.Recipe.WriteDefinitionFile(&buf)
91+
parser.WriteDefinitionFile(&(b.Recipe), &buf)
9192
def := buf.Bytes()
9293

9394
// make system partition image

src/pkg/build/build.go

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ import (
2121
"github.com/sylabs/singularity/src/pkg/build/assemblers"
2222
"github.com/sylabs/singularity/src/pkg/build/sources"
2323
"github.com/sylabs/singularity/src/pkg/build/types"
24+
"github.com/sylabs/singularity/src/pkg/build/types/parser"
2425
"github.com/sylabs/singularity/src/pkg/buildcfg"
2526
"github.com/sylabs/singularity/src/pkg/sylog"
27+
"github.com/sylabs/singularity/src/pkg/syplugin"
2628
syexec "github.com/sylabs/singularity/src/pkg/util/exec"
2729
"github.com/sylabs/singularity/src/runtime/engines/config"
2830
"github.com/sylabs/singularity/src/runtime/engines/config/oci"
@@ -173,6 +175,9 @@ func (b *Build) Full() error {
173175
}
174176
}
175177

178+
syplugin.BuildHandleBundles(b.b)
179+
b.b.Recipe.BuildData.Post += syplugin.BuildHandlePosts()
180+
176181
if hasScripts(b.d) {
177182
if syscall.Getuid() == 0 {
178183
sylog.Debugf("Starting build engine")
@@ -377,43 +382,41 @@ func getcp(def types.Definition, libraryURL, authToken string) (ConveyorPacker,
377382

378383
// makeDef gets a definition object from a spec
379384
func makeDef(spec string) (types.Definition, error) {
380-
var def types.Definition
381-
382385
if ok, err := IsValidURI(spec); ok && err == nil {
383386
// URI passed as spec
384-
def, err = types.NewDefinitionFromURI(spec)
385-
if err != nil {
386-
return def, fmt.Errorf("unable to parse URI %s: %v", spec, err)
387-
}
388-
} else if _, err := os.Stat(spec); err == nil {
389-
// Non-URI passed as spec
387+
return types.NewDefinitionFromURI(spec)
388+
}
389+
390+
// Non-URI passed as spec
391+
ok, err := parser.IsValidDefinition(spec)
392+
if ok {
393+
sylog.Debugf("Found valid definition: %s\n", spec)
394+
// File exists and contains valid definition
390395
defFile, err := os.Open(spec)
391396
if err != nil {
392-
return def, fmt.Errorf("unable to open file %s: %v", spec, err)
397+
return types.Definition{}, fmt.Errorf("unable to open file %s: %v", spec, err)
393398
}
394399
defer defFile.Close()
395400

396-
if d, err := types.ParseDefinitionFile(defFile); err == nil {
397-
// must be root to build from a definition
398-
if os.Getuid() != 0 {
399-
sylog.Fatalf("You must be the root user to build from a Singularity recipe file")
400-
}
401-
//definition used as input
402-
def = d
403-
} else {
404-
//local image or sandbox, make sure it exists on filesystem
405-
def = types.Definition{
406-
Header: map[string]string{
407-
"bootstrap": "localimage",
408-
"from": spec,
409-
},
410-
}
401+
// must be root to build from a definition
402+
if os.Getuid() != 0 {
403+
sylog.Fatalf("You must be the root user to build from a Singularity recipe file")
411404
}
412-
} else {
413-
return def, fmt.Errorf("unable to build from %s: %v", spec, err)
405+
406+
return parser.ParseDefinitionFile(defFile)
407+
} else if err == nil {
408+
// File exists and does NOT contain a valid definition
409+
// local image or sandbox
410+
return types.Definition{
411+
Header: map[string]string{
412+
"bootstrap": "localimage",
413+
"from": spec,
414+
},
415+
}, nil
414416
}
415417

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

419422
func (b *Build) addOptions() {
@@ -545,7 +548,7 @@ func insertDefinition(b *types.Bundle) error {
545548
return err
546549
}
547550

548-
b.Recipe.WriteDefinitionFile(f)
551+
parser.WriteDefinitionFile(&b.Recipe, f)
549552

550553
return nil
551554
}

src/pkg/build/sources/conveyorPacker_arch_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"github.com/sylabs/singularity/src/pkg/build/sources"
1414
"github.com/sylabs/singularity/src/pkg/build/types"
15+
"github.com/sylabs/singularity/src/pkg/build/types/parser"
1516
"github.com/sylabs/singularity/src/pkg/test"
1617
)
1718

@@ -41,7 +42,7 @@ func TestArchConveyor(t *testing.T) {
4142
return
4243
}
4344

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

78-
b.Recipe, err = types.ParseDefinitionFile(defFile)
79+
b.Recipe, err = parser.ParseDefinitionFile(defFile)
7980
if err != nil {
8081
t.Fatalf("failed to parse definition file %s: %v\n", archDef, err)
8182
}

src/pkg/build/sources/conveyorPacker_busybox_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/sylabs/singularity/src/pkg/build/sources"
1313
"github.com/sylabs/singularity/src/pkg/build/types"
14+
"github.com/sylabs/singularity/src/pkg/build/types/parser"
1415
"github.com/sylabs/singularity/src/pkg/test"
1516
)
1617

@@ -36,7 +37,7 @@ func TestBusyBoxConveyor(t *testing.T) {
3637
return
3738
}
3839

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

69-
b.Recipe, err = types.ParseDefinitionFile(defFile)
70+
b.Recipe, err = parser.ParseDefinitionFile(defFile)
7071
if err != nil {
7172
t.Fatalf("failed to parse definition file %s: %v\n", busyBoxDef, err)
7273
}

src/pkg/build/sources/conveyorPacker_yum_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"testing"
1212

1313
"github.com/sylabs/singularity/src/pkg/build/types"
14+
"github.com/sylabs/singularity/src/pkg/build/types/parser"
1415
"github.com/sylabs/singularity/src/pkg/test"
1516
)
1617

@@ -41,7 +42,7 @@ func TestYumConveyor(t *testing.T) {
4142
return
4243
}
4344

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

80-
b.Recipe, err = types.ParseDefinitionFile(defFile)
81+
b.Recipe, err = parser.ParseDefinitionFile(defFile)
8182
if err != nil {
8283
t.Fatalf("failed to parse definition file %s: %v\n", yumDef, err)
8384
}

src/pkg/build/types/definition.go

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -92,30 +92,3 @@ func NewDefinitionFromJSON(r io.Reader) (d Definition, err error) {
9292

9393
return d, nil
9494
}
95-
96-
// validSections just contains a list of all the valid sections a definition file
97-
// could contain. If any others are found, an error will generate
98-
var validSections = map[string]bool{
99-
"help": true,
100-
"setup": true,
101-
"files": true,
102-
"labels": true,
103-
"environment": true,
104-
"pre": true,
105-
"post": true,
106-
"runscript": true,
107-
"test": true,
108-
"startscript": true,
109-
}
110-
111-
// validHeaders just contains a list of all the valid headers a definition file
112-
// could contain. If any others are found, an error will generate
113-
var validHeaders = map[string]bool{
114-
"bootstrap": true,
115-
"from": true,
116-
"includecmd": true,
117-
"mirrorurl": true,
118-
"updateurl": true,
119-
"osversion": true,
120-
"include": true,
121-
}

0 commit comments

Comments
 (0)