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:]) return x.completeTag(line[1:])
} }
if len(line) > 0 && line[0] == '&' {
comp, ll := completeFiles(line[1:])
return comp, ll + 1
}
return x.completeHost(line) return x.completeHost(line)
} }

View File

@@ -6,6 +6,7 @@ import (
"os/exec" "os/exec"
"os/signal" "os/signal"
"runtime" "runtime"
"runtime/debug"
"strconv" "strconv"
"syscall" "syscall"
@@ -56,6 +57,7 @@ func (c *Cli) setupCmdHandlers() {
c.handlers["version"] = c.doVersion c.handlers["version"] = c.doVersion
c.handlers["goruntime"] = c.doGoruntime c.handlers["goruntime"] = c.doGoruntime
c.handlers["natural_sort"] = c.doNaturalSort c.handlers["natural_sort"] = c.doNaturalSort
c.handlers["_mem"] = c.doMemoryDump
commands := make([]string, len(c.handlers)) commands := make([]string, len(c.handlers))
i := 0 i := 0
@@ -74,6 +76,16 @@ func (c *Cli) doExit(name string, argsLine string, args ...string) {
c.stopped = true 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) { func (c *Cli) doMode(name string, argsLine string, args ...string) {
if len(args) < 1 { if len(args) < 1 {
term.Errorf("Usage: mode <[serial,parallel,collapse]>\n") term.Errorf("Usage: mode <[serial,parallel,collapse]>\n")

View File

@@ -252,7 +252,8 @@ with symlinks. It's more stable though.`,
Every expression is a comma-separated list of tokens, where token may be Every expression is a comma-separated list of tokens, where token may be
- a single host, - a single host,
- a single group, - a single group,
- a single workgroup, - a single workgroup,
- a filename containing a list of hosts
and every item may optionally be limited to a particular datacenter, a given tag, and every item may optionally be limited to a particular datacenter, a given tag,
or even be completely excluded from the list. or even be completely excluded from the list.
@@ -263,8 +264,9 @@ Some self-explanatory examples:
%group1,-host2 - all hosts from group1, excluding(!) host2 %group1,-host2 - all hosts from group1, excluding(!) host2
%group2@dc1 - all hosts from group2, located in datacenter dc1 %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 *myworkgroup@dc2,-%group3,host5 - all hosts from wg "myworkgroup" excluding hosts from group3, plus host5
%group5#tag1 - all hosts from group5 tagged with tag1 %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 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 almost always should be on the righthand side. For example, "-host1,host1" will end up with host1 in list
despite being excluded previously.`, despite being excluded previously.`,

View File

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

View File

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

View File

@@ -1,6 +1,8 @@
package store package store
import ( import (
"bufio"
"os"
"regexp" "regexp"
"sort" "sort"
"strings" "strings"
@@ -179,6 +181,22 @@ func (s *Store) HostList(expr []rune) ([]string, error) {
} }
switch token.Type { 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: case tTypeHostRegexp:
for _, host := range s.matchHost(token.RegexpFilter) { for _, host := range s.matchHost(token.RegexpFilter) {
etoken.hosts = append(etoken.hosts, host) etoken.hosts = append(etoken.hosts, host)