1
0
mirror of https://github.com/rancher/os.git synced 2025-07-12 06:07:59 +00:00

Merge pull request #1724 from rancher/docker-container-install-to-partition

Fixed install --partition and added scripts/run-install to use it in …
This commit is contained in:
Sven Dowideit 2017-03-26 22:22:19 +10:00 committed by GitHub
commit 53c88bc505
3 changed files with 150 additions and 64 deletions

View File

@ -51,6 +51,10 @@ var installCommand = cli.Command{
Name: "device, d",
Usage: "storage device",
},
cli.StringFlag{
Name: "partition, p",
Usage: "partition to install to",
},
cli.BoolFlag{
Name: "force, f",
Usage: "[ DANGEROUS! Data loss can happen ] partition/format without prompting",
@ -124,6 +128,7 @@ func installAction(c *cli.Context) error {
isoinstallerloaded = true // OMG this flag is aweful - kill it with fire
}
device := c.String("device")
partition := c.String("partition")
if installType != "noformat" &&
installType != "raid" &&
installType != "bootstrap" &&
@ -141,14 +146,15 @@ func installAction(c *cli.Context) error {
log.Warn("Cloud-config not provided: you might need to provide cloud-config on bootDir with ssh_authorized_keys")
}
} else {
os.MkdirAll("/opt", 0755)
uc := "/opt/user_config.yml"
if err := util.FileCopy(cloudConfig, uc); err != nil {
log.WithFields(log.Fields{"cloudConfig": cloudConfig}).Fatal("Failed to copy cloud-config")
log.WithFields(log.Fields{"cloudConfig": cloudConfig, "error": err}).Fatal("Failed to copy cloud-config")
}
cloudConfig = uc
}
if err := runInstall(image, installType, cloudConfig, device, kappend, force, kexec, isoinstallerloaded); err != nil {
if err := runInstall(image, installType, cloudConfig, device, partition, kappend, force, kexec, isoinstallerloaded); err != nil {
log.WithFields(log.Fields{"err": err}).Fatal("Failed to run install")
return err
}
@ -161,7 +167,7 @@ func installAction(c *cli.Context) error {
return nil
}
func runInstall(image, installType, cloudConfig, device, kappend string, force, kexec, isoinstallerloaded bool) error {
func runInstall(image, installType, cloudConfig, device, partition, kappend string, force, kexec, isoinstallerloaded bool) error {
fmt.Printf("Installing from %s\n", image)
if !force {
@ -294,21 +300,29 @@ func runInstall(image, installType, cloudConfig, device, kappend string, force,
log.Debugf("running installation")
if installType == "generic" ||
installType == "syslinux" ||
installType == "gptsyslinux" {
diskType := "msdos"
if installType == "gptsyslinux" {
diskType = "gpt"
}
log.Debugf("running setDiskpartitions")
err := setDiskpartitions(device, diskType)
if err != nil {
log.Errorf("error setDiskpartitions %s", err)
return err
}
// use the bind mounted host filesystem to get access to the /dev/vda1 device that udev on the host sets up (TODO: can we run a udevd inside the container? `mknod b 253 1 /dev/vda1` doesn't work)
if partition != "" {
device = "/host" + device
partition = "/host" + partition
} else {
if installType == "generic" ||
installType == "syslinux" ||
installType == "gptsyslinux" {
diskType := "msdos"
if installType == "gptsyslinux" {
diskType = "gpt"
}
log.Debugf("running setDiskpartitions")
err := setDiskpartitions(device, diskType)
if err != nil {
log.Errorf("error setDiskpartitions %s", err)
return err
}
// use the bind mounted host filesystem to get access to the /dev/vda1 device that udev on the host sets up (TODO: can we run a udevd inside the container? `mknod b 253 1 /dev/vda1` doesn't work)
device = "/host" + device
//# 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}
}
}
if installType == "upgrade" {
@ -320,11 +334,11 @@ func runInstall(image, installType, cloudConfig, device, kappend string, force,
// TODO: detect if its not mounted and then optionally mount?
if err := mountBootIso(); err != nil {
log.Errorf("error mountBootIso %s", err)
return err
//return err
}
}
err := layDownOS(image, installType, cloudConfig, device, kappend, kexec)
err := layDownOS(image, installType, cloudConfig, device, partition, kappend, kexec)
if err != nil {
log.Errorf("error layDownOS %s", err)
return err
@ -366,7 +380,7 @@ func mountBootIso() error {
return err
}
func layDownOS(image, installType, cloudConfig, device, kappend string, kexec bool) error {
func layDownOS(image, installType, cloudConfig, device, partition, kappend string, kexec bool) error {
// ENV == installType
//[[ "$ARCH" == "arm" && "$ENV" != "upgrade" ]] && ENV=arm
@ -380,9 +394,6 @@ func layDownOS(image, installType, cloudConfig, device, kappend string, kexec bo
CONSOLE := "tty0"
baseName := "/mnt/new_img"
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}
kernelArgs := "rancher.state.dev=LABEL=RANCHER_STATE rancher.state.wait" // console="+CONSOLE
// unmount on trap
@ -448,14 +459,14 @@ func layDownOS(image, installType, cloudConfig, device, kappend string, kexec bo
seedData(baseName, cloudConfig, FILES)
case "noformat":
var err error
device, partition, err = mountdevice(baseName, bootDir, partition, false)
device, partition, err = mountdevice(baseName, bootDir, device, partition, false)
if err != nil {
return err
}
installSyslinux(device, baseName, bootDir, diskType)
case "raid":
var err error
device, partition, err = mountdevice(baseName, bootDir, partition, false)
device, partition, err = mountdevice(baseName, bootDir, device, partition, false)
if err != nil {
return err
}
@ -463,7 +474,7 @@ func layDownOS(image, installType, cloudConfig, device, kappend string, kexec bo
case "bootstrap":
CONSOLE = "ttyS0"
var err error
device, partition, err = mountdevice(baseName, bootDir, partition, true)
device, partition, err = mountdevice(baseName, bootDir, device, partition, true)
if err != nil {
return err
}
@ -473,7 +484,7 @@ func layDownOS(image, installType, cloudConfig, device, kappend string, kexec bo
fallthrough
case "upgrade":
var err error
device, partition, err = mountdevice(baseName, bootDir, partition, false)
device, partition, err = mountdevice(baseName, bootDir, device, partition, false)
if err != nil {
return err
}
@ -706,53 +717,55 @@ func formatdevice(device, partition string) error {
return nil
}
func mountdevice(baseName, bootDir, partition string, raw bool) (string, string, error) {
func mountdevice(baseName, bootDir, device, partition string, raw bool) (string, string, error) {
log.Debugf("mountdevice %s, raw %v", partition, raw)
if raw {
log.Debugf("util.Mount (raw) %s, %s", partition, baseName)
if partition == "" {
if raw {
log.Debugf("util.Mount (raw) %s, %s", partition, baseName)
cmd := exec.Command("lsblk", "-no", "pkname", partition)
log.Debugf("Run(%v)", cmd)
cmd.Stderr = os.Stderr
device := ""
// TODO: out can == "" - this is used to "detect software RAID" which is terrible
if out, err := cmd.Output(); err == nil {
device = "/dev/" + strings.TrimSpace(string(out))
}
log.Debugf("mountdevice return -> d: %s, p: %s", device, partition)
return device, partition, util.Mount(partition, baseName, "", "")
}
//rootfs := partition
// Don't use ResolveDevice - it can fail, whereas `blkid -L LABEL` works more often
cfg := config.LoadConfig()
if d, _ := util.Blkid("RANCHER_BOOT"); d != "" {
partition = d
baseName = filepath.Join(baseName, "boot")
} else {
if dev := util.ResolveDevice(cfg.Rancher.State.Dev); dev != "" {
// try the rancher.state.dev setting
partition = dev
} else {
if d, _ := util.Blkid("RANCHER_STATE"); d != "" {
partition = d
}
}
}
cmd := exec.Command("lsblk", "-no", "pkname", partition)
log.Debugf("Run(%v)", cmd)
cmd.Stderr = os.Stderr
device := ""
// TODO: out can == "" - this is used to "detect software RAID" which is terrible
if out, err := cmd.Output(); err == nil {
device = "/dev/" + strings.TrimSpace(string(out))
}
return device, partition, util.Mount(partition, baseName, "", "")
}
//rootfs := partition
// Don't use ResolveDevice - it can fail, whereas `blkid -L LABEL` works more often
cfg := config.LoadConfig()
if d, _ := util.Blkid("RANCHER_BOOT"); d != "" {
partition = d
baseName = filepath.Join(baseName, "boot")
} else {
if dev := util.ResolveDevice(cfg.Rancher.State.Dev); dev != "" {
// try the rancher.state.dev setting
partition = dev
} else {
if d, _ := util.Blkid("RANCHER_STATE"); d != "" {
partition = d
}
}
}
device := ""
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", partition, baseName)
os.MkdirAll(baseName, 0755)
cmd = exec.Command("mount", partition, baseName)
log.Debugf("Run(%v)", cmd)
cmd := exec.Command("mount", partition, baseName)
//cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
log.Debugf("mountdevice return2 -> d: %s, p: %s", device, partition)
return device, partition, cmd.Run()
}
@ -764,7 +777,7 @@ func formatAndMount(baseName, bootDir, device, partition string) (string, string
log.Errorf("formatdevice %s", err)
return device, partition, err
}
device, partition, err = mountdevice(baseName, bootDir, partition, false)
device, partition, err = mountdevice(baseName, bootDir, device, partition, false)
if err != nil {
log.Errorf("mountdevice %s", err)
return device, partition, err
@ -874,6 +887,7 @@ func upgradeBootloader(device, baseName, bootDir, diskType string) error {
}
func installSyslinux(device, baseName, bootDir, diskType string) error {
log.Debugf("installSyslinux(%s)", device)
mbrFile := "mbr.bin"
if diskType == "gpt" {

72
scripts/run-install Executable file
View File

@ -0,0 +1,72 @@
#!/bin/bash
# see https://forums.rancher.com/t/proposal-to-install-on-qemu/1236
set -x -e
cd $(dirname $0)/..
source ./scripts/version
BASE=$(pwd)
STATE=/tmp
DISK=${STATE}/rancheros.img
CONFIG=${STATE}/cloud-config.yml
export LOOPBACK=$(losetup -f)
PARTITION=$(echo "${LOOPBACK}p1" | sed 's/dev/dev\/mapper/')
DISPLAY_OPTS="-curses"
# default
#DISPLAY_OPTS="-nographic -serial stdio -display none"
function clean_up {
sudo umount mount || true
sudo kpartx -d ${DISK} || true
sudo losetup -d ${LOOPBACK} || true
sudo rm ${DISK} || true
}
trap "clean_up; exit" SIGHUP SIGINT SIGTERM EXIT
echo "writing to ${CONFIG} in ${STATE}"
echo "#cloud-config" > ${CONFIG}
echo "ssh_authorized_keys:" >> ${CONFIG}
echo "- $(<${BASE}/assets/rancher.key.pub)" >> ${CONFIG}
qemu-img create ${DISK} 1G
sudo losetup ${LOOPBACK} ${DISK}
echo "n
p
1
a
w" | sudo fdisk ${LOOPBACK} || true
sudo kpartx -a ${DISK}
docker run --privileged -it --rm \
-v /dev/mapper:/dev/mapper \
-v /:/host \
-v ${STATE}:/cluster \
rancher/os:${VERSION} \
--isoinstallerloaded=1 \
--force \
--no-reboot \
--debug \
-c /cluster/cloud-config.yml \
-t generic \
-d ${LOOPBACK} \
-p ${PARTITION} \
--append "rancher.autologin=tty1"
#-f /cluster/images.tar.xz:var/lib/system-docker/preload/images.tar.xz
sync
qemu-system-x86_64 -enable-kvm \
${DISPLAY_OPTS} \
-m 1024 \
-net nic,model=virtio \
-net user,hostfwd=tcp::2222-:22 \
-drive if=virtio,file=${DISK},format=raw

View File

@ -62,7 +62,7 @@ func Blkid(label string) (deviceName, deviceType string) {
s := bufio.NewScanner(r)
for s.Scan() {
line := s.Text()
log.Debugf("blkid: %s", cmd, line)
//log.Debugf("blkid: %s", cmd, line)
if !strings.Contains(line, `LABEL="`+label+`"`) {
continue
}