// ReturnSvcInFileList returns a list of svc names for matches like: `/usr/lib/systemd/system/*.service`. func ReturnSvcInFileList(fileList []string) []string { result := []string{} for _, x := range fileList { dirname, basename := path.Split(path.Clean(x)) // TODO: do we also want to look for /etc/systemd/system/ ? if dirname != "/usr/lib/systemd/system/" { continue } if !strings.HasSuffix(basename, ".service") { continue } if s := strings.TrimSuffix(basename, ".service"); !util.StrInList(s, result) { result = append(result, s) } } return result }
// NewSSH is a helper function that does the initial parsing into an SSH obj. // It takes as input the path to a graph definition file. func (obj *Remotes) NewSSH(file string) (*SSH, error) { // first do the parsing... config := yamlgraph.ParseConfigFromFile(file) // FIXME: GAPI-ify somehow? if config == nil { return nil, fmt.Errorf("Remote: Error parsing remote graph: %s", file) } if config.Remote == "" { return nil, fmt.Errorf("Remote: No remote endpoint in the graph: %s", file) } // do the url parsing... u, err := url.Parse(config.Remote) if err != nil { return nil, err } if u.Scheme != "" && u.Scheme != "ssh" { return nil, fmt.Errorf("Unknown remote scheme: %s", u.Scheme) } host := "" port := defaultPort // default x := strings.Split(u.Host, ":") if c := len(x); c == 0 || c > 2 { // need one or two chunks return nil, fmt.Errorf("Can't parse host pattern: %s", u.Host) } else if c == 2 { v, err := strconv.ParseUint(x[1], 10, 16) if err != nil { return nil, fmt.Errorf("Can't parse port: %s", x[1]) } port = uint16(v) } host = x[0] if host == "" { return nil, fmt.Errorf("Empty hostname!") } user := defaultUser // default if x := u.User.Username(); x != "" { user = x } auth := []ssh.AuthMethod{} if secret, b := u.User.Password(); b { auth = append(auth, ssh.Password(secret)) } // get ssh key auth if available if a, err := obj.sshKeyAuth(); err == nil { auth = append(auth, a) } // if there are no auth methods available, add interactive to be helpful if len(auth) == 0 || obj.interactive { auth = append(auth, ssh.RetryableAuthMethod(ssh.PasswordCallback(obj.passwordCallback(user, host)), maxPasswordTries)) } if len(auth) == 0 { return nil, fmt.Errorf("No authentication methods available!") } //hostname := config.Hostname // TODO: optionally specify local hostname somehow hostname := "" if hostname == "" { hostname = host // default to above } if util.StrInList(hostname, obj.hostnames) { return nil, fmt.Errorf("Remote: Hostname `%s` already exists!", hostname) } obj.hostnames = append(obj.hostnames, hostname) return &SSH{ hostname: hostname, host: host, port: port, user: user, auth: auth, file: file, clientURLs: obj.clientURLs, remoteURLs: obj.remoteURLs, noop: obj.noop, noWatch: obj.fileWatch == nil, depth: obj.depth, caching: obj.caching, converger: obj.converger, prefix: obj.prefix, flags: obj.flags, }, nil }