diff --git a/cmd/control/config.go b/cmd/control/config.go index 7b7379a2..91d47f62 100644 --- a/cmd/control/config.go +++ b/cmd/control/config.go @@ -5,6 +5,7 @@ import ( "io" "io/ioutil" "os" + "os/exec" "sort" "strings" "text/template" @@ -76,6 +77,11 @@ func configSubcommands() []cli.Command { }, }, }, + { + Name: "syslinux", + Usage: "edit Syslinux boot global.cfg", + Action: editSyslinux, + }, { Name: "validate", Usage: "validate configuration from stdin", @@ -146,6 +152,21 @@ func env2map(env []string) map[string]string { return m } +func editSyslinux(c *cli.Context) error { + cmd := exec.Command("system-docker", "run", "--rm", "-it", + "-v", "/:/host", + "-w", "/host", + "--entrypoint=vi", + "rancher/os-console:"+config.Version, + "boot/global.cfg") + cmd.Stdout, cmd.Stderr, cmd.Stdin = os.Stdout, os.Stderr, os.Stdin + if err := cmd.Run(); err != nil { + return err + } + + return nil +} + func configSet(c *cli.Context) error { if c.NArg() < 2 { return nil diff --git a/cmd/control/install.go b/cmd/control/install.go index 188962ca..4af6695c 100755 --- a/cmd/control/install.go +++ b/cmd/control/install.go @@ -3,6 +3,7 @@ package control import ( "bufio" "bytes" + "crypto/md5" "fmt" "io" "io/ioutil" @@ -923,20 +924,45 @@ func installSyslinux(device, baseName, diskType string) error { return nil } +func different(existing, new string) bool { + // assume existing file exists + if _, err := os.Stat(new); os.IsNotExist(err) { + return true + } + data, err := ioutil.ReadFile(existing) + if err != nil { + return true + } + newData, err := ioutil.ReadFile(new) + if err != nil { + return true + } + md5sum := md5.Sum(data) + newmd5sum := md5.Sum(newData) + if md5sum != newmd5sum { + return true + } + return false +} + func installRancher(baseName, VERSION, DIST, kappend string) (string, error) { log.Debugf("installRancher") // detect if there already is a linux-current.cfg, if so, move it to linux-previous.cfg, currentCfg := filepath.Join(baseName, install.BootDir, "linux-current.cfg") if _, err := os.Stat(currentCfg); !os.IsNotExist(err) { - previousCfg := filepath.Join(baseName, install.BootDir, "linux-previous.cfg") - if _, err := os.Stat(previousCfg); !os.IsNotExist(err) { - if err := os.Remove(previousCfg); err != nil { - return currentCfg, err + existingCfg := filepath.Join(DIST, "linux-current.cfg") + // only remove previous if there is a change to the current + if different(currentCfg, existingCfg) { + previousCfg := filepath.Join(baseName, install.BootDir, "linux-previous.cfg") + if _, err := os.Stat(previousCfg); !os.IsNotExist(err) { + if err := os.Remove(previousCfg); err != nil { + return currentCfg, err + } } + os.Rename(currentCfg, previousCfg) + // TODO: now that we're parsing syslinux.cfg files, maybe we can delete old kernels and initrds } - os.Rename(currentCfg, previousCfg) - // TODO: now that we're parsing syslinux.cfg files, maybe we can delete old kernels and initrds } // 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 @@ -945,15 +971,26 @@ func installRancher(baseName, VERSION, DIST, kappend string) (string, error) { if file.IsDir() { continue } - if err := dfs.CopyFile(filepath.Join(DIST, file.Name()), filepath.Join(baseName, install.BootDir), file.Name()); err != nil { + // TODO: should overwrite anything other than the global.cfg + overwrite := true + if file.Name() == "global.cfg" { + overwrite = false + } + if err := dfs.CopyFileOverwrite(filepath.Join(DIST, file.Name()), filepath.Join(baseName, install.BootDir), file.Name(), overwrite); err != nil { log.Errorf("copy %s: %s", file.Name(), err) //return err } } + // the general INCLUDE syslinuxcfg - if err := dfs.CopyFile(filepath.Join(DIST, "isolinux", "isolinux.cfg"), filepath.Join(baseName, install.BootDir, "syslinux"), "syslinux.cfg"); err != nil { + isolinuxFile := filepath.Join(DIST, "isolinux", "isolinux.cfg") + syslinuxDir := filepath.Join(baseName, install.BootDir, "syslinux") + if err := dfs.CopyFileOverwrite(isolinuxFile, syslinuxDir, "syslinux.cfg", true); err != nil { log.Errorf("copy global syslinux.cfgS%s: %s", "syslinux.cfg", err) //return err + } else { + log.Debugf("installRancher copy global syslinux.cfgS OK") + } // The global.cfg INCLUDE - useful for over-riding the APPEND line diff --git a/dfs/scratch.go b/dfs/scratch.go index 560eca7d..cb89c2c3 100644 --- a/dfs/scratch.go +++ b/dfs/scratch.go @@ -264,15 +264,21 @@ func defaultFolders(folders ...string) error { } func CopyFile(src, folder, name string) error { + return CopyFileOverwrite(src, folder, name, false) +} + +func CopyFileOverwrite(src, folder, name string, overwrite bool) error { if _, err := os.Lstat(src); os.IsNotExist(err) { log.Debugf("Not copying %s, does not exists", src) return nil } dst := path.Join(folder, name) - if _, err := os.Lstat(dst); err == nil { - log.Debugf("Not copying %s => %s already exists", src, dst) - return nil + if !overwrite { + if _, err := os.Lstat(dst); err == nil { + log.Debugf("Not copying %s => %s already exists", src, dst) + return nil + } } if err := createDirs(folder); err != nil { diff --git a/docs/os/configuration/adding-kernel-parameters/index.md b/docs/os/configuration/adding-kernel-parameters/index.md index eb0179d2..35a3bcbd 100644 --- a/docs/os/configuration/adding-kernel-parameters/index.md +++ b/docs/os/configuration/adding-kernel-parameters/index.md @@ -10,14 +10,13 @@ There are two ways to edit the kernel parameters, in-place (editing the file and ### In-place editing -For in-place editing, you will need to run a container with an editor and a mount to access the `/boot/global.cfg` file containing the kernel parameters. +To edit the kernel boot parameters of an already installed RancherOS system, use the new `sudo ros config syslinux` editing command (uses `vi`). > To activate this setting, you will need to reboot. -```bash -$ sudo system-docker run --rm -it -v /:/host alpine vi /host/boot/global.cfg -``` +#### Graphical boot screen +RancherOS v1.1.0 added a syslinux boot menu, which on desktop systems can be switched to graphical mode by adding `UI vesamenu.c32` to a new line in `global.cfg` (use `sudo ros config syslinux` to edit the file). ### During installation diff --git a/scripts/isolinux.cfg b/scripts/isolinux.cfg index a5904699..627f72d0 100644 --- a/scripts/isolinux.cfg +++ b/scripts/isolinux.cfg @@ -1,4 +1,5 @@ -UI vesamenu.c32 +# Add `UI vesamenu.c32` to a new line in `global.cfg` to switch to GUI bootmenu (use `sudo ros config syslinux`) +UI menu.c32 TIMEOUT 20 #2s PROMPT 0 @@ -6,7 +7,14 @@ PROMPT 0 INCLUDE ../global.cfg # each INCLUDEd file has a `DEFAULT mylabel` in it, and the last one wins +LABEL rancheros-previous + MENU LABEL Previous RancherOS Version + MENU DISABLE INCLUDE ../linux-previous.cfg + +LABEL rancheros-current + MENU LABEL Current RancherOS Version + MENU DISABLE INCLUDE ../linux-current.cfg # http://www.syslinux.org/wiki/index.php?title=Comboot/menu.c32 diff --git a/scripts/isolinux_label.cfg b/scripts/isolinux_label.cfg index 40ac296f..c4d8ae63 100644 --- a/scripts/isolinux_label.cfg +++ b/scripts/isolinux_label.cfg @@ -1,5 +1,4 @@ -# TODO: should add ros-version to label and initrd DEFAULT rancheros-${LABEL} LABEL rancheros-${LABEL} SAY rancheros-${LABEL}: RancherOS ${VERSION} ${KERNEL_VERSION} @@ -22,4 +21,11 @@ LABEL rancheros-${LABEL}-debug COM32 cmd.c32 APPEND rancheros-${LABEL} rancher.debug=true +LABEL rancheros-${LABEL}-debug-autologin + SAY rancheros-${LABEL}-debug-autolgin: debug and autologin RancherOS ${VERSION} ${KERNEL_VERSION} + MENU LABEL rancher.debug and rancher.autologin + MENU INDENT 2 + COM32 cmd.c32 + APPEND rancheros-${LABEL} rancher.autologin=tty1 rancher.autologin=ttyS0 rancher.debug=true + MENU SEPARATOR diff --git a/scripts/ros b/scripts/ros index d6b30e23..086261cf 100755 --- a/scripts/ros +++ b/scripts/ros @@ -26,4 +26,4 @@ docker run --rm -it \ -v /usr/share/ca-certificates:/usr/share/ca-certificates \ -w /var/lib/rancher \ --entrypoint sh \ - rancher/os-base:v0.8.1 + rancher/os-base:v1.0.3