package org.ovirt.engine.core.bll.host; import java.security.KeyStoreException; import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; import java.util.List; import java.util.Set; import java.util.TreeSet; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.inject.Inject; import javax.inject.Singleton; import org.apache.commons.lang.StringUtils; import org.ovirt.engine.core.bll.hostdeploy.VdsDeploy; import org.ovirt.engine.core.bll.hostdeploy.VdsDeployPackagesUnit; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.HostUpgradeManagerResult; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VDSType; import org.ovirt.engine.core.common.config.Config; import org.ovirt.engine.core.common.config.ConfigValues; import org.ovirt.engine.core.compat.Version; import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogDirector; import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogable; import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogableImpl; import org.ovirt.engine.core.utils.CorrelationIdTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Singleton public class HostUpgradeManager implements UpdateAvailable, Updateable { private static Logger log = LoggerFactory.getLogger(HostUpgradeManager.class); @Inject private AuditLogDirector auditLogDirector; @Override public HostUpgradeManagerResult checkForUpdates(final VDS host) { Collection<String> packages = getPackagesForCheckUpdate(host.getVdsType(), host.getClusterCompatibilityVersion()); try (final VdsDeploy hostPackagesManager = createPackagesManager(host, false)) { VdsDeployPackagesUnit unit = new VdsDeployPackagesUnit(packages, true); hostPackagesManager.addUnit(unit); hostPackagesManager.execute(); Collection<String> availablePackages = unit.getUpdates(); boolean updatesAvailable = !availablePackages.isEmpty(); HostUpgradeManagerResult hostUpgradeManagerResult = new HostUpgradeManagerResult(); hostUpgradeManagerResult.setUpdatesAvailable(updatesAvailable); if (updatesAvailable) { hostUpgradeManagerResult.setAvailablePackages(availablePackages); log.info("There are available packages ({}) for host '{}'", StringUtils.join(availablePackages, ", "), host.getName()); AuditLogable auditLog = new AuditLogableImpl(); auditLog.setVdsId(host.getId()); auditLog.setVdsName(host.getName()); Set<String> relevantPackages = filterPackages(packages, availablePackages); if (relevantPackages.isEmpty()) { auditLogDirector.log(auditLog, AuditLogType.HOST_UPDATES_ARE_AVAILABLE); } else { auditLog.addCustomValue("Packages", StringUtils.join(relevantPackages, ",")); auditLogDirector.log(auditLog, AuditLogType.HOST_UPDATES_ARE_AVAILABLE_WITH_PACKAGES); } } return hostUpgradeManagerResult; } catch (final Exception e) { throw new RuntimeException(e.getMessage(), e); } } private Set<String> filterPackages(Collection<String> queriedPackages, Collection<String> reportedPackages) { Set<String> filtered = new TreeSet<>(); for (String reportedPackage : reportedPackages) { for (String queriedPackage : queriedPackages) { if (StringUtils.startsWith(reportedPackage, queriedPackage)) { filtered.add(queriedPackage); } } } return filtered; } @Override public EnumSet<VDSType> getHostTypes() { return EnumSet.of(VDSType.VDS, VDSType.oVirtNode); } @Override public void update(final VDS host) { Collection<String> packages = getPackagesForCheckUpdate(host.getVdsType(), host.getClusterCompatibilityVersion()); try (final VdsDeploy hostPackagesManager = createPackagesManager(host, true)) { hostPackagesManager.addUnit(new VdsDeployPackagesUnit(packages, false)); hostPackagesManager.execute(); } catch (final Exception e) { log.error("Failed to update host '{}' packages '{}': {}", host.getName(), StringUtils.join(packages, ", "), e.getMessage()); log.debug("Exception", e); throw new RuntimeException(e); } } private VdsDeploy createPackagesManager(final VDS host, boolean alertLog) throws KeyStoreException { final VdsDeploy hostPackagesManager = new VdsDeploy("ovirt-host-mgmt", host, alertLog); hostPackagesManager.useDefaultKeyPair(); hostPackagesManager.setCorrelationId(CorrelationIdTracker.getCorrelationId()); return hostPackagesManager; } protected static Collection<String> getPackagesForCheckUpdate(VDSType hostType, Version version) { List<String> systemPackages = new ArrayList<>(); List<String> userPackages = new ArrayList<>(); if (hostType == VDSType.VDS) { systemPackages = Config.getValue(ConfigValues.PackageNamesForCheckUpdate, version.toString()); userPackages = Config.getValue(ConfigValues.UserPackageNamesForCheckUpdate); } else if (hostType == VDSType.oVirtNode) { systemPackages = Config.getValue(ConfigValues.OvirtNodePackageNamesForCheckUpdate); } return Stream.concat(systemPackages.stream(), userPackages.stream().filter(StringUtils::isNotEmpty)).collect(Collectors.toSet()); } }