mirror of
https://github.com/rancher/os.git
synced 2025-09-16 06:59:12 +00:00
Installing 0.7.1, and then rebooting, and doing a ros upgrade to a faked up latest works \o/
Signed-off-by: Sven Dowideit <SvenDowideit@home.org.au>
This commit is contained in:
@@ -10,7 +10,7 @@ RUN apt-get update && \
|
||||
dosfstools \
|
||||
gccgo \
|
||||
genisoimage \
|
||||
gettext \
|
||||
gettext \
|
||||
git \
|
||||
isolinux \
|
||||
less \
|
||||
|
@@ -11,27 +11,17 @@ import (
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/rancher/os/log"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/rancher/os/cmd/control/install"
|
||||
"github.com/rancher/os/cmd/power"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/dfs" // TODO: move CopyFile into util or something.
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
type MenuEntry struct {
|
||||
Name, bootDir, Version, KernelArgs, Append string
|
||||
}
|
||||
type bootVars struct {
|
||||
baseName, bootDir string
|
||||
Timeout uint
|
||||
Fallback int
|
||||
Entries []MenuEntry
|
||||
}
|
||||
|
||||
var installCommand = cli.Command{
|
||||
Name: "install",
|
||||
Usage: "install RancherOS to disk",
|
||||
@@ -71,9 +61,18 @@ var installCommand = cli.Command{
|
||||
Name: "append, a",
|
||||
Usage: "append additional kernel parameters",
|
||||
},
|
||||
cli.StringFlag{ // TODO: hide..
|
||||
Name: "rollback, r",
|
||||
Usage: "rollback version",
|
||||
},
|
||||
cli.BoolFlag{ // TODO: this should be hidden and internal only
|
||||
Name: "isoinstallerloaded",
|
||||
Usage: "INTERNAL use only: mount the iso to get kernel and initrd",
|
||||
Hidden: true,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "mountiso",
|
||||
Usage: "mount the iso to get kernel and initrd",
|
||||
Name: "kexec",
|
||||
Usage: "reboot using kexec",
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -82,10 +81,11 @@ func installAction(c *cli.Context) error {
|
||||
if c.Args().Present() {
|
||||
log.Fatalf("invalid arguments %v", c.Args())
|
||||
}
|
||||
device := c.String("device")
|
||||
if device == "" {
|
||||
log.Fatal("Can not proceed without -d <dev> specified")
|
||||
}
|
||||
kappend := strings.TrimSpace(c.String("append"))
|
||||
force := c.Bool("force")
|
||||
kexec := c.Bool("kexec")
|
||||
reboot := !c.Bool("no-reboot")
|
||||
isoinstallerloaded := c.Bool("isoinstallerloaded")
|
||||
|
||||
image := c.String("image")
|
||||
cfg := config.LoadConfig()
|
||||
@@ -98,6 +98,23 @@ func installAction(c *cli.Context) error {
|
||||
log.Info("No install type specified...defaulting to generic")
|
||||
installType = "generic"
|
||||
}
|
||||
if installType == "rancher-upgrade" ||
|
||||
installType == "upgrade" {
|
||||
force = true // the os.go upgrade code already asks
|
||||
reboot = false
|
||||
isoinstallerloaded = true // OMG this flag is aweful - kill it with fire
|
||||
}
|
||||
device := c.String("device")
|
||||
if installType != "noformat" &&
|
||||
installType != "raid" &&
|
||||
installType != "bootstrap" &&
|
||||
installType != "upgrade" &&
|
||||
installType != "rancher-upgrade" {
|
||||
// These can use RANCHER_BOOT or RANCHER_STATE labels..
|
||||
if device == "" {
|
||||
log.Fatal("Can not proceed without -d <dev> specified")
|
||||
}
|
||||
}
|
||||
|
||||
cloudConfig := c.String("cloud-config")
|
||||
if cloudConfig == "" {
|
||||
@@ -110,19 +127,14 @@ func installAction(c *cli.Context) error {
|
||||
cloudConfig = uc
|
||||
}
|
||||
|
||||
kappend := strings.TrimSpace(c.String("append"))
|
||||
force := c.Bool("force")
|
||||
reboot := !c.Bool("no-reboot")
|
||||
mountiso := c.Bool("mountiso")
|
||||
|
||||
if err := runInstall(image, installType, cloudConfig, device, kappend, force, reboot, mountiso); err != nil {
|
||||
if err := runInstall(image, installType, cloudConfig, device, kappend, force, reboot, kexec, isoinstallerloaded); err != nil {
|
||||
log.WithFields(log.Fields{"err": err}).Fatal("Failed to run install")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runInstall(image, installType, cloudConfig, device, kappend string, force, reboot, mountiso bool) error {
|
||||
func runInstall(image, installType, cloudConfig, device, kappend string, force, reboot, kexec, isoinstallerloaded bool) error {
|
||||
fmt.Printf("Installing from %s\n", image)
|
||||
|
||||
if !force {
|
||||
@@ -132,6 +144,7 @@ func runInstall(image, installType, cloudConfig, device, kappend string, force,
|
||||
}
|
||||
}
|
||||
diskType := "msdos"
|
||||
|
||||
if installType == "gptsyslinux" {
|
||||
diskType = "gpt"
|
||||
}
|
||||
@@ -139,7 +152,7 @@ func runInstall(image, installType, cloudConfig, device, kappend string, force,
|
||||
// Versions before 0.8.0-rc2 use the old calling convention (from the lay-down-os shell script)
|
||||
imageVersion := strings.TrimPrefix(image, "rancher/os:v")
|
||||
if image != imageVersion {
|
||||
log.Infof("user spcified different install image: %s != %s", image, imageVersion)
|
||||
log.Infof("user specified different install image: %s != %s", image, imageVersion)
|
||||
imageVersion = strings.Replace(imageVersion, "-", ".", -1)
|
||||
vArray := strings.Split(imageVersion, ".")
|
||||
v, _ := strconv.ParseFloat(vArray[0]+"."+vArray[1], 32)
|
||||
@@ -166,10 +179,19 @@ func runInstall(image, installType, cloudConfig, device, kappend string, force,
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := os.Stat("/usr/bin/system-docker"); os.IsNotExist(err) {
|
||||
if err := os.Symlink("/usr/bin/ros", "/usr/bin/system-docker"); err != nil {
|
||||
log.Errorf("ln error %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
useIso := false
|
||||
if !mountiso {
|
||||
// --isoinstallerloaded is used if the ros has created the installer container from and image that was on the booted iso
|
||||
if !isoinstallerloaded {
|
||||
if _, err := os.Stat("/dist/initrd"); os.IsNotExist(err) {
|
||||
if err = mountBootIso(); err == nil {
|
||||
if err = mountBootIso(); err != nil {
|
||||
log.Debugf("mountBootIso error %s", err)
|
||||
} else {
|
||||
if _, err := os.Stat("/bootiso/rancheros/"); err == nil {
|
||||
cmd := exec.Command("system-docker", "load", "-i", "/bootiso/rancheros/installer.tar.gz")
|
||||
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||
@@ -196,7 +218,7 @@ func runInstall(image, installType, cloudConfig, device, kappend string, force,
|
||||
"-v", "/:/host",
|
||||
"--volumes-from=all-volumes",
|
||||
image,
|
||||
"install",
|
||||
// "install",
|
||||
"-t", installType,
|
||||
"-d", device,
|
||||
}
|
||||
@@ -213,7 +235,10 @@ func runInstall(image, installType, cloudConfig, device, kappend string, force,
|
||||
installerCmd = append(installerCmd, "-a", kappend)
|
||||
}
|
||||
if useIso {
|
||||
installerCmd = append(installerCmd, "--mountiso")
|
||||
installerCmd = append(installerCmd, "--isoinstallerloaded=1")
|
||||
}
|
||||
if kexec {
|
||||
installerCmd = append(installerCmd, "--kexec")
|
||||
}
|
||||
|
||||
cmd := exec.Command("system-docker", installerCmd...)
|
||||
@@ -255,8 +280,13 @@ func runInstall(image, installType, cloudConfig, device, kappend string, force,
|
||||
device = "/host" + device
|
||||
}
|
||||
|
||||
log.Debugf("running mountiso?")
|
||||
if mountiso {
|
||||
if installType == "rancher-upgrade" ||
|
||||
installType == "upgrade" {
|
||||
isoinstallerloaded = false
|
||||
}
|
||||
|
||||
if isoinstallerloaded {
|
||||
log.Debugf("running isoinstallerloaded...")
|
||||
// TODO: I hope to remove this from here later.
|
||||
if err := mountBootIso(); err != nil {
|
||||
log.Errorf("error mountBootIso %s", err)
|
||||
@@ -264,13 +294,13 @@ func runInstall(image, installType, cloudConfig, device, kappend string, force,
|
||||
}
|
||||
}
|
||||
|
||||
err := layDownOS(image, installType, cloudConfig, device, kappend)
|
||||
err := layDownOS(image, installType, cloudConfig, device, kappend, kexec)
|
||||
if err != nil {
|
||||
log.Errorf("error layDownOS %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if reboot && (force || yes("Continue with reboot")) {
|
||||
if !kexec && reboot && (force || yes("Continue with reboot")) {
|
||||
log.Info("Rebooting")
|
||||
power.Reboot()
|
||||
}
|
||||
@@ -334,7 +364,7 @@ func mountBootIso() error {
|
||||
return err
|
||||
}
|
||||
|
||||
func layDownOS(image, installType, cloudConfig, device, kappend string) error {
|
||||
func layDownOS(image, installType, cloudConfig, device, kappend string, kexec bool) error {
|
||||
// ENV == installType
|
||||
//[[ "$ARCH" == "arm" && "$ENV" != "rancher-upgrade" ]] && ENV=arm
|
||||
|
||||
@@ -347,7 +377,7 @@ func layDownOS(image, installType, cloudConfig, device, kappend string) error {
|
||||
//cloudConfig := SCRIPTS_DIR + "/conf/empty.yml" //${cloudConfig:-"${SCRIPTS_DIR}/conf/empty.yml"}
|
||||
CONSOLE := "tty0"
|
||||
baseName := "/mnt/new_img"
|
||||
bootDir := "boot/" // set by mountdevice
|
||||
bootDir := "boot/"
|
||||
//# TODO: Change this to a number so that users can specify.
|
||||
//# Will need to make it so that our builds and packer APIs remain consistent.
|
||||
partition := device + "1" //${partition:=${device}1}
|
||||
@@ -369,30 +399,24 @@ func layDownOS(image, installType, cloudConfig, device, kappend string) error {
|
||||
case "generic":
|
||||
log.Debugf("formatAndMount")
|
||||
var err error
|
||||
bootDir, err = formatAndMount(baseName, bootDir, device, partition)
|
||||
device, partition, err = formatAndMount(baseName, bootDir, device, partition)
|
||||
if err != nil {
|
||||
log.Errorf("formatAndMount %s", err)
|
||||
return err
|
||||
}
|
||||
//log.Infof("installGrub")
|
||||
//err = installGrub(baseName, device)
|
||||
log.Debugf("installSyslinux")
|
||||
err = installSyslinux(device, baseName, bootDir, diskType)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("installSyslinux %s", err)
|
||||
return err
|
||||
}
|
||||
log.Debugf("seedData")
|
||||
err = seedData(baseName, cloudConfig, FILES)
|
||||
if err != nil {
|
||||
log.Errorf("seedData %s", err)
|
||||
return err
|
||||
}
|
||||
log.Debugf("seedData done")
|
||||
case "arm":
|
||||
var err error
|
||||
bootDir, err = formatAndMount(baseName, bootDir, device, partition)
|
||||
device, partition, err = formatAndMount(baseName, bootDir, device, partition)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -402,56 +426,56 @@ func layDownOS(image, installType, cloudConfig, device, kappend string) error {
|
||||
case "amazon-ebs-hvm":
|
||||
CONSOLE = "ttyS0"
|
||||
var err error
|
||||
bootDir, err = formatAndMount(baseName, bootDir, device, partition)
|
||||
device, partition, err = formatAndMount(baseName, bootDir, device, partition)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if installType == "amazon-ebs-hvm" {
|
||||
installGrub(baseName, device)
|
||||
installSyslinux(device, baseName, bootDir, diskType)
|
||||
}
|
||||
//# AWS Networking recommends disabling.
|
||||
seedData(baseName, cloudConfig, FILES)
|
||||
case "googlecompute":
|
||||
CONSOLE = "ttyS0"
|
||||
var err error
|
||||
bootDir, err = formatAndMount(baseName, bootDir, device, partition)
|
||||
device, partition, err = formatAndMount(baseName, bootDir, device, partition)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
installGrub(baseName, device)
|
||||
installSyslinux(device, baseName, bootDir, diskType)
|
||||
seedData(baseName, cloudConfig, FILES)
|
||||
case "noformat":
|
||||
var err error
|
||||
bootDir, err = mountdevice(baseName, bootDir, partition, false)
|
||||
device, partition, err = mountdevice(baseName, bootDir, partition, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
createbootDirs(baseName, bootDir)
|
||||
installSyslinux(device, baseName, bootDir, diskType)
|
||||
case "raid":
|
||||
var err error
|
||||
bootDir, err = mountdevice(baseName, bootDir, partition, false)
|
||||
device, partition, err = mountdevice(baseName, bootDir, partition, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
createbootDirs(baseName, bootDir)
|
||||
installSyslinuxRaid(baseName, bootDir, diskType)
|
||||
case "bootstrap":
|
||||
CONSOLE = "ttyS0"
|
||||
var err error
|
||||
bootDir, err = mountdevice(baseName, bootDir, partition, true)
|
||||
device, partition, err = mountdevice(baseName, bootDir, partition, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
createbootDirs(baseName, bootDir)
|
||||
kernelArgs = kernelArgs + " rancher.cloud_init.datasources=[ec2,gce]"
|
||||
case "upgrade":
|
||||
fallthrough
|
||||
case "rancher-upgrade":
|
||||
var err error
|
||||
bootDir, err = mountdevice(baseName, bootDir, partition, false)
|
||||
device, partition, err = mountdevice(baseName, bootDir, partition, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
createbootDirs(baseName, bootDir)
|
||||
// TODO: detect pv-grub, and don't kill it with syslinux
|
||||
upgradeBootloader(device, baseName, bootDir, diskType)
|
||||
default:
|
||||
return fmt.Errorf("unexpected install type %s", installType)
|
||||
}
|
||||
@@ -464,23 +488,18 @@ func layDownOS(image, installType, cloudConfig, device, kappend string) error {
|
||||
ioutil.WriteFile(filepath.Join(baseName, bootDir+"append"), []byte(kappend), 0644)
|
||||
}
|
||||
|
||||
//menu := bootVars{
|
||||
// baseName: baseName,
|
||||
// bootDir: bootDir,
|
||||
// Timeout: 1,
|
||||
// Fallback: 1, // need to be conditional on there being a 'rollback'?
|
||||
// Entries: []MenuEntry{
|
||||
// MenuEntry{"RancherOS-current", bootDir, VERSION, kernelArgs, kappend},
|
||||
// // MenuEntry{"RancherOS-rollback", bootDir, ROLLBACK_VERSION, kernelArgs, kappend},
|
||||
// },
|
||||
//}
|
||||
|
||||
//log.Debugf("grubConfig")
|
||||
//grubConfig(menu)
|
||||
//log.Debugf("syslinuxConfig")
|
||||
//syslinuxConfig(menu)
|
||||
//log.Debugf("pvGrubConfig")
|
||||
//pvGrubConfig(menu)
|
||||
if installType == "amazon-ebs-pv" {
|
||||
menu := install.BootVars{
|
||||
BaseName: baseName,
|
||||
BootDir: bootDir,
|
||||
Timeout: 0,
|
||||
Fallback: 0, // need to be conditional on there being a 'rollback'?
|
||||
Entries: []install.MenuEntry{
|
||||
install.MenuEntry{"RancherOS-current", bootDir, VERSION, kernelArgs, kappend},
|
||||
},
|
||||
}
|
||||
install.PvGrubConfig(menu)
|
||||
}
|
||||
log.Debugf("installRancher")
|
||||
err := installRancher(baseName, bootDir, VERSION, DIST, kernelArgs+" "+kappend)
|
||||
if err != nil {
|
||||
@@ -489,10 +508,22 @@ func layDownOS(image, installType, cloudConfig, device, kappend string) error {
|
||||
}
|
||||
log.Debugf("installRancher done")
|
||||
|
||||
//unused by us? :)
|
||||
//if [ "$KEXEC" = "y" ]; then
|
||||
// kexec -l ${DIST}/vmlinuz --initrd=${DIST}/initrd --append="${kernelArgs} ${APPEND}" -f
|
||||
//fi
|
||||
// Used by upgrade
|
||||
if kexec {
|
||||
// kexec -l ${DIST}/vmlinuz --initrd=${DIST}/initrd --append="${kernelArgs} ${APPEND}" -f
|
||||
cmd := exec.Command("kexec", "-l "+DIST+"/vmlinuz",
|
||||
"--initrd="+DIST+"/initrd",
|
||||
"--append='"+kernelArgs+" "+kappend+"'",
|
||||
"-f")
|
||||
log.Debugf("Run(%v)", cmd)
|
||||
cmd.Stderr = os.Stderr
|
||||
if _, err := cmd.Output(); err != nil {
|
||||
log.Errorf("Failed to kexec: %s", err)
|
||||
return err
|
||||
}
|
||||
log.Infof("kexec'd to new install")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -508,7 +539,7 @@ func seedData(baseName, cloudData string, files []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if strings.HasSuffix(cloudData, "empty.yml") {
|
||||
if !strings.HasSuffix(cloudData, "empty.yml") {
|
||||
if err = dfs.CopyFile(cloudData, baseName+"/var/lib/rancher/conf/cloud-config.d/", filepath.Base(cloudData)); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -576,11 +607,6 @@ func setDiskpartitions(device, diskType string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: work out where to do this - it is a so-so place for it
|
||||
if err := os.Symlink("/usr/bin/ros", "/usr/bin/system-docker"); err != nil {
|
||||
log.Errorf("ln error %s", err)
|
||||
}
|
||||
|
||||
cmd := exec.Command("system-docker", "ps", "-q")
|
||||
var outb bytes.Buffer
|
||||
cmd.Stdout = &outb
|
||||
@@ -626,20 +652,18 @@ func setDiskpartitions(device, diskType string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
bootflag := "boot"
|
||||
if diskType == "gpt" {
|
||||
bootflag = "legacy_boot"
|
||||
}
|
||||
log.Debugf("running parted")
|
||||
log.Debugf("making single RANCHER_STATE partition")
|
||||
cmd = exec.Command("parted", "-s", "-a", "optimal", device,
|
||||
"mklabel "+diskType, "--",
|
||||
"mkpart primary ext4 1 -1",
|
||||
"set 1 "+bootflag+" on")
|
||||
"mkpart primary ext4 1 -1")
|
||||
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Errorf("parted: %s", err)
|
||||
return err
|
||||
}
|
||||
if err := setBootable(device, diskType); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -678,64 +702,76 @@ func formatdevice(device, partition string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func mountdevice(baseName, bootDir, partition string, raw bool) (string, error) {
|
||||
func mountdevice(baseName, bootDir, partition string, raw bool) (string, string, error) {
|
||||
log.Debugf("mountdevice %s, raw %v", partition, raw)
|
||||
device := ""
|
||||
|
||||
if raw {
|
||||
log.Debugf("util.Mount (raw) %s, %s", partition, baseName)
|
||||
return bootDir, util.Mount(partition, baseName, "", "")
|
||||
|
||||
cmd := exec.Command("lsblk", "-no", "pkname", partition)
|
||||
log.Debugf("Run(%v)", cmd)
|
||||
cmd.Stderr = os.Stderr
|
||||
if out, err := cmd.Output(); err == nil {
|
||||
device = "/dev/" + strings.TrimSpace(string(out))
|
||||
}
|
||||
|
||||
return device, partition, util.Mount(partition, baseName, "", "")
|
||||
}
|
||||
|
||||
rootfs := partition
|
||||
//rootfs := partition
|
||||
// Don't use ResolveDevice - it can fail, whereas `blkid -L LABEL` works more often
|
||||
//if dev := util.ResolveDevice("LABEL=RANCHER_BOOT"); dev != "" {
|
||||
cmd := exec.Command("blkid", "-L", "RANCHER_BOOT")
|
||||
log.Debugf("Run(%v)", cmd)
|
||||
cmd.Stderr = os.Stderr
|
||||
if out, err := cmd.Output(); err == nil {
|
||||
rootfs = string(out)
|
||||
partition = strings.TrimSpace(string(out))
|
||||
} else {
|
||||
cmd := exec.Command("blkid", "-L", "RANCHER_STATE")
|
||||
log.Debugf("Run(%v)", cmd)
|
||||
cmd.Stderr = os.Stderr
|
||||
if out, err := cmd.Output(); err == nil {
|
||||
rootfs = string(out)
|
||||
partition = strings.TrimSpace(string(out))
|
||||
}
|
||||
}
|
||||
rootfs = strings.TrimSpace(rootfs)
|
||||
cmd = exec.Command("lsblk", "-no", "pkname", partition)
|
||||
log.Debugf("Run(%v)", cmd)
|
||||
cmd.Stderr = os.Stderr
|
||||
if out, err := cmd.Output(); err == nil {
|
||||
device = "/dev/" + strings.TrimSpace(string(out))
|
||||
}
|
||||
|
||||
log.Debugf("util.Mount %s, %s", rootfs, baseName)
|
||||
// return bootDir, util.Mount(rootfs, baseName, "", "")
|
||||
log.Debugf("util.Mount %s, %s", partition, baseName)
|
||||
os.MkdirAll(baseName, 0755)
|
||||
cmd = exec.Command("mount", rootfs, baseName)
|
||||
cmd = exec.Command("mount", partition, baseName)
|
||||
log.Debugf("Run(%v)", cmd)
|
||||
//cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||
return bootDir, cmd.Run()
|
||||
|
||||
return device, partition, cmd.Run()
|
||||
}
|
||||
|
||||
func formatAndMount(baseName, bootDir, device, partition string) (string, error) {
|
||||
func formatAndMount(baseName, bootDir, device, partition string) (string, string, error) {
|
||||
log.Debugf("formatAndMount")
|
||||
|
||||
err := formatdevice(device, partition)
|
||||
if err != nil {
|
||||
log.Errorf("formatdevice %s", err)
|
||||
return bootDir, err
|
||||
return device, partition, err
|
||||
}
|
||||
bootDir, err = mountdevice(baseName, bootDir, partition, false)
|
||||
device, partition, err = mountdevice(baseName, bootDir, partition, false)
|
||||
if err != nil {
|
||||
log.Errorf("mountdevice %s", err)
|
||||
return bootDir, err
|
||||
return device, partition, err
|
||||
}
|
||||
err = createbootDirs(baseName, bootDir)
|
||||
if err != nil {
|
||||
log.Errorf("createbootDirs %s", err)
|
||||
return bootDir, err
|
||||
}
|
||||
return bootDir, nil
|
||||
//err = createbootDirs(baseName, bootDir)
|
||||
//if err != nil {
|
||||
// log.Errorf("createbootDirs %s", err)
|
||||
// return bootDir, err
|
||||
//}
|
||||
return device, partition, nil
|
||||
}
|
||||
|
||||
func createbootDirs(baseName, bootDir string) error {
|
||||
func NOPEcreatebootDir(baseName, bootDir string) error {
|
||||
log.Debugf("createbootDirs")
|
||||
|
||||
if err := os.MkdirAll(filepath.Join(baseName, bootDir+"grub"), 0755); err != nil {
|
||||
@@ -747,6 +783,71 @@ func createbootDirs(baseName, bootDir string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func setBootable(device, diskType string) error {
|
||||
// TODO make conditional - if there is a bootable device already, don't break it
|
||||
// TODO: make RANCHER_BOOT bootable - it might not be device 1
|
||||
|
||||
bootflag := "boot"
|
||||
if diskType == "gpt" {
|
||||
bootflag = "legacy_boot"
|
||||
}
|
||||
log.Debugf("making device 1 on %s bootable as %s", device, diskType)
|
||||
cmd := exec.Command("parted", "-s", "-a", "optimal", device, "set 1 "+bootflag+" on")
|
||||
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Errorf("parted: %s", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func upgradeBootloader(device, baseName, bootDir, diskType string) error {
|
||||
log.Debugf("start upgradeBootloader")
|
||||
|
||||
grubDir := filepath.Join(baseName, bootDir+"grub")
|
||||
if _, err := os.Stat(grubDir); os.IsNotExist(err) {
|
||||
log.Debugf("%s does not exist - no need to upgrade bootloader", grubDir)
|
||||
// we've already upgraded
|
||||
// TODO: in v0.9.0, need to detect what version syslinux we have
|
||||
return nil
|
||||
}
|
||||
if err := setBootable(device, diskType); err != nil {
|
||||
log.Debugf("setBootable(%s, %s): %s", device, diskType, err)
|
||||
//return err
|
||||
}
|
||||
if err := os.Rename(grubDir, filepath.Join(baseName, bootDir+"grub_backup")); err != nil {
|
||||
log.Debugf("Rename(%s): %s", grubDir, err)
|
||||
return err
|
||||
}
|
||||
|
||||
syslinuxDir := filepath.Join(baseName, bootDir+"syslinux")
|
||||
backupSyslinuxDir := filepath.Join(baseName, bootDir+"syslinux_backup")
|
||||
if err := os.Rename(syslinuxDir, backupSyslinuxDir); err != nil {
|
||||
log.Debugf("Rename(%s, %s): %s", syslinuxDir, backupSyslinuxDir, err)
|
||||
return err
|
||||
}
|
||||
//mv the old syslinux into linux-previous.cfg
|
||||
oldSyslinux, err := ioutil.ReadFile(filepath.Join(backupSyslinuxDir, "syslinux.cfg"))
|
||||
if err != nil {
|
||||
log.Debugf("read(%s / syslinux.cfg): %s", backupSyslinuxDir, err)
|
||||
|
||||
return err
|
||||
}
|
||||
cfg := string(oldSyslinux)
|
||||
//DEFAULT RancherOS-current
|
||||
//
|
||||
//LABEL RancherOS-current
|
||||
// LINUX ../vmlinuz-v0.7.1-rancheros
|
||||
// APPEND rancher.state.dev=LABEL=RANCHER_STATE rancher.state.wait console=tty0 rancher.password=rancher
|
||||
// INITRD ../initrd-v0.7.1-rancheros
|
||||
cfg = strings.Replace(cfg, "current", "previous", -1)
|
||||
cfg = strings.Replace(cfg, "../", "/boot/", -1)
|
||||
// TODO consider removing the APPEND line - as the global.cfg should have the same result
|
||||
ioutil.WriteFile(filepath.Join(baseName, bootDir, "linux-current.cfg"), []byte(cfg), 0644)
|
||||
|
||||
return installSyslinux(device, baseName, bootDir, diskType)
|
||||
}
|
||||
|
||||
func installSyslinux(device, baseName, bootDir, diskType string) error {
|
||||
log.Debugf("installSyslinux")
|
||||
|
||||
@@ -765,6 +866,10 @@ func installSyslinux(device, baseName, bootDir, diskType string) error {
|
||||
log.Errorf("dd: %s", err)
|
||||
return err
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Join(baseName, bootDir+"syslinux"), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//cp /usr/lib/syslinux/modules/bios/* ${baseName}/${bootDir}syslinux
|
||||
files, _ := ioutil.ReadDir("/usr/share/syslinux/")
|
||||
for _, file := range files {
|
||||
@@ -810,6 +915,9 @@ func installSyslinuxRaid(baseName, bootDir, diskType string) error {
|
||||
log.Errorf("%s", err)
|
||||
return err
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Join(baseName, bootDir+"syslinux"), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
//cp /usr/lib/syslinux/modules/bios/* ${baseName}/${bootDir}syslinux
|
||||
files, _ := ioutil.ReadDir("/usr/share/syslinux/")
|
||||
for _, file := range files {
|
||||
@@ -821,7 +929,7 @@ func installSyslinuxRaid(baseName, bootDir, diskType string) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
cmd = exec.Command("extlinux", "--install", filepath.Join(baseName, bootDir+"syslinux"))
|
||||
cmd = exec.Command("extlinux", "--install", "--raid", filepath.Join(baseName, bootDir+"syslinux"))
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Errorf("%s", err)
|
||||
return err
|
||||
@@ -829,96 +937,20 @@ func installSyslinuxRaid(baseName, bootDir, diskType string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func installGrub(baseName, device string) error {
|
||||
log.Debugf("installGrub")
|
||||
|
||||
//grub-install --boot-directory=${baseName}/boot ${device}
|
||||
cmd := exec.Command("grub-install", "--boot-directory="+baseName+"/boot", device)
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Errorf("%s", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func grubConfig(menu bootVars) error {
|
||||
log.Debugf("grubConfig")
|
||||
|
||||
filetmpl, err := template.New("grub2config").Parse(`{{define "grub2menu"}}menuentry "{{.Name}}" {
|
||||
set root=(hd0,msdos1)
|
||||
linux /{{.bootDir}}vmlinuz-{{.Version}}-rancheros {{.KernelArgs}} {{.Append}}
|
||||
initrd /{{.bootDir}}initrd-{{.Version}}-rancheros
|
||||
}
|
||||
|
||||
{{end}}
|
||||
set default="0"
|
||||
set timeout="{{.Timeout}}"
|
||||
{{if .Fallback}}set fallback={{.Fallback}}{{end}}
|
||||
|
||||
{{- range .Entries}}
|
||||
{{template "grub2menu" .}}
|
||||
{{- end}}
|
||||
|
||||
`)
|
||||
if err != nil {
|
||||
log.Errorf("grub2config %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
cfgFile := filepath.Join(menu.baseName, menu.bootDir+"grub/grub.cfg")
|
||||
log.Debugf("grubConfig written to %s", cfgFile)
|
||||
|
||||
f, err := os.Create(cfgFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = filetmpl.Execute(f, menu)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func syslinuxConfig(menu bootVars) error {
|
||||
log.Debugf("syslinuxConfig")
|
||||
|
||||
filetmpl, err := template.New("syslinuxconfig").Parse(`{{define "syslinuxmenu"}}
|
||||
LABEL {{.Name}}
|
||||
LINUX ../vmlinuz-{{.Version}}-rancheros
|
||||
APPEND {{.KernelArgs}} {{.Append}}
|
||||
INITRD ../initrd-{{.Version}}-rancheros
|
||||
{{end}}
|
||||
TIMEOUT 20 #2 seconds
|
||||
DEFAULT RancherOS-current
|
||||
|
||||
{{- range .Entries}}
|
||||
{{template "syslinuxmenu" .}}
|
||||
{{- end}}
|
||||
|
||||
`)
|
||||
if err != nil {
|
||||
log.Errorf("syslinuxconfig %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
cfgFile := filepath.Join(menu.baseName, menu.bootDir+"syslinux/syslinux.cfg")
|
||||
log.Debugf("syslinuxConfig written to %s", cfgFile)
|
||||
f, err := os.Create(cfgFile)
|
||||
if err != nil {
|
||||
log.Errorf("Create(%s) %s", cfgFile, err)
|
||||
return err
|
||||
}
|
||||
err = filetmpl.Execute(f, menu)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func installRancher(baseName, bootDir, VERSION, DIST, kappend string) error {
|
||||
log.Debugf("installRancher")
|
||||
|
||||
// TODO detect if there already is a linux-current.cfg, if so, move it to linux-previous.cfg, and replace only current with the one in the image/iso
|
||||
// detect if there already is a linux-current.cfg, if so, move it to linux-previous.cfg,
|
||||
currentCfg := filepath.Join(baseName, bootDir, "linux-current.cfg")
|
||||
if _, err := os.Stat(currentCfg); !os.IsNotExist(err) {
|
||||
previousCfg := filepath.Join(baseName, bootDir, "linux-previous.cfg")
|
||||
if _, err := os.Stat(previousCfg); !os.IsNotExist(err) {
|
||||
if err := os.Remove(previousCfg); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
os.Rename(currentCfg, previousCfg)
|
||||
}
|
||||
|
||||
// The image/ISO have all the files in it - the syslinux cfg's and the kernel&initrd, so we can copy them all from there
|
||||
files, _ := ioutil.ReadDir(DIST)
|
||||
@@ -931,11 +963,12 @@ func installRancher(baseName, bootDir, VERSION, DIST, kappend string) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// the main syslinuxcfg
|
||||
// the general INCLUDE syslinuxcfg
|
||||
if err := dfs.CopyFile(filepath.Join(DIST, "isolinux", "isolinux.cfg"), filepath.Join(baseName, bootDir, "syslinux"), "syslinux.cfg"); err != nil {
|
||||
log.Errorf("copy %s: %s", "syslinux.cfg", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// The global.cfg INCLUDE - useful for over-riding the APPEND line
|
||||
err := ioutil.WriteFile(filepath.Join(filepath.Join(baseName, bootDir), "global.cfg"), []byte("APPEND "+kappend), 0644)
|
||||
if err != nil {
|
||||
@@ -944,45 +977,3 @@ func installRancher(baseName, bootDir, VERSION, DIST, kappend string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func pvGrubConfig(menu bootVars) error {
|
||||
log.Debugf("pvGrubConfig")
|
||||
|
||||
filetmpl, err := template.New("grublst").Parse(`{{define "grubmenu"}}
|
||||
title RancherOS {{.Version}}-({{.Name}})
|
||||
root (hd0)
|
||||
kernel /${bootDir}vmlinuz-{{.Version}}-rancheros {{.KernelArgs}} {{.Append}}
|
||||
initrd /${bootDir}initrd-{{.Version}}-rancheros
|
||||
|
||||
{{end}}
|
||||
default 0
|
||||
timeout {{.Timeout}}
|
||||
{{if .Fallback}}fallback {{.Fallback}}{{end}}
|
||||
hiddenmenu
|
||||
|
||||
{{- range .Entries}}
|
||||
{{template "grubmenu" .}}
|
||||
{{- end}}
|
||||
|
||||
`)
|
||||
if err != nil {
|
||||
log.Errorf("pv grublst: %s", err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
cfgFile := filepath.Join(menu.baseName, menu.bootDir+"grub/menu.lst")
|
||||
log.Debugf("grubMenu written to %s", cfgFile)
|
||||
f, err := os.Create(cfgFile)
|
||||
if err != nil {
|
||||
log.Errorf("Create(%s) %s", cfgFile, err)
|
||||
|
||||
return err
|
||||
}
|
||||
err = filetmpl.Execute(f, menu)
|
||||
if err != nil {
|
||||
log.Errorf("execute %s", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
102
cmd/control/install/grub.go
Normal file
102
cmd/control/install/grub.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package install
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
func RunGrub(baseName, device string) error {
|
||||
log.Debugf("installGrub")
|
||||
|
||||
//grub-install --boot-directory=${baseName}/boot ${device}
|
||||
cmd := exec.Command("grub-install", "--boot-directory="+baseName+"/boot", device)
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Errorf("%s", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func grubConfig(menu BootVars) error {
|
||||
log.Debugf("grubConfig")
|
||||
|
||||
filetmpl, err := template.New("grub2config").Parse(`{{define "grub2menu"}}menuentry "{{.Name}}" {
|
||||
set root=(hd0,msdos1)
|
||||
linux /{{.bootDir}}vmlinuz-{{.Version}}-rancheros {{.KernelArgs}} {{.Append}}
|
||||
initrd /{{.bootDir}}initrd-{{.Version}}-rancheros
|
||||
}
|
||||
|
||||
{{end}}
|
||||
set default="0"
|
||||
set timeout="{{.Timeout}}"
|
||||
{{if .Fallback}}set fallback={{.Fallback}}{{end}}
|
||||
|
||||
{{- range .Entries}}
|
||||
{{template "grub2menu" .}}
|
||||
{{- end}}
|
||||
|
||||
`)
|
||||
if err != nil {
|
||||
log.Errorf("grub2config %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
cfgFile := filepath.Join(menu.BaseName, menu.BootDir+"grub/grub.cfg")
|
||||
log.Debugf("grubConfig written to %s", cfgFile)
|
||||
|
||||
f, err := os.Create(cfgFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = filetmpl.Execute(f, menu)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func PvGrubConfig(menu BootVars) error {
|
||||
log.Debugf("pvGrubConfig")
|
||||
|
||||
filetmpl, err := template.New("grublst").Parse(`{{define "grubmenu"}}
|
||||
title RancherOS {{.Version}}-({{.Name}})
|
||||
root (hd0)
|
||||
kernel /${bootDir}vmlinuz-{{.Version}}-rancheros {{.KernelArgs}} {{.Append}}
|
||||
initrd /${bootDir}initrd-{{.Version}}-rancheros
|
||||
|
||||
{{end}}
|
||||
default 0
|
||||
timeout {{.Timeout}}
|
||||
{{if .Fallback}}fallback {{.Fallback}}{{end}}
|
||||
hiddenmenu
|
||||
|
||||
{{- range .Entries}}
|
||||
{{template "grubmenu" .}}
|
||||
{{- end}}
|
||||
|
||||
`)
|
||||
if err != nil {
|
||||
log.Errorf("pv grublst: %s", err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
cfgFile := filepath.Join(menu.BaseName, menu.BootDir+"grub/menu.lst")
|
||||
log.Debugf("grubMenu written to %s", cfgFile)
|
||||
f, err := os.Create(cfgFile)
|
||||
if err != nil {
|
||||
log.Errorf("Create(%s) %s", cfgFile, err)
|
||||
|
||||
return err
|
||||
}
|
||||
err = filetmpl.Execute(f, menu)
|
||||
if err != nil {
|
||||
log.Errorf("execute %s", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
11
cmd/control/install/install.go
Normal file
11
cmd/control/install/install.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package install
|
||||
|
||||
type MenuEntry struct {
|
||||
Name, BootDir, Version, KernelArgs, Append string
|
||||
}
|
||||
type BootVars struct {
|
||||
BaseName, BootDir string
|
||||
Timeout uint
|
||||
Fallback int
|
||||
Entries []MenuEntry
|
||||
}
|
45
cmd/control/install/syslinux.go
Normal file
45
cmd/control/install/syslinux.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package install
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/rancher/os/log"
|
||||
)
|
||||
|
||||
func syslinuxConfig(menu BootVars) error {
|
||||
log.Debugf("syslinuxConfig")
|
||||
|
||||
filetmpl, err := template.New("syslinuxconfig").Parse(`{{define "syslinuxmenu"}}
|
||||
LABEL {{.Name}}
|
||||
LINUX ../vmlinuz-{{.Version}}-rancheros
|
||||
APPEND {{.KernelArgs}} {{.Append}}
|
||||
INITRD ../initrd-{{.Version}}-rancheros
|
||||
{{end}}
|
||||
TIMEOUT 20 #2 seconds
|
||||
DEFAULT RancherOS-current
|
||||
|
||||
{{- range .Entries}}
|
||||
{{template "syslinuxmenu" .}}
|
||||
{{- end}}
|
||||
|
||||
`)
|
||||
if err != nil {
|
||||
log.Errorf("syslinuxconfig %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
cfgFile := filepath.Join(menu.BaseName, menu.BootDir+"syslinux/syslinux.cfg")
|
||||
log.Debugf("syslinuxConfig written to %s", cfgFile)
|
||||
f, err := os.Create(cfgFile)
|
||||
if err != nil {
|
||||
log.Errorf("Create(%s) %s", cfgFile, err)
|
||||
return err
|
||||
}
|
||||
err = filetmpl.Execute(f, menu)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
@@ -117,9 +117,7 @@ func InitLogger() {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: look into containerized syslog
|
||||
//filename := "/dev/kmsg"
|
||||
filename := "/var/log/log"
|
||||
filename := "/dev/kmsg"
|
||||
f, err := os.OpenFile(filename, os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
logrus.Debugf("error opening %s: %s", filename, err)
|
||||
|
@@ -150,7 +150,6 @@ rancher:
|
||||
- /usr/bin/iptables:/sbin/iptables:ro
|
||||
- /media:/media:shared
|
||||
- /mnt:/mnt:shared
|
||||
- /:/host
|
||||
container-data-volumes:
|
||||
image: {{.OS_REPO}}/os-base:{{.VERSION}}{{.SUFFIX}}
|
||||
command: echo
|
||||
|
@@ -6,17 +6,18 @@ ARG KERNEL_VERSION
|
||||
ENV VERSION=${VERSION}
|
||||
ENV KERNEL_VERSION=${KERNEL_VERSION}
|
||||
|
||||
# not installed atm udev, grub2, kexe-toos
|
||||
# not installed atm udev, grub2, kexe-tools
|
||||
# parted: partprobe, e2fsprogs: mkfs.ext4, syslinux: extlinux&syslinux
|
||||
RUN apk --no-cache add syslinux parted e2fsprogs
|
||||
RUN apk --no-cache add syslinux parted e2fsprogs util-linux
|
||||
|
||||
COPY conf /scripts/
|
||||
COPY ./build/ros /bin/
|
||||
#RUN cd /bin && ln -s ./ros ./system-docker
|
||||
#OR softlink in the host one - this image should only be used when installing from ISO..
|
||||
# (except its useful for testing)
|
||||
# && ln -s /host/usr/bin/ros /bin/
|
||||
|
||||
RUN ln -s /bootiso/boot/ /dist
|
||||
|
||||
ENTRYPOINT ["/bin/ros"]
|
||||
ENTRYPOINT ["/bin/ros", "install"]
|
||||
|
||||
|
@@ -4,8 +4,6 @@ FROM rancher/os-installer
|
||||
RUN rm /dist/ \
|
||||
&& mkdir -p /dist/
|
||||
|
||||
# Run docker build in the `./build/` dir
|
||||
#COPY ./ros /bin/
|
||||
#needs to be a recursive copy
|
||||
COPY ./ /dist/
|
||||
COPY ./boot/ /dist/
|
||||
|
||||
|
@@ -16,10 +16,11 @@ do
|
||||
c) CLOUD_CONFIG="$OPTARG" ;;
|
||||
a) APPEND="$OPTARG" ;;
|
||||
g) MBR_FILE=gptmbr.bin ;;
|
||||
# used for testing?
|
||||
k) KEXEC=y ;;
|
||||
p) PARTITION="$OPTARG" ;;
|
||||
# upgrade!
|
||||
r) ROLLBACK_VERSION="$OPTARG" ;;
|
||||
k) KEXEC=y ;;
|
||||
# used for testing?
|
||||
p) PARTITION="$OPTARG" ;;
|
||||
# notused?
|
||||
i) DIST="$OPTARG" ;;
|
||||
f) FILES="$OPTARG" ;;
|
||||
|
@@ -12,7 +12,7 @@ if [ ! -f $DOCKERFILE ] || [ ! -f dist/artifacts/vmlinuz-${KERNEL_VERSION} ] ||
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# TODO maybe extract the cration of the syslinux cfg files
|
||||
# TODO maybe extract the creation of the syslinux cfg files
|
||||
mkdir -p ${DIST}/boot/isolinux/
|
||||
cat scripts/isolinux.cfg | envsubst > ${DIST}/boot/isolinux/isolinux.cfg
|
||||
cat scripts/isolinux_label.cfg | LABEL=${VERSION} envsubst > ${DIST}/boot/linux-current.cfg
|
||||
@@ -20,11 +20,8 @@ cat scripts/isolinux_label.cfg | LABEL=${VERSION} envsubst > ${DIST}/boot/linu
|
||||
cat scripts/global.cfg | LABEL=${VERSION} envsubst > ${DIST}/boot/global.cfg
|
||||
|
||||
|
||||
mkdir -p ./scripts/installer/build
|
||||
cp ./dist/artifacts/initrd ./scripts/installer/build
|
||||
cp ./dist/artifacts/vmlinuz-${KERNEL_VERSION} ./scripts/installer/build
|
||||
mkdir -p ./scripts/installer/build/boot
|
||||
cp ./bin/ros ./scripts/installer/build
|
||||
cp -r ${DIST}/boot/* ./scripts/installer/build/
|
||||
trap "rm -rf ./scripts/installer/build" EXIT
|
||||
|
||||
# installer base image - can be included in iso
|
||||
@@ -36,12 +33,16 @@ docker build \
|
||||
-f $BASEDOCKERFILE \
|
||||
./scripts/installer
|
||||
docker save -o dist/artifacts/installer.tar ${OS_REPO}/os-installer
|
||||
cp $DOCKERFILE dist/artifacts/
|
||||
|
||||
cp ./dist/artifacts/initrd ./scripts/installer/build/boot
|
||||
cp ./dist/artifacts/vmlinuz-${KERNEL_VERSION} ./scripts/installer/build/boot
|
||||
cp -r ${DIST}/boot/* ./scripts/installer/build/boot
|
||||
cp $DOCKERFILE ./scripts/installer/build/Dockerfile
|
||||
# Full installer image with initrd - used for pulling from network
|
||||
docker build \
|
||||
-t ${OS_REPO}/os:${VERSION}${SUFFIX} \
|
||||
-f $DOCKERFILE \
|
||||
./scripts/installer
|
||||
./scripts/installer/build
|
||||
|
||||
docker save -o dist/artifacts/fullinstaller.tar ${OS_REPO}/os:${VERSION}${SUFFIX}
|
||||
echo ${OS_REPO}/os:${VERSION}${SUFFIX} >> dist/images
|
||||
|
@@ -32,6 +32,7 @@ cp /usr/lib/ISOLINUX/isolinux.bin ${CD}/boot/isolinux/
|
||||
cp /usr/lib/syslinux/modules/bios/ldlinux.c32 ${CD}/boot/isolinux/
|
||||
# add the installer image to the iso for non-network / dev/test
|
||||
cp ${ARTIFACTS}/installer.tar ${CD}/rancheros/
|
||||
cp ${ARTIFACTS}/Dockerfile.amd64 ${CD}/rancheros/
|
||||
gzip ${CD}/rancheros/installer.tar
|
||||
cd ${CD} && xorriso \
|
||||
-as mkisofs \
|
||||
|
21
scripts/run
21
scripts/run
@@ -65,8 +65,9 @@ while [ "$#" -gt 0 ]; do
|
||||
--fresh)
|
||||
FRESH=1
|
||||
;;
|
||||
--nodisplay)
|
||||
NODISPLAY=1
|
||||
--console)
|
||||
# use the bios console, not serial (lets you see syslinux)
|
||||
CONSOLEDISPLAY=1
|
||||
;;
|
||||
--installed)
|
||||
INSTALLED=1
|
||||
@@ -154,6 +155,13 @@ if [ "$QIND" != "1" ]; then
|
||||
HOME=${HOME:-/}
|
||||
fi
|
||||
|
||||
if [ "$CONSOLEDISPLAY" == "1" ]; then
|
||||
DISPLAY_OPTS="-curses"
|
||||
else
|
||||
# default
|
||||
DISPLAY_OPTS="-nographic -serial stdio -display none"
|
||||
fi
|
||||
|
||||
if [ "$QEMU" == "1" ]; then
|
||||
|
||||
if [ "$INSTALLED" == "1" ]; then
|
||||
@@ -164,7 +172,7 @@ if [ "$QEMU" == "1" ]; then
|
||||
fi
|
||||
set -x
|
||||
exec qemu-system-${QEMUARCH} \
|
||||
-serial stdio \
|
||||
${DISPLAY_OPTS} \
|
||||
-rtc base=utc,clock=host \
|
||||
${INSTALLED_ARGS} \
|
||||
-append "${KERNEL_ARGS}" \
|
||||
@@ -176,8 +184,6 @@ if [ "$QEMU" == "1" ]; then
|
||||
$(eval "${hd["$ARCH"]} ${HD}") \
|
||||
${SECOND_DRIVE_ENABLE} \
|
||||
-smp 1 \
|
||||
-nographic \
|
||||
-display none \
|
||||
-fsdev local,security_model=passthrough,readonly,id=fsdev0,path=${CCROOT} \
|
||||
-device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=config-2 \
|
||||
-fsdev local,security_model=none,id=fsdev1,path=${HOME} \
|
||||
@@ -195,11 +201,6 @@ elif [ "$BOOT_ISO" == "1" ] ||
|
||||
-device virtio-9p-pci,id=fs1,fsdev=fsdev1,mount_tag=home "
|
||||
echo "----- $ISO_OPTS"
|
||||
fi
|
||||
if [ "$NODISPLAY" == "1" ]; then
|
||||
DISPLAY_OPTS="-nographic -serial stdio -display none"
|
||||
else
|
||||
DISPLAY_OPTS="-curses"
|
||||
fi
|
||||
set -x
|
||||
exec qemu-system-${QEMUARCH} \
|
||||
${DISPLAY_OPTS} \
|
||||
|
@@ -17,6 +17,7 @@ func init() {
|
||||
Suite(&QemuSuite{
|
||||
runCommand: "../scripts/run",
|
||||
sshCommand: "../scripts/ssh",
|
||||
qemuCmd: nil,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -42,14 +43,15 @@ type QemuSuite struct {
|
||||
}
|
||||
|
||||
func (s *QemuSuite) TearDownTest(c *C) {
|
||||
c.Assert(s.qemuCmd.Process.Kill(), IsNil)
|
||||
time.Sleep(time.Millisecond * 1000)
|
||||
if s.qemuCmd != nil {
|
||||
s.Stop(c)
|
||||
}
|
||||
}
|
||||
|
||||
// RunQemuWith requires user to specify all the `scripts/run` arguments
|
||||
func (s *QemuSuite) RunQemuWith(c *C, additionalArgs ...string) error {
|
||||
|
||||
err := s.runQemu(additionalArgs...)
|
||||
err := s.runQemu(c, additionalArgs...)
|
||||
c.Assert(err, IsNil)
|
||||
return err
|
||||
}
|
||||
@@ -79,13 +81,15 @@ func (s *QemuSuite) RunQemuInstalled(c *C, additionalArgs ...string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *QemuSuite) runQemu(args ...string) error {
|
||||
func (s *QemuSuite) runQemu(c *C, args ...string) error {
|
||||
c.Assert(s.qemuCmd, IsNil) // can't run 2 qemu's at once (yet)
|
||||
s.qemuCmd = exec.Command(s.runCommand, args...)
|
||||
s.qemuCmd.Stdout = os.Stdout
|
||||
//s.qemuCmd.Stdout = os.Stdout
|
||||
s.qemuCmd.Stderr = os.Stderr
|
||||
if err := s.qemuCmd.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("--- %s: starting qemu %s, %v\n", c.TestName(), s.runCommand, args)
|
||||
|
||||
return s.WaitForSSH()
|
||||
}
|
||||
@@ -148,11 +152,17 @@ func (s *QemuSuite) Stop(c *C) {
|
||||
//s.MakeCall("sudo halt")
|
||||
//time.Sleep(2000 * time.Millisecond)
|
||||
//c.Assert(s.WaitForSSH(), IsNil)
|
||||
|
||||
//fmt.Println("%s: stopping qemu", c.TestName())
|
||||
c.Assert(s.qemuCmd.Process.Kill(), IsNil)
|
||||
time.Sleep(time.Millisecond * 1000)
|
||||
s.qemuCmd.Process.Wait()
|
||||
//time.Sleep(time.Millisecond * 1000)
|
||||
s.qemuCmd = nil
|
||||
fmt.Printf("--- %s: qemu stopped", c.TestName())
|
||||
}
|
||||
|
||||
func (s *QemuSuite) Reboot(c *C) {
|
||||
fmt.Printf("--- %s: qemu reboot", c.TestName())
|
||||
s.MakeCall("sudo reboot")
|
||||
time.Sleep(3000 * time.Millisecond)
|
||||
c.Assert(s.WaitForSSH(), IsNil)
|
||||
|
@@ -1,20 +1,19 @@
|
||||
package integration
|
||||
|
||||
import . "gopkg.in/check.v1"
|
||||
import (
|
||||
"time"
|
||||
|
||||
// TODO: separate out into different tests - there's something that makes one pass and one fail.
|
||||
. "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
//func (s *QemuSuite) TestInstallMsDosMbr(c *C) {
|
||||
func (s *QemuSuite) TestInstall(c *C) {
|
||||
func (s *QemuSuite) TestInstallMsDosMbr(c *C) {
|
||||
// ./scripts/run --no-format --append "rancher.debug=true" --iso --fresh
|
||||
runArgs := []string{
|
||||
"--iso",
|
||||
"--fresh",
|
||||
"--nodisplay",
|
||||
}
|
||||
{
|
||||
s.RunQemuWith(c, runArgs...)
|
||||
defer s.Stop(c)
|
||||
|
||||
s.CheckCall(c, `
|
||||
echo "---------------------------------- generic"
|
||||
@@ -22,30 +21,33 @@ set -ex
|
||||
sudo parted /dev/vda print
|
||||
echo "ssh_authorized_keys:" > config.yml
|
||||
echo " - $(cat /home/rancher/.ssh/authorized_keys)" >> config.yml
|
||||
sudo ros install --force --no-reboot --device /dev/vda -c config.yml`)
|
||||
sudo ros install --force --no-reboot --device /dev/vda -c config.yml --append rancher.password=rancher
|
||||
sync
|
||||
`)
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
s.Stop(c)
|
||||
}
|
||||
|
||||
// ./scripts/run --no-format --append "rancher.debug=true"
|
||||
runArgs = []string{
|
||||
"--boothd",
|
||||
"--nodisplay",
|
||||
}
|
||||
s.RunQemuWith(c, runArgs...)
|
||||
defer s.Stop(c)
|
||||
|
||||
s.CheckCall(c, "sudo ros -v")
|
||||
//}
|
||||
s.Stop(c)
|
||||
}
|
||||
|
||||
//func (s *QemuSuite) TestInstallGptMbr(c *C) {
|
||||
func (s *QemuSuite) TestInstallGptMbr(c *C) {
|
||||
// ./scripts/run --no-format --append "rancher.debug=true" --iso --fresh
|
||||
runArgs = []string{
|
||||
runArgs := []string{
|
||||
"--iso",
|
||||
"--fresh",
|
||||
"--nodisplay",
|
||||
}
|
||||
{
|
||||
s.RunQemuWith(c, runArgs...)
|
||||
defer s.Stop(c)
|
||||
|
||||
s.CheckCall(c, "sudo ros -v") // sha from latest.
|
||||
|
||||
s.CheckCall(c, `
|
||||
echo "---------------------------------- gptsyslinux"
|
||||
@@ -53,17 +55,88 @@ set -ex
|
||||
sudo parted /dev/vda print
|
||||
echo "ssh_authorized_keys:" > config.yml
|
||||
echo " - $(cat /home/rancher/.ssh/authorized_keys)" >> config.yml
|
||||
sudo ros install --force --no-reboot --device /dev/vda -t gptsyslinux -c config.yml`)
|
||||
sudo ros install --force --no-reboot --device /dev/vda -t gptsyslinux -c config.yml
|
||||
sync
|
||||
`)
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
s.Stop(c)
|
||||
}
|
||||
|
||||
// ./scripts/run --no-format --append "rancher.debug=true"
|
||||
runArgs = []string{
|
||||
"--boothd",
|
||||
"--nodisplay",
|
||||
}
|
||||
s.RunQemuWith(c, runArgs...)
|
||||
defer s.Stop(c)
|
||||
|
||||
s.CheckCall(c, "sudo ros -v")
|
||||
// TEST parted output? (gpt non-uefi == legacy_boot)
|
||||
s.Stop(c)
|
||||
}
|
||||
|
||||
func (s *QemuSuite) TestUpgradeFromImage(c *C) {
|
||||
// ./scripts/run --no-format --append "rancher.debug=true" --iso --fresh
|
||||
|
||||
//TODO: --fresh isn't giving us a new disk why? (that's what the parted print is for atm)
|
||||
runArgs := []string{
|
||||
"--iso",
|
||||
"--fresh",
|
||||
}
|
||||
{
|
||||
s.RunQemuWith(c, runArgs...)
|
||||
|
||||
s.CheckCall(c, "sudo ros -v") // sha
|
||||
s.CheckCall(c, "sudo uname -a")
|
||||
//TODO: detect "last release, and install that
|
||||
s.CheckCall(c, `
|
||||
echo "---------------------------------- generic"
|
||||
set -ex
|
||||
sudo parted /dev/vda print
|
||||
echo "ssh_authorized_keys:" > config.yml
|
||||
echo " - $(cat /home/rancher/.ssh/authorized_keys)" >> config.yml
|
||||
sudo ros install --force --no-reboot --device /dev/vda -c config.yml -i rancher/os:v0.7.1 --append "console=ttyS0 rancher.password=rancher"
|
||||
#TODO copy installer image, new ros, and new kernel to HD, so we can fake things up next time? (or have next boot from HD, but have the iso available..)
|
||||
sudo mkdir -p /bootiso
|
||||
sudo mount -t iso9660 /dev/sr0 /bootiso/
|
||||
sudo mount /dev/vda1 /mnt/
|
||||
sudo mkdir -p /mnt/rancher-installer/build/
|
||||
sudo cp /bootiso/rancheros/installer.tar.gz /mnt/rancher-installer/build/
|
||||
sudo cp /bootiso/rancheros/Dockerfile.amd64 /mnt/rancher-installer/build/
|
||||
sudo cp -r /bootiso/boot /mnt/rancher-installer/build/
|
||||
sudo cp /bin/ros /mnt/rancher-installer/build/
|
||||
sync
|
||||
`)
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
s.Stop(c)
|
||||
}
|
||||
|
||||
{
|
||||
runArgs = []string{
|
||||
"--boothd",
|
||||
}
|
||||
s.RunQemuWith(c, runArgs...)
|
||||
|
||||
s.CheckCall(c, "sudo ros -v") // v0.7.1
|
||||
s.CheckCall(c, "sudo uname -a")
|
||||
|
||||
// load the installer.tar.gz, get the other install files into an image, and runit.
|
||||
s.CheckCall(c, `sudo system-docker run --name builder -dt --volumes-from system-volumes -v /:/host alpine sh
|
||||
sudo system-docker exec -t builder ln -s /host/rancher-installer/build/ros /bin/system-docker
|
||||
sudo system-docker exec -t builder system-docker load -i /host/rancher-installer/build/installer.tar.gz
|
||||
sudo system-docker exec -t builder system-docker build -t qwer -f /host/rancher-installer/build/Dockerfile.amd64 /host/rancher-installer/build
|
||||
sudo ros os upgrade -i qwer --no-reboot -f --append "console=tty0 console=ttyS0 rancher.password=rancher"
|
||||
sync
|
||||
`)
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
s.Stop(c)
|
||||
}
|
||||
|
||||
// ./scripts/run --no-format --append "rancher.debug=true"
|
||||
runArgs = []string{
|
||||
"--boothd",
|
||||
}
|
||||
s.RunQemuWith(c, runArgs...)
|
||||
|
||||
s.CheckCall(c, "sudo ros -v") // whatever sha we had in iso boot
|
||||
s.CheckCall(c, "sudo uname -a")
|
||||
s.Stop(c)
|
||||
}
|
||||
|
Reference in New Issue
Block a user