mirror of
https://github.com/rancher/os.git
synced 2025-07-12 22:27: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:
commit
53c88bc505
@ -51,6 +51,10 @@ var installCommand = cli.Command{
|
|||||||
Name: "device, d",
|
Name: "device, d",
|
||||||
Usage: "storage device",
|
Usage: "storage device",
|
||||||
},
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "partition, p",
|
||||||
|
Usage: "partition to install to",
|
||||||
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "force, f",
|
Name: "force, f",
|
||||||
Usage: "[ DANGEROUS! Data loss can happen ] partition/format without prompting",
|
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
|
isoinstallerloaded = true // OMG this flag is aweful - kill it with fire
|
||||||
}
|
}
|
||||||
device := c.String("device")
|
device := c.String("device")
|
||||||
|
partition := c.String("partition")
|
||||||
if installType != "noformat" &&
|
if installType != "noformat" &&
|
||||||
installType != "raid" &&
|
installType != "raid" &&
|
||||||
installType != "bootstrap" &&
|
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")
|
log.Warn("Cloud-config not provided: you might need to provide cloud-config on bootDir with ssh_authorized_keys")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
os.MkdirAll("/opt", 0755)
|
||||||
uc := "/opt/user_config.yml"
|
uc := "/opt/user_config.yml"
|
||||||
if err := util.FileCopy(cloudConfig, uc); err != nil {
|
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
|
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")
|
log.WithFields(log.Fields{"err": err}).Fatal("Failed to run install")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -161,7 +167,7 @@ func installAction(c *cli.Context) error {
|
|||||||
return nil
|
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)
|
fmt.Printf("Installing from %s\n", image)
|
||||||
|
|
||||||
if !force {
|
if !force {
|
||||||
@ -294,6 +300,10 @@ func runInstall(image, installType, cloudConfig, device, kappend string, force,
|
|||||||
|
|
||||||
log.Debugf("running installation")
|
log.Debugf("running installation")
|
||||||
|
|
||||||
|
if partition != "" {
|
||||||
|
device = "/host" + device
|
||||||
|
partition = "/host" + partition
|
||||||
|
} else {
|
||||||
if installType == "generic" ||
|
if installType == "generic" ||
|
||||||
installType == "syslinux" ||
|
installType == "syslinux" ||
|
||||||
installType == "gptsyslinux" {
|
installType == "gptsyslinux" {
|
||||||
@ -309,6 +319,10 @@ func runInstall(image, installType, cloudConfig, device, kappend string, force,
|
|||||||
}
|
}
|
||||||
// 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)
|
// 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
|
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" {
|
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?
|
// TODO: detect if its not mounted and then optionally mount?
|
||||||
if err := mountBootIso(); err != nil {
|
if err := mountBootIso(); err != nil {
|
||||||
log.Errorf("error mountBootIso %s", err)
|
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 {
|
if err != nil {
|
||||||
log.Errorf("error layDownOS %s", err)
|
log.Errorf("error layDownOS %s", err)
|
||||||
return err
|
return err
|
||||||
@ -366,7 +380,7 @@ func mountBootIso() error {
|
|||||||
return err
|
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
|
// ENV == installType
|
||||||
//[[ "$ARCH" == "arm" && "$ENV" != "upgrade" ]] && ENV=arm
|
//[[ "$ARCH" == "arm" && "$ENV" != "upgrade" ]] && ENV=arm
|
||||||
|
|
||||||
@ -380,9 +394,6 @@ func layDownOS(image, installType, cloudConfig, device, kappend string, kexec bo
|
|||||||
CONSOLE := "tty0"
|
CONSOLE := "tty0"
|
||||||
baseName := "/mnt/new_img"
|
baseName := "/mnt/new_img"
|
||||||
bootDir := "boot/"
|
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
|
kernelArgs := "rancher.state.dev=LABEL=RANCHER_STATE rancher.state.wait" // console="+CONSOLE
|
||||||
|
|
||||||
// unmount on trap
|
// unmount on trap
|
||||||
@ -448,14 +459,14 @@ func layDownOS(image, installType, cloudConfig, device, kappend string, kexec bo
|
|||||||
seedData(baseName, cloudConfig, FILES)
|
seedData(baseName, cloudConfig, FILES)
|
||||||
case "noformat":
|
case "noformat":
|
||||||
var err error
|
var err error
|
||||||
device, partition, err = mountdevice(baseName, bootDir, partition, false)
|
device, partition, err = mountdevice(baseName, bootDir, device, partition, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
installSyslinux(device, baseName, bootDir, diskType)
|
installSyslinux(device, baseName, bootDir, diskType)
|
||||||
case "raid":
|
case "raid":
|
||||||
var err error
|
var err error
|
||||||
device, partition, err = mountdevice(baseName, bootDir, partition, false)
|
device, partition, err = mountdevice(baseName, bootDir, device, partition, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -463,7 +474,7 @@ func layDownOS(image, installType, cloudConfig, device, kappend string, kexec bo
|
|||||||
case "bootstrap":
|
case "bootstrap":
|
||||||
CONSOLE = "ttyS0"
|
CONSOLE = "ttyS0"
|
||||||
var err error
|
var err error
|
||||||
device, partition, err = mountdevice(baseName, bootDir, partition, true)
|
device, partition, err = mountdevice(baseName, bootDir, device, partition, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -473,7 +484,7 @@ func layDownOS(image, installType, cloudConfig, device, kappend string, kexec bo
|
|||||||
fallthrough
|
fallthrough
|
||||||
case "upgrade":
|
case "upgrade":
|
||||||
var err error
|
var err error
|
||||||
device, partition, err = mountdevice(baseName, bootDir, partition, false)
|
device, partition, err = mountdevice(baseName, bootDir, device, partition, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -706,9 +717,10 @@ func formatdevice(device, partition string) error {
|
|||||||
return nil
|
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)
|
log.Debugf("mountdevice %s, raw %v", partition, raw)
|
||||||
|
|
||||||
|
if partition == "" {
|
||||||
if raw {
|
if raw {
|
||||||
log.Debugf("util.Mount (raw) %s, %s", partition, baseName)
|
log.Debugf("util.Mount (raw) %s, %s", partition, baseName)
|
||||||
|
|
||||||
@ -716,10 +728,12 @@ func mountdevice(baseName, bootDir, partition string, raw bool) (string, string,
|
|||||||
log.Debugf("Run(%v)", cmd)
|
log.Debugf("Run(%v)", cmd)
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
device := ""
|
device := ""
|
||||||
|
// TODO: out can == "" - this is used to "detect software RAID" which is terrible
|
||||||
if out, err := cmd.Output(); err == nil {
|
if out, err := cmd.Output(); err == nil {
|
||||||
device = "/dev/" + strings.TrimSpace(string(out))
|
device = "/dev/" + strings.TrimSpace(string(out))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debugf("mountdevice return -> d: %s, p: %s", device, partition)
|
||||||
return device, partition, util.Mount(partition, baseName, "", "")
|
return device, partition, util.Mount(partition, baseName, "", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -740,19 +754,18 @@ func mountdevice(baseName, bootDir, partition string, raw bool) (string, string,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
device := ""
|
|
||||||
cmd := exec.Command("lsblk", "-no", "pkname", partition)
|
cmd := exec.Command("lsblk", "-no", "pkname", partition)
|
||||||
log.Debugf("Run(%v)", cmd)
|
log.Debugf("Run(%v)", cmd)
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
|
// TODO: out can == "" - this is used to "detect software RAID" which is terrible
|
||||||
if out, err := cmd.Output(); err == nil {
|
if out, err := cmd.Output(); err == nil {
|
||||||
device = "/dev/" + strings.TrimSpace(string(out))
|
device = "/dev/" + strings.TrimSpace(string(out))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
log.Debugf("util.Mount %s, %s", partition, baseName)
|
|
||||||
os.MkdirAll(baseName, 0755)
|
os.MkdirAll(baseName, 0755)
|
||||||
cmd = exec.Command("mount", partition, baseName)
|
cmd := exec.Command("mount", partition, baseName)
|
||||||
log.Debugf("Run(%v)", cmd)
|
|
||||||
//cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
//cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||||
|
log.Debugf("mountdevice return2 -> d: %s, p: %s", device, partition)
|
||||||
return device, partition, cmd.Run()
|
return device, partition, cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -764,7 +777,7 @@ func formatAndMount(baseName, bootDir, device, partition string) (string, string
|
|||||||
log.Errorf("formatdevice %s", err)
|
log.Errorf("formatdevice %s", err)
|
||||||
return device, partition, 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 {
|
if err != nil {
|
||||||
log.Errorf("mountdevice %s", err)
|
log.Errorf("mountdevice %s", err)
|
||||||
return device, partition, 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 {
|
func installSyslinux(device, baseName, bootDir, diskType string) error {
|
||||||
|
log.Debugf("installSyslinux(%s)", device)
|
||||||
|
|
||||||
mbrFile := "mbr.bin"
|
mbrFile := "mbr.bin"
|
||||||
if diskType == "gpt" {
|
if diskType == "gpt" {
|
||||||
|
72
scripts/run-install
Executable file
72
scripts/run-install
Executable 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
|
@ -62,7 +62,7 @@ func Blkid(label string) (deviceName, deviceType string) {
|
|||||||
s := bufio.NewScanner(r)
|
s := bufio.NewScanner(r)
|
||||||
for s.Scan() {
|
for s.Scan() {
|
||||||
line := s.Text()
|
line := s.Text()
|
||||||
log.Debugf("blkid: %s", cmd, line)
|
//log.Debugf("blkid: %s", cmd, line)
|
||||||
if !strings.Contains(line, `LABEL="`+label+`"`) {
|
if !strings.Contains(line, `LABEL="`+label+`"`) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user