Example #1
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 := new(ServerController).SSHConnect(server)
	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)
		fmt.Println(installerBasePath)
		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(unzipCmd, "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(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/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)
	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)

	cRunCommand := make(chan string, 1)
	go func() {
		runCommand := fmt.Sprintf("cd %s && ./%s &", installerBasePath, installerFile)
		log.AddLog(runCommand, "INFO")
		_, err = sshSetting.RunCommandSsh(runCommand)
		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, "")
}
Example #2
0
func (p *Page) CopyFileToServer(server *Server, sourcePath string, destPath string, appID string, log *toolkit.LogEngine) error {
	var serverPathSeparator string
	if strings.Contains(destPath, "/") {
		serverPathSeparator = `/`
	} else {
		serverPathSeparator = "\\\\"
	}
	destZipPath := strings.Join([]string{destPath, appID}, serverPathSeparator)
	unzipCmd, sourceZipFile, destZipFile, err := p.DefineCommand(server, sourcePath, destZipPath, appID)

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

	log.AddLog(unzipCmd, "INFO") /*compress file on local colony manager*/
	if strings.Contains(sourceZipFile, ".zip") {
		err = toolkit.ZipCompress(sourcePath, sourceZipFile)
	} else if strings.Contains(sourceZipFile, ".tar") {
		err = toolkit.TarCompress(sourcePath, sourceZipFile)
	}
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		return err
	}

	rmCmdZip := toolkit.Sprintf("rm -rf %s", destZipFile)
	log.AddLog(rmCmdZip, "INFO")
	_, err = sshSetting.GetOutputCommandSsh(rmCmdZip) /*delete zip file on server before copy file*/
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		return err
	}

	log.AddLog(toolkit.Sprintf("scp from %s to %s", sourceZipFile, destPath), "INFO")
	err = sshSetting.SshCopyByPath(sourceZipFile, destPath) /*copy zip file from colony manager to server*/
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		return err
	}

	rmCmdZipOutput := toolkit.Sprintf("rm -rf %s", destZipPath)
	log.AddLog(rmCmdZipOutput, "INFO")
	_, err = sshSetting.GetOutputCommandSsh(rmCmdZipOutput) /*delete folder before extract zip file on server*/
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		return err
	}

	mkdirDestCmd := toolkit.Sprintf("%s %s%s%s", server.CmdMkDir, destZipPath, serverPathSeparator, appID)
	log.AddLog(mkdirDestCmd, "INFO")
	_, err = sshSetting.GetOutputCommandSsh(mkdirDestCmd) /*make new dest folder on server for folder extraction*/
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		return err
	}

	chmodDestCmd := toolkit.Sprintf("chmod -R 755 %s%s%s", destZipPath, serverPathSeparator, appID)
	log.AddLog(chmodDestCmd, "INFO")
	_, err = sshSetting.GetOutputCommandSsh(chmodDestCmd) /*set chmod on new folder extraction*/
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		return err
	}

	log.AddLog(unzipCmd, "INFO")
	_, err = sshSetting.GetOutputCommandSsh(unzipCmd) /*extract zip file to server*/
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		return err
	}

	log.AddLog(toolkit.Sprintf("remove %s", sourceZipFile), "INFO")
	err = os.Remove(sourceZipFile) /*remove zip file from local colony manager*/
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		return err
	}

	log.AddLog(rmCmdZip, "INFO")
	_, err = sshSetting.GetOutputCommandSsh(rmCmdZip) /*delete zip file on server after folder extraction*/
	if err != nil {
		log.AddLog(err.Error(), "ERROR")
		return err
	}
	return nil
}