Пример #1
0
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)

}
Пример #2
0
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)
			}
		}
	}
}
Пример #3
0
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)
	}
}
Пример #4
0
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)
	}
}
Пример #5
0
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)
			}
		}
	}
}
Пример #6
0
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)
			}
		}
	}
}