hosts files

This commit is contained in:
Воробьев Павел
2020-08-03 18:02:19 +03:00
parent a6fd56b667
commit 157cda66b7
6 changed files with 67 additions and 3 deletions

View File

@@ -176,6 +176,11 @@ func (x *completer) completeExec(line []rune) ([][]rune, int) {
return x.completeTag(line[1:])
}
if len(line) > 0 && line[0] == '&' {
comp, ll := completeFiles(line[1:])
return comp, ll + 1
}
return x.completeHost(line)
}

View File

@@ -6,6 +6,7 @@ import (
"os/exec"
"os/signal"
"runtime"
"runtime/debug"
"strconv"
"syscall"
@@ -56,6 +57,7 @@ func (c *Cli) setupCmdHandlers() {
c.handlers["version"] = c.doVersion
c.handlers["goruntime"] = c.doGoruntime
c.handlers["natural_sort"] = c.doNaturalSort
c.handlers["_mem"] = c.doMemoryDump
commands := make([]string, len(c.handlers))
i := 0
@@ -74,6 +76,16 @@ func (c *Cli) doExit(name string, argsLine string, args ...string) {
c.stopped = true
}
func (c *Cli) doMemoryDump(name string, argsLine string, args ...string) {
f, err := os.Create("/tmp/xcheap.dump")
if err != nil {
term.Errorf("Can't dump: %s\n", err)
return
}
defer f.Close()
debug.WriteHeapDump(f.Fd())
}
func (c *Cli) doMode(name string, argsLine string, args ...string) {
if len(args) < 1 {
term.Errorf("Usage: mode <[serial,parallel,collapse]>\n")

View File

@@ -253,6 +253,7 @@ Every expression is a comma-separated list of tokens, where token may be
- a single host,
- a single group,
- a single workgroup,
- a filename containing a list of hosts
and every item may optionally be limited to a particular datacenter, a given tag,
or even be completely excluded from the list.
@@ -264,6 +265,7 @@ Some self-explanatory examples:
%group2@dc1 - all hosts from group2, located in datacenter dc1
*myworkgroup@dc2,-%group3,host5 - all hosts from wg "myworkgroup" excluding hosts from group3, plus host5
%group5#tag1 - all hosts from group5 tagged with tag1
&hosts.txt - hosts from file hosts.txt
You may combine any number of tokens keeping in mind that they are resolved left to right, so exclusions
almost always should be on the righthand side. For example, "-host1,host1" will end up with host1 in list

View File

@@ -1,6 +1,7 @@
package main
import (
"net/http"
"os"
"path"
"strings"
@@ -9,12 +10,17 @@ import (
"github.com/viert/xc/backend/inventoree"
"github.com/viert/xc/backend/localini"
_ "net/http/pprof"
"github.com/viert/xc/cli"
"github.com/viert/xc/config"
"github.com/viert/xc/term"
)
func main() {
go http.ListenAndServe(":5001", nil)
var tool *cli.Cli
var err error

View File

@@ -14,6 +14,7 @@ const (
tTypeGroup
tTypeWorkGroup
tTypeHostRegexp
tTypeHostListFile
)
const (
@@ -25,6 +26,7 @@ const (
stateReadTag
stateReadHostBracePattern
stateReadRegexp
stateReadHostListFile
)
type token struct {
@@ -83,6 +85,12 @@ func parseExpression(expr []rune) ([]*token, error) {
continue
}
if sym == '&' {
ct.Type = tTypeHostListFile
state = stateReadHostListFile
continue
}
if sym == '/' || sym == '~' {
state = stateReadHost
ct.Type = tTypeHostRegexp
@@ -214,6 +222,19 @@ func parseExpression(expr []rune) ([]*token, error) {
}
ct.Value += string(sym)
case stateReadHostListFile:
if sym == ',' || last {
if last && sym != ',' {
ct.Value += string(sym)
}
res = append(res, ct)
ct = newToken()
state = stateWait
continue
}
ct.Value += string(sym)
case stateReadHostBracePattern:
if sym == '{' {
return nil, fmt.Errorf("nested patterns are not allowed (at %d)", i)

View File

@@ -1,6 +1,8 @@
package store
import (
"bufio"
"os"
"regexp"
"sort"
"strings"
@@ -179,6 +181,22 @@ func (s *Store) HostList(expr []rune) ([]string, error) {
}
switch token.Type {
case tTypeHostListFile:
filename := token.Value
f, err := os.Open(filename)
if err != nil {
return nil, err
}
sc := bufio.NewScanner(f)
for sc.Scan() {
hostname := strings.Trim(sc.Text(), " \t\r\n")
if hostname == "" || strings.Contains(hostname, " ") || strings.HasPrefix(hostname, "#") {
continue
}
etoken.hosts = append(etoken.hosts, hostname)
}
f.Close()
case tTypeHostRegexp:
for _, host := range s.matchHost(token.RegexpFilter) {
etoken.hosts = append(etoken.hosts, host)