Ejemplo n.º 1
0
func (s *ServerController) ToggleSedotanService(op string, id string) (bool, error) {
	data := new(colonycore.Server)
	cursor, err := colonycore.Find(new(colonycore.Server), dbox.Eq("_id", id))
	if err != nil {
		return false, err
	}
	dataAll := []colonycore.Server{}
	err = cursor.Fetch(&dataAll, 0, false)
	if err != nil {
		return false, err
	}
	defer cursor.Close()

	if len(dataAll) == 0 {
		return false, errors.New("Server not found")
	}

	data = &dataAll[0]

	sshSetting, client, err := s.SSHConnect(data)
	if err != nil {
		return false, err
	}
	defer client.Close()

	pgrepSedotanCmd, err := sshSetting.GetOutputCommandSsh("pgrep sedotand")
	if err != nil {
		// do something
	}
	isOn := false
	pid := strings.TrimSpace(pgrepSedotanCmd)
	if pid != "" {
		isOn = true
	}

	if strings.Contains(op, "stat") {
		return isOn, nil
	}

	if strings.Contains(op, "stop") {
		if pid != "" {
			killProcessCmd := fmt.Sprintf("kill -9 %s", pid)
			_, err = sshSetting.GetOutputCommandSsh(killProcessCmd)
			if err != nil {
				// do something
			}

			if !strings.Contains(op, "start") && err != nil {
				return isOn, err
			}
		}
	}

	if strings.Contains(op, "start") {
		sedotanConfigArg := fmt.Sprintf(`-config="%s"`, filepath.Join(data.AppPath, "config", "webgrabbers.json"))
		sedotanLogArg := fmt.Sprintf(`-logpath="%s"`, filepath.Join(data.DataPath, "daemon"))
		runSedotanCmd := fmt.Sprintf("cd %s && ./sedotand %s %s", filepath.Join(data.AppPath, "cli"), sedotanConfigArg, sedotanLogArg)
		err = helper.RunCommandWithTimeout(&sshSetting, runSedotanCmd, 5)
		if err != nil {
			return isOn, err
		}
	}

	return isOn, nil
}
Ejemplo n.º 2
0
func (a *ApplicationController) Deploy(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	path := filepath.Join(EC_DATA_PATH, "application", "log")
	log, _ := toolkit.NewLog(false, true, path, "log-%s", "20060102-1504")

	log.AddLog("Get payload", "INFO")
	payload := struct {
		ID     string `json:"_id",bson:"_id"`
		Server string
	}{}
	err := r.GetPayload(&payload)
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		return helper.CreateResult(false, nil, err.Error())
	}

	log.AddLog("Get application with ID: "+payload.ID, "INFO")
	app := new(colonycore.Application)
	err = colonycore.Get(app, payload.ID)
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		return helper.CreateResult(false, nil, err.Error())
	}

	log.AddLog("Get server with ID: "+payload.Server, "INFO")
	server := new(colonycore.Server)
	err = colonycore.Get(server, payload.Server)
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		return helper.CreateResult(false, nil, err.Error())
	}

	serverPathSeparator := a.GetServerPathSeparator(server)

	changeDeploymentStatus := func(status bool) {
		deployedTo := []string{}
		for _, each := range app.DeployedTo {
			if each != server.ID {
				deployedTo = append(deployedTo, server.ID)
			}
		}

		if status {
			app.DeployedTo = append(deployedTo, server.ID)
		}
		colonycore.Save(app)
	}

	log.AddLog(fmt.Sprintf("Connect to server %v", server), "INFO")
	sshSetting, sshClient, err := server.Connect()
	defer sshClient.Close()

	if server.OS == "windows" {
		sourcePath := filepath.Join(EC_APP_PATH, "src", app.ID)
		destinationPath := strings.Join([]string{server.AppPath, "src"}, serverPathSeparator)
		destinationZipPathOutput := strings.Join([]string{destinationPath, app.ID}, serverPathSeparator)
		var sourceZipPath string
		var unzipCmd string
		var destinationZipPath string

		if strings.Contains(server.CmdExtract, "7z") || strings.Contains(server.CmdExtract, "zip") {
			sourceZipPath = filepath.Join(EC_APP_PATH, "src", fmt.Sprintf("%s.zip", app.ID))
			destinationZipPath = fmt.Sprintf("%s.zip", destinationZipPathOutput)
			deszip := fmt.Sprintf("%s%s%s", destinationPath, serverPathSeparator, app.ID)

			// cmd /C 7z e -o %s -y %s
			unzipCmd = fmt.Sprintf("cmd /C %s", server.CmdExtract)
			unzipCmd = strings.Replace(unzipCmd, `%1`, deszip, -1)
			unzipCmd = strings.Replace(unzipCmd, `%2`, destinationZipPath, -1)

			log.AddLog(unzipCmd, "INFO")
			err = toolkit.ZipCompress(sourcePath, sourceZipPath)
			if err != nil {
				log.AddLog(err.Error(), "ERROR")
				changeDeploymentStatus(false)
				return helper.CreateResult(false, nil, err.Error())
			}
		} else {
			message := "currently only zip/7z command which is supported"
			log.AddLog(message, "ERROR")
			changeDeploymentStatus(false)
			return helper.CreateResult(false, nil, message)
		}

		rmCmdZip := fmt.Sprintf("rm -rf %s", destinationZipPath)
		log.AddLog(rmCmdZip, "INFO")
		_, err = sshSetting.GetOutputCommandSsh(rmCmdZip)
		if err != nil {
			log.AddLog(err.Error(), "ERROR")
			changeDeploymentStatus(false)
			return helper.CreateResult(false, nil, err.Error())
		}

		err = sshSetting.SshCopyByPath(sourceZipPath, destinationPath)
		log.AddLog(fmt.Sprintf("scp from %s to %s", sourceZipPath, destinationPath), "INFO")

		rmCmdZipOutput := fmt.Sprintf("rm -rf %s", destinationZipPathOutput)
		log.AddLog(rmCmdZipOutput, "INFO")
		_, err = sshSetting.GetOutputCommandSsh(rmCmdZipOutput)
		if err != nil {
			log.AddLog(err.Error(), "ERROR")
			changeDeploymentStatus(false)
			return helper.CreateResult(false, nil, err.Error())
		}

		mkdirDestCmd := fmt.Sprintf("%s %s%s%s", server.CmdMkDir, destinationPath, serverPathSeparator, app.ID)
		log.AddLog(mkdirDestCmd, "INFO")
		_, err = sshSetting.GetOutputCommandSsh(mkdirDestCmd)
		if err != nil {
			log.AddLog(err.Error(), "ERROR")
			changeDeploymentStatus(false)
			return helper.CreateResult(false, nil, err.Error())
		}

		chmodDestCmd := fmt.Sprintf("chmod -R 755 %s%s%s", destinationPath, serverPathSeparator, app.ID)
		log.AddLog(chmodDestCmd, "INFO")
		_, err = sshSetting.GetOutputCommandSsh(chmodDestCmd)
		if err != nil {
			log.AddLog(err.Error(), "ERROR")
			changeDeploymentStatus(false)
			return helper.CreateResult(false, nil, err.Error())
		}

		log.AddLog(unzipCmd, "INFO")
		_, err = sshSetting.GetOutputCommandSsh(unzipCmd)
		if err != nil {
			log.AddLog(err.Error(), "ERROR")
			changeDeploymentStatus(false)
			return helper.CreateResult(false, nil, err.Error())
		}

		err = os.Remove(sourceZipPath)
		log.AddLog(fmt.Sprintf("remove %s", sourceZipPath), "INFO")
		if err != nil {
			log.AddLog(err.Error(), "ERROR")
			changeDeploymentStatus(false)
			return helper.CreateResult(false, nil, err.Error())
		}

		findCommand := fmt.Sprintf(`find %s -name "*install.bat"`, destinationZipPathOutput)
		log.AddLog(findCommand, "INFO")
		installerPath, err := sshSetting.GetOutputCommandSsh(findCommand)
		installerPath = strings.TrimSpace(installerPath)
		if err != nil {
			log.AddLog(err.Error(), "ERROR")
			changeDeploymentStatus(false)
			return helper.CreateResult(false, nil, err.Error())
		}

		if installerPath == "" {
			errString := "installer not found"
			log.AddLog(errString, "ERROR")
			changeDeploymentStatus(false)
			return helper.CreateResult(false, nil, errString)
		}

		chmodCommand := fmt.Sprintf("chmod 755 %s%sinstall.bat", destinationZipPathOutput, serverPathSeparator)
		log.AddLog(chmodCommand, "INFO")
		_, err = sshSetting.GetOutputCommandSsh(chmodCommand)
		if err != nil {
			log.AddLog(err.Error(), "ERROR")
			changeDeploymentStatus(false)
			return helper.CreateResult(false, nil, err.Error())
		}

		// installerBasePath, _ := func(path string) (string, string) {
		// 	comps := strings.Split(path, serverPathSeparator)
		// 	ibp := strings.Join(comps[:len(comps)-1], serverPathSeparator)
		// 	ilf := comps[len(comps)-1]
		//
		// 	return ibp, ilf
		// }(installerPath)

		cRunCommand := make(chan string, 1)
		go func() {
			runCommand := fmt.Sprintf("cmd /C %s%sinstall.bat", destinationZipPathOutput, serverPathSeparator)
			log.AddLog(runCommand, "INFO")
			res, err := sshSetting.RunCommandSsh(runCommand)
			fmt.Println(res)
			if err != nil {
				log.AddLog(err.Error(), "ERROR")
				cRunCommand <- err.Error()
			} else {
				cRunCommand <- ""
			}
		}()

		errorMessage := ""
		select {
		case receiveRunCommandOutput := <-cRunCommand:
			errorMessage = receiveRunCommandOutput
		case <-time.After(time.Second * 3):
			errorMessage = ""
		}

		if errorMessage != "" {
			log.AddLog(errorMessage, "ERROR")
			changeDeploymentStatus(false)
			return helper.CreateResult(false, nil, errorMessage)
		}

		if app.DeployedTo == nil {
			app.DeployedTo = []string{}
		}

		changeDeploymentStatus(true)
		return helper.CreateResult(true, nil, "")
	}

	sourcePath := filepath.Join(EC_APP_PATH, "src", app.ID)
	destinationPath := strings.Join([]string{server.AppPath, "src"}, serverPathSeparator)
	destinationZipPathOutput := strings.Join([]string{destinationPath, app.ID}, serverPathSeparator)
	var sourceZipPath string
	var unzipCmd string
	var destinationZipPath string

	if strings.Contains(server.CmdExtract, "tar") {
		sourceZipPath = filepath.Join(EC_APP_PATH, "src", fmt.Sprintf("%s.tar", app.ID))
		destinationZipPath = fmt.Sprintf("%s.tar", destinationZipPathOutput)

		// tar -xvf %s -C %s
		unzipCmd = strings.Replace(server.CmdExtract, `%1`, destinationZipPath, -1)
		unzipCmd = strings.Replace(unzipCmd, `%2`, destinationZipPathOutput, -1)

		log.AddLog(fmt.Sprintf("tar compress %s -> %s", sourcePath, sourceZipPath), "INFO")
		err = toolkit.TarCompress(sourcePath, sourceZipPath)
		if err != nil {
			log.AddLog(err.Error(), "ERROR")
			changeDeploymentStatus(false)
			return helper.CreateResult(false, nil, err.Error())
		}
	} else if strings.Contains(server.CmdExtract, "zip") {
		sourceZipPath = filepath.Join(EC_APP_PATH, "src", fmt.Sprintf("%s.zip", app.ID))
		destinationZipPath = fmt.Sprintf("%s.zip", destinationZipPathOutput)

		// unzip %s -d %s
		unzipCmd = strings.Replace(server.CmdExtract, `%1`, destinationZipPath, -1)
		unzipCmd = strings.Replace(unzipCmd, `%2`, destinationZipPathOutput, -1)

		log.AddLog(fmt.Sprintf("zip compress %s -> %s", sourcePath, sourceZipPath), "INFO")
		err = toolkit.ZipCompress(sourcePath, sourceZipPath)
		if err != nil {
			log.AddLog(err.Error(), "ERROR")
			changeDeploymentStatus(false)
			return helper.CreateResult(false, nil, err.Error())
		}
	} else {
		message := "currently only zip/tar command which is supported"
		log.AddLog(message, "ERROR")
		changeDeploymentStatus(false)
		return helper.CreateResult(false, nil, message)
	}

	rmCmdZip := fmt.Sprintf("rm -rf %s", destinationZipPath)
	log.AddLog(rmCmdZip, "INFO")
	_, err = sshSetting.GetOutputCommandSsh(rmCmdZip)
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		changeDeploymentStatus(false)
		return helper.CreateResult(false, nil, err.Error())
	}

	err = sshSetting.SshCopyByPath(sourceZipPath, destinationPath)
	log.AddLog(fmt.Sprintf("scp from %s to %s", sourceZipPath, destinationPath), "INFO")

	rmCmdZipOutput := fmt.Sprintf("rm -rf %s", destinationZipPathOutput)
	log.AddLog(rmCmdZipOutput, "INFO")
	_, err = sshSetting.GetOutputCommandSsh(rmCmdZipOutput)
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		changeDeploymentStatus(false)
		return helper.CreateResult(false, nil, err.Error())
	}

	mkdirDestCmd := fmt.Sprintf("%s %s%s%s", server.CmdMkDir, destinationPath, serverPathSeparator, app.ID)
	log.AddLog(mkdirDestCmd, "INFO")
	_, err = sshSetting.GetOutputCommandSsh(mkdirDestCmd)
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		changeDeploymentStatus(false)
		return helper.CreateResult(false, nil, err.Error())
	}

	chmodDestCmd := fmt.Sprintf("chmod -R 777 %s%s%s", destinationPath, serverPathSeparator, app.ID)
	log.AddLog(chmodDestCmd, "INFO")
	_, err = sshSetting.GetOutputCommandSsh(chmodDestCmd)
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		changeDeploymentStatus(false)
		return helper.CreateResult(false, nil, err.Error())
	}

	log.AddLog(unzipCmd, "INFO")
	_, err = sshSetting.GetOutputCommandSsh(unzipCmd)
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		changeDeploymentStatus(false)
		return helper.CreateResult(false, nil, err.Error())
	}

	err = os.Remove(sourceZipPath)
	log.AddLog(fmt.Sprintf("remove %s", sourceZipPath), "INFO")
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		changeDeploymentStatus(false)
		return helper.CreateResult(false, nil, err.Error())
	}

	findCommand := fmt.Sprintf(`find %s -name "*install.sh"`, destinationZipPathOutput)
	log.AddLog(findCommand, "INFO")
	installerPath, err := sshSetting.GetOutputCommandSsh(findCommand)
	installerPath = strings.TrimSpace(installerPath)
	helper.FixPath(&installerPath)
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		changeDeploymentStatus(false)
		return helper.CreateResult(false, nil, err.Error())
	}

	if installerPath == "" {
		errString := "installer not found"
		log.AddLog(errString, "ERROR")
		changeDeploymentStatus(false)
		return helper.CreateResult(false, nil, errString)
	}

	chmodCommand := fmt.Sprintf("chmod 755 %s", installerPath)
	log.AddLog(chmodCommand, "INFO")
	_, err = sshSetting.GetOutputCommandSsh(chmodCommand)
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		changeDeploymentStatus(false)
		return helper.CreateResult(false, nil, err.Error())
	}

	installerBasePath, installerFile := func(path string) (string, string) {
		comps := strings.Split(path, serverPathSeparator)
		ibp := strings.Join(comps[:len(comps)-1], serverPathSeparator)
		ilf := comps[len(comps)-1]

		return ibp, ilf
	}(installerPath)

	runCommand := fmt.Sprintf(`cd %s && ./%s "%s"`, installerBasePath, installerFile, app.ID)
	log.AddLog(runCommand, "INFO")
	err = helper.RunCommandWithTimeout(&sshSetting, runCommand, 10)
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		// changeDeploymentStatus(false)
		// return helper.CreateResult(false, nil, err.Error())
	}

	isRunning, err := app.RunApp(server)
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		changeDeploymentStatus(false)
		return helper.CreateResult(false, nil, err.Error())
	}

	if app.DeployedTo == nil {
		app.DeployedTo = []string{}
	}

	changeDeploymentStatus(true)
	return helper.CreateResult(true, isRunning, "")
}