diff --git a/cmd/control/autologin.go b/cmd/control/autologin.go index b67aadd2..483255cc 100644 --- a/cmd/control/autologin.go +++ b/cmd/control/autologin.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "os/exec" + "path/filepath" "runtime" "strings" @@ -47,6 +48,10 @@ func autologinAction(c *cli.Context) error { tty = s[1] } } + + mode := filepath.Base(os.Args[0]) + console := CurrentConsole() + cfg := config.LoadConfig() // replace \n and \l banner := config.Banner @@ -57,20 +62,22 @@ func autologinAction(c *cli.Context) error { banner = strings.Replace(banner, "\\l", tty, -1) banner = strings.Replace(banner, "\\\\", "\\", -1) banner = banner + "\n" - banner = banner + "Autologin " + CurrentConsole() + "\n" + banner = banner + "Autologin " + console + "\n" fmt.Printf(banner) loginBin := "" args := []string{} - if CurrentConsole() == "centos" || CurrentConsole() == "fedora" { + if console == "centos" || console == "fedora" || + mode == "recovery" { // For some reason, centos and fedora ttyS0 and tty1 don't work with `login -f rancher` // until I make time to read their source, lets just give us a way to get work done loginBin = "bash" args = append(args, "--login") - + os.Setenv("PROMPT_COMMAND", `echo "[`+fmt.Sprintf("Recovery console %s@%s:${PWD}", user, cfg.Hostname)+`]"`) } else { loginBin = "login" args = append(args, "-f", user) + // TODO: add a PROMPT_COMMAND if we haven't switch-rooted } loginBinPath, err := exec.LookPath(loginBin) @@ -78,12 +85,13 @@ func autologinAction(c *cli.Context) error { fmt.Printf("error finding %s in path: %s", cmd.Args[0], err) return err } - os.Setenv("PS1", `[`+CurrentConsole()+`: \l \u@\h \W]\$`) + os.Setenv("TERM", "linux") // Causes all sorts of issues //return syscall.Exec(loginBinPath, args, os.Environ()) cmd = exec.Command(loginBinPath, args...) cmd.Env = os.Environ() + cmd.Env = append(cmd.Env, "SVEN", "MORE") cmd.Stderr = os.Stderr cmd.Stdout = os.Stdout diff --git a/cmd/control/console_init.go b/cmd/control/console_init.go index 0b56d7ef..12d42c1d 100644 --- a/cmd/control/console_init.go +++ b/cmd/control/console_init.go @@ -81,7 +81,7 @@ func consoleInitFunc() error { log.Error(err) } - if err := writeRespawn("rancher", true); err != nil { + if err := writeRespawn("rancher", true, false); err != nil { log.Error(err) } @@ -144,15 +144,20 @@ func consoleInitFunc() error { return syscall.Exec(respawnBinPath, []string{"respawn", "-f", "/etc/respawn.conf"}, os.Environ()) } -func generateRespawnConf(cmdline, user string, sshd bool) string { +func generateRespawnConf(cmdline, user string, sshd, recovery bool) string { var respawnConf bytes.Buffer + autologinBin := "/usr/bin/autologin" + if recovery { + autologinBin = "/usr/bin/recovery" + } + for i := 1; i < 7; i++ { tty := fmt.Sprintf("tty%d", i) respawnConf.WriteString(gettyCmd) if strings.Contains(cmdline, fmt.Sprintf("rancher.autologin=%s", tty)) { - respawnConf.WriteString(fmt.Sprintf(" -n -l /usr/bin/autologin -o %s:tty%d", user, i)) + respawnConf.WriteString(fmt.Sprintf(" -n -l %s -o %s:tty%d", autologinBin, user, i)) } respawnConf.WriteString(fmt.Sprintf(" --noclear %s linux\n", tty)) } @@ -164,7 +169,7 @@ func generateRespawnConf(cmdline, user string, sshd bool) string { respawnConf.WriteString(gettyCmd) if strings.Contains(cmdline, fmt.Sprintf("rancher.autologin=%s", tty)) { - respawnConf.WriteString(fmt.Sprintf(" -n -l /usr/bin/autologin -o %s:%s", user, tty)) + respawnConf.WriteString(fmt.Sprintf(" -n -l %s -o %s:%s", autologinBin, user, tty)) } respawnConf.WriteString(fmt.Sprintf(" %s\n", tty)) } @@ -176,13 +181,13 @@ func generateRespawnConf(cmdline, user string, sshd bool) string { return respawnConf.String() } -func writeRespawn(user string, sshd bool) error { +func writeRespawn(user string, sshd, recovery bool) error { cmdline, err := ioutil.ReadFile("/proc/cmdline") if err != nil { return err } - respawn := generateRespawnConf(string(cmdline), user, sshd) + respawn := generateRespawnConf(string(cmdline), user, sshd, recovery) files, err := ioutil.ReadDir("/etc/respawn.conf.d") if err == nil { diff --git a/cmd/control/entrypoint.go b/cmd/control/entrypoint.go index c5324b10..5f700661 100644 --- a/cmd/control/entrypoint.go +++ b/cmd/control/entrypoint.go @@ -80,6 +80,7 @@ func writeFiles(cfg *config.CloudConfig) error { func setupCommandSymlinks() { for _, link := range []symlink{ {config.RosBin, "/usr/bin/autologin"}, + {config.RosBin, "/usr/bin/recovery"}, {config.RosBin, "/usr/bin/cloud-init-execute"}, {config.RosBin, "/usr/bin/cloud-init-save"}, {config.RosBin, "/usr/bin/dockerlaunch"}, diff --git a/cmd/control/recovery_init.go b/cmd/control/recovery_init.go index 8c7b0841..b927a6db 100644 --- a/cmd/control/recovery_init.go +++ b/cmd/control/recovery_init.go @@ -10,13 +10,10 @@ import ( ) func recoveryInitAction(c *cli.Context) error { - if err := writeRespawn("root", false); err != nil { + if err := writeRespawn("root", false, true); err != nil { log.Error(err) } - os.Setenv("TERM", "linux") - os.Setenv("PS1", `[Recovery Console: \l \u@\h \W]\$`) - respawnBinPath, err := exec.LookPath("respawn") if err != nil { return err diff --git a/main.go b/main.go index 68a3e715..ea0ea804 100644 --- a/main.go +++ b/main.go @@ -32,6 +32,7 @@ var entrypoints = map[string]func(){ "dockerlaunch": dfs.Main, "init": osInit.MainInit, "netconf": network.Main, + "recovery": control.AutologinMain, "ros-sysinit": sysinit.Main, "system-docker": systemdocker.Main, "wait-for-docker": wait.Main,