1
0
mirror of https://github.com/rancher/os.git synced 2025-09-01 23:04:41 +00:00

Add a Recovery console prompt

Signed-off-by: Sven Dowideit <SvenDowideit@home.org.au>
This commit is contained in:
Sven Dowideit
2017-07-16 11:50:01 +10:00
parent a04c0f3740
commit 765a7c3ed4
5 changed files with 26 additions and 14 deletions

View File

@@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
"path/filepath"
"runtime" "runtime"
"strings" "strings"
@@ -47,6 +48,10 @@ func autologinAction(c *cli.Context) error {
tty = s[1] tty = s[1]
} }
} }
mode := filepath.Base(os.Args[0])
console := CurrentConsole()
cfg := config.LoadConfig() cfg := config.LoadConfig()
// replace \n and \l // replace \n and \l
banner := config.Banner banner := config.Banner
@@ -57,20 +62,22 @@ func autologinAction(c *cli.Context) error {
banner = strings.Replace(banner, "\\l", tty, -1) banner = strings.Replace(banner, "\\l", tty, -1)
banner = strings.Replace(banner, "\\\\", "\\", -1) banner = strings.Replace(banner, "\\\\", "\\", -1)
banner = banner + "\n" banner = banner + "\n"
banner = banner + "Autologin " + CurrentConsole() + "\n" banner = banner + "Autologin " + console + "\n"
fmt.Printf(banner) fmt.Printf(banner)
loginBin := "" loginBin := ""
args := []string{} 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` // 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 // until I make time to read their source, lets just give us a way to get work done
loginBin = "bash" loginBin = "bash"
args = append(args, "--login") args = append(args, "--login")
os.Setenv("PROMPT_COMMAND", `echo "[`+fmt.Sprintf("Recovery console %s@%s:${PWD}", user, cfg.Hostname)+`]"`)
} else { } else {
loginBin = "login" loginBin = "login"
args = append(args, "-f", user) args = append(args, "-f", user)
// TODO: add a PROMPT_COMMAND if we haven't switch-rooted
} }
loginBinPath, err := exec.LookPath(loginBin) 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) fmt.Printf("error finding %s in path: %s", cmd.Args[0], err)
return err return err
} }
os.Setenv("PS1", `[`+CurrentConsole()+`: \l \u@\h \W]\$`) os.Setenv("TERM", "linux")
// Causes all sorts of issues // Causes all sorts of issues
//return syscall.Exec(loginBinPath, args, os.Environ()) //return syscall.Exec(loginBinPath, args, os.Environ())
cmd = exec.Command(loginBinPath, args...) cmd = exec.Command(loginBinPath, args...)
cmd.Env = os.Environ() cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, "SVEN", "MORE")
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout cmd.Stdout = os.Stdout

View File

@@ -81,7 +81,7 @@ func consoleInitFunc() error {
log.Error(err) log.Error(err)
} }
if err := writeRespawn("rancher", true); err != nil { if err := writeRespawn("rancher", true, false); err != nil {
log.Error(err) log.Error(err)
} }
@@ -144,15 +144,20 @@ func consoleInitFunc() error {
return syscall.Exec(respawnBinPath, []string{"respawn", "-f", "/etc/respawn.conf"}, os.Environ()) 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 var respawnConf bytes.Buffer
autologinBin := "/usr/bin/autologin"
if recovery {
autologinBin = "/usr/bin/recovery"
}
for i := 1; i < 7; i++ { for i := 1; i < 7; i++ {
tty := fmt.Sprintf("tty%d", i) tty := fmt.Sprintf("tty%d", i)
respawnConf.WriteString(gettyCmd) respawnConf.WriteString(gettyCmd)
if strings.Contains(cmdline, fmt.Sprintf("rancher.autologin=%s", tty)) { 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)) respawnConf.WriteString(fmt.Sprintf(" --noclear %s linux\n", tty))
} }
@@ -164,7 +169,7 @@ func generateRespawnConf(cmdline, user string, sshd bool) string {
respawnConf.WriteString(gettyCmd) respawnConf.WriteString(gettyCmd)
if strings.Contains(cmdline, fmt.Sprintf("rancher.autologin=%s", tty)) { 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)) respawnConf.WriteString(fmt.Sprintf(" %s\n", tty))
} }
@@ -176,13 +181,13 @@ func generateRespawnConf(cmdline, user string, sshd bool) string {
return respawnConf.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") cmdline, err := ioutil.ReadFile("/proc/cmdline")
if err != nil { if err != nil {
return err return err
} }
respawn := generateRespawnConf(string(cmdline), user, sshd) respawn := generateRespawnConf(string(cmdline), user, sshd, recovery)
files, err := ioutil.ReadDir("/etc/respawn.conf.d") files, err := ioutil.ReadDir("/etc/respawn.conf.d")
if err == nil { if err == nil {

View File

@@ -80,6 +80,7 @@ func writeFiles(cfg *config.CloudConfig) error {
func setupCommandSymlinks() { func setupCommandSymlinks() {
for _, link := range []symlink{ for _, link := range []symlink{
{config.RosBin, "/usr/bin/autologin"}, {config.RosBin, "/usr/bin/autologin"},
{config.RosBin, "/usr/bin/recovery"},
{config.RosBin, "/usr/bin/cloud-init-execute"}, {config.RosBin, "/usr/bin/cloud-init-execute"},
{config.RosBin, "/usr/bin/cloud-init-save"}, {config.RosBin, "/usr/bin/cloud-init-save"},
{config.RosBin, "/usr/bin/dockerlaunch"}, {config.RosBin, "/usr/bin/dockerlaunch"},

View File

@@ -10,13 +10,10 @@ import (
) )
func recoveryInitAction(c *cli.Context) error { func recoveryInitAction(c *cli.Context) error {
if err := writeRespawn("root", false); err != nil { if err := writeRespawn("root", false, true); err != nil {
log.Error(err) log.Error(err)
} }
os.Setenv("TERM", "linux")
os.Setenv("PS1", `[Recovery Console: \l \u@\h \W]\$`)
respawnBinPath, err := exec.LookPath("respawn") respawnBinPath, err := exec.LookPath("respawn")
if err != nil { if err != nil {
return err return err

View File

@@ -32,6 +32,7 @@ var entrypoints = map[string]func(){
"dockerlaunch": dfs.Main, "dockerlaunch": dfs.Main,
"init": osInit.MainInit, "init": osInit.MainInit,
"netconf": network.Main, "netconf": network.Main,
"recovery": control.AutologinMain,
"ros-sysinit": sysinit.Main, "ros-sysinit": sysinit.Main,
"system-docker": systemdocker.Main, "system-docker": systemdocker.Main,
"wait-for-docker": wait.Main, "wait-for-docker": wait.Main,