func sendRegRequest(url, method, token, uuid string, data []byte) ([]byte, error) { headers := []string{"Authorization TutumAgentToken " + token, "Content-Type application/json", "User-Agent tutum-agent/" + VERSION} return SendRequest(method, utils.JoinURL(url, uuid), data, headers) }
func VerifyRegistration(url string) { headers := []string{"Authorization TutumAgentToken " + Conf.TutumToken, "Content-Type application/json", "User-Agent tutum-agent/" + VERSION} body, err := SendRequest("GET", utils.JoinURL(url, Conf.TutumUUID), nil, headers) if err != nil { SendError(err, "SendRequest error", nil) Logger.Printf("Get registration info error, %s", err) } else { var form RegGetForm if err = json.Unmarshal(body, &form); err != nil { SendError(err, "Json unmarshal error", nil) Logger.Println("Cannot unmarshal the response", err) } else { if form.State == "Deployed" { Logger.Println("Node registration successful with", Conf.TutumHost) return } } } time.Sleep(5 * time.Minute) body, err = SendRequest("GET", utils.JoinURL(url, Conf.TutumUUID), nil, headers) if err != nil { SendError(err, "Failed to get registration info after 5 minutes", nil) Logger.Printf("Get registration info error, %s", err) } else { var form RegGetForm if err = json.Unmarshal(body, &form); err != nil { SendError(err, "Json unmarshal error", nil) Logger.Println("Cannot unmarshal the response", err) } else { if form.State == "Deployed" { Logger.Println("Node registration successful with", Conf.TutumHost) } else { Logger.Println("Node registration timed out with", Conf.TutumHost) Logger.Println("Node state:", form.State) } } } }
func isNodeReachable(url, uuid string) bool { var reachableForm ReachableForm detailedUrl := utils.JoinURL(url, uuid+"/ping/") headers := []string{"Authorization TutumAgentToken " + Conf.TutumToken, "Content-Type application/json", "User-Agent tutum-agent/" + VERSION} //waiting for docker port opens Logger.Print("Waiting for docker unix socket to be ready") for { unixsock := DockerDefaultHost if strings.HasPrefix(unixsock, "unix://") { unixsock = DockerDefaultHost[7:] } _, err := net.DialTimeout("unix", unixsock, DialTimeOut*time.Second) if err == nil { break } else { time.Sleep(2 * time.Second) } } Logger.Print("Docker unix socket opened") //check the port from tutum server for i := 1; ; i *= 2 { if i > MaxWaitingTime { i = 1 } body, err := SendRequest("POST", detailedUrl, nil, headers) if err == nil { if err := json.Unmarshal(body, &reachableForm); err != nil { SendError(err, "Json unmarshal error", nil) Logger.Println("Failed to unmarshal the response", err) } else { return reachableForm.Reachable } } SendError(err, "Node reachable check HTTP error", nil) Logger.Printf("Node reachable check failed, %s. Retry in %d seconds", err, i) time.Sleep(time.Duration(i) * time.Second) } }
func patchTunnelToTutum(url, tunnel string) { Logger.Println("Sending tunnel address to Tutum") form := TunnelPatchForm{} form.Version = VERSION form.Tunnel = tunnel data, err := json.Marshal(form) if err != nil { SendError(err, "Json marshal error", nil) Logger.Printf("Cannot marshal the TunnelPatch form:%s\f", err) } headers := []string{"Authorization TutumAgentToken " + Conf.TutumToken, "Content-Type", "application/json"} _, err = SendRequest("PATCH", utils.JoinURL(url, Conf.TutumUUID), data, headers) if err != nil { SendError(err, "Failed to patch tunnel address to Tutum", nil) Logger.Println("Failed to patch tunnel address to Tutum,", err) } }
func updateNgrokHost(url string) { if NgrokHost != "" { return } headers := []string{"Authorization TutumAgentToken " + Conf.TutumToken, "Content-Type application/json"} body, err := SendRequest("GET", utils.JoinURL(url, Conf.TutumUUID), nil, headers) if err != nil { SendError(err, "SendRequest error", nil) Logger.Printf("Get registration info error, %s", err) } else { var form RegGetForm if err = json.Unmarshal(body, &form); err != nil { SendError(err, "Json unmarshal error", nil) Logger.Println("Cannot unmarshal the response", err) } else { if form.NgrokHost != "" { NgrokHost = form.NgrokHost Logger.Println("Ngrok server:", NgrokHost) } } } }
func main() { dockerBinPath := path.Join(DockerDir, DockerBinaryName) dockerNewBinPath := path.Join(DockerDir, DockerNewBinaryName) dockerNewBinSigPath := path.Join(DockerDir, DockerNewBinarySigName) configFilePath := path.Join(TutumHome, ConfigFileName) keyFilePath := path.Join(TutumHome, KeyFileName) certFilePath := path.Join(TutumHome, CertFileName) caFilePath := path.Join(TutumHome, CAFileName) ngrokPath := path.Join(DockerDir, NgrokBinaryName) ngrokLogPath := path.Join(LogDir, NgrokLogName) ngrokConfPath := path.Join(TutumHome, NgrokConfName) _ = os.MkdirAll(TutumHome, 0755) _ = os.MkdirAll(DockerDir, 0755) _ = os.MkdirAll(LogDir, 0755) ParseFlag() SetLogger(path.Join(LogDir, TutumLogFileName)) CreatePidFile(TutumPidFile) PrepareFiles(configFilePath, dockerBinPath, keyFilePath, certFilePath) SetConfigFile(configFilePath) regUrl := utils.JoinURL(Conf.TutumHost, RegEndpoint) if Conf.TutumUUID == "" { os.RemoveAll(keyFilePath) os.RemoveAll(certFilePath) os.RemoveAll(caFilePath) if !*FlagStandalone { Logger.Printf("Registering in Tutum via POST: %s...\n", regUrl) PostToTutum(regUrl, caFilePath, configFilePath) } } if *FlagStandalone { commonName := Conf.CertCommonName if commonName == "" { commonName = "*" } CreateCerts(keyFilePath, certFilePath, commonName) } else { CreateCerts(keyFilePath, certFilePath, Conf.CertCommonName) } if !*FlagStandalone { Logger.Printf("Registering in Tutum via PATCH: %s...\n", regUrl+Conf.TutumUUID) err := PatchToTutum(regUrl, caFilePath, certFilePath, configFilePath) if err != nil { Logger.Printf("TutumUUID (%s) is invalid, trying to allocate a new one...\n", Conf.TutumUUID) Conf.TutumUUID = "" SaveConf(configFilePath, Conf) os.RemoveAll(keyFilePath) os.RemoveAll(certFilePath) os.RemoveAll(caFilePath) Logger.Printf("Registering in Tutum via POST: %s...\n", regUrl) PostToTutum(regUrl, caFilePath, configFilePath) CreateCerts(keyFilePath, certFilePath, Conf.CertCommonName) Logger.Printf("Registering in Tutum via PATCH: %s...\n", regUrl+Conf.TutumUUID) if err = PatchToTutum(regUrl, caFilePath, certFilePath, configFilePath); err != nil { SendError(err, "Registion HTTP error", nil) } } } if err := SaveConf(configFilePath, Conf); err != nil { SendError(err, "Failed to save config to the conf file", nil) Logger.Fatalln(err) } DownloadDocker(DockerBinaryURL, dockerBinPath) HandleSig() syscall.Setpriority(syscall.PRIO_PROCESS, os.Getpid(), RenicePriority) Logger.Println("Starting docker daemon...") StartDocker(dockerBinPath, keyFilePath, certFilePath, caFilePath) if !*FlagStandalone { if *FlagSkipNatTunnel { Logger.Println("Skip NAT tunnel") } else { Logger.Println("Loading NAT tunnel module...") go NatTunnel(regUrl, ngrokPath, ngrokLogPath, ngrokConfPath, NodePublicIp) } } if !*FlagStandalone { Logger.Println("Verifying the registration with Tutum...") go VerifyRegistration(regUrl) } Logger.Println("Docker server started. Entering maintenance loop") for { time.Sleep(HeartBeatInterval * time.Second) UpdateDocker(dockerBinPath, dockerNewBinPath, dockerNewBinSigPath, keyFilePath, certFilePath, caFilePath) // try to restart docker daemon if it dies somehow if DockerProcess == nil { time.Sleep(HeartBeatInterval * time.Second) if DockerProcess == nil && ScheduleToTerminateDocker == false { Logger.Println("Respawning docker daemon") StartDocker(dockerBinPath, keyFilePath, certFilePath, caFilePath) } } } }