mirror of
https://github.com/rancher/os.git
synced 2025-08-06 09:14:21 +00:00
Convert install script to go
Signed-off-by: Sven Dowideit <SvenDowideit@home.org.au>
This commit is contained in:
parent
80820e610a
commit
087bc6fd2d
0
cmd/control/dev.go
Normal file → Executable file
0
cmd/control/dev.go
Normal file → Executable file
@ -1,19 +1,36 @@
|
|||||||
package control
|
package control
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
"github.com/rancher/os/log"
|
"github.com/rancher/os/log"
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
"github.com/rancher/os/cmd/power"
|
"github.com/rancher/os/cmd/power"
|
||||||
"github.com/rancher/os/config"
|
"github.com/rancher/os/config"
|
||||||
|
"github.com/rancher/os/dfs" // TODO: move CopyFile into util or something.
|
||||||
"github.com/rancher/os/util"
|
"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{
|
var installCommand = cli.Command{
|
||||||
Name: "install",
|
Name: "install",
|
||||||
Usage: "install RancherOS to disk",
|
Usage: "install RancherOS to disk",
|
||||||
@ -80,7 +97,7 @@ func installAction(c *cli.Context) error {
|
|||||||
|
|
||||||
cloudConfig := c.String("cloud-config")
|
cloudConfig := c.String("cloud-config")
|
||||||
if cloudConfig == "" {
|
if cloudConfig == "" {
|
||||||
log.Warn("Cloud-config not provided: you might need to provide cloud-config on boot 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 {
|
||||||
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 {
|
||||||
@ -89,22 +106,23 @@ func installAction(c *cli.Context) error {
|
|||||||
cloudConfig = uc
|
cloudConfig = uc
|
||||||
}
|
}
|
||||||
|
|
||||||
append := strings.TrimSpace(c.String("append"))
|
kappend := strings.TrimSpace(c.String("append"))
|
||||||
force := c.Bool("force")
|
force := c.Bool("force")
|
||||||
reboot := !c.Bool("no-reboot")
|
reboot := !c.Bool("no-reboot")
|
||||||
|
|
||||||
if err := runInstall(image, installType, cloudConfig, device, append, force, reboot); err != nil {
|
if err := runInstall(image, installType, cloudConfig, device, kappend, force, reboot); 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 nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runInstall(image, installType, cloudConfig, device, append string, force, reboot bool) error {
|
func runInstall(image, installType, cloudConfig, device, kappend string, force, reboot bool) error {
|
||||||
fmt.Printf("Installing from %s\n", image)
|
fmt.Printf("Installing from %s\n", image)
|
||||||
|
|
||||||
if !force {
|
if !force {
|
||||||
if !yes("Continue") {
|
if !yes("Continue") {
|
||||||
|
log.Infof("Not continuing with installation due to user not saying 'yes'")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,21 +135,110 @@ func runInstall(image, installType, cloudConfig, device, append string, force, r
|
|||||||
installType == "syslinux" ||
|
installType == "syslinux" ||
|
||||||
installType == "gptsyslinux" {
|
installType == "gptsyslinux" {
|
||||||
|
|
||||||
cmd := exec.Command("system-docker", "run",
|
// TODO: generalise to versions before 0.8.0-rc2
|
||||||
"--net=host", "--privileged", "--volumes-from=all-volumes",
|
if image == "rancher/os:v0.7.0" {
|
||||||
"--entrypoint=/scripts/set-disk-partitions",
|
log.Infof("starting installer container for %s", image)
|
||||||
image, device, diskType)
|
if installType == "generic" {
|
||||||
|
cmd := exec.Command("system-docker", "run", "--net=host", "--privileged", "--volumes-from=all-volumes",
|
||||||
|
"--entrypoint=/scripts/set-disk-partitions", image, device, diskType)
|
||||||
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd := exec.Command("system-docker", "run", "--net=host", "--privileged", "--volumes-from=user-volumes",
|
cmd := exec.Command("system-docker", "run", "--net=host", "--privileged", "--volumes-from=user-volumes",
|
||||||
"--volumes-from=command-volumes", image, "-d", device, "-t", installType, "-c", cloudConfig, "-a", append)
|
"--volumes-from=command-volumes", image, "-d", device, "-t", installType, "-c", cloudConfig, "-a", kappend)
|
||||||
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat("/dist/vmlinuz"); os.IsNotExist(err) {
|
||||||
|
log.Infof("trying to mount /dev/sr0 and then load image")
|
||||||
|
|
||||||
|
//try mounting cdrom/usb, and docker loading rancher/os:v...
|
||||||
|
os.MkdirAll("/ttt", 0755)
|
||||||
|
cmd := exec.Command("mount", "-t", "iso9660", "/dev/sr0", "/ttt")
|
||||||
|
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Infof("tried and failed to mount /dev/sr0: %s", err)
|
||||||
|
} else {
|
||||||
|
log.Infof("Mounted /dev/sr0")
|
||||||
|
if _, err := os.Stat("/ttt/rancheros/"); err == nil {
|
||||||
|
cmd := exec.Command("system-docker", "load", "-i", "/ttt/rancheros/installer.tar.gz")
|
||||||
|
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Infof("failed to load images from /ttt/rancheros: %s", err)
|
||||||
|
} else {
|
||||||
|
log.Infof("Loaded images from /ttt/rancheros/installer.tar.gz")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: could also poke around looking for the /boot/vmlinuz and initrd...
|
||||||
|
util.Unmount("/ttt")
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("starting installer container for %s (new)", image)
|
||||||
|
installerCmd := []string{
|
||||||
|
"run", "--rm", "--net=host", "--privileged",
|
||||||
|
// bind mount host fs to access its /dev (udev isn't running in container)
|
||||||
|
"-v", "/:/host",
|
||||||
|
"--volumes-from=user-volumes", "--volumes-from=command-volumes",
|
||||||
|
image,
|
||||||
|
"install",
|
||||||
|
"-t", installType,
|
||||||
|
"-d", device,
|
||||||
|
// "-f", strconv.FormatBool(force),
|
||||||
|
// "--no-reboot", strconv.FormatBool(!reboot),
|
||||||
|
// "-c", `"`+cloudConfig+`"`,
|
||||||
|
// "-a", `"`+kappend+`"`
|
||||||
|
}
|
||||||
|
if force {
|
||||||
|
installerCmd = append(installerCmd, "-f")
|
||||||
|
}
|
||||||
|
if !reboot {
|
||||||
|
installerCmd = append(installerCmd, "--no-reboot")
|
||||||
|
}
|
||||||
|
if cloudConfig != "" {
|
||||||
|
installerCmd = append(installerCmd, "-c", cloudConfig)
|
||||||
|
}
|
||||||
|
if kappend != "" {
|
||||||
|
installerCmd = append(installerCmd, "-a", kappend)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = exec.Command("system-docker", installerCmd...)
|
||||||
|
log.Debugf("Run(%v)", cmd)
|
||||||
|
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: needs to pass the log level on to the container
|
||||||
|
log.InitLogger()
|
||||||
|
log.SetLevel(log.DebugLevel)
|
||||||
|
|
||||||
|
log.Infof("running installation")
|
||||||
|
|
||||||
|
if installType == "generic" {
|
||||||
|
log.Infof("running setDiskpartitions")
|
||||||
|
err := setDiskpartitions(device)
|
||||||
|
if err != nil {
|
||||||
|
log.Infof("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
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("running layDownOS")
|
||||||
|
err := layDownOS(image, installType, cloudConfig, device, kappend)
|
||||||
|
if err != nil {
|
||||||
|
log.Infof("error layDownOS %s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if reboot && (force || yes("Continue with reboot")) {
|
if reboot && (force || yes("Continue with reboot")) {
|
||||||
log.Info("Rebooting")
|
log.Info("Rebooting")
|
||||||
@ -140,3 +247,594 @@ func runInstall(image, installType, cloudConfig, device, append string, force, r
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func layDownOS(image, installType, cloudConfig, device, kappend string) error {
|
||||||
|
log.Infof("layDownOS")
|
||||||
|
// ENV == installType
|
||||||
|
//[[ "$ARCH" == "arm" && "$ENV" != "rancher-upgrade" ]] && ENV=arm
|
||||||
|
|
||||||
|
// image == rancher/os:v0.7.0_arm
|
||||||
|
// TODO: remove the _arm suffix (but watch out, its not always there..)
|
||||||
|
VERSION := image[strings.Index(image, ":")+1:]
|
||||||
|
|
||||||
|
var FILES []string
|
||||||
|
DIST := "/dist" //${DIST:-/dist}
|
||||||
|
//cloudConfig := SCRIPTS_DIR + "/conf/empty.yml" //${cloudConfig:-"${SCRIPTS_DIR}/conf/empty.yml"}
|
||||||
|
CONSOLE := "tty0"
|
||||||
|
baseName := "/mnt/new_img"
|
||||||
|
bootDir := "boot/" // set by mountdevice
|
||||||
|
//# 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
|
||||||
|
defer util.Unmount(baseName)
|
||||||
|
|
||||||
|
switch installType {
|
||||||
|
case "generic":
|
||||||
|
log.Infof("formatAndMount")
|
||||||
|
var err error
|
||||||
|
bootDir, err = formatAndMount(baseName, bootDir, device, partition)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Infof("defer")
|
||||||
|
log.Infof("installGrub")
|
||||||
|
err = installGrub(baseName, device)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Infof("seedData")
|
||||||
|
err = seedData(baseName, cloudConfig, FILES)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Infof("seedData done")
|
||||||
|
case "arm":
|
||||||
|
var err error
|
||||||
|
bootDir, err = formatAndMount(baseName, bootDir, device, partition)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
seedData(baseName, cloudConfig, FILES)
|
||||||
|
case "amazon-ebs-pv":
|
||||||
|
fallthrough
|
||||||
|
case "amazon-ebs-hvm":
|
||||||
|
CONSOLE = "ttyS0"
|
||||||
|
var err error
|
||||||
|
bootDir, err = formatAndMount(baseName, bootDir, device, partition)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if installType == "amazon-ebs-hvm" {
|
||||||
|
installGrub(baseName, device)
|
||||||
|
}
|
||||||
|
//# AWS Networking recommends disabling.
|
||||||
|
seedData(baseName, cloudConfig, FILES)
|
||||||
|
case "googlecompute":
|
||||||
|
CONSOLE = "ttyS0"
|
||||||
|
var err error
|
||||||
|
bootDir, err = formatAndMount(baseName, bootDir, device, partition)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
installGrub(baseName, device)
|
||||||
|
seedData(baseName, cloudConfig, FILES)
|
||||||
|
case "noformat":
|
||||||
|
var err error
|
||||||
|
bootDir, err = mountdevice(baseName, bootDir, partition, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
createbootDirs(baseName, bootDir)
|
||||||
|
installSyslinux(device, baseName, bootDir)
|
||||||
|
case "raid":
|
||||||
|
var err error
|
||||||
|
bootDir, err = mountdevice(baseName, bootDir, partition, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
createbootDirs(baseName, bootDir)
|
||||||
|
installSyslinuxRaid(baseName, bootDir)
|
||||||
|
case "bootstrap":
|
||||||
|
CONSOLE = "ttyS0"
|
||||||
|
var err error
|
||||||
|
bootDir, err = mountdevice(baseName, bootDir, partition, true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
createbootDirs(baseName, bootDir)
|
||||||
|
kernelArgs = kernelArgs + " rancher.cloud_init.datasources=[ec2,gce]"
|
||||||
|
case "rancher-upgrade":
|
||||||
|
var err error
|
||||||
|
bootDir, err = mountdevice(baseName, bootDir, partition, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
createbootDirs(baseName, bootDir)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unexpected install type %s", installType)
|
||||||
|
}
|
||||||
|
kernelArgs = kernelArgs + " console=" + CONSOLE
|
||||||
|
|
||||||
|
if kappend == "" {
|
||||||
|
preservedAppend, _ := ioutil.ReadFile(filepath.Join(baseName, bootDir+"append"))
|
||||||
|
kappend = string(preservedAppend)
|
||||||
|
} else {
|
||||||
|
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)
|
||||||
|
log.Debugf("installRancher")
|
||||||
|
err := installRancher(baseName, bootDir, VERSION, DIST)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Debugf("installRancher done")
|
||||||
|
|
||||||
|
//unused by us? :)
|
||||||
|
//if [ "$KEXEC" = "y" ]; then
|
||||||
|
// kexec -l ${DIST}/vmlinuz --initrd=${DIST}/initrd --append="${kernelArgs} ${APPEND}" -f
|
||||||
|
//fi
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// files is an array of 'sourcefile:destination' - but i've not seen any examples of it being used.
|
||||||
|
func seedData(baseName, cloudData string, files []string) error {
|
||||||
|
log.Debugf("seedData")
|
||||||
|
_, err := os.Stat(baseName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = os.MkdirAll(filepath.Join(baseName, "/var/lib/rancher/conf/cloud-config.d"), 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range files {
|
||||||
|
e := strings.Split(f, ":")
|
||||||
|
//if err = os.MkdirAll(filepath.Join(baseName, e[1])); err != nil {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
if err = dfs.CopyFile(e[0], baseName, e[1]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// set-disk-partitions is called with device == **/dev/sda**
|
||||||
|
func setDiskpartitions(device string) error {
|
||||||
|
log.Debugf("setDiskpartitions")
|
||||||
|
|
||||||
|
d := strings.Split(device, "/")
|
||||||
|
if len(d) != 3 {
|
||||||
|
return fmt.Errorf("bad device name (%s)", device)
|
||||||
|
}
|
||||||
|
deviceName := d[2]
|
||||||
|
|
||||||
|
file, err := os.Open("/proc/partitions")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("failed to read /proc/partitions %s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
exists := false
|
||||||
|
haspartitions := false
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
for scanner.Scan() {
|
||||||
|
str := scanner.Text()
|
||||||
|
last := strings.LastIndex(str, " ")
|
||||||
|
|
||||||
|
if last > -1 {
|
||||||
|
dev := str[last+1:]
|
||||||
|
|
||||||
|
if strings.HasPrefix(dev, deviceName) {
|
||||||
|
if dev == deviceName {
|
||||||
|
exists = true
|
||||||
|
} else {
|
||||||
|
haspartitions = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
log.Printf("disk %s not found", device)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if haspartitions {
|
||||||
|
log.Printf("device %s already partitioned - checking if any are mounted", device)
|
||||||
|
file, err := os.Open("/proc/mounts")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("failed to read /proc/mounts %s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
if partitionMounted(device, file) {
|
||||||
|
err = fmt.Errorf("partition %s mounted, cannot repartition", device)
|
||||||
|
log.Printf("%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmd := exec.Command("system-docker", "ps", "-q")
|
||||||
|
var outb bytes.Buffer
|
||||||
|
cmd.Stdout = &outb
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Printf("%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, image := range strings.Split(outb.String(), "\n") {
|
||||||
|
if image == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
r, w := io.Pipe()
|
||||||
|
go func() {
|
||||||
|
// TODO: consider a timeout
|
||||||
|
cmd := exec.Command("system-docker", "exec", image, "cat /proc/mount")
|
||||||
|
cmd.Stdout = w
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Printf("%s", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if partitionMounted(device, r) {
|
||||||
|
err = fmt.Errorf("partition %s mounted in %s, cannot repartition", device, image)
|
||||||
|
log.Printf("%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//do it!
|
||||||
|
cmd := exec.Command("dd", "if=/dev/zero", "of="+device, "bs=512", "count=2048")
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Printf("%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmd = exec.Command("partprobe", device)
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Printf("%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
r, w := io.Pipe()
|
||||||
|
go func() {
|
||||||
|
w.Write([]byte(`n
|
||||||
|
p
|
||||||
|
1
|
||||||
|
|
||||||
|
|
||||||
|
w
|
||||||
|
`))
|
||||||
|
w.Close()
|
||||||
|
}()
|
||||||
|
cmd = exec.Command("fdisk", device)
|
||||||
|
cmd.Stdin = r
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Printf("%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func partitionMounted(device string, file io.Reader) bool {
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
for scanner.Scan() {
|
||||||
|
str := scanner.Text()
|
||||||
|
// /dev/sdb1 /data ext4 rw,relatime,errors=remount-ro,data=ordered 0 0
|
||||||
|
ele := strings.Split(str, " ")
|
||||||
|
if len(ele) > 5 {
|
||||||
|
if strings.HasPrefix(ele[0], device) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
log.Printf("%s", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatdevice(device, partition string) error {
|
||||||
|
log.Debugf("formatdevice %s", partition)
|
||||||
|
|
||||||
|
//mkfs.ext4 -F -i 4096 -L RANCHER_STATE ${partition}
|
||||||
|
cmd := exec.Command("mkfs.ext4", "-F", "-i", "4096", "-L", "RANCHER_STATE", partition)
|
||||||
|
log.Debugf("Run(%v)", cmd)
|
||||||
|
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Debugf("mkfs.ext4: %s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func mountdevice(baseName, bootDir, partition string, raw bool) (string, error) {
|
||||||
|
log.Debugf("mountdevice %s, raw %v", partition, raw)
|
||||||
|
|
||||||
|
if raw {
|
||||||
|
log.Debugf("util.Mount (raw) %s, %s", partition, baseName)
|
||||||
|
return bootDir, util.Mount(partition, baseName, "", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
} 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("util.Mount %s, %s", rootfs, baseName)
|
||||||
|
// return bootDir, util.Mount(rootfs, baseName, "", "")
|
||||||
|
os.MkdirAll(baseName, 0755)
|
||||||
|
cmd = exec.Command("mount", rootfs, baseName)
|
||||||
|
log.Debugf("Run(%v)", cmd)
|
||||||
|
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
|
||||||
|
return bootDir, cmd.Run()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatAndMount(baseName, bootDir, device, partition string) (string, error) {
|
||||||
|
log.Debugf("formatAndMount")
|
||||||
|
|
||||||
|
err := formatdevice(device, partition)
|
||||||
|
if err != nil {
|
||||||
|
return bootDir, err
|
||||||
|
}
|
||||||
|
bootDir, err = mountdevice(baseName, bootDir, partition, false)
|
||||||
|
if err != nil {
|
||||||
|
return bootDir, err
|
||||||
|
}
|
||||||
|
err = createbootDirs(baseName, bootDir)
|
||||||
|
if err != nil {
|
||||||
|
return bootDir, err
|
||||||
|
}
|
||||||
|
return bootDir, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createbootDirs(baseName, bootDir string) error {
|
||||||
|
log.Debugf("createbootDirs")
|
||||||
|
|
||||||
|
if err := os.MkdirAll(filepath.Join(baseName, bootDir+"grub"), 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(filepath.Join(baseName, bootDir+"syslinux"), 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func installSyslinux(device, baseName, bootDir string) error {
|
||||||
|
log.Debugf("installSyslinux")
|
||||||
|
|
||||||
|
//dd bs=440 count=1 if=/usr/lib/syslinux/mbr/mbr.bin of=${device}
|
||||||
|
cmd := exec.Command("dd", "bs=440", "count=1", "if=/usr/lib/syslinux/mbr/mbr.bin", "of="+device)
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Printf("%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
//cp /usr/lib/syslinux/modules/bios/* ${baseName}/${bootDir}syslinux
|
||||||
|
cmd = exec.Command("sh", "-c", "cp", "/usr/lib/syslinux/modules/bios/*", filepath.Join(baseName, bootDir+"syslinux"))
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Printf("%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
//extlinux --install ${baseName}/${bootDir}syslinux
|
||||||
|
cmd = exec.Command("extlinux", "--install", filepath.Join(baseName, bootDir+"syslinux"))
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Printf("%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func installSyslinuxRaid(baseName, bootDir string) error {
|
||||||
|
log.Debugf("installSyslinuxRaid")
|
||||||
|
|
||||||
|
//dd bs=440 count=1 if=/usr/lib/syslinux/mbr/mbr.bin of=/dev/sda
|
||||||
|
//dd bs=440 count=1 if=/usr/lib/syslinux/mbr/mbr.bin of=/dev/sdb
|
||||||
|
//cp /usr/lib/syslinux/modules/bios/* ${baseName}/${bootDir}syslinux
|
||||||
|
//extlinux --install --raid ${baseName}/${bootDir}syslinux
|
||||||
|
cmd := exec.Command("dd", "bs=440", "count=1", "if=/usr/lib/syslinux/mbr/mbr.bin", "of=/dev/sda")
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Printf("%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmd = exec.Command("dd", "bs=440", "count=1", "if=/usr/lib/syslinux/mbr/mbr.bin", "of=/dev/sdb")
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Printf("%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmd = exec.Command("sh", "-c", "cp", "/usr/lib/syslinux/modules/bios/*", filepath.Join(baseName, bootDir+"syslinux"))
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Printf("%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmd = exec.Command("extlinux", "--install", filepath.Join(baseName, bootDir+"syslinux"))
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
log.Printf("%s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
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.Printf("%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}}
|
||||||
|
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 string) error {
|
||||||
|
log.Debugf("installRancher")
|
||||||
|
|
||||||
|
//cp ${DIST}/initrd ${baseName}/${bootDir}initrd-${VERSION}-rancheros
|
||||||
|
if err := dfs.CopyFile(DIST+"/initrd", baseName, bootDir+"initrd-"+VERSION+"-rancheros"); err != nil {
|
||||||
|
log.Errorf("copy initrd: ", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
//cp ${DIST}/vmlinuz ${baseName}/${bootDir}vmlinuz-${VERSION}-rancheros
|
||||||
|
if err := dfs.CopyFile(DIST+"/vmlinuz", baseName, bootDir+"vmlinuz-"+VERSION+"-rancheros"); err != nil {
|
||||||
|
log.Errorf("copy vmlinuz: %s", err)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
21
init/init.go
Normal file → Executable file
21
init/init.go
Normal file → Executable file
@ -71,6 +71,7 @@ func loadModules(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func sysInit(c *config.CloudConfig) (*config.CloudConfig, error) {
|
func sysInit(c *config.CloudConfig) (*config.CloudConfig, error) {
|
||||||
|
showMounts("sysInit")
|
||||||
args := append([]string{config.SysInitBin}, os.Args[1:]...)
|
args := append([]string{config.SysInitBin}, os.Args[1:]...)
|
||||||
|
|
||||||
cmd := &exec.Cmd{
|
cmd := &exec.Cmd{
|
||||||
@ -224,10 +225,12 @@ func RunInit() error {
|
|||||||
var metadataFile []byte
|
var metadataFile []byte
|
||||||
initFuncs := []config.CfgFunc{
|
initFuncs := []config.CfgFunc{
|
||||||
func(c *config.CloudConfig) (*config.CloudConfig, error) {
|
func(c *config.CloudConfig) (*config.CloudConfig, error) {
|
||||||
|
showMounts("dfs.PrepareFs")
|
||||||
return c, dfs.PrepareFs(&mountConfig)
|
return c, dfs.PrepareFs(&mountConfig)
|
||||||
},
|
},
|
||||||
mountOem,
|
mountOem,
|
||||||
func(_ *config.CloudConfig) (*config.CloudConfig, error) {
|
func(_ *config.CloudConfig) (*config.CloudConfig, error) {
|
||||||
|
showMounts("showconfig")
|
||||||
cfg := config.LoadConfig()
|
cfg := config.LoadConfig()
|
||||||
|
|
||||||
if cfg.Rancher.Debug {
|
if cfg.Rancher.Debug {
|
||||||
@ -243,6 +246,7 @@ func RunInit() error {
|
|||||||
},
|
},
|
||||||
loadModules,
|
loadModules,
|
||||||
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
||||||
|
showMounts("read B2D_STATE")
|
||||||
if util.ResolveDevice("LABEL=B2D_STATE") != "" {
|
if util.ResolveDevice("LABEL=B2D_STATE") != "" {
|
||||||
boot2DockerEnvironment = true
|
boot2DockerEnvironment = true
|
||||||
cfg.Rancher.State.Dev = "LABEL=B2D_STATE"
|
cfg.Rancher.State.Dev = "LABEL=B2D_STATE"
|
||||||
@ -270,6 +274,7 @@ func RunInit() error {
|
|||||||
return cfg, nil
|
return cfg, nil
|
||||||
},
|
},
|
||||||
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
||||||
|
showMounts("tryMountAndBootstrap")
|
||||||
var err error
|
var err error
|
||||||
cfg, shouldSwitchRoot, err = tryMountAndBootstrap(cfg)
|
cfg, shouldSwitchRoot, err = tryMountAndBootstrap(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -278,6 +283,7 @@ func RunInit() error {
|
|||||||
return cfg, nil
|
return cfg, nil
|
||||||
},
|
},
|
||||||
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
||||||
|
showMounts("cloudinit")
|
||||||
if err := os.MkdirAll(config.CloudConfigDir, os.ModeDir|0755); err != nil {
|
if err := os.MkdirAll(config.CloudConfigDir, os.ModeDir|0755); err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
@ -313,6 +319,7 @@ func RunInit() error {
|
|||||||
return cfg, nil
|
return cfg, nil
|
||||||
},
|
},
|
||||||
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
||||||
|
showMounts("readconfig")
|
||||||
var err error
|
var err error
|
||||||
cloudConfigBootFile, err = ioutil.ReadFile(config.CloudConfigBootFile)
|
cloudConfigBootFile, err = ioutil.ReadFile(config.CloudConfigBootFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -325,6 +332,7 @@ func RunInit() error {
|
|||||||
return cfg, nil
|
return cfg, nil
|
||||||
},
|
},
|
||||||
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
||||||
|
showMounts("switchroot")
|
||||||
if !shouldSwitchRoot {
|
if !shouldSwitchRoot {
|
||||||
return cfg, nil
|
return cfg, nil
|
||||||
}
|
}
|
||||||
@ -336,6 +344,7 @@ func RunInit() error {
|
|||||||
},
|
},
|
||||||
mountOem,
|
mountOem,
|
||||||
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
||||||
|
showMounts("write meta")
|
||||||
if err := os.MkdirAll(config.CloudConfigDir, os.ModeDir|0755); err != nil {
|
if err := os.MkdirAll(config.CloudConfigDir, os.ModeDir|0755); err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
@ -348,6 +357,7 @@ func RunInit() error {
|
|||||||
return cfg, nil
|
return cfg, nil
|
||||||
},
|
},
|
||||||
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
||||||
|
showMounts("set sate")
|
||||||
if boot2DockerEnvironment {
|
if boot2DockerEnvironment {
|
||||||
if err := config.Set("rancher.state.dev", cfg.Rancher.State.Dev); err != nil {
|
if err := config.Set("rancher.state.dev", cfg.Rancher.State.Dev); err != nil {
|
||||||
log.Errorf("Failed to update rancher.state.dev: %v", err)
|
log.Errorf("Failed to update rancher.state.dev: %v", err)
|
||||||
@ -360,10 +370,12 @@ func RunInit() error {
|
|||||||
return config.LoadConfig(), nil
|
return config.LoadConfig(), nil
|
||||||
},
|
},
|
||||||
func(c *config.CloudConfig) (*config.CloudConfig, error) {
|
func(c *config.CloudConfig) (*config.CloudConfig, error) {
|
||||||
|
showMounts("preparefs2")
|
||||||
return c, dfs.PrepareFs(&mountConfig)
|
return c, dfs.PrepareFs(&mountConfig)
|
||||||
},
|
},
|
||||||
loadModules,
|
loadModules,
|
||||||
func(c *config.CloudConfig) (*config.CloudConfig, error) {
|
func(c *config.CloudConfig) (*config.CloudConfig, error) {
|
||||||
|
showMounts("setproxy")
|
||||||
network.SetProxyEnvironmentVariables(c)
|
network.SetProxyEnvironmentVariables(c)
|
||||||
return c, nil
|
return c, nil
|
||||||
},
|
},
|
||||||
@ -388,3 +400,12 @@ func RunInit() error {
|
|||||||
|
|
||||||
return pidOne()
|
return pidOne()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func showMounts(msg string) {
|
||||||
|
mounts, err := ioutil.ReadFile("/proc/mounts")
|
||||||
|
if err != nil {
|
||||||
|
log.Infof("+++++++++ showMounts(%s) ERROR: %s", msg, err)
|
||||||
|
} else {
|
||||||
|
log.Infof("+++++++++ showMounts(%s) %s", msg, mounts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
30
init/sysinit.go
Normal file → Executable file
30
init/sysinit.go
Normal file → Executable file
@ -1,6 +1,7 @@
|
|||||||
package init
|
package init
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -13,6 +14,7 @@ import (
|
|||||||
"github.com/rancher/os/config"
|
"github.com/rancher/os/config"
|
||||||
"github.com/rancher/os/docker"
|
"github.com/rancher/os/docker"
|
||||||
"github.com/rancher/os/log"
|
"github.com/rancher/os/log"
|
||||||
|
"github.com/rancher/os/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -96,11 +98,37 @@ func loadImages(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
|||||||
func SysInit() error {
|
func SysInit() error {
|
||||||
cfg := config.LoadConfig()
|
cfg := config.LoadConfig()
|
||||||
|
|
||||||
|
f, err := os.Create("/log")
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed to make /log file %s", err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
log.Infof("----------------------------------SVEN--------------------------------------------------")
|
||||||
|
if isInitrd() {
|
||||||
|
log.Infof("-----trying /dev/sr0-------------")
|
||||||
|
// loading from ramdisk/iso, so mount /dev/cdrom (or whatever it is) and see if theres a rancheros dir
|
||||||
|
err := util.Mount("/dev/sr0", "/mnt", "iso9660", "-r")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(f, "Failed to mount /dev/sr0: %s", err)
|
||||||
|
log.Debugf("Failed to mount /dev/sr0: %s", err)
|
||||||
|
} else {
|
||||||
|
if err := control.PreloadImages(docker.NewSystemClient, "/mnt/rancheros"); err != nil {
|
||||||
|
fmt.Fprintf(f, "Failed to preload ISO System Docker images: %v", err)
|
||||||
|
log.Errorf("Failed to preload ISO System Docker images: %v", err)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(f, "preloaded ISO images")
|
||||||
|
log.Infof("preloaded ISO images")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Infof("----------------------------------NEVS--------------------------------------------------")
|
||||||
|
f.Sync()
|
||||||
|
|
||||||
if err := control.PreloadImages(docker.NewSystemClient, systemImagesPreloadDirectory); err != nil {
|
if err := control.PreloadImages(docker.NewSystemClient, systemImagesPreloadDirectory); err != nil {
|
||||||
log.Errorf("Failed to preload System Docker images: %v", err)
|
log.Errorf("Failed to preload System Docker images: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := config.ChainCfgFuncs(cfg,
|
_, err = config.ChainCfgFuncs(cfg,
|
||||||
loadImages,
|
loadImages,
|
||||||
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {
|
||||||
p, err := compose.GetProject(cfg, false, true)
|
p, err := compose.GetProject(cfg, false, true)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
rancher:
|
rancher:
|
||||||
|
debug: true
|
||||||
environment:
|
environment:
|
||||||
VERSION: {{.VERSION}}
|
VERSION: {{.VERSION}}
|
||||||
SUFFIX: {{.SUFFIX}}
|
SUFFIX: {{.SUFFIX}}
|
||||||
@ -150,6 +151,7 @@ rancher:
|
|||||||
- /usr/bin/iptables:/sbin/iptables:ro
|
- /usr/bin/iptables:/sbin/iptables:ro
|
||||||
- /media:/media:shared
|
- /media:/media:shared
|
||||||
- /mnt:/mnt:shared
|
- /mnt:/mnt:shared
|
||||||
|
- /:/host
|
||||||
container-data-volumes:
|
container-data-volumes:
|
||||||
image: {{.OS_REPO}}/os-base:{{.VERSION}}{{.SUFFIX}}
|
image: {{.OS_REPO}}/os-base:{{.VERSION}}{{.SUFFIX}}
|
||||||
command: echo
|
command: echo
|
||||||
|
4
scripts/installer/Dockerfile.amd64
Normal file → Executable file
4
scripts/installer/Dockerfile.amd64
Normal file → Executable file
@ -5,9 +5,9 @@ RUN apt-get update && \
|
|||||||
rm -rf /var/lib/apt/*
|
rm -rf /var/lib/apt/*
|
||||||
|
|
||||||
COPY ./build/vmlinuz ./build/initrd /dist/
|
COPY ./build/vmlinuz ./build/initrd /dist/
|
||||||
COPY conf lay-down-os seed-data set-disk-partitions /scripts/
|
COPY conf ./build/ros /scripts/
|
||||||
|
|
||||||
ARG VERSION
|
ARG VERSION
|
||||||
ENV VERSION=${VERSION}
|
ENV VERSION=${VERSION}
|
||||||
|
|
||||||
ENTRYPOINT ["/scripts/lay-down-os"]
|
ENTRYPOINT ["/scripts/ros"]
|
||||||
|
@ -10,17 +10,20 @@ MBR_FILE=mbr.bin
|
|||||||
while getopts "i:f:c:d:t:r:o:p:ka:g" OPTION
|
while getopts "i:f:c:d:t:r:o:p:ka:g" OPTION
|
||||||
do
|
do
|
||||||
case ${OPTION} in
|
case ${OPTION} in
|
||||||
i) DIST="$OPTARG" ;;
|
# used by `ros install`
|
||||||
f) FILES="$OPTARG" ;;
|
|
||||||
c) CLOUD_CONFIG="$OPTARG" ;;
|
|
||||||
d) DEVICE="$OPTARG" ;;
|
d) DEVICE="$OPTARG" ;;
|
||||||
o) OEM="$OPTARG" ;;
|
t) ENV="$OPTARG" ;; # install type
|
||||||
|
c) CLOUD_CONFIG="$OPTARG" ;;
|
||||||
|
a) APPEND="$OPTARG" ;;
|
||||||
|
g) MBR_FILE=gptmbr.bin ;;
|
||||||
|
# used for testing?
|
||||||
|
k) KEXEC=y ;;
|
||||||
p) PARTITION="$OPTARG" ;;
|
p) PARTITION="$OPTARG" ;;
|
||||||
r) ROLLBACK_VERSION="$OPTARG" ;;
|
r) ROLLBACK_VERSION="$OPTARG" ;;
|
||||||
k) KEXEC=y ;;
|
# notused?
|
||||||
a) APPEND="$OPTARG" ;;
|
i) DIST="$OPTARG" ;;
|
||||||
t) ENV="$OPTARG" ;;
|
f) FILES="$OPTARG" ;;
|
||||||
g) MBR_FILE=gptmbr.bin ;;
|
o) OEM="$OPTARG" ;;
|
||||||
*) exit 1 ;;
|
*) exit 1 ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
@ -7,7 +7,6 @@ if [ "$ROOTFS" != "0" ]; then
|
|||||||
./package-rootfs
|
./package-rootfs
|
||||||
fi
|
fi
|
||||||
./package-initrd
|
./package-initrd
|
||||||
|
./package-installer
|
||||||
./package-iso
|
./package-iso
|
||||||
if [ "$INSTALLER" != "0" ]; then
|
|
||||||
./package-installer
|
|
||||||
fi
|
|
||||||
|
@ -13,6 +13,7 @@ fi
|
|||||||
|
|
||||||
mkdir -p ./scripts/installer/build
|
mkdir -p ./scripts/installer/build
|
||||||
cp ./dist/artifacts/{initrd,vmlinuz} ./scripts/installer/build
|
cp ./dist/artifacts/{initrd,vmlinuz} ./scripts/installer/build
|
||||||
|
cp ./bin/ros ./scripts/installer/build
|
||||||
trap "rm -rf ./scripts/installer/build" EXIT
|
trap "rm -rf ./scripts/installer/build" EXIT
|
||||||
|
|
||||||
docker build -t ${OS_REPO}/os:${VERSION}${SUFFIX} --build-arg VERSION=${VERSION} -f $DOCKERFILE ./scripts/installer
|
docker build -t ${OS_REPO}/os:${VERSION}${SUFFIX} --build-arg VERSION=${VERSION} -f $DOCKERFILE ./scripts/installer
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
source $(dirname $0)/version
|
source $(dirname $0)/version
|
||||||
cd $(dirname $0)/..
|
cd $(dirname $0)/..
|
||||||
@ -10,6 +11,7 @@ ISO=${ARTIFACTS}/$(echo ${DISTRIB_ID} | tr '[:upper:]' '[:lower:]').iso
|
|||||||
CHECKSUM=iso-checksums.txt
|
CHECKSUM=iso-checksums.txt
|
||||||
|
|
||||||
mkdir -p ${CD}/boot/isolinux
|
mkdir -p ${CD}/boot/isolinux
|
||||||
|
mkdir -p ${CD}/rancheros
|
||||||
|
|
||||||
if [ ! -f ${ARTIFACTS}/vmlinuz ] || [ ! -f ${ARTIFACTS}/initrd ]; then
|
if [ ! -f ${ARTIFACTS}/vmlinuz ] || [ ! -f ${ARTIFACTS}/initrd ]; then
|
||||||
exit 0
|
exit 0
|
||||||
@ -20,6 +22,10 @@ cp ${ARTIFACTS}/vmlinuz ${CD}/boot
|
|||||||
cp scripts/isolinux.cfg ${CD}/boot/isolinux
|
cp scripts/isolinux.cfg ${CD}/boot/isolinux
|
||||||
cp /usr/lib/ISOLINUX/isolinux.bin ${CD}/boot/isolinux
|
cp /usr/lib/ISOLINUX/isolinux.bin ${CD}/boot/isolinux
|
||||||
cp /usr/lib/syslinux/modules/bios/ldlinux.c32 ${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 assets/bootinfoscript ${CD}/rancheros
|
||||||
|
gzip ${CD}/rancheros/installer.tar
|
||||||
cd ${CD} && xorriso \
|
cd ${CD} && xorriso \
|
||||||
-as mkisofs \
|
-as mkisofs \
|
||||||
-l -J -R -V "${DISTRIB_ID}" \
|
-l -J -R -V "${DISTRIB_ID}" \
|
||||||
|
@ -12,6 +12,7 @@ while [ "$#" -gt 0 ]; do
|
|||||||
BOOT_ISO=1
|
BOOT_ISO=1
|
||||||
QEMU=0
|
QEMU=0
|
||||||
QIND=0
|
QIND=0
|
||||||
|
REBUILD=0
|
||||||
;;
|
;;
|
||||||
--append)
|
--append)
|
||||||
shift 1
|
shift 1
|
||||||
@ -59,7 +60,6 @@ while [ "$#" -gt 0 ]; do
|
|||||||
FRESH=1
|
FRESH=1
|
||||||
;;
|
;;
|
||||||
--installed)
|
--installed)
|
||||||
./scripts/create-installed
|
|
||||||
INSTALLED=1
|
INSTALLED=1
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
@ -107,8 +107,12 @@ if [ "$QEMU" == "1" ] || [ "$BOOT_ISO" == "1" ]; then
|
|||||||
|
|
||||||
if [ ! -e ${HD} ]; then
|
if [ ! -e ${HD} ]; then
|
||||||
mkdir -p $(dirname ${HD})
|
mkdir -p $(dirname ${HD})
|
||||||
|
if [ ¨$INSTALLED¨ == ¨1¨ ]; then
|
||||||
|
./scripts/create-installed
|
||||||
|
else
|
||||||
qemu-img create -f qcow2 -o size=10G ${HD}
|
qemu-img create -f qcow2 -o size=10G ${HD}
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$SECOND_DRIVE" == "1" ]; then
|
if [ "$SECOND_DRIVE" == "1" ]; then
|
||||||
qemu-img create -f qcow2 -o size=10G ${HD2}
|
qemu-img create -f qcow2 -o size=10G ${HD2}
|
||||||
|
@ -46,4 +46,4 @@ REBUILD=1
|
|||||||
QEMUARCH=${qemuarch["${ARCH}"]}
|
QEMUARCH=${qemuarch["${ARCH}"]}
|
||||||
TTYCONS=${ttycons["${ARCH}"]}
|
TTYCONS=${ttycons["${ARCH}"]}
|
||||||
|
|
||||||
DEFAULT_KERNEL_ARGS="quiet rancher.password=rancher console=${TTYCONS} rancher.autologin=${TTYCONS}"
|
DEFAULT_KERNEL_ARGS="rancher.debug=true rancher.password=rancher console=${TTYCONS} rancher.autologin=${TTYCONS}"
|
||||||
|
@ -64,6 +64,7 @@ func (s *QemuSuite) RunQemuInstalled(c *C, additionalArgs ...string) {
|
|||||||
"--no-rebuild",
|
"--no-rebuild",
|
||||||
"--no-rm-usr",
|
"--no-rm-usr",
|
||||||
"--installed",
|
"--installed",
|
||||||
|
"--fresh",
|
||||||
}
|
}
|
||||||
runArgs = append(runArgs, additionalArgs...)
|
runArgs = append(runArgs, additionalArgs...)
|
||||||
|
|
||||||
|
1
util/cutil.go
Normal file → Executable file
1
util/cutil.go
Normal file → Executable file
@ -15,6 +15,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Sadly, this isn't reliable - blkid -L LABEL works more often :(
|
||||||
func ResolveDevice(spec string) string {
|
func ResolveDevice(spec string) string {
|
||||||
cSpec := C.CString(spec)
|
cSpec := C.CString(spec)
|
||||||
defer C.free(unsafe.Pointer(cSpec))
|
defer C.free(unsafe.Pointer(cSpec))
|
||||||
|
4
util/util_linux.go
Normal file → Executable file
4
util/util_linux.go
Normal file → Executable file
@ -39,3 +39,7 @@ func Mount(device, directory, fsType, options string) error {
|
|||||||
|
|
||||||
return mount.Mount(device, directory, fsType, options)
|
return mount.Mount(device, directory, fsType, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Unmount(target string) error {
|
||||||
|
return mount.Unmount(target)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user