package org.zstack.compute.vm; import org.springframework.beans.factory.annotation.Autowire; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.zstack.core.cloudbus.CloudBus; import org.zstack.core.cloudbus.CloudBusCallBack; import org.zstack.core.db.DatabaseFacade; import org.zstack.core.db.SimpleQuery; import org.zstack.core.db.SimpleQuery.Op; import org.zstack.core.errorcode.ErrorFacade; import org.zstack.header.core.workflow.FlowTrigger; import org.zstack.header.core.workflow.NoRollbackFlow; import org.zstack.header.errorcode.OperationFailureException; import org.zstack.header.host.HostInventory; import org.zstack.header.image.ImageBackupStorageRefInventory; import org.zstack.header.image.ImageInventory; import org.zstack.header.image.ImageVO; import org.zstack.header.message.MessageReply; import org.zstack.header.storage.primary.DownloadIsoToPrimaryStorageMsg; import org.zstack.header.storage.primary.DownloadIsoToPrimaryStorageReply; import org.zstack.header.storage.primary.PrimaryStorageConstant; import org.zstack.header.vm.VmInstanceConstant; import org.zstack.header.vm.VmInstanceSpec; import org.zstack.header.vm.VmInstanceSpec.ImageSpec; import org.zstack.header.volume.VolumeVO; import org.zstack.header.volume.VolumeVO_; import org.zstack.utils.CollectionUtils; import org.zstack.utils.function.Function; import static org.zstack.core.Platform.operr; import java.util.Map; /** * Created by frank on 10/17/2015. */ @Configurable(preConstruction = true, autowire = Autowire.BY_TYPE) public class VmDownloadIsoFlow extends NoRollbackFlow { @Autowired private CloudBus bus; @Autowired private DatabaseFacade dbf; @Autowired private ErrorFacade errf; @Override public void run(final FlowTrigger trigger, Map data) { final VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); final ImageInventory iso = ImageInventory.valueOf(dbf.findByUuid(spec.getDestIso().getImageUuid(), ImageVO.class)); SimpleQuery<VolumeVO> q = dbf.createQuery(VolumeVO.class); q.select(VolumeVO_.primaryStorageUuid); q.add(VolumeVO_.uuid, Op.EQ, spec.getVmInventory().getRootVolumeUuid()); final String psUuid = q.findValue(); final HostInventory host = spec.getDestHost(); ImageBackupStorageSelector selector = new ImageBackupStorageSelector(); selector.setImageUuid(iso.getUuid()); selector.setZoneUuid(host.getZoneUuid()); final String bsUuid = selector.select(); if (bsUuid == null) { throw new OperationFailureException(operr("cannot find the iso[uuid:%s] in any connected backup storage attached to the zone[uuid:%s]. check below:\n" + "1. if the backup storage is attached to the zone where the VM[name: %s, uuid:%s] is running\n" + "2. if the backup storage is in connected status, if not, try reconnecting it", iso.getUuid(), host.getZoneUuid(), spec.getVmInventory().getName(), spec.getVmInventory().getUuid()) ); } ImageSpec imageSpec = new ImageSpec(); imageSpec.setSelectedBackupStorage(CollectionUtils.find(iso.getBackupStorageRefs(), new Function<ImageBackupStorageRefInventory, ImageBackupStorageRefInventory>() { @Override public ImageBackupStorageRefInventory call(ImageBackupStorageRefInventory arg) { return arg.getBackupStorageUuid().equals(bsUuid) ? arg : null; } })); imageSpec.setInventory(iso); DownloadIsoToPrimaryStorageMsg msg = new DownloadIsoToPrimaryStorageMsg(); msg.setPrimaryStorageUuid(psUuid); msg.setIsoSpec(imageSpec); msg.setVmInstanceUuid(spec.getVmInventory().getUuid()); msg.setDestHostUuid(spec.getDestHost().getUuid()); bus.makeTargetServiceIdByResourceUuid(msg, PrimaryStorageConstant.SERVICE_ID, psUuid); bus.send(msg, new CloudBusCallBack(trigger) { @Override public void run(MessageReply reply) { if (!reply.isSuccess()) { trigger.fail(reply.getError()); return; } DownloadIsoToPrimaryStorageReply r = reply.castReply(); spec.getDestIso().setInstallPath(r.getInstallPath()); spec.getDestIso().setPrimaryStorageUuid(psUuid); trigger.next(); } }); } }