package org.zstack.appliancevm;
import org.springframework.beans.factory.annotation.Autowired;
import org.zstack.core.CoreGlobalProperty;
import org.zstack.core.db.DatabaseFacade;
import org.zstack.core.errorcode.ErrorFacade;
import org.zstack.header.errorcode.OperationFailureException;
import org.zstack.header.vm.VmBeforeCreateOnHypervisorExtensionPoint;
import org.zstack.header.vm.VmBeforeStartOnHypervisorExtensionPoint;
import org.zstack.header.vm.VmInstanceSpec;
import org.zstack.header.vm.VmNicInventory;
import org.zstack.utils.*;
import org.zstack.utils.function.Function;
import org.zstack.utils.logging.CLogger;
/**
*/
public class ApplianceVmManagementIpChecker implements VmBeforeCreateOnHypervisorExtensionPoint, VmBeforeStartOnHypervisorExtensionPoint {
private static final CLogger logger = Utils.getLogger(ApplianceVmManagementIpChecker.class);
@Autowired
private DatabaseFacade dbf;
@Autowired
private ErrorFacade errf;
private void checkManagementIp(VmInstanceSpec spec, boolean isNewCreated) {
if (CoreGlobalProperty.UNIT_TEST_ON) {
return;
}
if (!ApplianceVmConstant.APPLIANCE_VM_TYPE.equals(spec.getVmInventory().getType())) {
return;
}
VmNicInventory mgmtNic;
if (isNewCreated) {
final ApplianceVmSpec aspec = spec.getExtensionData(ApplianceVmConstant.Params.applianceVmSpec.toString(), ApplianceVmSpec.class);
mgmtNic = CollectionUtils.find(spec.getDestNics(), new Function<VmNicInventory, VmNicInventory>() {
@Override
public VmNicInventory call(VmNicInventory arg) {
return arg.getL3NetworkUuid().equals(aspec.getManagementNic().getL3NetworkUuid()) ? arg : null;
}
});
} else {
ApplianceVmInventory apvm = ApplianceVmInventory.valueOf(dbf.findByUuid(spec.getVmInventory().getUuid(), ApplianceVmVO.class));
mgmtNic = apvm.getManagementNic();
}
DebugUtils.Assert(mgmtNic!=null, String.format("cannot find management nic of appliance vm[uuid:%s, newCreated: %s]", spec.getVmInventory().getUuid(), isNewCreated));
ShellResult ret = ShellUtils.runAndReturn(String.format("ping -c 1 -W 1 %s", mgmtNic.getIp()));
if (ret.isReturnCode(0)) {
throw new OperationFailureException(errf.instantiateErrorCode(ApplianceVmErrors.MANAGEMENT_IP_OCCUPIED,
String.format("the management nic IP[%s] has been occupied by another device in the data center, we can ping it", mgmtNic.getIp())
));
}
}
@Override
public void beforeCreateVmOnHypervisor(VmInstanceSpec spec) {
checkManagementIp(spec, true);
}
@Override
public void beforeStartVmOnHypervisor(VmInstanceSpec spec) {
checkManagementIp(spec, false);
}
}