From 95c726f455b3a3c3fe04450512bc1974ead403a4 Mon Sep 17 00:00:00 2001 From: Yevhenii Voievodin Date: Tue, 20 Jun 2017 12:44:48 +0300 Subject: [PATCH] fixup! fixup! fixup! fixup! fixup! fixup! fixup! fixup! Implement bootstrapper spec(#4096) --- .../go-agents/bootstrapper/booter/booter.go | 3 -- .../bootstrapper/booter/installations.go | 52 ++++++++----------- 2 files changed, 22 insertions(+), 33 deletions(-) diff --git a/agents/go-agents/bootstrapper/booter/booter.go b/agents/go-agents/bootstrapper/booter/booter.go index 78fc62b9f3cd..a2c5a16c3660 100644 --- a/agents/go-agents/bootstrapper/booter/booter.go +++ b/agents/go-agents/bootstrapper/booter/booter.go @@ -109,9 +109,6 @@ func installOne(installer Installer) error { } else { inst = &scriptInst{installer, installerTimeout} } - if err := inst.preCheck(); err != nil { - return err - } return inst.execute() } diff --git a/agents/go-agents/bootstrapper/booter/installations.go b/agents/go-agents/bootstrapper/booter/installations.go index 1b9284eb5e95..ff57fbf8eb7f 100644 --- a/agents/go-agents/bootstrapper/booter/installations.go +++ b/agents/go-agents/bootstrapper/booter/installations.go @@ -23,10 +23,6 @@ import ( // Process of getting certain installer software/servers installed. type installation interface { - // Check installation preconditions e.g. ports are free. - // If error is returned installation is not executed. - preCheck() error - // Executes the installation in implementation specific way. execute() error } @@ -38,8 +34,6 @@ type scriptInst struct { timeout time.Duration } -func (sci *scriptInst) preCheck() error { return nil } - func (sci *scriptInst) execute() error { _, diedC, err := executeScript(sci.installer) if err != nil { @@ -68,15 +62,6 @@ type serverInst struct { timeout time.Duration } -func (svi *serverInst) preCheck() error { - for _, server := range svi.installer.Servers { - if tryConn(server) == nil { - return fmt.Errorf("server address 'localhost:%s' already in use", server.Port) - } - } - return nil -} - func (svi *serverInst) execute() error { pid, diedC, err := executeScript(svi.installer) if err != nil { @@ -84,15 +69,21 @@ func (svi *serverInst) execute() error { } checker := &dialChecker{svi.period, make(chan bool, 1)} select { - case <-checker.allAvailable(svi.installer.Servers): + case <-checker.availableC(svi.installer.Servers): process.RemoveSubscriber(pid, svi.installer.ID) return nil case <-time.After(svi.timeout): checker.stop() return fmt.Errorf("Timeout reached before installation of '%s' finished", svi.installer.ID) - case <-diedC: + case died := <-diedC: checker.stop() - return fmt.Errorf("Process of installation '%s' exited before server became available", svi.installer.ID) + if died.ExitCode != 0 { + return fmt.Errorf("Installation '%s' failed, script exit code is %d", svi.installer.ID, died.ExitCode) + } + if !checker.available(svi.installer.Servers) { + fmt.Errorf("Process of installation '%s' exit code is 0 but servers are not available", svi.installer.ID) + } + return nil } } @@ -116,7 +107,7 @@ func executeScript(installer Installer) (uint64, chan *process.DiedEvent, error) return p.Pid, diedC, nil } -// dialChecker performs a servers availability check +// dialChecker performs a servers availability available type dialChecker struct { // period defines period between checks period time.Duration @@ -124,22 +115,15 @@ type dialChecker struct { stopped chan bool } -func (cc *dialChecker) allAvailable(servers map[string]Server) chan bool { +func (cc *dialChecker) availableC(servers map[string]Server) chan bool { ticker := time.NewTicker(cc.period) state := make(chan bool, 1) go func() { for { - ok := true select { case <-ticker.C: - for _, server := range servers { - if tryConn(server) != nil { - ok = false - break - } - } - if ok { - state <- ok + if cc.available(servers) { + state <- true ticker.Stop() return } @@ -153,7 +137,15 @@ func (cc *dialChecker) allAvailable(servers map[string]Server) chan bool { return state } -// stop stops server health checking +func (cc *dialChecker) available(servers map[string]Server) bool { + for _, server := range servers { + if tryConn(server) != nil { + return false + } + } + return true +} + func (cc *dialChecker) stop() { close(cc.stopped) }