// vim: shiftwidth=4 tabstop=4 noexpandtab package main import ( "time" "log" "os/exec" "fmt" "io" ) type Transporter struct { statemachine Machine } type TransportConfig struct { Enabled bool `json:"enabled"` LocalPathToSshPrivateKey string `json:"local_path_to_ssh_private_key"` FileserverHostOrIp string `json:"fileserver_host_or_ip"` FileserverSshPort string `json:"fileserver_ssh_port"` RemoteUser string `json:"remote_user"` RemotePathToTargetDirectory string `json:"remote_path_to_target_directory"` } func NewTransporter() Transporter { return Transporter{ statemachine: Machine{ name: "transporter", initial: "idle", states: StateMap{ "idle": MachineState{ // nothing to transport on: TransitionMap{ "transport_request": MachineTransition{ to: "transport", }, }, }, "transport": MachineState{ // rsync process for transport is running on: TransitionMap{ "transport_request": MachineTransition{ to: "transport_queue", }, "transport_finished": MachineTransition{ to: "idle", }, }, }, "transport_queue": MachineState{ // like transport but also a pending transport request on: TransitionMap{ "transport_finished": MachineTransition{ to: "transport", }, }, }, }, api: make(chan string), state_listeners: make([]*(chan string), 0), hook: runTransporterHooks, }, } } func (transp *Transporter) Run() { transp.statemachine.Run() } func runTransporterHooks(last string, next string, m *Machine) { if last == "idle" && next == "transport" { go transportData(m) } if last == "transport_queue" && next == "transport" { go transportData(m) } } func transportData(m *Machine) { if config.Transport.Enabled { if !config.Flag.Debug { // generate command string from config cmdString := fmt.Sprintf( "\"rsync --remove-source-files -rltgoDv -e 'ssh -p %s -i %s' /var/lib/birdscan/ %s@%s:%s\"", config.Transport.FileserverSshPort, config.Transport.LocalPathToSshPrivateKey, config.Transport.RemoteUser, config.Transport.FileserverHostOrIp, config.Transport.RemotePathToTargetDirectory, ) // create command cmd := exec.Command( "/bin/bash", "-c", cmdString, ) log.Printf("Executing: '%s'", cmd.String()) // get stderr stderr,err := cmd.StderrPipe() if err != nil { log.Print(err) } defer stderr.Close() // execute command and fetch stderr err = cmd.Start() if err != nil { log.Print(err) } stderrData,err := io.ReadAll(stderr) if err != nil { log.Print(err) } err = cmd.Wait() if err != nil { log.Print(err) log.Println(string(stderrData)) } } else { time.Sleep(8 * time.Second) } } m.SendEvent("transport_finished") }