コード例 #1
0
func GetServer(w rest.ResponseWriter, r *rest.Request) {
	dbConn, err := util.GetConnection(CLUSTERADMIN_DB)
	if err != nil {
		logit.Error.Println("BackupNow: error " + err.Error())
		rest.Error(w, err.Error(), 400)
		return

	}
	defer dbConn.Close()
	err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-read")
	if err != nil {
		logit.Error.Println("GetServer: authorize error " + err.Error())
		rest.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}
	ID := r.PathParam("ID")
	logit.Info.Println("in GetServer with ID=" + ID)

	results, err := admindb.GetServer(dbConn, ID)
	if err != nil {
		logit.Error.Println("GetServer:" + err.Error())
		rest.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	server := Server{results.ID, results.Name, results.IPAddress,
		results.DockerBridgeIP, results.PGDataPath, results.ServerClass, results.CreateDate}
	logit.Info.Println("GetServer: results=" + results.ID)

	w.WriteJson(&server)
}
func AdminStartNode(w rest.ResponseWriter, r *rest.Request) {
	dbConn, err := util.GetConnection(CLUSTERADMIN_DB)
	if err != nil {
		logit.Error.Println("BackupNow: error " + err.Error())
		rest.Error(w, err.Error(), 400)
		return

	}
	defer dbConn.Close()

	err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-read")
	if err != nil {
		logit.Error.Println("AdminStartNode: validate token error " + err.Error())
		rest.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}

	ID := r.PathParam("ID")
	if ID == "" {
		logit.Error.Println("AdminStartNode: error ID required")
		rest.Error(w, "ID required", http.StatusBadRequest)
		return
	}

	node, err := admindb.GetContainer(dbConn, ID)
	if err != nil {
		logit.Error.Println("AdminStartNode:" + err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	server := admindb.Server{}
	server, err = admindb.GetServer(dbConn, node.ServerID)
	if err != nil {
		logit.Error.Println("AdminStartNode:" + err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	var url = "http://" + server.IPAddress + ":10001"
	var response cpmserverapi.DockerStartResponse
	request := &cpmserverapi.DockerStartRequest{}
	request.ContainerName = node.Name
	response, err = cpmserverapi.DockerStartClient(url, request)
	if err != nil {
		logit.Error.Println("AdminStartNode: error when trying to start container " + err.Error())
	}
	logit.Info.Println(response.Output)

	w.WriteHeader(http.StatusOK)
	status := SimpleStatus{}
	status.Status = "OK"
	w.WriteJson(&status)

}
コード例 #3
0
func BackupNow(w rest.ResponseWriter, r *rest.Request) {

	dbConn, err := util.GetConnection(CLUSTERADMIN_DB)
	if err != nil {
		logit.Error.Println("BackupNow: error " + err.Error())
		rest.Error(w, err.Error(), 400)
		return

	}
	defer dbConn.Close()
	postMsg := BackupNowPost{}
	err = r.DecodeJsonPayload(&postMsg)
	if err != nil {
		logit.Error.Println("BackupNow: error in decode" + err.Error())
		rest.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	err = secimpl.Authorize(dbConn, postMsg.Token, "perm-backup")
	if err != nil {
		logit.Error.Println("BackupNow: validate token error " + err.Error())
		rest.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}

	if postMsg.ServerID == "" {
		logit.Error.Println("BackupNow: error node ServerID required")
		rest.Error(w, "server ID required", 400)
		return
	}
	if postMsg.ProfileName == "" {
		logit.Error.Println("BackupNow: error node ProfileName required")
		rest.Error(w, "ProfileName required", 400)
		return
	}

	if postMsg.ScheduleID == "" {
		logit.Error.Println("BackupNow: error schedule ID required")
		rest.Error(w, "schedule ID required", 400)
		return
	}

	schedule, err2 := backup.GetSchedule(dbConn, postMsg.ScheduleID)
	if err2 != nil {
		logit.Error.Println("BackupNow: " + err2.Error())
		rest.Error(w, err2.Error(), 400)
		return
	}

	//get the server details for where the backup should be made
	server := admindb.Server{}
	server, err = admindb.GetServer(dbConn, postMsg.ServerID)
	if err != nil {
		logit.Error.Println("BackupNow: " + err.Error())
		rest.Error(w, err.Error(), 400)
		return
	}

	//get the domain name
	//get domain name
	var domainname admindb.Setting
	domainname, err = admindb.GetSetting(dbConn, "DOMAIN-NAME")
	if err != nil {
		logit.Error.Println("BackupNow: DOMAIN-NAME err " + err.Error())
	}

	request := backup.BackupRequest{}
	request.ScheduleID = postMsg.ScheduleID
	request.ServerID = server.ID
	if KubeEnv {
		request.ContainerName = schedule.ContainerName + "-db"
	} else {
		request.ContainerName = schedule.ContainerName
	}
	request.ServerName = server.Name
	request.ServerIP = server.IPAddress
	request.ProfileName = postMsg.ProfileName
	backupServerURL := "cpm-backup." + domainname.Value + ":13000"
	output, err := backup.BackupNowClient(backupServerURL, request)
	if err != nil {
		logit.Error.Println(err.Error())
		rest.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	logit.Info.Println("output=" + output)

	w.WriteHeader(http.StatusOK)
	status := SimpleStatus{}
	status.Status = "OK"
	w.WriteJson(&status)
}
コード例 #4
0
func DeleteCluster(w rest.ResponseWriter, r *rest.Request) {
	dbConn, err := util.GetConnection(CLUSTERADMIN_DB)
	if err != nil {
		logit.Error.Println("BackupNow: error " + err.Error())
		rest.Error(w, err.Error(), 400)
		return

	}
	defer dbConn.Close()

	err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-cluster")
	if err != nil {
		logit.Error.Println("DeleteCluster: authorize error " + err.Error())
		rest.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}

	ID := r.PathParam("ID")
	if ID == "" {
		logit.Error.Println("DeleteCluster: error cluster ID required")
		rest.Error(w, "cluster ID required", http.StatusBadRequest)
		return
	}

	cluster, err := admindb.GetCluster(dbConn, ID)
	if err != nil {
		logit.Error.Println("DeleteCluster:" + err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
	}

	//delete docker containers
	containers, err := admindb.GetAllContainersForCluster(dbConn, cluster.ID)
	if err != nil {
		logit.Error.Println("DeleteCluster:" + err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
	}

	i := 0

	i = 0
	server := admindb.Server{}
	for i = range containers {

		//go get the docker server IPAddress
		server, err = admindb.GetServer(dbConn, containers[i].ServerID)
		if err != nil {
			logit.Error.Println("DeleteCluster:" + err.Error())
			rest.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		logit.Info.Println("DeleteCluster: got server IP " + server.IPAddress)

		//it is possible that someone can remove a container
		//outside of us, so we let it pass that we can't remove
		//it
		//err = removeContainer(server.IPAddress, containers[i].Name)
		dremreq := &cpmserverapi.DockerRemoveRequest{}
		dremreq.ContainerName = containers[i].Name
		logit.Info.Println("will attempt to delete container " + dremreq.ContainerName)
		var url = "http://" + server.IPAddress + ":10001"
		_, err = cpmserverapi.DockerRemoveClient(url, dremreq)
		if err != nil {
			logit.Error.Println("DeleteCluster: error when trying to remove container" + err.Error())
		}

		//send the server a deletevolume command
		url = "http://" + server.IPAddress + ":10001"
		ddreq := &cpmserverapi.DiskDeleteRequest{}
		ddreq.Path = server.PGDataPath + "/" + containers[i].Name
		_, err = cpmserverapi.DiskDeleteClient(url, ddreq)
		if err != nil {
			logit.Error.Println("DeleteCluster: error when trying to remove disk volume" + err.Error())
		}

		i++
	}

	//delete the container entries
	//delete the cluster entry
	admindb.DeleteCluster(dbConn, ID)

	for i = range containers {

		err = admindb.DeleteContainer(dbConn, containers[i].ID)
		if err != nil {
			logit.Error.Println("DeleteCluster:" + err.Error())
			rest.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
	}

	status := SimpleStatus{}
	status.Status = "OK"
	w.WriteHeader(http.StatusOK)
	w.WriteJson(&status)
}
コード例 #5
0
//monitor server - get info
func MonitorServerGetInfo(w rest.ResponseWriter, r *rest.Request) {
	dbConn, err := util.GetConnection(CLUSTERADMIN_DB)
	if err != nil {
		logit.Error.Println("BackupNow: error " + err.Error())
		rest.Error(w, err.Error(), 400)
		return

	}
	defer dbConn.Close()
	err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-read")
	if err != nil {
		logit.Error.Println("MonitorServerGetInfo: authorize error " + err.Error())
		rest.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}
	ServerID := r.PathParam("ServerID")
	Metric := r.PathParam("Metric")

	if ServerID == "" {
		logit.Error.Println("MonitorServerGetInfo: error ServerID required")
		rest.Error(w, "ServerID required", http.StatusBadRequest)
		return
	}
	if Metric == "" {
		logit.Error.Println("MonitorServerGetInfo: error metric required")
		rest.Error(w, "Metric required", http.StatusBadRequest)
		return
	}

	//go get the IPAddress
	server, err := admindb.GetServer(dbConn, ServerID)
	if err != nil {
		logit.Error.Println("MonitorServerGetInfo:" + err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	var output string
	url := "http://" + server.IPAddress + ":10001"
	if Metric == "cpmiostat" {
		iostatreq := cpmserverapi.MetricIostatRequest{}
		var iostatResp cpmserverapi.MetricIostatResponse
		iostatResp, err = cpmserverapi.MetricIostatClient(url, &iostatreq)
		if err != nil {
			logit.Error.Println("MonitorServerGetInfo:" + err.Error())
			rest.Error(w, err.Error(), 400)
			return
		}
		output = iostatResp.Output
	} else if Metric == "cpmdf" {
		dfreq := cpmserverapi.MetricDfRequest{}
		var dfResp cpmserverapi.MetricDfResponse
		dfResp, err = cpmserverapi.MetricDfClient(url, &dfreq)
		if err != nil {
			logit.Error.Println("MonitorServerGetInfo:" + err.Error())
			rest.Error(w, err.Error(), 400)
			return
		}
		output = dfResp.Output
	} else {
		logit.Error.Println("unknown Metric received")
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	w.(http.ResponseWriter).Write([]byte(output))
	//w.Header().set("Content-Type", "text/json")
	w.WriteHeader(http.StatusOK)
}
func AdminStopServerContainers(w rest.ResponseWriter, r *rest.Request) {
	dbConn, err := util.GetConnection(CLUSTERADMIN_DB)
	if err != nil {
		logit.Error.Println("BackupNow: error " + err.Error())
		rest.Error(w, err.Error(), 400)
		return

	}
	defer dbConn.Close()

	err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-read")
	if err != nil {
		logit.Error.Println("AdminStopServerContainers: validate token error " + err.Error())
		rest.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}

	//serverID
	serverid := r.PathParam("ID")
	if serverid == "" {
		logit.Error.Println("AdminStopoServerContainers: error ID required")
		rest.Error(w, "ID required", http.StatusBadRequest)
		return
	}

	//fetch the server
	containers, err := admindb.GetAllContainersForServer(dbConn, serverid)
	if err != nil {
		logit.Error.Println("AdminStopServerContainers:" + err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	var url string
	//for each, get server, stop container
	for i := range containers {
		server := admindb.Server{}
		server, err = admindb.GetServer(dbConn, containers[i].ServerID)
		if err != nil {
			logit.Error.Println("AdminStopServerContainers:" + err.Error())
			rest.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		//send stop command before stopping container
		if containers[i].Role == "pgpool" {
			var stoppoolResp cpmcontainerapi.StopPgpoolResponse
			stoppoolResp, err = cpmcontainerapi.StopPgpoolClient(containers[i].Name)
			logit.Info.Println("AdminStoppg:" + stoppoolResp.Output)
		} else {
			var stopResp cpmcontainerapi.StopPGResponse
			stopResp, err = cpmcontainerapi.StopPGClient(containers[i].Name)
			logit.Info.Println("AdminStoppg:" + stopResp.Output)
		}
		if err != nil {
			logit.Error.Println("AdminStopServerContainers:" + err.Error())
			rest.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		time.Sleep(2000 * time.Millisecond)
		//stop container
		request := &cpmserverapi.DockerStopRequest{}
		request.ContainerName = containers[i].Name
		url = "http://" + server.IPAddress + ":10001"
		_, err = cpmserverapi.DockerStopClient(url, request)
		if err != nil {
			logit.Error.Println("AdminStopServerContainers: error when trying to start container " + err.Error())
		}
	}

	w.WriteHeader(http.StatusOK)
	status := SimpleStatus{}
	status.Status = "OK"
	w.WriteJson(&status)

}
func AdminStartServerContainers(w rest.ResponseWriter, r *rest.Request) {
	dbConn, err := util.GetConnection(CLUSTERADMIN_DB)
	if err != nil {
		logit.Error.Println("BackupNow: error " + err.Error())
		rest.Error(w, err.Error(), 400)
		return

	}
	defer dbConn.Close()

	err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-read")
	if err != nil {
		logit.Error.Println("AdminStartServerContainers: validate token error " + err.Error())
		rest.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}

	//serverID
	serverid := r.PathParam("ID")
	if serverid == "" {
		logit.Error.Println("AdminStartServerContainers: error ID required")
		rest.Error(w, "ID required", http.StatusBadRequest)
		return
	}

	containers, err := admindb.GetAllContainersForServer(dbConn, serverid)
	if err != nil {
		logit.Error.Println("AdminStartServerContainers:" + err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	//for each, get server, start container
	//use a 'best effort' approach here since containers
	//can be removed outside of CPM's control

	var url string

	for i := range containers {
		//fetch the server
		server := admindb.Server{}
		server, err = admindb.GetServer(dbConn, containers[i].ServerID)
		if err != nil {
			logit.Error.Println("AdminStartServerContainers:" + err.Error())
			rest.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		//start the container
		var response cpmserverapi.DockerStartResponse
		var err error
		request := &cpmserverapi.DockerStartRequest{}
		request.ContainerName = containers[i].Name
		url = "http://" + server.IPAddress + ":10001"
		response, err = cpmserverapi.DockerStartClient(url, request)
		if err != nil {
			logit.Error.Println("AdminStartServerContainers: error when trying to start container " + err.Error())
		}
		logit.Info.Println(response.Output)

	}

	w.WriteHeader(http.StatusOK)
	status := SimpleStatus{}
	status.Status = "OK"
	w.WriteJson(&status)

}
func GetAllNodesForServer(w rest.ResponseWriter, r *rest.Request) {
	dbConn, err := util.GetConnection(CLUSTERADMIN_DB)
	if err != nil {
		logit.Error.Println("BackupNow: error " + err.Error())
		rest.Error(w, err.Error(), 400)
		return

	}
	defer dbConn.Close()

	err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-read")
	if err != nil {
		logit.Error.Println("GetAllNodesForServer: validate token error " + err.Error())
		rest.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}

	serverID := r.PathParam("ServerID")
	if serverID == "" {
		logit.Error.Println("GetAllNodesForServer: error serverID required")
		rest.Error(w, "serverID required", http.StatusBadRequest)
		return
	}

	results, err := admindb.GetAllContainersForServer(dbConn, serverID)
	if err != nil {
		logit.Error.Println("GetAllNodesForServer:" + err.Error())
		logit.Error.Println("error " + err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	server, err2 := admindb.GetServer(dbConn, serverID)
	if err2 != nil {
		logit.Error.Println("GetAllNodesForServer:" + err2.Error())
		logit.Error.Println("error " + err2.Error())
		rest.Error(w, err2.Error(), http.StatusBadRequest)
		return
	}

	var response cpmserverapi.DockerInspectResponse
	var e error
	var url string
	nodes := make([]ClusterNode, len(results))
	i := 0
	for i = range results {
		nodes[i].ID = results[i].ID
		nodes[i].Name = results[i].Name
		nodes[i].ClusterID = results[i].ClusterID
		nodes[i].ServerID = results[i].ServerID
		nodes[i].Role = results[i].Role
		nodes[i].Image = results[i].Image
		nodes[i].CreateDate = results[i].CreateDate
		nodes[i].ProjectID = results[i].ProjectID
		nodes[i].ProjectName = results[i].ProjectName
		nodes[i].ServerName = results[i].ServerName
		nodes[i].Status = "down"

		request := &cpmserverapi.DockerInspectRequest{}
		request.ContainerName = results[i].Name
		url = "http://" + server.IPAddress + ":10001"
		response, e = cpmserverapi.DockerInspectClient(url, request)
		logit.Info.Println("GetAllNodesForServer:" + results[i].Name + " " + response.IPAddress + " " + response.RunningState)
		if e != nil {
			logit.Error.Println("GetAllNodesForServer:" + e.Error())
			logit.Error.Println(e.Error())
			nodes[i].Status = "notfound"
		} else {
			logit.Info.Println("GetAllNodesForServer: setting " + results[i].Name + " to " + response.RunningState)
			nodes[i].Status = response.RunningState
		}

		i++
	}

	w.WriteJson(&nodes)

}
/*
 TODO refactor this to share code with DeleteCluster!!!!!
*/
func DeleteNode(w rest.ResponseWriter, r *rest.Request) {
	dbConn, err := util.GetConnection(CLUSTERADMIN_DB)
	if err != nil {
		logit.Error.Println("BackupNow: error " + err.Error())
		rest.Error(w, err.Error(), 400)
		return

	}
	defer dbConn.Close()

	err = secimpl.Authorize(dbConn, r.PathParam("Token"), "perm-container")
	if err != nil {
		logit.Error.Println("DeleteNode: validate token error " + err.Error())
		rest.Error(w, err.Error(), http.StatusUnauthorized)
		return
	}

	ID := r.PathParam("ID")
	if ID == "" {
		logit.Error.Println("DeleteNode: error node ID required")
		rest.Error(w, "node ID required", http.StatusBadRequest)
		return
	}

	//go get the node we intend to delete
	var dbNode admindb.Container
	dbNode, err = admindb.GetContainer(dbConn, ID)
	if err != nil {
		logit.Error.Println("DeleteNode: " + err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	//go get the docker server IPAddress
	server := admindb.Server{}
	server, err = admindb.GetServer(dbConn, dbNode.ServerID)
	if err != nil {
		logit.Error.Println("DeleteNode: " + err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	var url = "http://" + server.IPAddress + ":10001"

	err = admindb.DeleteContainer(dbConn, ID)
	if err != nil {
		logit.Error.Println("DeleteNode: " + err.Error())
		rest.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	logit.Info.Println("got server IP " + server.IPAddress)

	//it is possible that someone can remove a container
	//outside of us, so we let it pass that we can't remove
	//it

	request := &cpmserverapi.DockerRemoveRequest{}
	request.ContainerName = dbNode.Name
	_, err = cpmserverapi.DockerRemoveClient(url, request)
	if err != nil {
		logit.Error.Println("DeleteNode: error when trying to remove container " + err.Error())
	}

	//send the server a deletevolume command
	request2 := &cpmserverapi.DiskDeleteRequest{}
	request2.Path = server.PGDataPath + "/" + dbNode.Name
	_, err = cpmserverapi.DiskDeleteClient(url, request2)
	if err != nil {
		fmt.Println(err.Error())
	}

	//we should not have to delete the DNS entries because
	//of the dnsbridge, it should remove them when we remove
	//the containers via the docker api

	w.WriteHeader(http.StatusOK)
	status := SimpleStatus{}
	status.Status = "OK"
	w.WriteJson(&status)
}
コード例 #10
0
func ProvisionBackupJob(dbConn *sql.DB, args *BackupRequest) error {

	logit.Info.Println("backup.Provision called")
	logit.Info.Println("with scheduleid=" + args.ScheduleID)
	logit.Info.Println("with serverid=" + args.ServerID)
	logit.Info.Println("with servername=" + args.ServerName)
	logit.Info.Println("with serverip=" + args.ServerIP)
	logit.Info.Println("with containername=" + args.ContainerName)
	logit.Info.Println("with profilename=" + args.ProfileName)

	params := &cpmserverapi.DockerRunRequest{}
	params.Image = "crunchydata/cpm-backup-job"
	params.ServerID = args.ServerID
	backupcontainername := args.ContainerName + "-backup"
	params.ContainerName = backupcontainername
	params.Standalone = "false"

	//get server info
	server, err := admindb.GetServer(dbConn, params.ServerID)
	if err != nil {
		logit.Error.Println("Provision:" + err.Error())
		return err
	}

	params.PGDataPath = server.PGDataPath + "/" + backupcontainername + "/" + getFormattedDate()

	//get the docker profile settings
	var setting admindb.Setting
	setting, err = admindb.GetSetting(dbConn, "S-DOCKER-PROFILE-CPU")
	params.CPU = setting.Value
	setting, err = admindb.GetSetting(dbConn, "S-DOCKER-PROFILE-MEM")
	params.MEM = setting.Value

	params.EnvVars = make(map[string]string)

	setting, err = admindb.GetSetting(dbConn, "DOMAIN-NAME")
	if err != nil {
		logit.Error.Println("Provision:" + err.Error())
		return err
	}
	var domain = setting.Value

	params.EnvVars["BACKUP_NAME"] = backupcontainername
	params.EnvVars["BACKUP_SERVERNAME"] = server.Name
	params.EnvVars["BACKUP_SERVERIP"] = server.IPAddress
	params.EnvVars["BACKUP_SCHEDULEID"] = args.ScheduleID
	params.EnvVars["BACKUP_PROFILENAME"] = args.ProfileName
	params.EnvVars["BACKUP_CONTAINERNAME"] = args.ContainerName
	params.EnvVars["BACKUP_PATH"] = params.PGDataPath
	params.EnvVars["BACKUP_HOST"] = args.ContainerName + "." + setting.Value

	setting, err = admindb.GetSetting(dbConn, "PG-PORT")
	if err != nil {
		logit.Error.Println("Provision:" + err.Error())
		return err
	}
	params.EnvVars["BACKUP_PORT"] = setting.Value
	params.EnvVars["BACKUP_USER"] = "******"
	params.EnvVars["BACKUP_SERVER_URL"] = "cpm-backup" + "." + domain + ":" + "13000"

	//provision the volume
	request := &cpmserverapi.DiskProvisionRequest{"/tmp/foo"}
	request.Path = params.PGDataPath
	var url = "http://" + server.IPAddress + ":10001"
	_, err = cpmserverapi.DiskProvisionClient(url, request)
	if err != nil {
		logit.Error.Println(err.Error())
		return err
	}

	//run the container
	params.CommandPath = "docker-run-backup.sh"
	var response cpmserverapi.DockerRunResponse
	url = "http://" + server.IPAddress + ":10001"
	response, err = cpmserverapi.DockerRunClient(url, params)
	if err != nil {
		logit.Error.Println("Provision: " + response.Output)
		return err
	}
	logit.Info.Println("docker-run-backup.sh output=" + response.Output)

	return nil
}