package org.zstack.storage.volume;
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.header.core.Completion;
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.*;
import org.zstack.header.vm.PreVmInstantiateResourceExtensionPoint;
import org.zstack.header.vm.VmInstanceConstant.VmOperation;
import org.zstack.header.vm.VmInstanceSpec;
import org.zstack.header.vm.VmInstanceSpec.ImageSpec;
import org.zstack.header.vm.VmInstanceSpec.IsoSpec;
import org.zstack.header.vm.VmInstanceSpec.VolumeSpec;
import org.zstack.header.vm.VmInstantiateResourceException;
import org.zstack.utils.CollectionUtils;
import org.zstack.utils.Utils;
import org.zstack.utils.function.Function;
import org.zstack.utils.logging.CLogger;
import java.util.List;
import static org.zstack.utils.CollectionDSL.list;
/**
* Created by frank on 5/23/2015.
*/
@Configurable(preConstruction = true, autowire = Autowire.BY_TYPE)
public class DownloadIsoForVmExtension implements PreVmInstantiateResourceExtensionPoint {
private CLogger logger = Utils.getLogger(DownloadIsoForVmExtension.class);
@Autowired
private CloudBus bus;
@Autowired
private DatabaseFacade dbf;
private static List<VmOperation> operations;
static {
operations = list(
VmOperation.NewCreate,
VmOperation.Start,
VmOperation.Reboot
);
}
@Override
public void preBeforeInstantiateVmResource(VmInstanceSpec spec) throws VmInstantiateResourceException {
}
@Override
public void preInstantiateVmResource(final VmInstanceSpec spec, final Completion completion) {
if (spec.getDestIso() == null || !operations.contains(spec.getCurrentVmOperation())) {
completion.success();
return;
}
assert spec.getDestIso().getBackupStorageUuid() != null : "backup storage uuid cannot be null";
final String psUuid;
ImageSpec imageSpec = new ImageSpec();
final ImageInventory iso = ImageInventory.valueOf(dbf.findByUuid(spec.getDestIso().getImageUuid(), ImageVO.class));
imageSpec.setInventory(iso);
imageSpec.setSelectedBackupStorage(CollectionUtils.find(iso.getBackupStorageRefs(), new Function<ImageBackupStorageRefInventory, ImageBackupStorageRefInventory>() {
@Override
public ImageBackupStorageRefInventory call(ImageBackupStorageRefInventory arg) {
return arg.getBackupStorageUuid().equals(spec.getDestIso().getBackupStorageUuid()) ? arg : null;
}
}));
if (VmOperation.NewCreate == spec.getCurrentVmOperation()) {
VolumeSpec vspec = spec.getVolumeSpecs().get(0);
PrimaryStorageInventory pinv = vspec.getPrimaryStorageInventory();
psUuid = pinv.getUuid();
} else {
psUuid = spec.getVmInventory().getRootVolume().getPrimaryStorageUuid();
}
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(completion) {
@Override
public void run(MessageReply reply) {
if (reply.isSuccess()) {
DownloadIsoToPrimaryStorageReply re = reply.castReply();
IsoSpec isoSpec = new IsoSpec();
isoSpec.setInstallPath(re.getInstallPath());
isoSpec.setPrimaryStorageUuid(psUuid);
isoSpec.setImageUuid(iso.getUuid());
spec.setDestIso(isoSpec);
completion.success();
} else {
completion.fail(reply.getError());
}
}
});
}
@Override
public void preReleaseVmResource(VmInstanceSpec spec, final Completion completion) {
if (spec.getDestIso() != null) {
String psUuid;
if (VmOperation.NewCreate == spec.getCurrentVmOperation()) {
VolumeSpec vspec = spec.getVolumeSpecs().get(0);
PrimaryStorageInventory pinv = vspec.getPrimaryStorageInventory();
psUuid = pinv.getUuid();
} else {
psUuid = spec.getVmInventory().getRootVolume().getPrimaryStorageUuid();
}
DeleteIsoFromPrimaryStorageMsg msg = new DeleteIsoFromPrimaryStorageMsg();
msg.setVmInstanceUuid(spec.getVmInventory().getUuid());
msg.setIsoSpec(spec.getImageSpec());
msg.setPrimaryStorageUuid(psUuid);
bus.makeTargetServiceIdByResourceUuid(msg, PrimaryStorageConstant.SERVICE_ID, psUuid);
bus.send(msg, new CloudBusCallBack(completion) {
@Override
public void run(MessageReply reply) {
if (!reply.isSuccess()) {
logger.warn(reply.getError().toString());
}
completion.success();
}
});
} else {
completion.success();
}
}
}