func (p *DeployService) CreateCluster(request entity.Request) (servers []entity.Server, errorCode string, err error) { logrus.Infof("start to Deploy Docker Cluster...") sshUser := request.ProviderInfo.Provider.SshUser //Call the Docker Machines to create machines, change /etc/hosts and Replace PubKey File servers, swarmServers, mgmtServers, _, sharedServers, _, err := dockerMachineCreateCluster(request) if err != nil { logrus.Errorf("Call docker-machine to create cluster failed , err is %v", err) return } storagePath := DOCKERMACHINE_STORAGEPATH_PREFIX + request.UserName + "/" + request.ClusterName //TODO prepare ".env" file for new Cluster, need to understand whether 'slave on master' //call docker-compose to deploy the management clusters and slave clusters clusterSlaveSize := request.ClusterNumber - 1 if request.IsLinkerMgmt == false { clusterSlaveSize = request.ClusterNumber - 4 } logrus.Infof("start to Call Docker Compose") err = dockerComposeCreateCluster(request.UserName, request.ClusterName, swarmServers, clusterSlaveSize) if err != nil { logrus.Errorf("Call docker-compose to create cluster failed , err is %v", err) return } //get the first ip of mgmtServer as marathon Ip marathonEndpoint := fmt.Sprintf("%s:8080", mgmtServers[0].IpAddress) logrus.Debugf("marathon endpoint is %s", marathonEndpoint) //Start create Linker Components if request.IsLinkerMgmt { //copy the key for mongo db for _, server := range mgmtServers { commandStr := fmt.Sprintf("sudo mkdir -p /linker/key && sudo chown -R %s:%s /linker", sshUser, sshUser) _, _, err = command.ExecCommandOnMachine(server.Hostname, commandStr, storagePath) if err != nil { errorCode = DEPLOY_ERROR_COPY_CONFIG_FILE logrus.Errorf("mkdir /linker/config failed when copy dns config file", err) return } _, _, err = command.ScpToMachine(server.Hostname, "/linker/key/mongodb-keyfile", "/linker/key/mongodb-keyfile", storagePath) if err != nil { errorCode = DEPLOY_ERROR_COPY_CONFIG_FILE logrus.Errorf("copy mongodb key file to target server %s fail, err is %v", server.Hostname, err) return } } //call the marathon to deploy the linker service containers for Linker-Management Cluster payload := prepareLinkerComponents(mgmtServers, swarmServers[0]) deploymentId, _ := GetMarathonService().CreateGroup(payload, marathonEndpoint) flag, errDeploy := waitForMarathon(deploymentId, marathonEndpoint) if flag { if errDeploy != nil { errorCode = DEPLOY_ERROR_CREATE err = errDeploy logrus.Errorf("deploy the linker management components fail, err is %v", errDeploy) return } else { logrus.Infof("deploy the linker management components finished successfully...") } } else { errorCode = DEPLOY_ERROR_CREATE err = errDeploy logrus.Errorf("deploy the linker management components fail because of timeout, err is %v", errDeploy) return } } //call the marathon to deploy the mesos-UI for Linker-Management Cluster and User-Management Cluster logrus.Infof("Start to deploy the linker ui ...") payload := prepareMesosUI(mgmtServers, sharedServers[0], request.IsLinkerMgmt) deploymentId, _ := GetMarathonService().CreateGroup(payload, marathonEndpoint) logrus.Infof("Start to deploy the linker ui with deployment Id: %s", deploymentId) flag, errDeploy := waitForMarathon(deploymentId, marathonEndpoint) if flag { if errDeploy != nil { errorCode = DEPLOY_ERROR_CREATE err = errDeploy logrus.Errorf("deploy the linker ui and user mgmt components fail, err is %v", errDeploy) return } else { logrus.Infof("deploy the linker ui and user mgmt components finished successfully...") } } else { errorCode = DEPLOY_ERROR_CREATE err = errDeploy logrus.Errorf("deploy the linker ui and user mgmt components fail because of timeout, err is %v", errDeploy) return } return }
func dockerMachineCreateCluster(request entity.Request) (servers, swarmServers, mgmtServers, dnsServers, sharedServers []entity.Server, errorCode string, err error) { sshUser := request.ProviderInfo.Provider.SshUser storagePath := DOCKERMACHINE_STORAGEPATH_PREFIX + request.UserName + "/" + request.ClusterName var slaveServers []entity.Server isLinkerMgmt := request.IsLinkerMgmt requestIdLabel := entity.Label{Key: "requestId", Value: request.RequestId} masterLabel := entity.Label{Key: "master", Value: "true"} slaveLabel := entity.Label{Key: "slave", Value: "true"} //create Server and install consule labels := []entity.Label{} labels = append(labels, requestIdLabel) consuleServer, _, err := GetDockerMachineService().Create(request.UserName, request.ClusterName, false, false, "", request.ProviderInfo, labels) consuleServer.IsConsul = true _, _, err = command.BootUpConsul(consuleServer.Hostname, consuleServer.StoragePath) if err != nil { err = errors.New("Bootup Consul server error!") return } servers = append(servers, consuleServer) if isLinkerMgmt { labels := []entity.Label{} labels = append(labels, masterLabel) labels = append(labels, slaveLabel) labels = append(labels, requestIdLabel) //create Server, install Swarm Master and Label as Mgmt and Slave Node swarmMasterServer, _, _ := GetDockerMachineService().Create(request.UserName, request.ClusterName, true, true, consuleServer.Hostname, request.ProviderInfo, labels) swarmMasterServer.IsMaster = true swarmMasterServer.IsSlave = true swarmMasterServer.IsSwarmMaster = true swarmServers = append(swarmServers, swarmMasterServer) mgmtServers = append(mgmtServers, swarmMasterServer) dnsServers = append(dnsServers, swarmMasterServer) servers = append(servers, swarmMasterServer) //create Server, install Swarm Slave and Label as Mgmt and Slave Node for i := 0; i < request.ClusterNumber-2; i++ { server, _, _ := GetDockerMachineService().Create(request.UserName, request.ClusterName, true, false, consuleServer.Hostname, request.ProviderInfo, labels) server.IsMaster = true server.IsSlave = true swarmServers = append(swarmServers, server) mgmtServers = append(mgmtServers, server) dnsServers = append(dnsServers, server) servers = append(servers, server) } } else { labels := []entity.Label{} labels = append(labels, masterLabel) labels = append(labels, requestIdLabel) //create Server, install Swarm Master and Label as MgmtOnly Node swarmMasterServer, _, _ := GetDockerMachineService().Create(request.UserName, request.ClusterName, true, true, consuleServer.Hostname, request.ProviderInfo, labels) swarmMasterServer.IsMaster = true swarmMasterServer.IsSwarmMaster = true swarmMasterServer.IsDnsServer = true swarmServers = append(swarmServers, swarmMasterServer) mgmtServers = append(mgmtServers, swarmMasterServer) servers = append(servers, swarmMasterServer) dnsServers = append(dnsServers, swarmMasterServer) //create Server, install Swarm Slave and Label as Mgmt Node for i := 0; i < 2; i++ { server, _, _ := GetDockerMachineService().Create(request.UserName, request.ClusterName, true, false, consuleServer.Hostname, request.ProviderInfo, labels) server.IsMaster = true server.IsDnsServer = true //TODO : install lb and dns on the master by swarm swarmServers = append(swarmServers, server) mgmtServers = append(mgmtServers, server) servers = append(servers, server) dnsServers = append(dnsServers, server) } slavelabels := []entity.Label{} slavelabels = append(slavelabels, slaveLabel) slavelabels = append(slavelabels, requestIdLabel) //create Server, install Swarm Slave and Label as Slave Node for i := 0; i < request.ClusterNumber-4; i++ { server, _, _ := GetDockerMachineService().Create(request.UserName, request.ClusterName, true, false, consuleServer.Hostname, request.ProviderInfo, slavelabels) server.IsSlave = true swarmServers = append(swarmServers, server) servers = append(servers, server) slaveServers = append(slaveServers, server) //choose the first slave server as shared server } } //prepare the dns config and copy to all managements nodes logrus.Infof("start to prepare the dns config ") err = changeDnsConfig(mgmtServers) if err != nil { errorCode = DEPLOY_ERROR_CHANGE_DNSCONFIG return } //copy the dns config file to target dns server logrus.Infof("start to copy the dns config file to target dns server") for _, server := range dnsServers { commandStr := fmt.Sprintf("sudo mkdir -p /linker/config && sudo chown -R %s:%s /linker", sshUser, sshUser) _, _, err = command.ExecCommandOnMachine(server.Hostname, commandStr, storagePath) if err != nil { errorCode = DEPLOY_ERROR_COPY_CONFIG_FILE logrus.Errorf("mkdir /linker/config failed when copy dns config file", err) return } _, _, err = command.ScpToMachine(server.Hostname, "/linker/config/config.json", "/linker/config/config.json", storagePath) if err != nil { errorCode = DEPLOY_ERROR_COPY_CONFIG_FILE logrus.Errorf("copy dns config file to target server %s fail, err is %v", server.Hostname, err) return } } //Change "/etc/resolve.conf" if Linker Management Cluster logrus.Infof("start to change name server for all nodes") err = changeNameserver(swarmServers, dnsServers, storagePath, request.IsLinkerMgmt) if err != nil { errorCode = DEPLOY_ERROR_CHANGE_NAMESERVER return } //weave should be boot after dns configured var weaveServer entity.Server for i, server := range slaveServers { if i == 0 { weaveServer = server sharedServers = append(sharedServers, weaveServer) } _, _, err = command.BootUpWeave(server.Hostname, server.StoragePath, weaveServer.PrivateIpAddress) if err != nil { err = errors.New("Bootup Weave error!") return } } return }