func (vm SoftLayerVM) DetachDisk(disk bslcdisk.Disk) error { virtualGuest, volume, err := vm.fetchVMandIscsiVolume(vm.ID(), disk.ID()) if err != nil { return bosherr.WrapError(err, fmt.Sprintf("failed in disk `%d` from virtual gusest `%d`", disk.ID(), virtualGuest.Id)) } hasMultiPath, err := vm.hasMulitPathToolBasedOnShellScript(virtualGuest) if err != nil { return bosherr.WrapError(err, fmt.Sprintf("Failed to get multipath information from virtual guest `%d`", virtualGuest.Id)) } err = vm.detachVolumeBasedOnShellScript(virtualGuest, volume, hasMultiPath) if err != nil { return bosherr.WrapErrorf(err, "Failed to detach volume with id %d from virtual guest with id: %d.", volume.Id, virtualGuest.Id) } networkStorageService, err := vm.softLayerClient.GetSoftLayer_Network_Storage_Service() if err != nil { return bosherr.WrapError(err, "Cannot get network storage service.") } allowed, err := networkStorageService.HasAllowedVirtualGuest(disk.ID(), vm.ID()) if err == nil && allowed == true { err = networkStorageService.DetachIscsiVolume(virtualGuest, disk.ID()) } if err != nil { return bosherr.WrapError(err, fmt.Sprintf("Failed to revoke access of disk `%d` from virtual gusest `%d`", disk.ID(), virtualGuest.Id)) } oldAgentEnv, err := vm.agentEnvService.Fetch() if err != nil { return bosherr.WrapErrorf(err, "Failed to unmarshal userdata from virutal guest with id: %d.", virtualGuest.Id) } newAgentEnv := oldAgentEnv.DetachPersistentDisk(strconv.Itoa(disk.ID())) err = vm.agentEnvService.Update(newAgentEnv) if err != nil { return bosherr.WrapError(err, fmt.Sprintf("Configuring userdata on VirtualGuest with id: `%d`", virtualGuest.Id)) } if len(newAgentEnv.Disks.Persistent) == 1 { for key, devicePath := range newAgentEnv.Disks.Persistent { leftDiskId, err := strconv.Atoi(key) if err != nil { return bosherr.WrapError(err, fmt.Sprintf("Failed to transfer disk id %s from string to int", key)) } vm.logger.Debug(SOFTLAYER_VM_LOG_TAG, "Left Disk Id %d", leftDiskId) vm.logger.Debug(SOFTLAYER_VM_LOG_TAG, "Left Disk device path %s", devicePath) virtualGuest, volume, err := vm.fetchVMandIscsiVolume(vm.ID(), leftDiskId) if err != nil { return bosherr.WrapError(err, fmt.Sprintf("Failed to fetch disk `%d` and virtual gusest `%d`", disk.ID(), virtualGuest.Id)) } _, err = vm.discoveryOpenIscsiTargetsBasedOnShellScript(virtualGuest, volume) if err != nil { return bosherr.WrapError(err, fmt.Sprintf("Failed to reattach volume `%s` to virtual guest `%d`", key, virtualGuest.Id)) } command := fmt.Sprintf("sleep 5; mount %s-part1 /var/vcap/store", devicePath) _, err = vm.sshClient.ExecCommand(ROOT_USER_NAME, vm.getRootPassword(virtualGuest), virtualGuest.PrimaryBackendIpAddress, command) if err != nil { return bosherr.WrapError(err, "mount /var/vcap/store") } } } return nil }
func (vm SoftLayerVM) AttachDisk(disk bslcdisk.Disk) error { virtualGuest, volume, err := vm.fetchVMandIscsiVolume(vm.ID(), disk.ID()) if err != nil { return bosherr.WrapError(err, fmt.Sprintf("Failed to fetch disk `%d` and virtual gusest `%d`", disk.ID(), virtualGuest.Id)) } networkStorageService, err := vm.softLayerClient.GetSoftLayer_Network_Storage_Service() if err != nil { return bosherr.WrapError(err, "Cannot get network storage service.") } allowed, err := networkStorageService.HasAllowedVirtualGuest(disk.ID(), vm.ID()) totalTime := time.Duration(0) if err == nil && allowed == false { for totalTime < bslcommon.TIMEOUT { allowable, err := networkStorageService.AttachIscsiVolume(virtualGuest, disk.ID()) if err != nil { if !strings.Contains(err.Error(), "HTTP error code") { return bosherr.WrapError(err, fmt.Sprintf("Granting volume access to vitrual guest %d", virtualGuest.Id)) } } else { if allowable { break } } totalTime += bslcommon.POLLING_INTERVAL time.Sleep(bslcommon.POLLING_INTERVAL) } } if totalTime >= bslcommon.TIMEOUT { return bosherr.Error("Waiting for grantting access to virutal guest TIME OUT!") } hasMultiPath, err := vm.hasMulitPathToolBasedOnShellScript(virtualGuest) if err != nil { return bosherr.WrapError(err, fmt.Sprintf("Failed to get multipath information from virtual guest `%d`", virtualGuest.Id)) } deviceName, err := vm.waitForVolumeAttached(virtualGuest, volume, hasMultiPath) if err != nil { return bosherr.WrapError(err, fmt.Sprintf("Failed to attach volume `%d` to virtual guest `%d`", disk.ID(), virtualGuest.Id)) } oldAgentEnv, err := vm.agentEnvService.Fetch() if err != nil { return bosherr.WrapErrorf(err, "Failed to unmarshal userdata from virutal guest with id: %d.", virtualGuest.Id) } var newAgentEnv AgentEnv if hasMultiPath { newAgentEnv = oldAgentEnv.AttachPersistentDisk(strconv.Itoa(disk.ID()), "/dev/mapper/"+deviceName) } else { newAgentEnv = oldAgentEnv.AttachPersistentDisk(strconv.Itoa(disk.ID()), "/dev/"+deviceName) } err = vm.agentEnvService.Update(newAgentEnv) if err != nil { return bosherr.WrapError(err, fmt.Sprintf("Configuring userdata on VirtualGuest with id: `%d`", virtualGuest.Id)) } return nil }