Files
fx-serverless/provision/provision.go
2019-11-11 15:35:52 +08:00

128 lines
3.4 KiB
Go

package provision
import (
"fmt"
"os"
"sync"
"github.com/apex/log"
"github.com/metrue/fx/constants"
"github.com/metrue/fx/pkg/command"
ssh "github.com/metrue/go-ssh-client"
)
// Provisioner provision
type Provisioner interface {
Start() error
}
// Provisionor provision-or
type Provisionor struct {
sshClient ssh.Client
host string
}
func isLocal(host string) bool {
if host == "" {
return false
}
return host == "127.0.0.1" || host == "localhost" || host == "0.0.0.0"
}
// NewWithHost create a provisionor with host, user, and password
func NewWithHost(host string, user string, password string) *Provisionor {
p := &Provisionor{
host: host,
}
if !isLocal(host) {
p.sshClient = ssh.New(host).
WithUser(user).
WithPassword(password)
}
return p
}
// IsFxAgentRunning check if fx-agent is running on host
func (p *Provisionor) IsFxAgentRunning() bool {
script := fmt.Sprintf("docker inspect %s", constants.AgentContainerName)
var cmd *command.Command
if !isLocal(p.host) {
cmd = command.New("inspect fx-agent", script, command.NewRemoteRunner(p.sshClient))
} else {
cmd = command.New("inspect fx-agent", script, command.NewLocalRunner())
}
output, err := cmd.Exec()
if os.Getenv("DEBUG") != "" {
log.Infof(string(output))
}
if err != nil {
return false
}
return true
}
// StartFxAgent start fx agent
func (p *Provisionor) StartFxAgent() error {
script := fmt.Sprintf("docker run -d --name=%s --rm -v /var/run/docker.sock:/var/run/docker.sock -p 0.0.0.0:%s:1234 bobrik/socat TCP-LISTEN:1234,fork UNIX-CONNECT:/var/run/docker.sock", constants.AgentContainerName, constants.AgentPort)
var cmd *command.Command
if !isLocal(p.host) {
cmd = command.New("start fx-agent", script, command.NewRemoteRunner(p.sshClient))
} else {
cmd = command.New("start fx-agent", script, command.NewLocalRunner())
}
if output, err := cmd.Exec(); err != nil {
log.Info(string(output))
return err
}
return nil
}
// StopFxAgent stop fx agent
func (p *Provisionor) StopFxAgent() error {
script := fmt.Sprintf("docker stop %s", constants.AgentContainerName)
var cmd *command.Command
if !isLocal(p.host) {
cmd = command.New("stop fx agent", script, command.NewRemoteRunner(p.sshClient))
} else {
cmd = command.New("stop fx agent", script, command.NewLocalRunner())
}
if output, err := cmd.Exec(); err != nil {
log.Infof(string(output))
return err
}
return nil
}
// Start start provision progress
func (p *Provisionor) Start() error {
scripts := map[string]string{
"pull java Docker base image": "docker pull metrue/fx-java-base",
"pull julia Docker base image": "docker pull metrue/fx-julia-base",
"pull python Docker base iamge": "docker pull metrue/fx-python-base",
"pull node Docker base image": "docker pull metrue/fx-node-base",
"pull d Docker base image": "docker pull metrue/fx-d-base",
"pull go Docker base image": "docker pull metrue/fx-go-base",
}
var wg sync.WaitGroup
for n, s := range scripts {
wg.Add(1)
go func(name, script string) {
var cmd *command.Command
if !isLocal(p.host) {
cmd = command.New(name, script, command.NewRemoteRunner(p.sshClient))
} else {
cmd = command.New(name, script, command.NewLocalRunner())
}
if _, err := cmd.Exec(); err != nil {
log.Fatalf("Provision:%s: %s", cmd.Name, err)
} else {
log.Infof("Provision:%s: \u2713", cmd.Name)
}
wg.Done()
}(n, s)
}
wg.Wait()
return nil
}