github.com/blixtra/rkt@v0.8.1-0.20160204105720-ab0d1add1a43/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/appc/spec/schema"
    23  	"github.com/appc/spec/schema/types"
    24  )
    25  
    26  // AppImageType describes a type of an image reference. The reference
    27  // can either be guessed or be a hash, a URL, a path, or a name. The
    28  // first option means that the application will have to deduce the
    29  // actual type (one of the last four).
    30  type AppImageType int
    31  
    32  const (
    33  	AppImageGuess AppImageType = iota // image type to be guessed
    34  	AppImageHash                      // image hash
    35  	AppImageURL                       // image URL with a scheme
    36  	AppImagePath                      // absolute or relative path
    37  	AppImageName                      // image name
    38  )
    39  
    40  type App struct {
    41  	Image       string                // the image reference as supplied by the user on the cli
    42  	ImType      AppImageType          // the type of the image reference (to be guessed, url, path or hash)
    43  	Args        []string              // any arguments the user supplied for this app
    44  	Asc         string                // signature file override for image verification (if fetching occurs)
    45  	Exec        string                // exec override for image
    46  	Mounts      []schema.Mount        // mounts for this app (superseding any mounts in rktApps.mounts of same MountPoint)
    47  	MemoryLimit *types.ResourceMemory // memory isolator override
    48  	CPULimit    *types.ResourceCPU    // cpu isolator override
    49  
    50  	// TODO(jonboulle): These images are partially-populated hashes, this should be clarified.
    51  	ImageID types.Hash // resolved image identifier
    52  }
    53  
    54  type Apps struct {
    55  	apps    []App
    56  	Mounts  []schema.Mount // global mounts applied to all apps
    57  	Volumes []types.Volume // volumes available to all apps
    58  }
    59  
    60  // Reset creates a new slice for al.apps, needed by tests
    61  func (al *Apps) Reset() {
    62  	al.apps = make([]App, 0)
    63  }
    64  
    65  // Count returns the number of apps in al
    66  func (al *Apps) Count() int {
    67  	return len(al.apps)
    68  }
    69  
    70  // Create creates a new app in al and returns a pointer to it
    71  func (al *Apps) Create(img string) {
    72  	al.apps = append(al.apps, App{Image: img})
    73  }
    74  
    75  // Last returns a pointer to the top app in al
    76  func (al *Apps) Last() *App {
    77  	if len(al.apps) == 0 {
    78  		return nil
    79  	}
    80  	return &al.apps[len(al.apps)-1]
    81  }
    82  
    83  // Validate validates al for things like referential integrity of mounts<->volumes.
    84  func (al *Apps) Validate() error {
    85  	vs := map[types.ACName]struct{}{}
    86  	for _, v := range al.Volumes {
    87  		vs[v.Name] = struct{}{}
    88  	}
    89  
    90  	f := func(mnts []schema.Mount) error {
    91  		for _, m := range mnts {
    92  			if _, ok := vs[m.Volume]; !ok {
    93  				return fmt.Errorf("dangling mount point %q: volume %q not found", m.Path, m.Volume)
    94  			}
    95  		}
    96  		return nil
    97  	}
    98  
    99  	if err := f(al.Mounts); err != nil {
   100  		return err
   101  	}
   102  
   103  	err := al.Walk(func(app *App) error {
   104  		return f(app.Mounts)
   105  	})
   106  
   107  	/* TODO(vc): in debug/verbose mode say something about unused volumes? */
   108  	return err
   109  }
   110  
   111  // Walk iterates on al.apps calling f for each app
   112  // walking stops if f returns an error, the error is simply returned
   113  func (al *Apps) Walk(f func(*App) error) error {
   114  	for i, _ := range al.apps {
   115  		// XXX(vc): note we supply f() with a pointer to the app instance in al.apps to enable modification by f()
   116  		if err := f(&al.apps[i]); err != nil {
   117  			return err
   118  		}
   119  	}
   120  	return nil
   121  }
   122  
   123  // these convenience functions just return typed lists containing just the named member
   124  // TODO(vc): these probably go away when we just pass Apps to stage0
   125  
   126  // GetImages returns a list of the images in al, one per app.
   127  // The order reflects the app order in al.
   128  func (al *Apps) GetImages() []string {
   129  	var il []string
   130  	for _, a := range al.apps {
   131  		il = append(il, a.Image)
   132  	}
   133  	return il
   134  }
   135  
   136  // GetArgs returns a list of lists of arguments in al, one list of args per app.
   137  // The order reflects the app order in al.
   138  func (al *Apps) GetArgs() [][]string {
   139  	var aal [][]string
   140  	for _, a := range al.apps {
   141  		aal = append(aal, a.Args)
   142  	}
   143  	return aal
   144  }
   145  
   146  // GetImageIDs returns a list of the imageIDs in al, one per app.
   147  // The order reflects the app order in al.
   148  func (al *Apps) GetImageIDs() []types.Hash {
   149  	var hl []types.Hash
   150  	for _, a := range al.apps {
   151  		hl = append(hl, a.ImageID)
   152  	}
   153  	return hl
   154  }