github.com/stackdocker/rkt@v0.10.1-0.20151109095037-1aa827478248/common/apps/apps.go (about) 1 // Copyright 2015 The rkt Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //+build linux 16 17 package apps 18 19 import ( 20 "fmt" 21 22 "github.com/coreos/rkt/Godeps/_workspace/src/github.com/appc/spec/schema" 23 "github.com/coreos/rkt/Godeps/_workspace/src/github.com/appc/spec/schema/types" 24 ) 25 26 type App struct { 27 Image string // the image reference as supplied by the user on the cli 28 Args []string // any arguments the user supplied for this app 29 Asc string // signature file override for image verification (if fetching occurs) 30 Exec string // exec override for image 31 Mounts []schema.Mount // mounts for this app (superseding any mounts in rktApps.mounts of same MountPoint) 32 33 // TODO(jonboulle): These images are partially-populated hashes, this should be clarified. 34 ImageID types.Hash // resolved image identifier 35 } 36 37 type Apps struct { 38 apps []App 39 Mounts []schema.Mount // global mounts applied to all apps 40 Volumes []types.Volume // volumes available to all apps 41 } 42 43 // Reset creates a new slice for al.apps, needed by tests 44 func (al *Apps) Reset() { 45 al.apps = make([]App, 0) 46 } 47 48 // Count returns the number of apps in al 49 func (al *Apps) Count() int { 50 return len(al.apps) 51 } 52 53 // Create creates a new app in al and returns a pointer to it 54 func (al *Apps) Create(img string) { 55 al.apps = append(al.apps, App{Image: img}) 56 } 57 58 // Last returns a pointer to the top app in al 59 func (al *Apps) Last() *App { 60 if len(al.apps) == 0 { 61 return nil 62 } 63 return &al.apps[len(al.apps)-1] 64 } 65 66 // Validate validates al for things like referential integrity of mounts<->volumes. 67 func (al *Apps) Validate() error { 68 vs := map[types.ACName]struct{}{} 69 for _, v := range al.Volumes { 70 vs[v.Name] = struct{}{} 71 } 72 73 f := func(mnts []schema.Mount) error { 74 for _, m := range mnts { 75 if _, ok := vs[m.Volume]; !ok { 76 return fmt.Errorf("dangling mount point %q: volume %q not found", m.Path, m.Volume) 77 } 78 } 79 return nil 80 } 81 82 if err := f(al.Mounts); err != nil { 83 return err 84 } 85 86 err := al.Walk(func(app *App) error { 87 return f(app.Mounts) 88 }) 89 90 /* TODO(vc): in debug/verbose mode say something about unused volumes? */ 91 return err 92 } 93 94 // Walk iterates on al.apps calling f for each app 95 // walking stops if f returns an error, the error is simply returned 96 func (al *Apps) Walk(f func(*App) error) error { 97 for i, _ := range al.apps { 98 // XXX(vc): note we supply f() with a pointer to the app instance in al.apps to enable modification by f() 99 if err := f(&al.apps[i]); err != nil { 100 return err 101 } 102 } 103 return nil 104 } 105 106 // these convenience functions just return typed lists containing just the named member 107 // TODO(vc): these probably go away when we just pass Apps to stage0 108 109 // GetImages returns a list of the images in al, one per app. 110 // The order reflects the app order in al. 111 func (al *Apps) GetImages() []string { 112 var il []string 113 for _, a := range al.apps { 114 il = append(il, a.Image) 115 } 116 return il 117 } 118 119 // GetArgs returns a list of lists of arguments in al, one list of args per app. 120 // The order reflects the app order in al. 121 func (al *Apps) GetArgs() [][]string { 122 var aal [][]string 123 for _, a := range al.apps { 124 aal = append(aal, a.Args) 125 } 126 return aal 127 } 128 129 // GetImageIDs returns a list of the imageIDs in al, one per app. 130 // The order reflects the app order in al. 131 func (al *Apps) GetImageIDs() []types.Hash { 132 var hl []types.Hash 133 for _, a := range al.apps { 134 hl = append(hl, a.ImageID) 135 } 136 return hl 137 }