Environment (#7)

* remote environ

* tagsfilter fixed and tested
This commit is contained in:
Pavel Vorobyov
2020-03-06 15:24:21 +03:00
committed by GitHub
parent 1168db5943
commit f3877d7e0b
6 changed files with 102 additions and 5 deletions

View File

@@ -135,6 +135,7 @@ func New(cfg *config.XCConfig, backend store.Backend) (*Cli, error) {
remote.SetDebug(cli.debug)
remote.SetUsePasswordManager(cli.usePasswordMgr)
remote.SetNumThreads(cli.sshThreads)
remote.SetRemoteEnvironment(cfg.RemoteEnvironment)
// interpreter
cli.setInterpreter("none", cfg.Interpreter)
@@ -232,6 +233,9 @@ func (c *Cli) OneCmd(line string) {
var argsLine string
line = strings.Trim(line, " \n\t")
if strings.HasPrefix(line, "#") {
return
}
cmdRunes, rest := split([]rune(line))
cmd := string(cmdRunes)

View File

@@ -90,6 +90,7 @@ type XCConfig struct {
PasswordManagerPath string
PasswordManagerOptions map[string]string
LocalEnvironment map[string]string
RemoteEnvironment map[string]string
Distribute string
}
@@ -163,6 +164,7 @@ func read(filename string, secondPass bool) (*XCConfig, error) {
cfg.Readline = defaultReadlineConfig
cfg.BackendCfg = &BackendConfig{Type: BTIni, Options: make(map[string]string)}
cfg.LocalEnvironment = make(map[string]string)
cfg.RemoteEnvironment = make(map[string]string)
hf, err := props.GetString("main.history_file")
if err != nil {
@@ -351,5 +353,13 @@ func read(filename string, secondPass bool) (*XCConfig, error) {
}
}
envkeys, err = props.Subkeys("remote_environ")
if err == nil {
for _, key := range envkeys {
value, _ := props.GetString(fmt.Sprintf("remote_environ.%s", key))
cfg.RemoteEnvironment[key] = value
}
}
return cfg, nil
}

View File

@@ -24,6 +24,7 @@ var (
outputFile *os.File
poolLock *sync.Mutex
poolSize int
remoteEnvironment map[string]string
noneInterpreter string
suInterpreter string
@@ -114,6 +115,11 @@ func SetNumThreads(numThreads int) {
poolSize = numThreads
}
// SetRemoteEnvironment sets remote environ variables
func SetRemoteEnvironment(environ map[string]string) {
remoteEnvironment = environ
}
func prepareTempFiles(cmd string) (string, string, error) {
f, err := ioutil.TempFile("", "xc.")
if err != nil {
@@ -123,6 +129,10 @@ func prepareTempFiles(cmd string) (string, string, error) {
remoteFilename := filepath.Join(currentRemoteTmpdir, filepath.Base(f.Name()))
io.WriteString(f, "#!/bin/bash\n\n")
for varName, value := range remoteEnvironment {
io.WriteString(f, fmt.Sprintf("%s=%s\n", varName, value))
}
io.WriteString(f, "\n")
io.WriteString(f, fmt.Sprintf("nohup bash -c \"sleep 1; rm -f $0\" >/dev/null 2>&1 </dev/null &\n")) // self-destroy
io.WriteString(f, cmd+"\n") // run command
f.Chmod(0755)

View File

@@ -246,6 +246,12 @@ execLoop:
r.Codes[host] = ErrCopyFailed
continue
}
} else {
for varName, value := range remoteEnvironment {
remoteCmd += fmt.Sprintf("%s=%s ", varName, value)
}
remoteCmd += "$SHELL"
remoteCmd = "'" + remoteCmd + "'"
}
cmd = createSSHCmd(host, remoteCmd)

View File

@@ -176,7 +176,7 @@ func (s *Store) HostList(expr []rune) ([]string, error) {
continue
}
for _, tag := range token.TagsFilter {
if !stringslice.Contains(invhost.Tags, tag) {
if !stringslice.Contains(invhost.AllTags, tag) {
continue
}
}
@@ -201,7 +201,7 @@ func (s *Store) HostList(expr []rune) ([]string, error) {
}
for _, tag := range token.TagsFilter {
if !stringslice.Contains(host.Tags, tag) {
if !stringslice.Contains(host.AllTags, tag) {
continue hostLoop1
}
}
@@ -250,7 +250,7 @@ func (s *Store) HostList(expr []rune) ([]string, error) {
}
for _, tag := range token.TagsFilter {
if !stringslice.Contains(host.Tags, tag) {
if !stringslice.Contains(host.AllTags, tag) {
continue hostLoop2
}
}

View File

@@ -51,7 +51,16 @@ func (fb *FakeBackend) Load() error {
ParentID: "g1",
Tags: []string{"tag3", "tag4"},
}
fb.groups = append(fb.groups, group1, group2)
group3 := &Group{
ID: "g3",
Name: "group3",
WorkGroupID: "wg1",
ParentID: "g1",
Tags: []string{"special"},
}
fb.groups = append(fb.groups, group1, group2, group3)
dc1 := &Datacenter{
ID: "dc1",
@@ -74,7 +83,17 @@ func (fb *FakeBackend) Load() error {
GroupID: "g2",
DatacenterID: "dc2",
}
fb.hosts = append(fb.hosts, host)
host2 := &Host{
ID: "h2",
FQDN: "host2.example.com",
Aliases: []string{"host2", "host2.i"},
Tags: []string{},
GroupID: "g3",
DatacenterID: "dc2",
}
fb.hosts = append(fb.hosts, host, host2)
return nil
}
@@ -177,3 +196,51 @@ func TestStoreRelations(t *testing.T) {
}
}
func TestHostlist1(t *testing.T) {
fb := newFB()
fb.Load()
s, err := CreateStore(fb)
if err != nil {
t.Error(err)
return
}
hostlist, err := s.HostList([]rune("%group1#special"))
if err != nil {
t.Error(err)
return
}
if len(hostlist) != 1 {
t.Errorf("hostlist %%group1#special is expected to contain exactly 1 element")
return
}
if hostlist[0] != "host2.example.com" {
t.Errorf("host is expected to be host2.example.gom, got %s instead", hostlist[0])
}
}
func TestHostlist2(t *testing.T) {
fb := newFB()
fb.Load()
s, err := CreateStore(fb)
if err != nil {
t.Error(err)
return
}
hostlist, err := s.HostList([]rune("%group1#tag1"))
if err != nil {
t.Error(err)
return
}
if len(hostlist) != 2 {
t.Errorf("hostlist %%group1#tag1 is expected to contain exactly 2 elements")
return
}
}