package org.ovirt.engine.core.bll.hostdeploy; import java.util.Collections; import java.util.Map; import javax.inject.Inject; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.StringUtils; import org.ovirt.engine.core.bll.LockMessagesMatchUtil; import org.ovirt.engine.core.bll.NonTransactiveCommandAttribute; import org.ovirt.engine.core.bll.VdsCommand; import org.ovirt.engine.core.bll.context.CommandContext; import org.ovirt.engine.core.bll.network.NetworkConfigurator; import org.ovirt.engine.core.bll.network.cluster.ManagementNetworkUtil; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.action.LockProperties; import org.ovirt.engine.core.common.action.LockProperties.Scope; import org.ovirt.engine.core.common.action.hostdeploy.InstallVdsParameters; import org.ovirt.engine.core.common.businessentities.OpenstackNetworkProviderProperties; import org.ovirt.engine.core.common.businessentities.Provider; import org.ovirt.engine.core.common.businessentities.ProviderType; import org.ovirt.engine.core.common.businessentities.VDSStatus; import org.ovirt.engine.core.common.businessentities.VdsStatic; import org.ovirt.engine.core.common.errors.EngineMessage; import org.ovirt.engine.core.common.locks.LockingGroup; import org.ovirt.engine.core.common.utils.Pair; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dao.VdsStaticDao; import org.ovirt.engine.core.dao.provider.ProviderDao; import org.ovirt.engine.core.vdsbroker.ResourceManager; import org.ovirt.engine.core.vdsbroker.vdsbroker.VDSNetworkException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @NonTransactiveCommandAttribute public class InstallVdsInternalCommand<T extends InstallVdsParameters> extends VdsCommand<T> { private static Logger log = LoggerFactory.getLogger(InstallVdsInternalCommand.class); private VDSStatus vdsInitialStatus; @Inject private ManagementNetworkUtil managementNetworkUtil; @Inject private ResourceManager resourceManager; @Inject private ProviderDao providerDao; @Inject private VdsStaticDao vdsStaticDao; public InstallVdsInternalCommand(T parameters, CommandContext commandContext) { super(parameters, commandContext); } @Override protected LockProperties applyLockProperties(LockProperties lockProperties) { return lockProperties.withScope(Scope.Execution); } @Override protected boolean validate() { if (Guid.isNullOrEmpty(getVdsId())) { return failValidation(EngineMessage.VDS_INVALID_SERVER_ID); } if (getVds() == null) { return failValidation(EngineMessage.ACTION_TYPE_FAILED_HOST_NOT_EXIST); } return true; } @Override public AuditLogType getAuditLogTypeValue() { AuditLogType result = null; if (getSucceeded()) { result = AuditLogType.VDS_INSTALL; } else { // In case of failure - add to audit log the error as achieved from // the host addCustomValue("FailedInstallMessage", getErrorMessage(_failureMessage)); result = AuditLogType.VDS_INSTALL_FAILED; } return result; } @Override protected void executeCommand() { if (getVds() == null) { return; } vdsInitialStatus = getVds().getStatus(); installHost(); } private void installHost() { try (final VdsDeploy deploy = new VdsDeploy("ovirt-host-deploy", getVds(), true)) { log.info( "Before Installation host {}, {}", getVds().getId(), getVds().getName() ); T parameters = getParameters(); deploy.setCorrelationId(getCorrelationId()); deploy.addUnit( new VdsDeployMiscUnit(), new VdsDeployVdsmUnit(), new VdsDeployPKIUnit(), new VdsDeployKdumpUnit(), new VdsDeployKernelUnit() ); if (parameters.getNetworkProviderId() != null) { Provider<?> provider = providerDao.get(parameters.getNetworkProviderId()); if (provider.getType() == ProviderType.OPENSTACK_NETWORK) { OpenstackNetworkProviderProperties agentProperties = (OpenstackNetworkProviderProperties) provider.getAdditionalProperties(); if (StringUtils.isNotBlank(parameters.getNetworkMappings())) { agentProperties.getAgentConfiguration().setNetworkMappings( parameters.getNetworkMappings() ); } deploy.addUnit(new VdsDeployOpenStackUnit(agentProperties)); } } if (parameters.getOverrideFirewall()) { switch (getVds().getVdsType()) { case VDS: case oVirtNode: deploy.addUnit(new VdsDeployIptablesUnit()); break; case oVirtVintageNode: log.warn( "Installation of Host {} will ignore Firewall Override option, since it is not supported for Host type {}", getVds().getName(), getVds().getVdsType().name() ); break; default: throw new IllegalArgumentException( String.format( "Not handled VDS type: %1$s", getVds().getVdsType() ) ); } } if (parameters.getEnableSerialConsole()) { deploy.addUnit(new VdsDeployVmconsoleUnit()); } if (MapUtils.isNotEmpty(parameters.getHostedEngineConfiguration())) { deploy.addUnit(new VdsDeployHostedEngineUnit(parameters.getHostedEngineConfiguration())); } switch (getParameters().getAuthMethod()) { case Password: deploy.setPassword(parameters.getPassword()); break; case PublicKey: deploy.useDefaultKeyPair(); break; default: throw new Exception("Invalid authentication method value was sent to InstallVdsInternalCommand"); } setVdsStatus(VDSStatus.Installing); deploy.execute(); switch (deploy.getDeployStatus()) { case Failed: throw new VdsInstallException(VDSStatus.InstallFailed, StringUtils.EMPTY); case Incomplete: markCurrentCmdlineAsStored(); throw new VdsInstallException(VDSStatus.InstallFailed, "Partial installation"); case Reboot: markCurrentCmdlineAsStored(); setVdsStatus(VDSStatus.Reboot); runSleepOnReboot(getStatusOnReboot()); break; case Complete: markCurrentCmdlineAsStored(); configureManagementNetwork(); if (!getParameters().getActivateHost() && VDSStatus.Maintenance.equals(vdsInitialStatus)) { setVdsStatus(VDSStatus.Maintenance); } else { setVdsStatus(VDSStatus.Initializing); } break; } log.info( "After Installation host {}, {}", getVds().getName(), getVds().getVdsType().name() ); setSucceeded(true); } catch (VdsInstallException e) { handleError(e, e.getStatus()); } catch (Exception e) { handleError(e, VDSStatus.InstallFailed); } } private void markCurrentCmdlineAsStored() { final VdsStatic vdsStatic = getVds().getStaticData(); vdsStaticDao.updateLastStoredKernelCmdline(vdsStatic.getId(), vdsStatic.getCurrentKernelCmdline()); } private void configureManagementNetwork() { final NetworkConfigurator networkConfigurator = new NetworkConfigurator(getVds(), getContext()); if (!networkConfigurator.awaitVdsmResponse()) { throw new VdsInstallException( VDSStatus.NonResponsive, "Network error during communication with the host" ); } try { networkConfigurator.refreshNetworkConfiguration(); networkConfigurator.createManagementNetworkIfRequired(); } catch (VDSNetworkException e) { log.error("Exception", e); throw new VdsInstallException( VDSStatus.NonResponsive, "Network error during communication with the host", e ); } catch (Exception e) { log.error("Exception", e); throw new VdsInstallException( VDSStatus.NonOperational, "Failed to configure management network on the host", e ); } } @Override protected Map<String, Pair<String, String>> getExclusiveLocks() { return Collections.singletonMap( getParameters().getVdsId().toString(), LockMessagesMatchUtil.makeLockingPair( LockingGroup.VDS, EngineMessage.ACTION_TYPE_FAILED_OBJECT_LOCKED ) ); } private VDSStatus getStatusOnReboot() { if (getParameters().getActivateHost()) { return VDSStatus.NonResponsive; } return VDSStatus.Maintenance.equals(vdsInitialStatus) ? VDSStatus.Maintenance : VDSStatus.NonResponsive; } }