diff --git a/config/types.go b/config/types.go index fa49477e..04fb7e6f 100644 --- a/config/types.go +++ b/config/types.go @@ -149,6 +149,7 @@ type StateConfig struct { Directory string `yaml:"directory,omitempty"` FsType string `yaml:"fstype,omitempty"` Dev string `yaml:"dev,omitempty"` + Wait bool `yaml:"wait,omitempty"` Required bool `yaml:"required,omitempty"` Autoformat []string `yaml:"autoformat,omitempty"` FormatZero bool `yaml:"formatzero,omitempty"` diff --git a/images/02-autoformat/auto-format.sh b/images/02-autoformat/auto-format.sh index 053b1b2a..e56f7c02 100755 --- a/images/02-autoformat/auto-format.sh +++ b/images/02-autoformat/auto-format.sh @@ -12,7 +12,7 @@ for dev in ${DEVS[@]}; do # Test for our magic string (it means that the disk was made by ./boot2docker init) HEADER=`dd if=${dev} bs=1 count=${#MAGIC} 2>/dev/null` - + if [ "$HEADER" = "$MAGIC" ]; then # save the preload userdata.tar file dd if=${dev} of=/userdata.tar bs=1 count=8192 @@ -23,10 +23,10 @@ for dev in ${DEVS[@]}; do # do not auto-format if the disk does not begin with 1MB filled with 00 continue fi - - mkfs.ext4 -L RANCHER_STATE ${dev} - + + if [ -e "/userdata.tar" ]; then + mkfs.ext4 -L B2D_STATE ${dev} mkdir -p /mnt/new-root mount -t ext4 ${dev} /mnt/new-root pushd /mnt/new-root @@ -49,7 +49,7 @@ rancher: ssh_authorized_keys: - ${AUTHORIZED_KEY1} - - ${AUTHORIZED_KEY2} + - ${AUTHORIZED_KEY2} users: - name: docker @@ -59,6 +59,8 @@ users: EOF popd umount /mnt/new-root + else + mkfs.ext4 -L RANCHER_STATE ${dev} fi # do not check another device diff --git a/images/02-udev/udev.sh b/images/02-udev/udev.sh index 2bfa8b49..b91a9cc9 100755 --- a/images/02-udev/udev.sh +++ b/images/02-udev/udev.sh @@ -8,11 +8,26 @@ udevd --daemon udevadm trigger --action=add udevadm settle -if [ "$BOOTSTRAP" = true ]; then - # This was needed to get USB devices to fully register - # There is probably a better way to do this - killall udevd - udevd --daemon - udevadm trigger --action=add - udevadm settle +dev=$(ros config get rancher.state.dev) +wait=$(ros config get rancher.state.wait) +if [ "$BOOTSTRAP" != true ] || [ "$dev" == "" ] || [ "$wait" != "true" ]; then + exit fi + +for i in `seq 1 30`; do + drive=$(ros dev $dev) + if [ "$drive" != "" ]; then + break + fi + sleep 1 +done +drive=$(ros dev $dev) +if [ "$drive" = "" ]; then + exit +fi +for i in `seq 1 30`; do + if [ -e $drive ]; then + break + fi + sleep 1 +done diff --git a/init/init.go b/init/init.go index 86432a69..2b7b84fe 100644 --- a/init/init.go +++ b/init/init.go @@ -19,7 +19,8 @@ import ( ) const ( - STATE string = "/state" + STATE string = "/state" + BOOT2DOCKER_MAGIC string = "boot2docker, please format-me" TMPFS_MAGIC int64 = 0x01021994 RAMFS_MAGIC int64 = 0x858458f6 @@ -143,18 +144,21 @@ func tryMountState(cfg *config.CloudConfig) error { } func tryMountAndBootstrap(cfg *config.CloudConfig) (*config.CloudConfig, error) { - if isInitrd() { - if err := tryMountState(cfg); !cfg.Rancher.State.Required && err != nil { - return cfg, nil - } else if err != nil { - return cfg, err - } - - log.Debugf("Switching to new root at %s %s", STATE, cfg.Rancher.State.Directory) - if err := switchRoot(STATE, cfg.Rancher.State.Directory, cfg.Rancher.RmUsr); err != nil { - return cfg, err - } + if !isInitrd() || cfg.Rancher.State.Dev == "" { + return cfg, nil } + + if err := tryMountState(cfg); !cfg.Rancher.State.Required && err != nil { + return cfg, nil + } else if err != nil { + return cfg, err + } + + log.Debugf("Switching to new root at %s %s", STATE, cfg.Rancher.State.Directory) + if err := switchRoot(STATE, cfg.Rancher.State.Directory, cfg.Rancher.RmUsr); err != nil { + return cfg, err + } + return mountOem(cfg) } @@ -213,6 +217,7 @@ func RunInit() error { log.Debug("Booting off a persistent filesystem") } + boot2DockerEnvironment := false initFuncs := []config.CfgFunc{ func(c *config.CloudConfig) (*config.CloudConfig, error) { return c, dockerlaunch.PrepareFs(&mountConfig) @@ -233,8 +238,44 @@ func RunInit() error { return cfg, nil }, loadModules, + func(cfg *config.CloudConfig) (*config.CloudConfig, error) { + if util.ResolveDevice("LABEL=B2D_STATE") != "" { + boot2DockerEnvironment = true + cfg.Rancher.State.Dev = "LABEL=B2D_STATE" + return cfg, nil + } + + devices := []string{"/dev/sda", "/dev/vda"} + data := make([]byte, len(BOOT2DOCKER_MAGIC)) + + for _, device := range devices { + f, err := os.Open(device) + if err == nil { + defer f.Close() + + _, err = f.Read(data) + if err == nil && string(data) == BOOT2DOCKER_MAGIC { + boot2DockerEnvironment = true + cfg.Rancher.State.Dev = "LABEL=B2D_STATE" + cfg.Rancher.State.Autoformat = []string{device} + break + } + } + } + + return cfg, nil + }, tryMountAndBootstrap, - func(_ *config.CloudConfig) (*config.CloudConfig, error) { + func(cfg *config.CloudConfig) (*config.CloudConfig, error) { + if boot2DockerEnvironment { + if err := config.Set("rancher.state.dev", cfg.Rancher.State.Dev); err != nil { + log.Errorf("Failed to update rancher.state.dev: %v", err) + } + if err := config.Set("rancher.state.autoformat", cfg.Rancher.State.Autoformat); err != nil { + log.Errorf("Failed to update rancher.state.autoformat: %v", err) + } + } + return config.LoadConfig(), nil }, loadModules, diff --git a/os-config.tpl.yml b/os-config.tpl.yml index 8da06cd6..32d3bf07 100644 --- a/os-config.tpl.yml +++ b/os-config.tpl.yml @@ -39,6 +39,7 @@ rancher: - /dev:/host/dev - /lib/modules:/lib/modules - /lib/firmware:/lib/firmware + - /usr/bin/ros:/usr/bin/ros:ro autoformat: autoformat: image: {{.OS_REPO}}/os-autoformat:{{.VERSION}}{{.SUFFIX}} @@ -74,7 +75,6 @@ rancher: url: {{.OS_SERVICES_REPO}}/{{.REPO_VERSION}} state: fstype: auto - dev: LABEL=RANCHER_STATE oem_fstype: auto oem_dev: LABEL=RANCHER_OEM services: diff --git a/scripts/installer/lay-down-os b/scripts/installer/lay-down-os index 7a8d7c4e..a6ce4332 100755 --- a/scripts/installer/lay-down-os +++ b/scripts/installer/lay-down-os @@ -85,7 +85,7 @@ set timeout="1" menuentry "RancherOS-current" { set root=(hd0,msdos1) - linux /boot/vmlinuz-${VERSION}-rancheros ${append_line} console=${CONSOLE} + linux /boot/vmlinuz-${VERSION}-rancheros ${append_line} rancher.state.dev=LABEL=RANCHER_STATE rancher.state.wait console=${CONSOLE} initrd /boot/initrd-${VERSION}-rancheros } @@ -96,7 +96,7 @@ if [ ! -z ${ROLLBACK_VERSION} ]; then cat >>${grub_cfg} <> ${grub_file}<