func decolateCmd(c conf.ServerInfo, cmd string, sudo bool) string { c.SudoOpt.ExecBySudo = true if sudo && c.User != "root" && !c.IsContainer() { switch { case c.SudoOpt.ExecBySudo: cmd = fmt.Sprintf("echo %s | sudo -S %s", c.Password, cmd) case c.SudoOpt.ExecBySudoSh: cmd = fmt.Sprintf("echo %s | sudo sh -c '%s'", c.Password, cmd) } } if c.Family != "FreeBSD" { // set pipefail option. Bash only // http://unix.stackexchange.com/questions/14270/get-exit-status-of-process-thats-piped-to-another cmd = fmt.Sprintf("set -o pipefail; %s", cmd) } if c.IsContainer() { switch c.Container.Type { case "", "docker": cmd = fmt.Sprintf(`docker exec %s /bin/bash -c "%s"`, c.Container.ContainerID, cmd) } } return cmd }
// https://github.com/serverspec/specinfra/blob/master/lib/specinfra/helper/detect_os/redhat.rb func detectRedhat(c config.ServerInfo) (itsMe bool, red osTypeInterface) { red = newRedhat(c) // set sudo option flag c.SudoOpt = config.SudoOption{ExecBySudo: true} red.setServerInfo(c) if r := sshExec(c, "ls /etc/fedora-release", noSudo); r.isSuccess() { red.setDistributionInfo("fedora", "unknown") Log.Warn("Fedora not tested yet. Host: %s:%s", c.Host, c.Port) return true, red } if r := sshExec(c, "ls /etc/redhat-release", noSudo); r.isSuccess() { // https://www.rackaid.com/blog/how-to-determine-centos-or-red-hat-version/ // e.g. // $ cat /etc/redhat-release // CentOS release 6.5 (Final) if r := sshExec(c, "cat /etc/redhat-release", noSudo); r.isSuccess() { re, _ := regexp.Compile(`(.*) release (\d[\d.]*)`) result := re.FindStringSubmatch(strings.TrimSpace(r.Stdout)) if len(result) != 3 { Log.Warn( "Failed to parse RedHat/CentOS version. stdout: %s, Host: %s:%s", r.Stdout, c.Host, c.Port) return true, red } release := result[2] switch strings.ToLower(result[1]) { case "centos", "centos linux": red.setDistributionInfo("centos", release) default: red.setDistributionInfo("rhel", release) } return true, red } return true, red } if r := sshExec(c, "ls /etc/system-release", noSudo); r.isSuccess() { family := "amazon" release := "unknown" if r := sshExec(c, "cat /etc/system-release", noSudo); r.isSuccess() { fields := strings.Fields(r.Stdout) if len(fields) == 5 { release = fields[4] } } red.setDistributionInfo(family, release) return true, red } Log.Debugf("Not RedHat like Linux. Host: %s:%s", c.Host, c.Port) return false, red }
// NewCustomLogger creates logrus func NewCustomLogger(c config.ServerInfo) *logrus.Entry { log := logrus.New() log.Formatter = &formatter.TextFormatter{MsgAnsiColor: c.LogMsgAnsiColor} log.Out = os.Stderr log.Level = logrus.InfoLevel if config.Conf.Debug { log.Level = logrus.DebugLevel } // File output logDir := GetDefaultLogDir() if 0 < len(config.Conf.LogDir) { logDir = config.Conf.LogDir } if _, err := os.Stat(logDir); os.IsNotExist(err) { if err := os.Mkdir(logDir, 0700); err != nil { logrus.Errorf("Failed to create log directory: %s", err) } } whereami := "localhost" if 0 < len(c.ServerName) { whereami = c.GetServerName() } if _, err := os.Stat(logDir); err == nil { path := filepath.Join(logDir, whereami) log.Hooks.Add(lfshook.NewHook(lfshook.PathMap{ logrus.DebugLevel: path, logrus.InfoLevel: path, logrus.WarnLevel: path, logrus.ErrorLevel: path, logrus.FatalLevel: path, logrus.PanicLevel: path, })) } fields := logrus.Fields{"prefix": whereami} return log.WithFields(fields) }
func decolateCmd(c conf.ServerInfo, cmd string, sudo bool) string { if sudo && c.User != "root" && !c.IsContainer() { cmd = fmt.Sprintf("sudo -S %s", cmd) cmd = strings.Replace(cmd, "|", "| sudo ", -1) } if c.Distro.Family != "FreeBSD" { // set pipefail option. Bash only // http://unix.stackexchange.com/questions/14270/get-exit-status-of-process-thats-piped-to-another cmd = fmt.Sprintf("set -o pipefail; %s", cmd) } if c.IsContainer() { switch c.Container.Type { case "", "docker": cmd = fmt.Sprintf(`docker exec %s /bin/bash -c "%s"`, c.Container.ContainerID, cmd) case "lxd": cmd = fmt.Sprintf(`lxc exec %s -- /bin/bash -c "%s"`, c.Container.Name, cmd) } } // cmd = fmt.Sprintf("set -x; %s", cmd) return cmd }
//https://github.com/mizzy/specinfra/blob/master/lib/specinfra/helper/detect_os/freebsd.rb func detectFreebsd(c config.ServerInfo) (itsMe bool, bsd osTypeInterface) { bsd = newBsd(c) c.Family = "FreeBSD" if r := sshExec(c, "uname", noSudo); r.isSuccess() { if strings.Contains(r.Stdout, "FreeBSD") == true { if b := sshExec(c, "uname -r", noSudo); b.isSuccess() { bsd.setDistributionInfo("FreeBSD", strings.TrimSpace(b.Stdout)) bsd.setServerInfo(c) return true, bsd } } } Log.Debugf("Not FreeBSD. Host: %s:%s", c.Host, c.Port) return false, bsd }
//https://github.com/mizzy/specinfra/blob/master/lib/specinfra/helper/detect_os/freebsd.rb func detectFreebsd(c config.ServerInfo) (itsMe bool, bsd osTypeInterface) { bsd = newBsd(c) // Prevent from adding `set -o pipefail` option c.Distro = config.Distro{Family: "FreeBSD"} if r := exec(c, "uname", noSudo); r.isSuccess() { if strings.Contains(r.Stdout, "FreeBSD") == true { if b := exec(c, "uname -r", noSudo); b.isSuccess() { rel := strings.TrimSpace(b.Stdout) bsd.setDistro("FreeBSD", rel) return true, bsd } } } Log.Debugf("Not FreeBSD. servernam: %s", c.ServerName) return false, bsd }
// Ubuntu, Debian // https://github.com/serverspec/specinfra/blob/master/lib/specinfra/helper/detect_os/debian.rb func detectDebian(c config.ServerInfo) (itsMe bool, deb osTypeInterface, err error) { deb = newDebian(c) // set sudo option flag c.SudoOpt = config.SudoOption{ExecBySudo: true} deb.setServerInfo(c) if r := sshExec(c, "ls /etc/debian_version", noSudo); !r.isSuccess() { if r.ExitStatus == 255 { return false, deb, fmt.Errorf( "Unable to connect via SSH. Check SSH settings. servername: %s, %s@%s:%s, status: %d, stdout: %s, stderr: %s", c.ServerName, c.User, c.Host, c.Port, r.ExitStatus, r.Stdout, r.Stderr, ) } Log.Debugf("Not Debian like Linux. Host: %s:%s", c.Host, c.Port) return false, deb, nil } if r := sshExec(c, "lsb_release -ir", noSudo); r.isSuccess() { // e.g. // root@fa3ec524be43:/# lsb_release -ir // Distributor ID: Ubuntu // Release: 14.04 re, _ := regexp.Compile( `(?s)^Distributor ID:\s*(.+?)\n*Release:\s*(.+?)$`) result := re.FindStringSubmatch(trim(r.Stdout)) if len(result) == 0 { deb.setDistributionInfo("debian/ubuntu", "unknown") Log.Warnf( "Unknown Debian/Ubuntu version. lsb_release -ir: %s, Host: %s:%s", r.Stdout, c.Host, c.Port) } else { distro := strings.ToLower(trim(result[1])) deb.setDistributionInfo(distro, trim(result[2])) } return true, deb, nil } if r := sshExec(c, "cat /etc/lsb-release", noSudo); r.isSuccess() { // e.g. // DISTRIB_ID=Ubuntu // DISTRIB_RELEASE=14.04 // DISTRIB_CODENAME=trusty // DISTRIB_DESCRIPTION="Ubuntu 14.04.2 LTS" re, _ := regexp.Compile( `(?s)^DISTRIB_ID=(.+?)\n*DISTRIB_RELEASE=(.+?)\n.*$`) result := re.FindStringSubmatch(trim(r.Stdout)) if len(result) == 0 { Log.Warnf( "Unknown Debian/Ubuntu. cat /etc/lsb-release: %s, Host: %s:%s", r.Stdout, c.Host, c.Port) deb.setDistributionInfo("debian/ubuntu", "unknown") } else { distro := strings.ToLower(trim(result[1])) deb.setDistributionInfo(distro, trim(result[2])) } return true, deb, nil } // Debian cmd := "cat /etc/debian_version" if r := sshExec(c, cmd, noSudo); r.isSuccess() { deb.setDistributionInfo("debian", trim(r.Stdout)) return true, deb, nil } Log.Debugf("Not Debian like Linux. Host: %s:%s", c.Host, c.Port) return false, deb, nil }