mirror of
https://github.com/rancher/os.git
synced 2025-07-13 06:34:04 +00:00
Merge pull request #1655 from SvenDowideit/fail-cloud-init-datasources-based-on-error-types
Fail cloud init datasources based on error types
This commit is contained in:
commit
d26d20d730
@ -20,12 +20,10 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/mount"
|
|
||||||
"github.com/rancher/os/cmd/control"
|
"github.com/rancher/os/cmd/control"
|
||||||
"github.com/rancher/os/cmd/network"
|
"github.com/rancher/os/cmd/network"
|
||||||
rancherConfig "github.com/rancher/os/config"
|
rancherConfig "github.com/rancher/os/config"
|
||||||
@ -49,9 +47,6 @@ const (
|
|||||||
datasourceInterval = 100 * time.Millisecond
|
datasourceInterval = 100 * time.Millisecond
|
||||||
datasourceMaxInterval = 30 * time.Second
|
datasourceMaxInterval = 30 * time.Second
|
||||||
datasourceTimeout = 5 * time.Minute
|
datasourceTimeout = 5 * time.Minute
|
||||||
configDevName = "config-2"
|
|
||||||
configDev = "LABEL=" + configDevName
|
|
||||||
configDevMountPoint = "/media/config-2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Main() {
|
func Main() {
|
||||||
@ -70,34 +65,85 @@ func Main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func MountConfigDrive() error {
|
|
||||||
if err := os.MkdirAll(configDevMountPoint, 644); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
configDev := util.ResolveDevice(configDev)
|
|
||||||
|
|
||||||
if configDev == "" {
|
|
||||||
return mount.Mount(configDevName, configDevMountPoint, "9p", "trans=virtio,version=9p2000.L")
|
|
||||||
}
|
|
||||||
|
|
||||||
fsType, err := util.GetFsType(configDev)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return mount.Mount(configDev, configDevMountPoint, fsType, "ro")
|
|
||||||
}
|
|
||||||
|
|
||||||
func UnmountConfigDrive() error {
|
|
||||||
return syscall.Unmount(configDevMountPoint, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SaveCloudConfig(network bool) error {
|
func SaveCloudConfig(network bool) error {
|
||||||
userDataBytes, metadata, err := fetchUserData(network)
|
log.Debugf("SaveCloudConfig")
|
||||||
|
cfg := rancherConfig.LoadConfig()
|
||||||
|
|
||||||
|
dss := getDatasources(cfg, network)
|
||||||
|
if len(dss) == 0 {
|
||||||
|
log.Errorf("currentDatasource - none found")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
selectDatasource(dss)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RequiresNetwork(datasource string) bool {
|
||||||
|
// TODO: move into the datasources (and metadatasources)
|
||||||
|
parts := strings.SplitN(datasource, ":", 2)
|
||||||
|
requiresNetwork, ok := map[string]bool{
|
||||||
|
"ec2": true,
|
||||||
|
"file": false,
|
||||||
|
"url": true,
|
||||||
|
"cmdline": true,
|
||||||
|
"configdrive": false,
|
||||||
|
"digitalocean": true,
|
||||||
|
"gce": true,
|
||||||
|
"packet": true,
|
||||||
|
}[parts[0]]
|
||||||
|
return ok && requiresNetwork
|
||||||
|
}
|
||||||
|
|
||||||
|
func saveFiles(cloudConfigBytes, scriptBytes []byte, metadata datasource.Metadata) error {
|
||||||
|
os.MkdirAll(rancherConfig.CloudConfigDir, os.ModeDir|0600)
|
||||||
|
|
||||||
|
if len(scriptBytes) > 0 {
|
||||||
|
log.Infof("Writing to %s", rancherConfig.CloudConfigScriptFile)
|
||||||
|
if err := util.WriteFileAtomic(rancherConfig.CloudConfigScriptFile, scriptBytes, 500); err != nil {
|
||||||
|
log.Errorf("Error while writing file %s: %v", rancherConfig.CloudConfigScriptFile, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cloudConfigBytes) > 0 {
|
||||||
|
if err := util.WriteFileAtomic(rancherConfig.CloudConfigBootFile, cloudConfigBytes, 400); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Don't put secrets into the log
|
||||||
|
//log.Infof("Written to %s:\n%s", rancherConfig.CloudConfigBootFile, string(cloudConfigBytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
metaDataBytes, err := yaml.Marshal(metadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = util.WriteFileAtomic(rancherConfig.MetaDataFile, metaDataBytes, 400); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Don't put secrets into the log
|
||||||
|
//log.Infof("Written to %s:\n%s", rancherConfig.MetaDataFile, string(metaDataBytes))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchAndSave(ds datasource.Datasource) error {
|
||||||
|
var metadata datasource.Metadata
|
||||||
|
|
||||||
|
log.Infof("Fetching user-data from datasource %s", ds)
|
||||||
|
userDataBytes, err := ds.FetchUserdata()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed fetching user-data from datasource: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Infof("Fetching meta-data from datasource of type %v", ds.Type())
|
||||||
|
metadata, err = ds.FetchMetadata()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed fetching meta-data from datasource: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
userData := string(userDataBytes)
|
userData := string(userDataBytes)
|
||||||
scriptBytes := []byte{}
|
scriptBytes := []byte{}
|
||||||
|
|
||||||
@ -127,86 +173,6 @@ func SaveCloudConfig(network bool) error {
|
|||||||
return saveFiles(userDataBytes, scriptBytes, metadata)
|
return saveFiles(userDataBytes, scriptBytes, metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RequiresNetwork(datasource string) bool {
|
|
||||||
parts := strings.SplitN(datasource, ":", 2)
|
|
||||||
requiresNetwork, ok := map[string]bool{
|
|
||||||
"ec2": true,
|
|
||||||
"file": false,
|
|
||||||
"url": true,
|
|
||||||
"cmdline": true,
|
|
||||||
"configdrive": false,
|
|
||||||
"digitalocean": true,
|
|
||||||
"gce": true,
|
|
||||||
"packet": true,
|
|
||||||
}[parts[0]]
|
|
||||||
return ok && requiresNetwork
|
|
||||||
}
|
|
||||||
|
|
||||||
func saveFiles(cloudConfigBytes, scriptBytes []byte, metadata datasource.Metadata) error {
|
|
||||||
os.MkdirAll(rancherConfig.CloudConfigDir, os.ModeDir|0600)
|
|
||||||
|
|
||||||
if len(scriptBytes) > 0 {
|
|
||||||
log.Infof("Writing to %s", rancherConfig.CloudConfigScriptFile)
|
|
||||||
if err := util.WriteFileAtomic(rancherConfig.CloudConfigScriptFile, scriptBytes, 500); err != nil {
|
|
||||||
log.Errorf("Error while writing file %s: %v", rancherConfig.CloudConfigScriptFile, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cloudConfigBytes) > 0 {
|
|
||||||
if err := util.WriteFileAtomic(rancherConfig.CloudConfigBootFile, cloudConfigBytes, 400); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Infof("Written to %s:\n%s", rancherConfig.CloudConfigBootFile, string(cloudConfigBytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
metaDataBytes, err := yaml.Marshal(metadata)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = util.WriteFileAtomic(rancherConfig.MetaDataFile, metaDataBytes, 400); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Infof("Written to %s:\n%s", rancherConfig.MetaDataFile, string(metaDataBytes))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func currentDatasource(network bool) (datasource.Datasource, error) {
|
|
||||||
cfg := rancherConfig.LoadConfig()
|
|
||||||
|
|
||||||
dss := getDatasources(cfg, network)
|
|
||||||
if len(dss) == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ds := selectDatasource(dss)
|
|
||||||
return ds, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func fetchUserData(network bool) ([]byte, datasource.Metadata, error) {
|
|
||||||
var metadata datasource.Metadata
|
|
||||||
ds, err := currentDatasource(network)
|
|
||||||
if err != nil || ds == nil {
|
|
||||||
log.Errorf("Failed to select datasource: %v", err)
|
|
||||||
return nil, metadata, err
|
|
||||||
}
|
|
||||||
log.Infof("Fetching user-data from datasource %v", ds.Type())
|
|
||||||
userDataBytes, err := ds.FetchUserdata()
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Failed fetching user-data from datasource: %v", err)
|
|
||||||
return nil, metadata, err
|
|
||||||
}
|
|
||||||
log.Infof("Fetching meta-data from datasource of type %v", ds.Type())
|
|
||||||
metadata, err = ds.FetchMetadata()
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Failed fetching meta-data from datasource: %v", err)
|
|
||||||
return nil, metadata, err
|
|
||||||
}
|
|
||||||
return userDataBytes, metadata, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getDatasources creates a slice of possible Datasources for cloudinit based
|
// getDatasources creates a slice of possible Datasources for cloudinit based
|
||||||
// on the different source command-line flags.
|
// on the different source command-line flags.
|
||||||
func getDatasources(cfg *rancherConfig.CloudConfig, network bool) []datasource.Datasource {
|
func getDatasources(cfg *rancherConfig.CloudConfig, network bool) []datasource.Datasource {
|
||||||
@ -299,13 +265,17 @@ func selectDatasource(sources []datasource.Datasource) datasource.Datasource {
|
|||||||
|
|
||||||
duration := datasourceInterval
|
duration := datasourceInterval
|
||||||
for {
|
for {
|
||||||
log.Infof("Checking availability of %q\n", s.Type())
|
log.Infof("cloud-init: Checking availability of %q\n", s.Type())
|
||||||
if s.IsAvailable() {
|
if s.IsAvailable() {
|
||||||
|
log.Infof("cloud-init: Datasource available: %s", s)
|
||||||
ds <- s
|
ds <- s
|
||||||
return
|
return
|
||||||
} else if !s.AvailabilityChanges() {
|
}
|
||||||
|
if !s.AvailabilityChanges() {
|
||||||
|
log.Infof("cloud-init: Datasource unavailable, skipping: %s", s)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
log.Errorf("cloud-init: Datasource not ready, will retry: %s", s)
|
||||||
select {
|
select {
|
||||||
case <-stop:
|
case <-stop:
|
||||||
return
|
return
|
||||||
@ -325,6 +295,10 @@ func selectDatasource(sources []datasource.Datasource) datasource.Datasource {
|
|||||||
var s datasource.Datasource
|
var s datasource.Datasource
|
||||||
select {
|
select {
|
||||||
case s = <-ds:
|
case s = <-ds:
|
||||||
|
err := fetchAndSave(s)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Error fetching cloud-init datasource(%s): %s", s, err)
|
||||||
|
}
|
||||||
case <-done:
|
case <-done:
|
||||||
case <-time.After(datasourceTimeout):
|
case <-time.After(datasourceTimeout):
|
||||||
}
|
}
|
||||||
|
82
config/cloudinit/datasource/configdrive/configdrive.go
Normal file → Executable file
82
config/cloudinit/datasource/configdrive/configdrive.go
Normal file → Executable file
@ -16,34 +16,67 @@ package configdrive
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/rancher/os/log"
|
||||||
|
|
||||||
|
"github.com/docker/docker/pkg/mount"
|
||||||
"github.com/rancher/os/config/cloudinit/datasource"
|
"github.com/rancher/os/config/cloudinit/datasource"
|
||||||
|
"github.com/rancher/os/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
configDevName = "config-2"
|
||||||
|
configDev = "LABEL=" + configDevName
|
||||||
|
configDevMountPoint = "/media/config-2"
|
||||||
openstackAPIVersion = "latest"
|
openstackAPIVersion = "latest"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConfigDrive struct {
|
type ConfigDrive struct {
|
||||||
root string
|
root string
|
||||||
readFile func(filename string) ([]byte, error)
|
readFile func(filename string) ([]byte, error)
|
||||||
|
lastError error
|
||||||
|
availabilityChanges bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDatasource(root string) *ConfigDrive {
|
func NewDatasource(root string) *ConfigDrive {
|
||||||
return &ConfigDrive{root, ioutil.ReadFile}
|
return &ConfigDrive{root, ioutil.ReadFile, nil, true}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cd *ConfigDrive) IsAvailable() bool {
|
func (cd *ConfigDrive) IsAvailable() bool {
|
||||||
_, err := os.Stat(cd.root)
|
if cd.root == configDevMountPoint {
|
||||||
return !os.IsNotExist(err)
|
cd.lastError = MountConfigDrive()
|
||||||
|
if cd.lastError != nil {
|
||||||
|
log.Error(cd.lastError)
|
||||||
|
// Don't keep retrying if we can't mount
|
||||||
|
cd.availabilityChanges = false
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
defer cd.Finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
_, cd.lastError = os.Stat(cd.root)
|
||||||
|
return !os.IsNotExist(cd.lastError)
|
||||||
|
// TODO: consider changing IsNotExists to not-available _and_ does not change
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cd *ConfigDrive) Finish() error {
|
||||||
|
return UnmountConfigDrive()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cd *ConfigDrive) String() string {
|
||||||
|
if cd.lastError != nil {
|
||||||
|
return fmt.Sprintf("%s: %s (lastError: %s)", cd.Type(), cd.root, cd.lastError)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s: %s", cd.Type(), cd.root)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cd *ConfigDrive) AvailabilityChanges() bool {
|
func (cd *ConfigDrive) AvailabilityChanges() bool {
|
||||||
return true
|
return cd.availabilityChanges
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cd *ConfigDrive) ConfigRoot() string {
|
func (cd *ConfigDrive) ConfigRoot() string {
|
||||||
@ -93,10 +126,43 @@ func (cd *ConfigDrive) openstackVersionRoot() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cd *ConfigDrive) tryReadFile(filename string) ([]byte, error) {
|
func (cd *ConfigDrive) tryReadFile(filename string) ([]byte, error) {
|
||||||
log.Printf("Attempting to read from %q\n", filename)
|
if cd.root == configDevMountPoint {
|
||||||
|
cd.lastError = MountConfigDrive()
|
||||||
|
if cd.lastError != nil {
|
||||||
|
log.Error(cd.lastError)
|
||||||
|
return nil, cd.lastError
|
||||||
|
}
|
||||||
|
defer cd.Finish()
|
||||||
|
}
|
||||||
|
log.Debugf("Attempting to read from %q\n", filename)
|
||||||
data, err := cd.readFile(filename)
|
data, err := cd.readFile(filename)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("ERROR read cloud-config file(%s) - err: %q", filename, err)
|
||||||
|
}
|
||||||
return data, err
|
return data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MountConfigDrive() error {
|
||||||
|
if err := os.MkdirAll(configDevMountPoint, 644); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
configDev := util.ResolveDevice(configDev)
|
||||||
|
|
||||||
|
if configDev == "" {
|
||||||
|
return mount.Mount(configDevName, configDevMountPoint, "9p", "trans=virtio,version=9p2000.L")
|
||||||
|
}
|
||||||
|
|
||||||
|
fsType, err := util.GetFsType(configDev)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return mount.Mount(configDev, configDevMountPoint, fsType, "ro")
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmountConfigDrive() error {
|
||||||
|
return syscall.Unmount(configDevMountPoint, 0)
|
||||||
|
}
|
||||||
|
6
config/cloudinit/datasource/configdrive/configdrive_test.go
Normal file → Executable file
6
config/cloudinit/datasource/configdrive/configdrive_test.go
Normal file → Executable file
@ -57,7 +57,7 @@ func TestFetchMetadata(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
cd := ConfigDrive{tt.root, tt.files.ReadFile}
|
cd := ConfigDrive{tt.root, tt.files.ReadFile, nil, true}
|
||||||
metadata, err := cd.FetchMetadata()
|
metadata, err := cd.FetchMetadata()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("bad error for %+v: want %v, got %q", tt, nil, err)
|
t.Fatalf("bad error for %+v: want %v, got %q", tt, nil, err)
|
||||||
@ -91,7 +91,7 @@ func TestFetchUserdata(t *testing.T) {
|
|||||||
"userdata",
|
"userdata",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
cd := ConfigDrive{tt.root, tt.files.ReadFile}
|
cd := ConfigDrive{tt.root, tt.files.ReadFile, nil, true}
|
||||||
userdata, err := cd.FetchUserdata()
|
userdata, err := cd.FetchUserdata()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("bad error for %+v: want %v, got %q", tt, nil, err)
|
t.Fatalf("bad error for %+v: want %v, got %q", tt, nil, err)
|
||||||
@ -116,7 +116,7 @@ func TestConfigRoot(t *testing.T) {
|
|||||||
"/media/configdrive/openstack",
|
"/media/configdrive/openstack",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
cd := ConfigDrive{tt.root, nil}
|
cd := ConfigDrive{tt.root, nil, nil, true}
|
||||||
if configRoot := cd.ConfigRoot(); configRoot != tt.configRoot {
|
if configRoot := cd.ConfigRoot(); configRoot != tt.configRoot {
|
||||||
t.Fatalf("bad config root for %q: want %q, got %q", tt, tt.configRoot, configRoot)
|
t.Fatalf("bad config root for %q: want %q, got %q", tt, tt.configRoot, configRoot)
|
||||||
}
|
}
|
||||||
|
3
config/cloudinit/datasource/datasource.go
Normal file → Executable file
3
config/cloudinit/datasource/datasource.go
Normal file → Executable file
@ -25,6 +25,9 @@ type Datasource interface {
|
|||||||
FetchMetadata() (Metadata, error)
|
FetchMetadata() (Metadata, error)
|
||||||
FetchUserdata() ([]byte, error)
|
FetchUserdata() ([]byte, error)
|
||||||
Type() string
|
Type() string
|
||||||
|
String() string
|
||||||
|
// Finish gives the datasource the oportunity to clean up, unmount or release any open / cache resources
|
||||||
|
Finish() error
|
||||||
}
|
}
|
||||||
|
|
||||||
type Metadata struct {
|
type Metadata struct {
|
||||||
|
18
config/cloudinit/datasource/file/file.go
Normal file → Executable file
18
config/cloudinit/datasource/file/file.go
Normal file → Executable file
@ -15,6 +15,7 @@
|
|||||||
package file
|
package file
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
@ -22,16 +23,25 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type LocalFile struct {
|
type LocalFile struct {
|
||||||
path string
|
path string
|
||||||
|
lastError error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDatasource(path string) *LocalFile {
|
func NewDatasource(path string) *LocalFile {
|
||||||
return &LocalFile{path}
|
return &LocalFile{path, nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *LocalFile) IsAvailable() bool {
|
func (f *LocalFile) IsAvailable() bool {
|
||||||
_, err := os.Stat(f.path)
|
_, f.lastError = os.Stat(f.path)
|
||||||
return !os.IsNotExist(err)
|
return !os.IsNotExist(f.lastError)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *LocalFile) Finish() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *LocalFile) String() string {
|
||||||
|
return fmt.Sprintf("%s: %s (lastError: %s)", f.Type(), f.path, f.lastError)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *LocalFile) AvailabilityChanges() bool {
|
func (f *LocalFile) AvailabilityChanges() bool {
|
||||||
|
16
config/cloudinit/datasource/metadata/metadata.go
Normal file → Executable file
16
config/cloudinit/datasource/metadata/metadata.go
Normal file → Executable file
@ -15,6 +15,7 @@
|
|||||||
package metadata
|
package metadata
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -27,18 +28,27 @@ type Service struct {
|
|||||||
APIVersion string
|
APIVersion string
|
||||||
UserdataPath string
|
UserdataPath string
|
||||||
MetadataPath string
|
MetadataPath string
|
||||||
|
lastError error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDatasource(root, apiVersion, userdataPath, metadataPath string, header http.Header) Service {
|
func NewDatasource(root, apiVersion, userdataPath, metadataPath string, header http.Header) Service {
|
||||||
if !strings.HasSuffix(root, "/") {
|
if !strings.HasSuffix(root, "/") {
|
||||||
root += "/"
|
root += "/"
|
||||||
}
|
}
|
||||||
return Service{root, pkg.NewHTTPClientHeader(header), apiVersion, userdataPath, metadataPath}
|
return Service{root, pkg.NewHTTPClientHeader(header), apiVersion, userdataPath, metadataPath, nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ms Service) IsAvailable() bool {
|
func (ms Service) IsAvailable() bool {
|
||||||
_, err := ms.Client.Get(ms.Root + ms.APIVersion)
|
_, ms.lastError = ms.Client.Get(ms.Root + ms.APIVersion)
|
||||||
return (err == nil)
|
return (ms.lastError == nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ms *Service) Finish() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ms *Service) String() string {
|
||||||
|
return fmt.Sprintf("%s: %s (lastError: %s)", "metadata", ms.Root+":"+ms.UserdataPath, ms.lastError)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ms Service) AvailabilityChanges() bool {
|
func (ms Service) AvailabilityChanges() bool {
|
||||||
|
24
config/cloudinit/datasource/proccmdline/proc_cmdline.go
Normal file → Executable file
24
config/cloudinit/datasource/proccmdline/proc_cmdline.go
Normal file → Executable file
@ -16,10 +16,12 @@ package proccmdline
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/rancher/os/log"
|
||||||
|
|
||||||
"github.com/rancher/os/config/cloudinit/datasource"
|
"github.com/rancher/os/config/cloudinit/datasource"
|
||||||
"github.com/rancher/os/config/cloudinit/pkg"
|
"github.com/rancher/os/config/cloudinit/pkg"
|
||||||
)
|
)
|
||||||
@ -30,7 +32,8 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ProcCmdline struct {
|
type ProcCmdline struct {
|
||||||
Location string
|
Location string
|
||||||
|
lastError error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDatasource() *ProcCmdline {
|
func NewDatasource() *ProcCmdline {
|
||||||
@ -38,14 +41,23 @@ func NewDatasource() *ProcCmdline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *ProcCmdline) IsAvailable() bool {
|
func (c *ProcCmdline) IsAvailable() bool {
|
||||||
contents, err := ioutil.ReadFile(c.Location)
|
var contents []byte
|
||||||
if err != nil {
|
contents, c.lastError = ioutil.ReadFile(c.Location)
|
||||||
|
if c.lastError != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdline := strings.TrimSpace(string(contents))
|
cmdline := strings.TrimSpace(string(contents))
|
||||||
_, err = findCloudConfigURL(cmdline)
|
_, c.lastError = findCloudConfigURL(cmdline)
|
||||||
return (err == nil)
|
return (c.lastError == nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ProcCmdline) Finish() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ProcCmdline) String() string {
|
||||||
|
return fmt.Sprintf("%s: %s (lastError: %s)", c.Type(), c.Location, c.lastError)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ProcCmdline) AvailabilityChanges() bool {
|
func (c *ProcCmdline) AvailabilityChanges() bool {
|
||||||
|
0
config/cloudinit/datasource/test/filesystem.go
Normal file → Executable file
0
config/cloudinit/datasource/test/filesystem.go
Normal file → Executable file
26
config/cloudinit/datasource/url/url.go
Normal file → Executable file
26
config/cloudinit/datasource/url/url.go
Normal file → Executable file
@ -15,25 +15,43 @@
|
|||||||
package url
|
package url
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/rancher/os/config/cloudinit/datasource"
|
"github.com/rancher/os/config/cloudinit/datasource"
|
||||||
"github.com/rancher/os/config/cloudinit/pkg"
|
"github.com/rancher/os/config/cloudinit/pkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RemoteFile struct {
|
type RemoteFile struct {
|
||||||
url string
|
url string
|
||||||
|
lastError error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDatasource(url string) *RemoteFile {
|
func NewDatasource(url string) *RemoteFile {
|
||||||
return &RemoteFile{url}
|
return &RemoteFile{url, nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *RemoteFile) IsAvailable() bool {
|
func (f *RemoteFile) IsAvailable() bool {
|
||||||
client := pkg.NewHTTPClient()
|
client := pkg.NewHTTPClient()
|
||||||
_, err := client.Get(f.url)
|
_, f.lastError = client.Get(f.url)
|
||||||
return (err == nil)
|
return (f.lastError == nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RemoteFile) Finish() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *RemoteFile) String() string {
|
||||||
|
return fmt.Sprintf("%s: %s (lastError: %s)", f.Type(), f.url, f.lastError)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *RemoteFile) AvailabilityChanges() bool {
|
func (f *RemoteFile) AvailabilityChanges() bool {
|
||||||
|
if f.lastError != nil {
|
||||||
|
// if we have a Network error, then we should retry.
|
||||||
|
// otherwise, we've made a request to the server, and its said nope.
|
||||||
|
if _, ok := f.lastError.(pkg.ErrNetwork); !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
9
config/cloudinit/datasource/vmware/vmware.go
Normal file → Executable file
9
config/cloudinit/datasource/vmware/vmware.go
Normal file → Executable file
@ -29,6 +29,15 @@ type VMWare struct {
|
|||||||
ovfFileName string
|
ovfFileName string
|
||||||
readConfig readConfigFunction
|
readConfig readConfigFunction
|
||||||
urlDownload urlDownloadFunction
|
urlDownload urlDownloadFunction
|
||||||
|
lastError error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v VMWare) Finish() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v VMWare) String() string {
|
||||||
|
return fmt.Sprintf("%s: %s (lastError: %s)", v.Type(), v.ovfFileName, v.lastError)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v VMWare) AvailabilityChanges() bool {
|
func (v VMWare) AvailabilityChanges() bool {
|
||||||
|
9
config/cloudinit/datasource/vmware/vmware_amd64.go
Normal file → Executable file
9
config/cloudinit/datasource/vmware/vmware_amd64.go
Normal file → Executable file
@ -16,14 +16,15 @@ package vmware
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/rancher/os/log"
|
||||||
|
|
||||||
"github.com/rancher/os/config/cloudinit/pkg"
|
"github.com/rancher/os/config/cloudinit/pkg"
|
||||||
|
|
||||||
"github.com/sigma/vmw-guestinfo/rpcvmx"
|
"github.com/sigma/vmw-guestinfo/rpcvmx"
|
||||||
"github.com/sigma/vmw-guestinfo/vmcheck"
|
"github.com/sigma/vmw-guestinfo/vmcheck"
|
||||||
"github.com/sigma/vmw-ovflib"
|
ovf "github.com/sigma/vmw-ovflib"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ovfWrapper struct {
|
type ovfWrapper struct {
|
||||||
@ -69,8 +70,8 @@ func NewDatasource(fileName string) *VMWare {
|
|||||||
|
|
||||||
func (v VMWare) IsAvailable() bool {
|
func (v VMWare) IsAvailable() bool {
|
||||||
if v.ovfFileName != "" {
|
if v.ovfFileName != "" {
|
||||||
_, err := os.Stat(v.ovfFileName)
|
_, v.lastError = os.Stat(v.ovfFileName)
|
||||||
return !os.IsNotExist(err)
|
return !os.IsNotExist(v.lastError)
|
||||||
}
|
}
|
||||||
return vmcheck.IsVirtualWorld()
|
return vmcheck.IsVirtualWorld()
|
||||||
}
|
}
|
||||||
|
23
config/cloudinit/datasource/waagent/waagent.go
Normal file → Executable file
23
config/cloudinit/datasource/waagent/waagent.go
Normal file → Executable file
@ -16,27 +16,38 @@ package waagent
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
|
"github.com/rancher/os/log"
|
||||||
|
|
||||||
"github.com/rancher/os/config/cloudinit/datasource"
|
"github.com/rancher/os/config/cloudinit/datasource"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Waagent struct {
|
type Waagent struct {
|
||||||
root string
|
root string
|
||||||
readFile func(filename string) ([]byte, error)
|
readFile func(filename string) ([]byte, error)
|
||||||
|
lastError error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDatasource(root string) *Waagent {
|
func NewDatasource(root string) *Waagent {
|
||||||
return &Waagent{root, ioutil.ReadFile}
|
return &Waagent{root, ioutil.ReadFile, nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Waagent) IsAvailable() bool {
|
func (a *Waagent) IsAvailable() bool {
|
||||||
_, err := os.Stat(path.Join(a.root, "provisioned"))
|
_, a.lastError = os.Stat(path.Join(a.root, "provisioned"))
|
||||||
return !os.IsNotExist(err)
|
return !os.IsNotExist(a.lastError)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Waagent) Finish() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Waagent) String() string {
|
||||||
|
return fmt.Sprintf("%s: %s (lastError: %s)", a.Type(), a.root, a.lastError)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Waagent) AvailabilityChanges() bool {
|
func (a *Waagent) AvailabilityChanges() bool {
|
||||||
|
@ -86,7 +86,7 @@ func TestFetchMetadata(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
a := Waagent{tt.root, tt.files.ReadFile}
|
a := Waagent{tt.root, tt.files.ReadFile, nil}
|
||||||
metadata, err := a.FetchMetadata()
|
metadata, err := a.FetchMetadata()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("bad error for %+v: want %v, got %q", tt, nil, err)
|
t.Fatalf("bad error for %+v: want %v, got %q", tt, nil, err)
|
||||||
@ -115,7 +115,7 @@ func TestFetchUserdata(t *testing.T) {
|
|||||||
test.NewMockFilesystem(test.File{Path: "/var/lib/Waagent/CustomData", Contents: ""}),
|
test.NewMockFilesystem(test.File{Path: "/var/lib/Waagent/CustomData", Contents: ""}),
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
a := Waagent{tt.root, tt.files.ReadFile}
|
a := Waagent{tt.root, tt.files.ReadFile, nil}
|
||||||
_, err := a.FetchUserdata()
|
_, err := a.FetchUserdata()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("bad error for %+v: want %v, got %q", tt, nil, err)
|
t.Fatalf("bad error for %+v: want %v, got %q", tt, nil, err)
|
||||||
@ -137,7 +137,7 @@ func TestConfigRoot(t *testing.T) {
|
|||||||
"/var/lib/Waagent",
|
"/var/lib/Waagent",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
a := Waagent{tt.root, nil}
|
a := Waagent{tt.root, nil, nil}
|
||||||
if configRoot := a.ConfigRoot(); configRoot != tt.configRoot {
|
if configRoot := a.ConfigRoot(); configRoot != tt.configRoot {
|
||||||
t.Fatalf("bad config root for %q: want %q, got %q", tt, tt.configRoot, configRoot)
|
t.Fatalf("bad config root for %q: want %q, got %q", tt, tt.configRoot, configRoot)
|
||||||
}
|
}
|
||||||
|
24
init/init.go
Normal file → Executable file
24
init/init.go
Normal file → Executable file
@ -12,7 +12,6 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/mount"
|
"github.com/docker/docker/pkg/mount"
|
||||||
"github.com/rancher/os/cmd/cloudinitsave"
|
|
||||||
"github.com/rancher/os/config"
|
"github.com/rancher/os/config"
|
||||||
"github.com/rancher/os/dfs"
|
"github.com/rancher/os/dfs"
|
||||||
"github.com/rancher/os/log"
|
"github.com/rancher/os/log"
|
||||||
@ -294,29 +293,10 @@ func RunInit() error {
|
|||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
network := false
|
if err := runCloudInitServices(cfg); err != nil {
|
||||||
for _, datasource := range cfg.Rancher.CloudInit.Datasources {
|
log.Error(err)
|
||||||
if cloudinitsave.RequiresNetwork(datasource) {
|
|
||||||
network = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if network {
|
|
||||||
if err := runCloudInitServices(cfg); err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err := cloudinitsave.MountConfigDrive(); err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
if err := cloudinitsave.SaveCloudConfig(false); err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
if err := cloudinitsave.UnmountConfigDrive(); err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cfg, nil
|
return cfg, nil
|
||||||
},
|
},
|
||||||
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
rancher:
|
rancher:
|
||||||
|
debug: true
|
||||||
environment:
|
environment:
|
||||||
VERSION: {{.VERSION}}
|
VERSION: {{.VERSION}}
|
||||||
SUFFIX: {{.SUFFIX}}
|
SUFFIX: {{.SUFFIX}}
|
||||||
|
@ -48,4 +48,4 @@ REBUILD=1
|
|||||||
QEMUARCH=${qemuarch["${ARCH}"]}
|
QEMUARCH=${qemuarch["${ARCH}"]}
|
||||||
TTYCONS=${ttycons["${ARCH}"]}
|
TTYCONS=${ttycons["${ARCH}"]}
|
||||||
|
|
||||||
DEFAULT_KERNEL_ARGS="rancher.debug=false rancher.password=rancher console=${TTYCONS} rancher.autologin=${TTYCONS}"
|
DEFAULT_KERNEL_ARGS="printk.devkmsg=on rancher.debug=true rancher.password=rancher console=${TTYCONS} rancher.autologin=${TTYCONS}"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#cloud-config
|
#cloud-config
|
||||||
rancher:
|
rancher:
|
||||||
console: debian
|
console: alpine
|
||||||
services:
|
services:
|
||||||
missing_image:
|
missing_image:
|
||||||
image: tianon/true
|
image: tianon/true
|
||||||
|
@ -106,7 +106,8 @@ func (s *QemuSuite) WaitForSSH() error {
|
|||||||
if err = cmd.Run(); err == nil {
|
if err = cmd.Run(); err == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
time.Sleep(500 * time.Millisecond)
|
fmt.Printf("s%d", i)
|
||||||
|
time.Sleep(time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -126,6 +127,7 @@ func (s *QemuSuite) WaitForSSH() error {
|
|||||||
if err = cmd.Run(); err == nil {
|
if err = cmd.Run(); err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
fmt.Printf("d%d", i)
|
||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +187,7 @@ func (s *QemuSuite) LoadInstallerImage(c *C) {
|
|||||||
c.Assert(cmd.Run(), IsNil)
|
c.Assert(cmd.Run(), IsNil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *QemuSuite) PullAndLoadInstallerImage(c *C, image string) {
|
func (s *QemuSuite) PullAndLoadImage(c *C, image string) {
|
||||||
cmd := exec.Command("sh", "-c", fmt.Sprintf("docker pull %s", image))
|
cmd := exec.Command("sh", "-c", fmt.Sprintf("docker pull %s", image))
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
|
2
tests/network_on_boot_test.go
Normal file → Executable file
2
tests/network_on_boot_test.go
Normal file → Executable file
@ -5,6 +5,6 @@ import . "gopkg.in/check.v1"
|
|||||||
func (s *QemuSuite) TestNetworkOnBoot(c *C) {
|
func (s *QemuSuite) TestNetworkOnBoot(c *C) {
|
||||||
s.RunQemu(c, "--cloud-config", "./tests/assets/test_18/cloud-config.yml", "-net", "nic,vlan=1,model=virtio")
|
s.RunQemu(c, "--cloud-config", "./tests/assets/test_18/cloud-config.yml", "-net", "nic,vlan=1,model=virtio")
|
||||||
|
|
||||||
s.CheckCall(c, "apt-get --version")
|
s.CheckCall(c, "apk --version")
|
||||||
s.CheckCall(c, "sudo system-docker images | grep tianon/true")
|
s.CheckCall(c, "sudo system-docker images | grep tianon/true")
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ func (s *QemuSuite) DisableTestUpgradeInner(c *C) {
|
|||||||
c.Assert(Version, Equals, version)
|
c.Assert(Version, Equals, version)
|
||||||
|
|
||||||
fmt.Printf("installing %s", startWithVersion)
|
fmt.Printf("installing %s", startWithVersion)
|
||||||
s.PullAndLoadInstallerImage(c, fmt.Sprintf("rancher/os:%s", startWithVersion))
|
s.PullAndLoadImage(c, fmt.Sprintf("rancher/os:%s", startWithVersion))
|
||||||
|
|
||||||
//ADD a custom append line and make sure its kept in the upgraded version too
|
//ADD a custom append line and make sure its kept in the upgraded version too
|
||||||
|
|
||||||
@ -77,10 +77,10 @@ sync
|
|||||||
|
|
||||||
if console != "default" {
|
if console != "default" {
|
||||||
// Can't preload the startWithVersion console image, as some don't exist by that name - not sure how to approach that
|
// Can't preload the startWithVersion console image, as some don't exist by that name - not sure how to approach that
|
||||||
//s.PullAndLoadInstallerImage(c, fmt.Sprintf("rancher/os-%sconsole:%s", console, startWithVersion))
|
//s.PullAndLoadImage(c, fmt.Sprintf("rancher/os-%sconsole:%s", console, startWithVersion))
|
||||||
// TODO: ouch. probably need to tag the dev / master version as latest cos this won't work
|
// TODO: ouch. probably need to tag the dev / master version as latest cos this won't work
|
||||||
// Need to pull the image here - if we do it at boot, then the test will fail.
|
// Need to pull the image here - if we do it at boot, then the test will fail.
|
||||||
s.PullAndLoadInstallerImage(c, fmt.Sprintf("rancher/os-%sconsole:%s", console, "v0.8.0-rc3"))
|
s.PullAndLoadImage(c, fmt.Sprintf("rancher/os-%sconsole:%s", console, "v0.8.0-rc3"))
|
||||||
s.MakeCall(fmt.Sprintf("sudo ros console switch -f %s", console))
|
s.MakeCall(fmt.Sprintf("sudo ros console switch -f %s", console))
|
||||||
c.Assert(s.WaitForSSH(), IsNil)
|
c.Assert(s.WaitForSSH(), IsNil)
|
||||||
}
|
}
|
||||||
@ -111,7 +111,7 @@ func (s *QemuSuite) commonTestCode(c *C, startWithVersion, console string) {
|
|||||||
c.Assert(Version, Equals, version)
|
c.Assert(Version, Equals, version)
|
||||||
|
|
||||||
fmt.Printf("installing %s", startWithVersion)
|
fmt.Printf("installing %s", startWithVersion)
|
||||||
s.PullAndLoadInstallerImage(c, fmt.Sprintf("rancher/os:%s", startWithVersion))
|
s.PullAndLoadImage(c, fmt.Sprintf("rancher/os:%s", startWithVersion))
|
||||||
|
|
||||||
//ADD a custom append line and make sure its kept in the upgraded version too
|
//ADD a custom append line and make sure its kept in the upgraded version too
|
||||||
|
|
||||||
@ -137,13 +137,13 @@ sync
|
|||||||
|
|
||||||
if console != "default" {
|
if console != "default" {
|
||||||
// Can't preload the startWithVersion console image, as some don't exist by that name - not sure how to approach that
|
// Can't preload the startWithVersion console image, as some don't exist by that name - not sure how to approach that
|
||||||
//s.PullAndLoadInstallerImage(c, fmt.Sprintf("rancher/os-%sconsole:%s", console, startWithVersion))
|
//s.PullAndLoadImage(c, fmt.Sprintf("rancher/os-%sconsole:%s", console, startWithVersion))
|
||||||
// TODO: ouch. probably need to tag the dev / master version as latest cos this won't work
|
// TODO: ouch. probably need to tag the dev / master version as latest cos this won't work
|
||||||
// Need to pull the image here - if we do it at boot, then the test will fail.
|
// Need to pull the image here - if we do it at boot, then the test will fail.
|
||||||
if console == "alpine" {
|
if console == "alpine" {
|
||||||
s.PullAndLoadInstallerImage(c, fmt.Sprintf("rancher/os-%sconsole:%s", console, "v0.8.0-rc5"))
|
s.PullAndLoadImage(c, fmt.Sprintf("rancher/os-%sconsole:%s", console, "v0.8.0-rc5"))
|
||||||
} else {
|
} else {
|
||||||
s.PullAndLoadInstallerImage(c, fmt.Sprintf("rancher/os-%sconsole:%s", console, "v0.8.0-rc3"))
|
s.PullAndLoadImage(c, fmt.Sprintf("rancher/os-%sconsole:%s", console, "v0.8.0-rc3"))
|
||||||
}
|
}
|
||||||
s.MakeCall(fmt.Sprintf("sudo ros console switch -f %s", console))
|
s.MakeCall(fmt.Sprintf("sudo ros console switch -f %s", console))
|
||||||
c.Assert(s.WaitForSSH(), IsNil)
|
c.Assert(s.WaitForSSH(), IsNil)
|
||||||
|
Loading…
Reference in New Issue
Block a user