func (glusterfsCluster *GlusterfsCluster) GetAllVolume() ([]GlusterfsVolume, error) { host, err := glusterfsCluster.getAvailableHost() if err != nil { return nil, err } commandSlice := make([]string, 0) commandSlice = append(commandSlice, "sudo gluster volume info\n") interactiveMap := make(map[string]string) interactiveMap["[sudo]"] = glusterfsCluster.SSHPassword + "\n" resultSlice, err := sshclient.InteractiveSSH( glusterfsCluster.SSHDialTimeout, glusterfsCluster.SSHSessionTimeout, *host, glusterfsCluster.SSHPort, glusterfsCluster.SSHUser, glusterfsCluster.SSHPassword, commandSlice, interactiveMap) glusterfsVolumeSlice, err := glusterfsCluster.parseVolumeInfo(resultSlice[0]) if err != nil { log.Error("Parse volume info error %s", err) return nil, err } else { return glusterfsVolumeSlice, nil } }
func (glusterfsCluster *GlusterfsCluster) GetHostStatus() map[string]bool { commandSlice := make([]string, 0) commandSlice = append(commandSlice, "exit\n") hostStatusMap := make(map[string]bool) for _, host := range glusterfsCluster.HostSlice { _, err := sshclient.InteractiveSSH( glusterfsCluster.SSHDialTimeout, glusterfsCluster.SSHSessionTimeout, host, glusterfsCluster.SSHPort, glusterfsCluster.SSHUser, glusterfsCluster.SSHPassword, commandSlice, nil) if err == nil { hostStatusMap[host] = true } else { hostStatusMap[host] = false log.Error(err) } } return hostStatusMap }
func RemoveImageFromAllHost(imageRecordSlcie []ImageRecord) error { credentialSlice, err := host.GetStorage().LoadAllCredential() if err != nil { log.Error(err) return err } amount := len(imageRecordSlcie) commandSlice := make([]string, 0) // Delete all stopped instance so image could be removed commandSlice = append(commandSlice, "sudo docker rm $(sudo docker ps -aqf status=exited | xargs)\n") for _, imageRecord := range imageRecordSlcie { commandSlice = append(commandSlice, "sudo docker rmi "+imageRecord.Path+"\n") } hasError := false buffer := bytes.Buffer{} for _, credential := range credentialSlice { if credential.Disabled == false { interactiveMap := make(map[string]string) interactiveMap["[sudo]"] = credential.SSH.Password + "\n" resultSlice, err := sshclient.InteractiveSSH( 2*time.Second, time.Duration(amount)*time.Minute, credential.IP, credential.SSH.Port, credential.SSH.User, credential.SSH.Password, commandSlice, interactiveMap) log.Info("Issue command via ssh with result:\n %v", resultSlice) if err != nil { hasError = true errorMessage := fmt.Sprintf("Error message: %v Result Output: %v .", err, resultSlice) log.Error(errorMessage) buffer.WriteString(errorMessage) } } } if hasError { return errors.New(buffer.String()) } else { return nil } }
func (glusterfsCluster *GlusterfsCluster) DeleteVolume(name string) error { host, err := glusterfsCluster.getAvailableHost() if err != nil { return err } commandBuffer := bytes.Buffer{} commandBuffer.WriteString("sudo gluster --mode=script volume delete ") commandBuffer.WriteString(name) commandBuffer.WriteString(" \n") commandSlice := make([]string, 0) commandSlice = append(commandSlice, commandBuffer.String()) interactiveMap := make(map[string]string) interactiveMap["[sudo]"] = glusterfsCluster.SSHPassword + "\n" resultSlice, err := sshclient.InteractiveSSH( glusterfsCluster.SSHDialTimeout, glusterfsCluster.SSHSessionTimeout, *host, glusterfsCluster.SSHPort, glusterfsCluster.SSHUser, glusterfsCluster.SSHPassword, commandSlice, interactiveMap) if err != nil { log.Error("Create volume error %s resultSlice %s", err, resultSlice) return err } if strings.Contains(resultSlice[0], "success") == false { log.Debug("Issue command: " + commandBuffer.String()) log.Error("Fail to delete volume with error: " + resultSlice[0]) return errors.New(resultSlice[0]) } err = GetStorage().DeleteGlusterfsVolumeCreateParameter(glusterfsCluster.Name, name) if err != nil { log.Error(err) return err } return nil }
func (glusterfsCluster *GlusterfsCluster) CleanDataOnDisk(glusterfsVolume *GlusterfsVolume) error { if glusterfsVolume != nil { for _, brick := range glusterfsVolume.Bricks { splitSlice := strings.Split(brick, ":") if len(splitSlice) != 3 { log.Error("brick format error %s", brick) return errors.New("brick format error " + brick) } brickHost := strings.TrimSpace(splitSlice[1]) brickPath := strings.TrimSpace(splitSlice[2]) commandBuffer := bytes.Buffer{} commandBuffer.WriteString("sudo rm -rf ") commandBuffer.WriteString(brickPath) commandBuffer.WriteString(" \n") commandSlice := make([]string, 0) commandSlice = append(commandSlice, commandBuffer.String()) interactiveMap := make(map[string]string) interactiveMap["[sudo]"] = glusterfsCluster.SSHPassword + "\n" resultSlice, err := sshclient.InteractiveSSH( glusterfsCluster.SSHDialTimeout, glusterfsCluster.SSHSessionTimeout, brickHost, glusterfsCluster.SSHPort, glusterfsCluster.SSHUser, glusterfsCluster.SSHPassword, commandSlice, interactiveMap) if err != nil { log.Error("Delete data on disk error %s resultSlice %s", err, resultSlice) return err } } } return nil }
func (glusterfsCluster *GlusterfsCluster) getAvailableHost() (*string, error) { commandSlice := make([]string, 0) commandSlice = append(commandSlice, "exit\n") for _, host := range glusterfsCluster.HostSlice { _, err := sshclient.InteractiveSSH( glusterfsCluster.SSHDialTimeout, glusterfsCluster.SSHSessionTimeout, host, glusterfsCluster.SSHPort, glusterfsCluster.SSHUser, glusterfsCluster.SSHPassword, commandSlice, nil) if err == nil { return &host, nil } else { log.Error(err) } } return nil, errors.New("No available host") }
func stopDockerContainer(credential Credential, containerID string) error { commandSlice := make([]string, 0) commandSlice = append(commandSlice, "sudo docker stop "+containerID+"\n") interactiveMap := make(map[string]string) interactiveMap["[sudo]"] = credential.SSH.Password + "\n" resultSlice, err := sshclient.InteractiveSSH( 2*time.Second, 3*time.Minute, credential.IP, credential.SSH.Port, credential.SSH.User, credential.SSH.Password, commandSlice, interactiveMap) if err != nil { errorMessage := fmt.Sprintf("%v %v", err, resultSlice) return errors.New(errorMessage) } else { return nil } }
func (glusterfsCluster *GlusterfsCluster) GetVolume(name string) (*GlusterfsVolume, error) { host, err := glusterfsCluster.getAvailableHost() if err != nil { return nil, err } commandSlice := make([]string, 0) commandSlice = append(commandSlice, "sudo gluster volume info "+name+"\n") interactiveMap := make(map[string]string) interactiveMap["[sudo]"] = glusterfsCluster.SSHPassword + "\n" resultSlice, err := sshclient.InteractiveSSH( glusterfsCluster.SSHDialTimeout, glusterfsCluster.SSHSessionTimeout, *host, glusterfsCluster.SSHPort, glusterfsCluster.SSHUser, glusterfsCluster.SSHPassword, commandSlice, interactiveMap) glusterfsVolumeSlice, err := glusterfsCluster.parseVolumeInfo(resultSlice[0]) if err != nil { log.Error("Parse volume info error %s", err) return nil, err } else { if len(glusterfsVolumeSlice) == 1 { return &glusterfsVolumeSlice[0], nil } else { log.Error("The result it not the only one. glusterfsVolumeSlice %s", glusterfsVolumeSlice) return nil, errors.New("The result it not the only one.") } } }
func (glusterfsCluster *GlusterfsCluster) CreateVolume(glusterfsVolumeCreateParameter *GlusterfsVolumeCreateParameter) error { host, err := glusterfsCluster.getAvailableHost() if err != nil { return err } commandBuffer := bytes.Buffer{} commandBuffer.WriteString("sudo gluster --mode=script volume create ") commandBuffer.WriteString(glusterfsVolumeCreateParameter.VolumeName) if glusterfsVolumeCreateParameter.Stripe > 0 { commandBuffer.WriteString(" stripe ") commandBuffer.WriteString(strconv.Itoa(glusterfsVolumeCreateParameter.Stripe)) } if glusterfsVolumeCreateParameter.Replica > 0 { commandBuffer.WriteString(" replica ") commandBuffer.WriteString(strconv.Itoa(glusterfsVolumeCreateParameter.Replica)) } if glusterfsVolumeCreateParameter.Arbiter > 0 { commandBuffer.WriteString(" arbiter ") commandBuffer.WriteString(strconv.Itoa(glusterfsVolumeCreateParameter.Arbiter)) } if glusterfsVolumeCreateParameter.Disperse > 0 { commandBuffer.WriteString(" disperse ") commandBuffer.WriteString(strconv.Itoa(glusterfsVolumeCreateParameter.Disperse)) } if glusterfsVolumeCreateParameter.DisperseData > 0 { commandBuffer.WriteString(" disperse-data ") commandBuffer.WriteString(strconv.Itoa(glusterfsVolumeCreateParameter.DisperseData)) } if glusterfsVolumeCreateParameter.Redundancy > 0 { commandBuffer.WriteString(" redundancy ") commandBuffer.WriteString(strconv.Itoa(glusterfsVolumeCreateParameter.Redundancy)) } // <tcp|rdma|tcp,rdma> commandBuffer.WriteString(" transport ") commandBuffer.WriteString(glusterfsVolumeCreateParameter.Transport) uuid := random.UUID() for _, ip := range glusterfsVolumeCreateParameter.HostSlice { path := " " + ip + ":" + glusterfsCluster.Path + "/" + glusterfsVolumeCreateParameter.VolumeName + "_" + uuid commandBuffer.WriteString(path) } commandBuffer.WriteString(" force\n") commandSlice := make([]string, 0) commandSlice = append(commandSlice, commandBuffer.String()) interactiveMap := make(map[string]string) interactiveMap["[sudo]"] = glusterfsCluster.SSHPassword + "\n" resultSlice, err := sshclient.InteractiveSSH( glusterfsCluster.SSHDialTimeout, glusterfsCluster.SSHSessionTimeout, *host, glusterfsCluster.SSHPort, glusterfsCluster.SSHUser, glusterfsCluster.SSHPassword, commandSlice, interactiveMap) if err != nil { log.Error("Create volume error %s resultSlice %v", err, resultSlice) return err } if strings.Contains(resultSlice[0], "success") == false { log.Debug("Issue command: " + commandBuffer.String()) log.Error("Fail to create volume with error: " + resultSlice[0]) return errors.New(resultSlice[0]) } err = GetStorage().SaveGlusterfsVolumeCreateParameter(glusterfsVolumeCreateParameter) if err != nil { log.Error(err) return err } return nil }
func UpgradeDockerImage(ws *websocket.Conn, credentialSlice []Credential, path string, version string) error { if len(credentialSlice) == 0 { return errors.New("No credential data") } if path == "" { return errors.New("Image path can't be empty") } imageUri := path if version != "" { imageUri = imageUri + ":" + version } totalAmount := len(credentialSlice) errorChannel := make(chan error, totalAmount) for _, credential := range credentialSlice { if credential.Disabled == false { go func(credential Credential) { ws.Write([]byte("Start to pull " + imageUri + " on host " + credential.IP + "\n")) commandSlice := make([]string, 0) commandSlice = append(commandSlice, "sudo docker pull "+imageUri+"\n") interactiveMap := make(map[string]string) interactiveMap["[sudo]"] = credential.SSH.Password + "\n" resultSlice, err := sshclient.InteractiveSSH( 2*time.Second, 10*time.Minute, credential.IP, credential.SSH.Port, credential.SSH.User, credential.SSH.Password, commandSlice, interactiveMap) if err != nil { errorChannel <- err ws.Write([]byte(imageUri + " on host " + credential.IP + " has error to upgraded\n")) for _, result := range resultSlice { ws.Write([]byte(result + "\n")) } } else { errorChannel <- nil ws.Write([]byte(imageUri + " on host " + credential.IP + " is upgraded\n")) } }(credential) } else { errorChannel <- nil ws.Write([]byte("The host " + credential.IP + " is passed since it is disabled\n")) } } // Wait for all go routine to finish hasError := false errorSlice := make([]error, 0) for i := 0; i < totalAmount; i++ { err, _ := <-errorChannel if err != nil { hasError = true } errorSlice = append(errorSlice, err) } close(errorChannel) if hasError { errorMessage := fmt.Sprintf("%v", errorSlice) return errors.New(errorMessage) } else { return nil } }