github.com/rkt/rkt@v1.30.1-0.20200224141603-171c416fac02/stage0/manifest.go (about)

     1  // Copyright 2016 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 stage0
    18  
    19  import (
    20  	"encoding/json"
    21  	"errors"
    22  	"fmt"
    23  	"io/ioutil"
    24  	"strconv"
    25  
    26  	"github.com/appc/spec/schema"
    27  	"github.com/hashicorp/errwrap"
    28  	"github.com/rkt/rkt/common"
    29  )
    30  
    31  const (
    32  	enterEntrypoint  = "coreos.com/rkt/stage1/enter"
    33  	runEntrypoint    = "coreos.com/rkt/stage1/run"
    34  	gcEntrypoint     = "coreos.com/rkt/stage1/gc"
    35  	stopEntrypoint   = "coreos.com/rkt/stage1/stop"
    36  	attachEntrypoint = "coreos.com/rkt/stage1/attach"
    37  
    38  	appAddEntrypoint   = "coreos.com/rkt/stage1/app/add"
    39  	appRmEntrypoint    = "coreos.com/rkt/stage1/app/rm"
    40  	appStartEntrypoint = "coreos.com/rkt/stage1/app/start"
    41  	appStopEntrypoint  = "coreos.com/rkt/stage1/app/stop"
    42  )
    43  
    44  const (
    45  	interfaceVersion = "coreos.com/rkt/stage1/interface-version"
    46  )
    47  
    48  // supportsMutableEnvironment returns whether the given stage1 image supports mutable pod operations.
    49  // It introspects the stage1 manifest and checks the presence of app* entrypoints.
    50  func supportsMutableEnvironment(cdir string) (bool, error) {
    51  	b, err := ioutil.ReadFile(common.Stage1ManifestPath(cdir))
    52  	if err != nil {
    53  		return false, errwrap.Wrap(errors.New("error reading pod manifest"), err)
    54  	}
    55  
    56  	s1m := schema.ImageManifest{}
    57  	if err := json.Unmarshal(b, &s1m); err != nil {
    58  		return false, errwrap.Wrap(errors.New("error unmarshaling stage1 manifest"), err)
    59  	}
    60  
    61  	_, appRmOk := s1m.Annotations.Get(appRmEntrypoint)
    62  	_, appStartOk := s1m.Annotations.Get(appStartEntrypoint)
    63  	_, appStopOk := s1m.Annotations.Get(appStopEntrypoint)
    64  
    65  	return appRmOk && appStartOk && appStopOk, nil
    66  }
    67  
    68  // getStage1Entrypoint retrieves the named entrypoint from the stage1 manifest for a given pod
    69  func getStage1Entrypoint(cdir string, entrypoint string) (string, error) {
    70  	b, err := ioutil.ReadFile(common.Stage1ManifestPath(cdir))
    71  	if err != nil {
    72  		return "", errwrap.Wrap(errors.New("error reading pod manifest"), err)
    73  	}
    74  
    75  	s1m := schema.ImageManifest{}
    76  	if err := json.Unmarshal(b, &s1m); err != nil {
    77  		return "", errwrap.Wrap(errors.New("error unmarshaling stage1 manifest"), err)
    78  	}
    79  
    80  	if ep, ok := s1m.Annotations.Get(entrypoint); ok {
    81  		return ep, nil
    82  	}
    83  
    84  	return "", fmt.Errorf("entrypoint %q not found", entrypoint)
    85  }
    86  
    87  // getStage1InterfaceVersion retrieves the interface version from the stage1
    88  // manifest for a given pod
    89  func getStage1InterfaceVersion(cdir string) (int, error) {
    90  	b, err := ioutil.ReadFile(common.Stage1ManifestPath(cdir))
    91  	if err != nil {
    92  		return -1, errwrap.Wrap(errors.New("error reading pod manifest"), err)
    93  	}
    94  
    95  	s1m := schema.ImageManifest{}
    96  	if err := json.Unmarshal(b, &s1m); err != nil {
    97  		return -1, errwrap.Wrap(errors.New("error unmarshaling stage1 manifest"), err)
    98  	}
    99  
   100  	if iv, ok := s1m.Annotations.Get(interfaceVersion); ok {
   101  		v, err := strconv.Atoi(iv)
   102  		if err != nil {
   103  			return -1, errwrap.Wrap(errors.New("error parsing interface version"), err)
   104  		}
   105  		return v, nil
   106  	}
   107  
   108  	// "interface-version" annotation not found, assume version 1
   109  	return 1, nil
   110  }
   111  
   112  func interfaceVersionSupportsHostname(version int) bool {
   113  	return version > 1
   114  }
   115  
   116  func interfaceVersionSupportsInsecureOptions(version int) bool {
   117  	return version > 2
   118  }
   119  
   120  // support --dns-mode and --hostentry
   121  func interfaceVersionSupportsDNSConfMode(version int) bool {
   122  	return version > 3
   123  }
   124  
   125  func interfaceVersionSupportsGCLocalConfig(version int) bool {
   126  	return version >= 5
   127  }
   128  
   129  func interfaceVersionSupportsIPCMode(version int) bool {
   130  	return version >= 6
   131  }