diff --git a/cmd/control/install.go b/cmd/control/install.go index f3e3c737..09ac95d7 100755 --- a/cmd/control/install.go +++ b/cmd/control/install.go @@ -55,6 +55,10 @@ var installCommand = cli.Command{ Name: "partition, p", Usage: "partition to install to", }, + cli.StringFlag{ + Name: "statedir", + Usage: "install to rancher.state.directory", + }, cli.BoolFlag{ Name: "force, f", Usage: "[ DANGEROUS! Data loss can happen ] partition/format without prompting", @@ -130,6 +134,10 @@ func installAction(c *cli.Context) error { } device := c.String("device") partition := c.String("partition") + statedir := c.String("statedir") + if statedir != "" && installType != "noformat" { + log.Fatal("--statedir %s requires --type noformat", statedir) + } if installType != "noformat" && installType != "raid" && installType != "bootstrap" && @@ -155,7 +163,7 @@ func installAction(c *cli.Context) error { cloudConfig = uc } - if err := runInstall(image, installType, cloudConfig, device, partition, kappend, force, kexec, isoinstallerloaded, debug); err != nil { + if err := runInstall(image, installType, cloudConfig, device, partition, statedir, kappend, force, kexec, isoinstallerloaded, debug); err != nil { log.WithFields(log.Fields{"err": err}).Fatal("Failed to run install") return err } @@ -168,7 +176,7 @@ func installAction(c *cli.Context) error { return nil } -func runInstall(image, installType, cloudConfig, device, partition, kappend string, force, kexec, isoinstallerloaded, debug bool) error { +func runInstall(image, installType, cloudConfig, device, partition, statedir, kappend string, force, kexec, isoinstallerloaded, debug bool) error { fmt.Printf("Installing from %s\n", image) if !force { @@ -282,6 +290,12 @@ func runInstall(image, installType, cloudConfig, device, partition, kappend stri if debug { installerCmd = append(installerCmd, "--debug") } + if partition != "" { + installerCmd = append(installerCmd, "--partition", partition) + } + if statedir != "" { + installerCmd = append(installerCmd, "--statedir", statedir) + } // TODO: mount at /mnt for shared mount? if useIso { @@ -339,7 +353,7 @@ func runInstall(image, installType, cloudConfig, device, partition, kappend stri } } - err := layDownOS(image, installType, cloudConfig, device, partition, kappend, kexec) + err := layDownOS(image, installType, cloudConfig, device, partition, statedir, kappend, kexec) if err != nil { log.Errorf("error layDownOS %s", err) return err @@ -381,7 +395,7 @@ func mountBootIso() error { return err } -func layDownOS(image, installType, cloudConfig, device, partition, kappend string, kexec bool) error { +func layDownOS(image, installType, cloudConfig, device, partition, statedir, kappend string, kexec bool) error { // ENV == installType //[[ "$ARCH" == "arm" && "$ENV" != "upgrade" ]] && ENV=arm @@ -396,6 +410,9 @@ func layDownOS(image, installType, cloudConfig, device, partition, kappend strin baseName := "/mnt/new_img" bootDir := "boot/" kernelArgs := "printk.devkmsg=on rancher.state.dev=LABEL=RANCHER_STATE rancher.state.wait" // console="+CONSOLE + if statedir != "" { + kernelArgs = kernelArgs + " rancher.state.directory=" + statedir + } // unmount on trap defer util.Unmount(baseName) @@ -465,6 +482,9 @@ func layDownOS(image, installType, cloudConfig, device, partition, kappend strin return err } installSyslinux(device, baseName, bootDir, diskType) + if err := os.MkdirAll(filepath.Join(baseName, statedir), 0755); err != nil { + return err + } case "raid": var err error device, partition, err = mountdevice(baseName, bootDir, device, partition, false) diff --git a/scripts/hosting/digitalocean/fedora-symbiote.yml b/scripts/hosting/digitalocean/fedora-symbiote.yml new file mode 100644 index 00000000..a0c11e20 --- /dev/null +++ b/scripts/hosting/digitalocean/fedora-symbiote.yml @@ -0,0 +1,55 @@ +#!/bin/bash + +# +# This can be invoked either from the commandline of a fedora 25 vm, or as user-data +# either way, the part inside the "if" needs to be run by hand from the console atmA +# +# The most experimental way, is to use the ./scripts/hosting/digitalocean/host.sh script to modify this one for the current build +# push the rancher/os:sha image to hub, and then use +# doctl.exe compute droplet create --enable-ipv6 --enable-private-networking --image fedora-25-x64 --region sfo1 --size 2gb --ssh-keys 6956055 --ssh-keys 7170404 --user-data-file digitalocean.yml sven +# where: +#$ cat digitalocean.yml +##include +#http://:2115/digitalocean.sh +# +# + +ROS_VERSION="v1.0.1-rc1" +URL_BASE="https://github.com/rancher/os/releases/download/${ROS_VERSION}" +VMLINUX="vmlinuz-4.9.22-rancher" +INITRD="initrd + +cd /tmp +echo "downloading ${URL_BASE}/${VMLINUX}" > /dev/kmsg +curl -O -L "${URL_BASE}/${VMLINUX}" +echo "downloading ${URL_BASE}/${INITRD}" > /dev/kmsg +curl -O -L "${URL_BASE}/${INITRD}" + +if type ros 2>/dev/null; then + if [ "$(ros config get rancher.environment.installer)" == "true" ] && ros --version &>/dev/null; then + # This stuff isn't called automatically atm, need to ru manually + #FIXME removing the grub dir stops `ros os upgrade` from re-installing syslinux, which seems to cause havoc + system-docker run -dit --privileged --name stuff alpine top + system-docker exec -it stuff mount /dev/vda1 /mnt + system-docker exec -it stuff rm -rf /mnt/boot/grub /mnt/boot/*fc25* /mnt/var /mnt/usr /mnt/dev /mnt/proc /mnt/sys /mnt/tmp + system-docker exec -it stuff umount /mnt + system-docker rm -f stuff + + + ros config set rancher.debug true + ros install -f --no-reboot \ + -d /dev/vda -p /dev/vda1 \ + --statedir ros -t noformat \ + --append "rancher.state.dev=LABEL=DOROOT rancher.state.directory=ros rancher.debug=true printk.devkmsg=on notsc clocksource=kvm-clock rancher.network.interfaces.eth0.ipv4ll rancher.cloud_init.datasources=[digitalocean] rancher.autologin=tty1 rancher.autologin=ttyS0" + exit 0 + fi +fi + +echo "installing kexec" > /dev/kmsg +#apt-get update && apt-get install -y kexec-tools ipcalc +#dnf update +dnf install -y kexec-tools ipcalc + +echo "running kexec" > /dev/kmsg + +kexec --initrd=${INITRD} -l ${VMLINUX} -f --command-line="rancher.debug=true printk.devkmsg=on notsc clocksource=kvm-clock rancher.network.interfaces.eth0.ipv4ll rancher.cloud_init.datasources=[digitalocean] rancher.autologin=tty1 rancher.autologin=ttyS0 rancher.environment.installer=true" diff --git a/scripts/hosting/digitalocean/host.sh b/scripts/hosting/digitalocean/host.sh index 19989811..11ffed1e 100755 --- a/scripts/hosting/digitalocean/host.sh +++ b/scripts/hosting/digitalocean/host.sh @@ -14,6 +14,10 @@ DIST="../../../dist/artifacts" command -v caddy >/dev/null 2>&1 || { echo >&2 "I require caddy but it's not installed, see https://github.com/mholt/caddy#quick-start . Aborting."; exit 1; } +if [[ -e "dist/artifacts" ]]; then + cd scripts/hosting/digitalocean +fi + if [[ ! -e "$DIST" ]]; then echo "Need to 'make release' so that there are files to serve. Aborting." exit 1 @@ -26,15 +30,23 @@ INITRD="initrd-${VERSION}" IP=$(curl ipinfo.io/ip) PORT=2115 +#SOURCECONFIG="cloud-config.yml" +SOURCECONFIG="fedora-symbiote.yml" CLOUDCONFIG="digitalocean.sh" -cat cloud-config.yml \ +cat ${SOURCECONFIG} \ | sed "s|^URL_BASE.*$|URL_BASE=http://${IP}:${PORT}|g" \ | sed "s|^VMLINUX.*$|VMLINUX=${VMLINUX}|g" \ | sed "s|^INITRD.*$|INITRD=${INITRD}|g" \ > ${DIST}/${CLOUDCONFIG} echo "Hosting a cloud-config script at http://${IP}:${PORT}/${CLOUDCONFIG}" +echo "Usage:" +echo +echo "#include" +echo "http://${IP}:${PORT}/${CLOUDCONFIG}" +echo +echo cd ${DIST} -caddy -port ${PORT} +caddy -log stdout -port ${PORT}