/** * Copyright (c) 2009--2015 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.redhat.rhn.manager.action; import com.redhat.rhn.common.conf.Config; import com.redhat.rhn.common.conf.ConfigDefaults; import com.redhat.rhn.common.db.datasource.DataResult; import com.redhat.rhn.common.db.datasource.ModeFactory; import com.redhat.rhn.common.db.datasource.SelectMode; import com.redhat.rhn.common.db.datasource.WriteMode; import com.redhat.rhn.common.hibernate.LookupException; import com.redhat.rhn.common.localization.LocalizationService; import com.redhat.rhn.domain.action.Action; import com.redhat.rhn.domain.action.ActionFactory; import com.redhat.rhn.domain.action.ActionType; import com.redhat.rhn.domain.action.config.ConfigAction; import com.redhat.rhn.domain.action.config.ConfigUploadAction; import com.redhat.rhn.domain.action.errata.ErrataAction; import com.redhat.rhn.domain.action.image.DeployImageAction; import com.redhat.rhn.domain.action.image.DeployImageActionDetails; import com.redhat.rhn.domain.action.kickstart.KickstartAction; import com.redhat.rhn.domain.action.kickstart.KickstartActionDetails; import com.redhat.rhn.domain.action.kickstart.KickstartGuestAction; import com.redhat.rhn.domain.action.kickstart.KickstartGuestActionDetails; import com.redhat.rhn.domain.action.rhnpackage.PackageAction; import com.redhat.rhn.domain.action.script.ScriptActionDetails; import com.redhat.rhn.domain.action.script.ScriptRunAction; import com.redhat.rhn.domain.action.scap.ScapAction; import com.redhat.rhn.domain.action.scap.ScapActionDetails; import com.redhat.rhn.domain.action.server.ServerAction; import com.redhat.rhn.domain.common.FileList; import com.redhat.rhn.domain.config.ConfigChannel; import com.redhat.rhn.domain.config.ConfigFileName; import com.redhat.rhn.domain.config.ConfigRevision; import com.redhat.rhn.domain.config.ConfigurationFactory; import com.redhat.rhn.domain.errata.Errata; import com.redhat.rhn.domain.image.Image; import com.redhat.rhn.domain.image.ProxyConfig; import com.redhat.rhn.domain.kickstart.KickstartData; import com.redhat.rhn.domain.kickstart.KickstartFactory; import com.redhat.rhn.domain.org.Org; import com.redhat.rhn.domain.rhnpackage.PackageDelta; import com.redhat.rhn.domain.rhnpackage.PackageFactory; import com.redhat.rhn.domain.rhnset.RhnSet; import com.redhat.rhn.domain.rhnset.RhnSetElement; import com.redhat.rhn.domain.server.Server; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.frontend.dto.PackageMetadata; import com.redhat.rhn.frontend.listview.PageControl; import com.redhat.rhn.frontend.xmlrpc.InvalidActionTypeException; import com.redhat.rhn.manager.BaseManager; import com.redhat.rhn.manager.MissingCapabilityException; import com.redhat.rhn.manager.MissingEntitlementException; import com.redhat.rhn.manager.configuration.ConfigurationManager; import com.redhat.rhn.manager.entitlement.EntitlementManager; import com.redhat.rhn.manager.errata.ErrataManager; import com.redhat.rhn.manager.kickstart.ProvisionVirtualInstanceCommand; import com.redhat.rhn.manager.kickstart.cobbler.CobblerVirtualSystemCommand; import com.redhat.rhn.manager.kickstart.cobbler.CobblerXMLRPCHelper; import com.redhat.rhn.manager.system.SystemManager; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; import org.cobbler.Profile; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Calendar; /** * ActionManager - the singleton class used to provide Business Operations * on Actions where those operations interact with other top tier Business * Objects. * * Operations that require the Action make changes to * @version $Rev$ */ public class ActionManager extends BaseManager { private static Logger log = Logger.getLogger(ActionManager.class); // List of package names that we want to make sure we dont // remove when doing a package sync. Never remove running kernel // for instance. public static final String[] PACKAGES_NOT_REMOVABLE = {"kernel"}; /** * This was extracted to a constant from the * {@link #scheduleAction(User, Server, ActionType, String, Date)} method. At the time * it was in there, there was a comment "hmm 10?". Not sure what the hesitation is * but I wanted to retain that comment with regard to this value. */ private static final Long REMAINING_TRIES = 10L; private ActionManager() { } /** * Removes a list of actions. * @param actionIds actions to remove * @return int the number of failed action removals */ public static int removeActions(List actionIds) { int failed = 0; for (Iterator ids = actionIds.iterator(); ids.hasNext();) { Long actionId = (Long) ids.next(); failed += ActionFactory.removeAction(actionId); } return failed; } /** * Mark action as failed for specified system * @param loggedInUser The user making the request. * @param serverId server id * @param actionId The id of the Action to be set as failed * @param message Message from user, reason of this fail * @return int 1 if succeed */ public static int failSystemAction(User loggedInUser, Long serverId, Long actionId, String message) { Action action = ActionFactory.lookupByUserAndId(loggedInUser, actionId); Server server = SystemManager.lookupByIdAndUser(serverId, loggedInUser); ServerAction serverAction = ActionFactory.getServerActionForServerAndAction(server, action); Date now = Calendar.getInstance().getTime(); serverAction.setStatus(ActionFactory.STATUS_FAILED); serverAction.setResultMsg(message); serverAction.setCompletionTime(now); return 1; } /** * Retreive the specified Action, assuming that the User making the request * has the required permissions. * @param user The user making the lookup request. * @param aid The id of the Action to lookup. * @return the specified Action. * @throws com.redhat.rhn.common.hibernate.LookupException if the Action * can't be looked up. */ public static Action lookupAction(User user, Long aid) { Action returnedAction = null; if (aid == null) { return null; } returnedAction = ActionFactory.lookupByUserAndId(user, aid); //TODO: put this in the hibernate lookup query SelectMode m = ModeFactory.getMode("Action_queries", "visible_to_user"); Map<String, Object> params = new HashMap<String, Object>(); params.put("user_id", user.getId()); params.put("aid", aid); if (m.execute(params).size() < 1) { returnedAction = null; } if (returnedAction == null) { LocalizationService ls = LocalizationService.getInstance(); LookupException e = new LookupException("Could not find action with id: " + aid); e.setLocalizedTitle(ls.getMessage("lookup.jsp.title.action")); e.setLocalizedReason1(ls.getMessage("lookup.jsp.reason1.action")); e.setLocalizedReason2(ls.getMessage("lookup.jsp.reason2.action")); throw e; } return returnedAction; } /** * Lookup the last completed Action on a Server * given the user, action type and server. * This is useful especially in cases where we want to * find the last deployed config action ... * * @param user the user doing the search (needed for permssion checking) * @param type the action type of the action to be queried. * @param server the server who's latest completed action is desired. * @return the Action found or null if none exists */ public static Action lookupLastCompletedAction(User user, ActionType type, Server server) { // TODO: check on user visibility ?? return ActionFactory.lookupLastCompletedAction(user, type, server); } /** * Deletes the action set with the given label. * @param user User associated with the set of actions. * @param label Action label to be updated. */ public static void deleteActions(User user, String label) { WriteMode m = ModeFactory.getWriteMode("Action_queries", "delete_actions"); Map<String, Object> params = new HashMap<String, Object>(); params.put("user_id", user.getId()); params.put("org_id", user.getOrg().getId()); params.put("label", label); m.executeUpdate(params); } /** * Archives the action set with the given label. * @param user User associated with the set of actions. * @param label Action label to be updated. */ public static void archiveActions(User user, String label) { WriteMode m = ModeFactory.getWriteMode("Action_queries", "archive_actions"); Map<String, Object> params = new HashMap<String, Object>(); params.put("user_id", user.getId()); params.put("org_id", user.getOrg().getId()); params.put("label", label); m.executeUpdate(params); } /** * Cancels all actions in given list. * @param user User associated with the set of actions. * @param actionsToCancel List of actions to be cancelled. */ public static void cancelActions(User user, List actionsToCancel) { Iterator it = actionsToCancel.iterator(); while (it.hasNext()) { Action a = (Action) it.next(); cancelAction(user, a); } } /** * Cancels the server actions associated with a given action, and if * required deals with associated pending kickstart actions. * * Actions themselves are not deleted, only the ServerActions associated * with them. * * @param user User requesting the action be cancelled. * @param action Action to be cancelled. */ public static void cancelAction(User user, Action action) { log.debug("Cancelling action: " + action.getId() + " for user: " + user.getLogin()); // Can only top level actions: if (action.getPrerequisite() != null) { throw new ActionIsChildException(); } Set actionsToDelete = new HashSet(); actionsToDelete.add(action); actionsToDelete.addAll(ActionFactory.lookupDependentActions(action)); // Delete the server actions associated with the actions queried: StringBuilder actionsToDeleteBuffer = new StringBuilder( "Actions to be cancelled (including children):"); Iterator iter = actionsToDelete.iterator(); while (iter.hasNext()) { Action a = (Action)iter.next(); actionsToDeleteBuffer.append(" " + a.getId()); } Set servers = new HashSet(); Iterator serverActionsIter = action.getServerActions().iterator(); while (serverActionsIter.hasNext()) { ServerAction sa = (ServerAction)serverActionsIter.next(); servers.add(sa.getServer()); } KickstartFactory.failKickstartSessions(actionsToDelete, servers); ActionFactory.deleteServerActionsByParent(actionsToDelete); } /** * Deletes the archived actions * * @param user User requesting the delete action * @param actionsIds List of action ids to be deleted */ public static void deleteActionsById(User user, List actionsIds) { List<Action> actions = new ArrayList<Action>(); for (Iterator<Number> ai = actionsIds.iterator(); ai.hasNext();) { long actionId = ai.next().longValue(); Action action = ActionManager.lookupAction(user, actionId); if (action != null) { // check, whether the actions are archived if (action.getArchived() == 0) { throw new InvalidActionTypeException( "Archive following action before deletion: " + action.getId()); } actions.add(action); } } // now, delete them for (Action action : actions) { ActionFactory.remove(action); } } /** * Adds a server to an action * @param sid The server id * @param action The parent action */ public static void addServerToAction(Long sid, Action action) { ActionFactory.addServerToAction(sid, action); } /** * Adds a server to an action * @param server The server * @param action The parent action */ public static void addServerToAction(Server server, Action action) { ActionFactory.addServerToAction(server, action); } /** * Creates an errata action with the specified Org * @return The created action * @param org The org that needs the errata. * @param errata The errata pertaining to this action */ public static ErrataAction createErrataAction(Org org, Errata errata) { ErrataAction a = (ErrataAction) createErrataAction((User) null, errata); a.setOrg(org); return a; } /** * Creates an errata action * @return The created action * @param user The user scheduling errata * @param errata The errata pertaining to this action */ public static Action createErrataAction(User user, Errata errata) { ErrataAction a = (ErrataAction)ActionFactory .createAction(ActionFactory.TYPE_ERRATA); if (user != null) { a.setSchedulerUser(user); a.setOrg(user.getOrg()); } a.addErrata(errata); Object[] args = new Object[2]; args[0] = errata.getAdvisory(); args[1] = errata.getSynopsis(); a.setName(LocalizationService.getInstance().getMessage("action.name", args)); return a; } /** * Create a Config Upload action. This is a much different action from the * other config actions (doesn't involve revisions). * @param user The scheduler for this config action. * @param filenames A set of config file name ids as Longs * @param server The server for which to schedule this action. * @param channel The config channel to which files will be uploaded. * @param earliest The soonest time that this action could be executed. * @return The created upload action */ public static Action createConfigUploadAction(User user, Set filenames, Server server, ConfigChannel channel, Date earliest) { //TODO: right now, our general rule is that upload actions will //always upload into the sandbox for a system. If we ever wish to //make that a strict business rule, here is where we can verify that //the given channel is the sandbox for the given server. ConfigUploadAction a = (ConfigUploadAction)ActionFactory.createAction( ActionFactory.TYPE_CONFIGFILES_UPLOAD, earliest); a.setOrg(user.getOrg()); a.setSchedulerUser(user); a.setName(a.getActionType().getName()); //put a single row into rhnActionConfigChannel a.addConfigChannelAndServer(channel, server); //put a single row into rhnServerAction addServerToAction(server.getId(), a); //now put a row into rhnActionConfigFileName for each path we have. Iterator i = filenames.iterator(); while (i.hasNext()) { Long cfnid = (Long)i.next(); /* * We are using ConfigurationFactory to lookup the config file name * instead of ConfigurationManager. If we used ConfigurationManager, * then we couldn't have new file names because the user wouldn't * have access to them yet. */ ConfigFileName name = ConfigurationFactory.lookupConfigFileNameById(cfnid); if (name != null) { a.addConfigFileName(name, server); } } //if this is a pointless action, don't do it. if (a.getRhnActionConfigFileName().size() < 1) { return null; } ActionFactory.save(a); return a; } /** * Create a Config File Diff action. * @param user The user scheduling a diff action. * @param revisions A set of revision ids as Longs * @param serverIds A set of server ids as Longs * @return The created diff action */ public static Action createConfigDiffAction(User user, Collection<Long> revisions, Collection<Long> serverIds) { //diff actions are non-destructive, so there is no point to schedule them for any //later than now. return createConfigAction(user, revisions, serverIds, ActionFactory.TYPE_CONFIGFILES_DIFF, new Date()); } /** * Create a Config Action. * @param user The user scheduling the action. * @param revisions A set of revision ids as Longs * @param servers A set of server objects * @param type The type of config action * @param earliest The earliest time this action could execute. * @return The created config action */ public static Action createConfigActionForServers(User user, Collection<Long> revisions, Collection<Server> servers, ActionType type, Date earliest) { ConfigAction a = createConfigAction(user, type, earliest); for (Server server : servers) { checkConfigActionOnServer(type, server); ActionFactory.addServerToAction(server.getId(), a); //now that we made a server action, we must make config revision actions //which depend on the server as well. addConfigurationRevisionsToAction(user, revisions, a, server); } Set<ServerAction> sa = a.getServerActions(); if ((sa == null) || (sa.isEmpty())) { return null; } ActionFactory.save(a); return a; } /** * Adds configuration revisions to a ConfigurationAction object * @param user the user scheduling the action * @param revisions a set of revision ids as Longs * @param configAction the action to add revisions to * @param server a server object */ public static void addConfigurationRevisionsToAction(User user, Collection<Long> revisions, ConfigAction configAction, Server server) { for (Long revId : revisions) { try { ConfigRevision rev = ConfigurationManager.getInstance() .lookupConfigRevision(user, revId); ActionFactory.addConfigRevisionToAction(rev, server, configAction); } catch (LookupException e) { log.error("Failed lookup for revision " + revId + "by user " + user.getId()); } } } /** * Checks that a server can be the target of a ConfigAction * @param type type of ConfigAction * @param server a server object * @throws MissingCapabilityException if server does not have needed capabilities */ public static void checkConfigActionOnServer(ActionType type, Server server) { if (ActionFactory.TYPE_CONFIGFILES_DEPLOY.equals(type) && !SystemManager.clientCapable(server.getId(), SystemManager.CAP_CONFIGFILES_DEPLOY)) { throw new MissingCapabilityException( SystemManager.CAP_CONFIGFILES_DEPLOY, server); } } /** * Returns a new ConfigAction object * @param user the user scheduling the action * @param type type of ConfigAction * @param earliest earliest action scheduling date * @return a ConfigAction */ public static ConfigAction createConfigAction(User user, ActionType type, Date earliest) { ConfigAction a = (ConfigAction)ActionFactory.createAction(type, earliest); /** This is not localized, because the perl that prints this when the action is * rescheduled doesn't do localization. If the reschedule page ever get * converted to java, we should pass in a LS key and then simply do the lookup * on display */ a.setName(a.getActionType().getName()); a.setOrg(user.getOrg()); a.setSchedulerUser(user); return a; } /** * Create a Config Action. * @param user The user scheduling the action. * @param revisions A set of revision ids as Longs * @param serverIds A set of server ids as Longs * @param type The type of config action * @param earliest The earliest time this action could execute. * @return The created config action */ public static Action createConfigAction(User user, Collection<Long> revisions, Collection<Long> serverIds, ActionType type, Date earliest) { List <Server> servers = SystemManager.hydrateServerFromIds(serverIds, user); return createConfigActionForServers(user, revisions, servers, type, earliest); } /** * Schedule deployment of an image to a vhost. * * @return The created action * @param user The user scheduling image deployment * @param image The image that will be deployed * @param vcpus number of vcpus * @param memkb memory in Kb * @param bridge device * @param proxy proxy configuration */ public static Action createDeployImageAction(User user, Image image, Long vcpus, Long memkb, String bridge, ProxyConfig proxy) { DeployImageAction a = (DeployImageAction) ActionFactory .createAction(ActionFactory.TYPE_DEPLOY_IMAGE); if (user != null) { a.setSchedulerUser(user); a.setOrg(user.getOrg()); } DeployImageActionDetails details = new DeployImageActionDetails(); details.setParentAction(a); details.setVcpus(vcpus); details.setMemKb(memkb); details.setBridgeDevice(bridge); details.setDownloadUrl(image.getDownloadUrl()); if (proxy != null) { details.setProxyServer(proxy.getServer()); details.setProxyUser(proxy.getUser()); details.setProxyPass(new String(Base64.encodeBase64( proxy.getPass().getBytes()))); } a.setDetails(details); a.setName("Image Deployment: " + image.getName() + " - " + image.getVersion()); return a; } /** * * @param user The user scheduling the action * @param server The server the action is being scheduled for * @param type The type of the action * * @return The Action we have created * */ public static Action createBaseAction(User user, Server server, ActionType type) { Action action = ActionFactory.createAction(type); action.setSchedulerUser(user); action.setOrg(user.getOrg()); ServerAction sa = new ServerAction(); sa.setStatus(ActionFactory.STATUS_QUEUED); sa.setRemainingTries(new Long(5)); sa.setServer(server); sa.setParentAction(action); action.addServerAction(sa); return action; } /** * Stores the action in the database through hibernate * @param actionIn The action to be stored * @return action */ public static Action storeAction(Action actionIn) { return ActionFactory.save(actionIn); } /** * Reschedule the action so it can be attempted again. * * @param action Action to reschedule */ public static void rescheduleAction(Action action) { rescheduleAction(action, false); } /** * Reschedule the action so it can be attempted again. * * @param action Action to reschedule * @param onlyFailed reschedule only the ServerActions w/failed status */ public static void rescheduleAction(Action action, boolean onlyFailed) { //5 was hardcoded from perl :/ if (onlyFailed) { ActionFactory.rescheduleFailedServerActions(action, 5L); } else { ActionFactory.rescheduleAllServerActions(action, 5L); } } /** * Retrieve the list of unarchived scheduled actions for the * current user * @param user The user in question * @param pc The details of which results to return * @param age how many days old a system can be in order to count as a "recently" * scheduled action * @return A list containing the pending actions for the user */ public static DataResult recentlyScheduledActions(User user, PageControl pc, long age) { SelectMode m = ModeFactory.getMode("Action_queries", "recently_scheduled_action_list"); Map<String, Object> params = new HashMap<String, Object>(); params.put("user_id", user.getId()); params.put("org_id", user.getOrg().getId()); params.put("age", new Long(age)); if (pc != null) { return makeDataResult(params, params, pc, m); } DataResult dr = m.execute(params); dr.setTotalSize(dr.size()); return dr; } /** * Retrieve the list of all actions for a particular user. * This includes pending, completed, failed and archived actions. * @param user The user in question * @param pc The details of which results to return * @return A list containing the all actions for the user */ public static DataResult allActions(User user, PageControl pc) { return getActions(user, pc, "all_action_list"); } /** * Retrieve the list of pending actions for a particular user * @param user The user in question * @param pc The details of which results to return * @return A list containing the pending actions for the user */ public static DataResult pendingActions(User user, PageControl pc) { return getActions(user, pc, "pending_action_list"); } /** * Retrieve the list of pending actions for a particular user within the given set. * * @param user The user in question * @param pc The details of which results to return * @param setLabel Label of an RhnSet of actions IDs to limit the results to. * @return A list containing the pending actions for the user. */ public static DataResult pendingActionsInSet(User user, PageControl pc, String setLabel) { return getActions(user, pc, "pending_actions_in_set", setLabel); } /** * Retrieve the list of pending actions for a particular user within the given set. * * @param user The user in question * @param pc The details of which results to return * @param setLabel Label of an RhnSet of actions IDs to limit the results to. * @param sid Server id * @return A list containing the pending actions for the user. */ public static DataResult pendingActionsToDeleteInSet(User user, PageControl pc, String setLabel, Long sid) { SelectMode m = ModeFactory.getMode("System_queries", "pending_actions_to_delete_in_set"); Map<String, Object> params = new HashMap<String, Object>(); params.put("sid", sid); params.put("user_id", user.getId()); params.put("set_label", setLabel); if (pc != null) { return makeDataResult(params, params, pc, m); } DataResult dr = m.execute(params); dr.setTotalSize(dr.size()); dr.setElaborationParams(params); return dr; } /** * Retrieve the list of failed actions for a particular user * @param user The user in question * @param pc The details of which results to return * @return A list containing the pending actions for the user */ public static DataResult failedActions(User user, PageControl pc) { return getActions(user, pc, "failed_action_list"); } /** * Retrieve the list of completed actions for a particular user * @param user The user in question * @param pc The details of which results to return * @return A list containing the pending actions for the user */ public static DataResult completedActions(User user, PageControl pc) { return getActions(user, pc, "completed_action_list"); } /** * Retrieve the list of completed actions for a particular user * @param user The user in question * @param pc The details of which results to return * @return A list containing the pending actions for the user */ public static DataResult archivedActions(User user, PageControl pc) { return getActions(user, pc, "archived_action_list"); } /** * Helper method that does the work of getting a specific * DataResult for scheduled actions. * @param user The user in question * @param pc The details of which results to return * @param mode The mode * @return Returns a list containing the actions for the user */ private static DataResult getActions(User user, PageControl pc, String mode, String setLabel) { SelectMode m = ModeFactory.getMode("Action_queries", mode); Map<String, Object> params = new HashMap<String, Object>(); params.put("user_id", user.getId()); params.put("org_id", user.getOrg().getId()); if (setLabel != null) { params.put("set_label", setLabel); } if (pc != null) { return makeDataResult(params, params, pc, m); } Integer limit = new Config().getInt(ConfigDefaults.ACTIONS_DISPLAY_LIMIT); if (limit > 0) { m.setMaxRows(limit); } DataResult dr = m.execute(params); dr.setTotalSize(dr.size()); dr.setElaborationParams(params); return dr; } /** * Helper method that does the work of getting a specific * DataResult for scheduled actions. * @param user The user in question * @param pc The details of which results to return * @param mode The mode * @return Returns a list containing the actions for the user */ private static DataResult getActions(User user, PageControl pc, String mode) { return getActions(user, pc, mode, null); } /** * Returns the list of packages associated with a specific action. * @param aid The action id for the action in question * @param pc The details of which results to return * @return Return a list containing the packages for the action. */ public static DataResult getPackageList(Long aid, PageControl pc) { SelectMode m = ModeFactory.getMode("Package_queries", "packages_associated_with_action"); Map<String, Object> params = new HashMap<String, Object>(); params.put("aid", aid); if (pc != null) { return makeDataResult(params, params, pc, m); } DataResult dr = m.execute(params); dr.setTotalSize(dr.size()); return dr; } /** * Returns the list of errata associated with a specific action. * @param aid The action id for the action in question * @return Return a list containing the errata for the action. */ public static DataResult getErrataList(Long aid) { SelectMode m = ModeFactory.getMode("Errata_queries", "errata_associated_with_action"); Map<String, Object> params = new HashMap<String, Object>(); params.put("aid", aid); DataResult dr = m.execute(params); dr.setTotalSize(dr.size()); return dr; } /** * Returns the list of details associated with a config file upload action. * @param aid The action id for the action in question * @return Return a list containing the errata for the action. */ public static DataResult getConfigFileUploadList(Long aid) { SelectMode m = ModeFactory.getMode("config_queries", "upload_action_status"); Map<String, Object> params = new HashMap<String, Object>(); params.put("aid", aid); DataResult dr = m.execute(params); dr.setTotalSize(dr.size()); return dr; } /** * Returns the list of details associated with a config file deploy action. * @param aid The action id for the action in question * @return Return a list containing the details for the action. */ public static DataResult getConfigFileDeployList(Long aid) { SelectMode m = ModeFactory.getMode("config_queries", "config_action_revisions"); Map<String, Object> params = new HashMap<String, Object>(); params.put("aid", aid); DataResult dr = m.execute(params); dr.setTotalSize(dr.size()); return dr; } /** * Returns the list of details associated with a config file diff action. * @param aid The action id for the action in question * @return Return a list containing the details for the action. */ public static DataResult getConfigFileDiffList(Long aid) { SelectMode m = ModeFactory.getMode("config_queries", "diff_action_revisions"); Map<String, Object> params = new HashMap<String, Object>(); params.put("aid", aid); DataResult dr = m.execute(params); dr.setTotalSize(dr.size()); return dr; } /** * Retrieves the systems that have completed a given action * @param user The user in question. * @param action The Action. * @param pc The PageControl. * @param mode The DataSource mode to run * @return Returns list containing the completed systems. */ private static DataResult getActionSystems(User user, Action action, PageControl pc, String mode) { SelectMode m = ModeFactory.getMode("System_queries", mode); Map<String, Object> params = new HashMap<String, Object>(); params.put("org_id", user.getOrg().getId()); params.put("aid", action.getId()); params.put("user_id", user.getId()); if (pc != null) { return makeDataResult(params, params, pc, m); } DataResult dr = m.execute(params); dr.setTotalSize(dr.size()); return dr; } /** * Retrieves the systems that have completed a given action * @param user The user in question. * @param action The Action. * @param pc The PageControl. * @return Returns list containing the completed systems. */ public static DataResult completedSystems(User user, Action action, PageControl pc) { return getActionSystems(user, action, pc, "systems_completed_action"); } /** * Retrieves the systems that are in the process of completing * a given action * @param user The user in question. * @param action The Action. * @param pc The PageControl. * @return Returns list containing the completed systems. */ public static DataResult inProgressSystems(User user, Action action, PageControl pc) { return getActionSystems(user, action, pc, "systems_in_progress_action"); } /** * Retrieves the systems that failed completing * a given action * @param user The user in question. * @param action The Action. * @param pc The PageControl. * @return Returns list containing the completed systems. */ public static DataResult failedSystems(User user, Action action, PageControl pc) { return getActionSystems(user, action, pc, "systems_failed_action"); } /** * Schedules a package list refresh action for the given server. * @param scheduler User scheduling the action. * @param server Server for which the action affects. * @return The scheduled PackageAction */ public static PackageAction schedulePackageRefresh(User scheduler, Server server) { return (schedulePackageRefresh(scheduler, server, new Date())); } /** * Schedules a package list refresh action for the given server. * @param scheduler User scheduling the action. * @param server Server for which the action affects. * @param earliest The earliest time this action should be run. * @return The scheduled PackageAction */ public static PackageAction schedulePackageRefresh(User scheduler, Server server, Date earliest) { PackageAction pa = (PackageAction) schedulePackageAction(scheduler, (List) null, ActionFactory.TYPE_PACKAGES_REFRESH_LIST, earliest, server); storeAction(pa); return pa; } /** * Schedules a package runtransaction action. * @param scheduler User scheduling the action. * @param server Server for which the action affects. * @param pkgs List of PackageMetadata's to be run. * @param earliest The earliest time this action should be run. * @return The scheduled PackageAction */ public static PackageAction schedulePackageRunTransaction(User scheduler, Server server, List pkgs, Date earliest) { if (pkgs == null || pkgs.isEmpty()) { return null; } Action action = scheduleAction(scheduler, server, ActionFactory.TYPE_PACKAGES_RUNTRANSACTION, "Package Synchronization", new Date()); action.setEarliestAction(earliest); if (!SystemManager.clientCapable(server.getId(), "packages.runTransaction")) { // We need to schedule a hardware refresh to pull // in the packages.runTransaction capability Action hwrefresh = scheduleHardwareRefreshAction(scheduler, server, earliest); ActionFactory.save(hwrefresh); action.setPrerequisite(hwrefresh); } ActionFactory.save(action); PackageDelta pd = new PackageDelta(); pd.setLabel("delta-" + System.currentTimeMillis()); PackageFactory.save(pd); // this is SOOOO WRONG, we need to get rid of DataSource WriteMode m = ModeFactory.getWriteMode("Action_queries", "insert_package_delta_element"); for (Iterator itr = pkgs.iterator(); itr.hasNext();) { PackageMetadata pm = (PackageMetadata) itr.next(); Map<String, Object> params = new HashMap<String, Object>(); params.put("delta_id", pd.getId()); if (pm.getComparisonAsInt() == PackageMetadata.KEY_THIS_ONLY) { if (log.isDebugEnabled()) { log.debug("compare returned [KEY_THIS_ONLY]; " + "deleting package from system"); } params.put("operation", ActionFactory.TXN_OPERATION_DELETE); params.put("n", pm.getName()); params.put("v", pm.getSystem().getVersion()); params.put("r", pm.getSystem().getRelease()); String epoch = pm.getSystem().getEpoch(); params.put("e", epoch == "" ? null : epoch); params.put("a", pm.getSystem().getArch() != null ? pm.getSystem().getArch() : ""); m.executeUpdate(params); } else if (pm.getComparisonAsInt() == PackageMetadata.KEY_OTHER_ONLY) { if (log.isDebugEnabled()) { log.debug("compare returned [KEY_OTHER_ONLY]; " + "installing package to system: " + pm.getName() + "-" + pm.getOtherEvr()); } params.put("operation", ActionFactory.TXN_OPERATION_INSERT); params.put("n", pm.getName()); params.put("v", pm.getOther().getVersion()); params.put("r", pm.getOther().getRelease()); String epoch = pm.getOther().getEpoch(); params.put("e", epoch == "" ? null : epoch); params.put("a", pm.getOther().getArch() != null ? pm.getOther().getArch() : ""); m.executeUpdate(params); } else if (pm.getComparisonAsInt() == PackageMetadata.KEY_THIS_NEWER || pm.getComparisonAsInt() == PackageMetadata.KEY_OTHER_NEWER) { if (log.isDebugEnabled()) { log.debug("compare returned [KEY_THIS_NEWER OR KEY_OTHER_NEWER]; " + "deleting package [" + pm.getName() + "-" + pm.getSystemEvr() + "] from system " + "installing package [" + pm.getName() + "-" + pm.getOther().getEvr() + "] to system"); } String epoch; if (isPackageRemovable(pm.getName())) { params.put("operation", ActionFactory.TXN_OPERATION_DELETE); params.put("n", pm.getName()); params.put("v", pm.getSystem().getVersion()); params.put("r", pm.getSystem().getRelease()); epoch = pm.getSystem().getEpoch(); params.put("e", epoch == "" ? null : epoch); params.put("a", pm.getSystem().getArch() != null ? pm.getOther().getArch() : ""); m.executeUpdate(params); } params.put("operation", ActionFactory.TXN_OPERATION_INSERT); params.put("n", pm.getName()); params.put("v", pm.getOther().getVersion()); params.put("r", pm.getOther().getRelease()); epoch = pm.getOther().getEpoch(); params.put("e", epoch == "" ? null : epoch); params.put("a", pm.getOther().getArch() != null ? pm.getOther().getArch() : ""); m.executeUpdate(params); } } // this is SOOOO WRONG, we need to get rid of DataSource m = ModeFactory.getWriteMode("Action_queries", "insert_action_package_delta"); Map<String, Object> params = new HashMap<String, Object>(); params.put("action_id", action.getId()); params.put("delta_id", pd.getId()); m.executeUpdate(params); return (PackageAction) action; } // Check if we want to delete the old package when installing a // new rev of one. private static boolean isPackageRemovable(String name) { for (int i = 0; i < PACKAGES_NOT_REMOVABLE.length; i++) { log.debug("Checking: " + name + " for: " + PACKAGES_NOT_REMOVABLE[i]); if (name.equals(PACKAGES_NOT_REMOVABLE[i])) { return false; } } return true; } /** * Schedules one or more package removal actions for the given server. * @param scheduler User scheduling the action. * @param srvr Server for which the action affects. * @param pkgs The set of packages to be removed. * @param earliestAction Date of earliest action to be executed * @return Currently scheduled PackageAction */ public static PackageAction schedulePackageRemoval(User scheduler, Server srvr, RhnSet pkgs, Date earliestAction) { return (PackageAction) schedulePackageAction(scheduler, srvr, pkgs, ActionFactory.TYPE_PACKAGES_REMOVE, earliestAction); } /** * Schedules one or more package removal actions for the given server. * @param scheduler User scheduling the action. * @param srvr Server for which the action affects. * @param pkgs The list of packages to be removed. * @param earliestAction Date of earliest action to be executed * @return Currently scheduled PackageAction */ public static PackageAction schedulePackageRemoval(User scheduler, Server srvr, List<Map<String, Long>> pkgs, Date earliestAction) { return (PackageAction) schedulePackageAction(scheduler, pkgs, ActionFactory.TYPE_PACKAGES_REMOVE, earliestAction, srvr); } /** * Schedules one or more package installation actions for the given server. * @param scheduler User scheduling the action. * @param srvr Server for which the action affects. * @param pkgs The set of packages to be removed. * @param earliestAction Date of earliest action to be executed * @return Currently scheduled PackageAction */ public static PackageAction schedulePackageInstall(User scheduler, Server srvr, List pkgs, Date earliestAction) { return (PackageAction) schedulePackageAction(scheduler, pkgs, ActionFactory.TYPE_PACKAGES_UPDATE, earliestAction, srvr); } /** * Schedules one or more package verification actions for the given server. * @param scheduler User scheduling the action. * @param srvr Server for which the action affects. * @param pkgs The set of packages to be removed. * @param earliest Earliest occurrence of the script. * @return Currently scheduled PackageAction */ public static PackageAction schedulePackageVerify(User scheduler, Server srvr, RhnSet pkgs, Date earliest) { return (PackageAction) schedulePackageAction(scheduler, srvr, pkgs, ActionFactory.TYPE_PACKAGES_VERIFY, earliest); } /** * Schedules a script action for the given servers * * @param scheduler User scheduling the action. * @param sids Servers for which the action affects. * @param script The set of packages to be removed. * @param name Name of Script action. * @param earliest Earliest occurrence of the script. * @return Currently scheduled ScriptRunAction * @throws MissingCapabilityException if any server in the list is missing script.run; * schedule fails * @throws MissingEntitlementException if any server in the list is missing * Provisioning; schedule fails */ public static ScriptRunAction scheduleScriptRun(User scheduler, List<Long> sids, String name, ScriptActionDetails script, Date earliest) { checkScriptingOnServers(sids); Set<Long> sidSet = new HashSet<Long>(); sidSet.addAll(sids); ScriptRunAction sra = (ScriptRunAction) scheduleAction(scheduler, ActionFactory.TYPE_SCRIPT_RUN, name, earliest, sidSet); sra.setScriptActionDetails(script); ActionFactory.save(sra); return sra; } /** * Checks that ScriptRunActions can be run on the servers with specified * IDs. * @param sids servers' ids * @throws MissingCapabilityException if scripts cannot be run */ public static void checkScriptingOnServers(List<Long> sids) throws MissingCapabilityException { for (Long sid : sids) { if (!SystemManager.clientCapable(sid, "script.run")) { throw new MissingCapabilityException("script.run", sid); } if (!SystemManager.hasEntitlement(sid, EntitlementManager.MANAGEMENT)) { throw new MissingEntitlementException( EntitlementManager.MANAGEMENT.getHumanReadableLabel()); } } } /** * Creates a ScriptActionDetails which contains an arbitrary script to be * run by a ScriptRunAction. * @param username Username of script * @param groupname Group script runs as * @param script Script contents * @param timeout script timeout * @return ScriptActionDetails containing script to be run by ScriptRunAction */ public static ScriptActionDetails createScript(String username, String groupname, Long timeout, String script) { return ActionFactory.createScriptActionDetails(username, groupname, timeout, script); } private static Action scheduleAction(User scheduler, ActionType type, String name, Date earliestAction, Set<Long> serverIds) { Action action = createAction(scheduler, type, name, earliestAction); scheduleForExecution(action, serverIds); return action; } /** * Schedules an action for execution on one or more servers (adding rows to * rhnServerAction) * @param action the action * @param serverIds server IDs */ public static void scheduleForExecution(Action action, Set<Long> serverIds) { Map<String, Object> params = new HashMap<String, Object>(); params.put("status_id", ActionFactory.STATUS_QUEUED.getId()); params.put("tries", REMAINING_TRIES); params.put("parent_id", action.getId()); WriteMode m = ModeFactory.getWriteMode("Action_queries", "insert_server_actions"); List<Long> sidList = new ArrayList<Long>(); sidList.addAll(serverIds); m.executeUpdate(params, sidList); } /** * Creates, saves and returns a new Action * @param user the user who created this action * @param type the action type * @param name the action name * @param earliestAction the earliest execution date * @return a saved Action */ public static Action createAction(User user, ActionType type, String name, Date earliestAction) { /** * We have to relookup the type here, because most likely a static final variable * was passed in. If we use this and the .reload() gets called below * if we try to save a new action the instace of the type in the cache * will be different than the final static variable * sometimes hibernate is no fun */ ActionType lookedUpType = ActionFactory.lookupActionTypeByLabel(type.getLabel()); Action action = createScheduledAction(user, lookedUpType, name, earliestAction); ActionFactory.save(action); ActionFactory.getSession().flush(); return action; } private static Action scheduleAction(User scheduler, Server srvr, ActionType type, String name, Date earliestAction) { Action action = createScheduledAction(scheduler, type, name, earliestAction); ServerAction sa = new ServerAction(); sa.setStatus(ActionFactory.STATUS_QUEUED); sa.setRemainingTries(REMAINING_TRIES); sa.setServer(srvr); action.addServerAction(sa); sa.setParentAction(action); return action; } private static Action createScheduledAction(User scheduler, ActionType type, String name, Date earliestAction) { Action pa = ActionFactory.createAction(type); pa.setName(name); pa.setOrg(scheduler.getOrg()); pa.setSchedulerUser(scheduler); pa.setEarliestAction(earliestAction); return pa; } /** * Schedule a KickstartAction against a system * @param ksdata KickstartData to associate with this Action * @param scheduler User scheduling the action. * @param srvr Server for which the action affects. * @param earliestAction Date run the Action * @param appendString extra options to add to the action. * @param kickstartHost host that serves up the kickstart file. * @return Currently scheduled KickstartAction */ public static KickstartAction scheduleKickstartAction( KickstartData ksdata, User scheduler, Server srvr, Date earliestAction, String appendString, String kickstartHost) { if (log.isDebugEnabled()) { log.debug("scheduleKickstartAction(KickstartData ksdata=" + ksdata + ", User scheduler=" + scheduler + ", Server srvr=" + srvr + ", Date earliestAction=" + earliestAction + ", String appendString=" + appendString + ", String kickstartHost=" + kickstartHost + ") - start"); } return scheduleKickstartAction(ksdata.getPreserveFileLists(), scheduler, srvr, earliestAction, appendString, kickstartHost); } /** * Schedule a KickstartAction against a system * @param fileList file preservation lists to be included in the system records. * @param scheduler User scheduling the action. * @param srvr Server for which the action affects. * @param earliestAction Date run the Action * @param appendString extra options to add to the action. * @param kickstartHost host that serves up the kickstart file. * @return Currently scheduled KickstartAction */ public static KickstartAction scheduleKickstartAction( Set<FileList> fileList, User scheduler, Server srvr, Date earliestAction, String appendString, String kickstartHost) { if (log.isDebugEnabled()) { log.debug("scheduleKickstartAction(" + ", User scheduler=" + scheduler + ", Server srvr=" + srvr + ", Date earliestAction=" + earliestAction + ", String appendString=" + appendString + ", String kickstartHost=" + kickstartHost + ") - start"); } KickstartAction ksaction = (KickstartAction) scheduleAction(scheduler, srvr, ActionFactory.TYPE_KICKSTART_INITIATE, ActionFactory.TYPE_KICKSTART_INITIATE.getName(), earliestAction); KickstartActionDetails kad = new KickstartActionDetails(); kad.setAppendString(appendString); kad.setParentAction(ksaction); kad.setKickstartHost(kickstartHost); ksaction.setKickstartActionDetails(kad); if (fileList != null) { for (FileList list : fileList) { kad.addFileList(list); } } return ksaction; } /** * Schedule a KickstartGuestAction against a system * @param pcmd most information needed to create this action * @param ksSessionId Kickstart Session ID to associate with this action * @return Currently scheduled KickstartAction */ public static KickstartGuestAction scheduleKickstartGuestAction( ProvisionVirtualInstanceCommand pcmd, Long ksSessionId ) { KickstartGuestAction ksAction = (KickstartGuestAction) scheduleAction(pcmd.getUser(), pcmd.getHostServer(), ActionFactory.TYPE_KICKSTART_INITIATE_GUEST, ActionFactory.TYPE_KICKSTART_INITIATE_GUEST.getName(), pcmd.getScheduleDate()); KickstartGuestActionDetails kad = new KickstartGuestActionDetails(); kad.setAppendString(pcmd.getExtraOptions()); kad.setParentAction(ksAction); kad.setDiskGb(pcmd.getLocalStorageSize()); kad.setMemMb(pcmd.getMemoryAllocation().longValue()); kad.setDiskPath(pcmd.getFilePath()); kad.setVcpus(new Long(pcmd.getVirtualCpus())); kad.setGuestName(pcmd.getGuestName()); kad.setMacAddress(pcmd.getMacAddress()); kad.setKickstartSessionId(ksSessionId); Profile cProfile = Profile.lookupById(CobblerXMLRPCHelper.getConnection( pcmd.getUser()), pcmd.getKsdata().getCobblerId()); if (pcmd.getVirtBridge() == null) { kad.setVirtBridge(cProfile.getVirtBridge()); } else { kad.setVirtBridge(pcmd.getVirtBridge()); } CobblerVirtualSystemCommand vcmd = new CobblerVirtualSystemCommand( pcmd.getServer(), cProfile.getName(), pcmd.getGuestName(), pcmd.getKsdata()); kad.setCobblerSystemName(vcmd.getCobblerSystemRecordName()); String hostname = pcmd.getKickstartServerName(); if (pcmd.getProxyHost() != null) { hostname = pcmd.getProxyHost(); } kad.setKickstartHost(hostname); ksAction.setKickstartGuestActionDetails(kad); return ksAction; } /** * Schedule a scheduleRebootAction against a system * @param scheduler User scheduling the action. * @param srvr Server for which the action affects. * @param earliestAction Date run the Action * @return Currently scheduled KickstartAction */ public static Action scheduleRebootAction(User scheduler, Server srvr, Date earliestAction) { return scheduleAction(scheduler, srvr, ActionFactory.TYPE_REBOOT, ActionFactory.TYPE_REBOOT.getName(), earliestAction); } /** * Schedule a KickstartAction against a system * @param scheduler User scheduling the action. * @param srvr Server for which the action affects. * @param earliestAction Date run the Action * @return Currently scheduled KickstartAction */ public static Action scheduleHardwareRefreshAction(User scheduler, Server srvr, Date earliestAction) { return scheduleAction(scheduler, srvr, ActionFactory.TYPE_HARDWARE_REFRESH_LIST, ActionFactory.TYPE_HARDWARE_REFRESH_LIST.getName(), earliestAction); } /** * Schedule a scheduleHardwareRefreshAction against a system or systems * @param scheduler User scheduling the action. * @param earliestAction Date run the Action * @param serverIds server ids meant for the action * @return Currently scheduled KickstartAction */ public static Action scheduleHardwareRefreshAction(User scheduler, Date earliestAction, Set<Long> serverIds) { return scheduleAction(scheduler, ActionFactory.TYPE_HARDWARE_REFRESH_LIST, ActionFactory.TYPE_HARDWARE_REFRESH_LIST.getName(), earliestAction, serverIds); } /** * Schedules all Errata for the given system. * @param scheduler Person scheduling the action. * @param srvr Server whose errata is going to be scheduled. * @param earliest Earliest possible time action will occur. */ public static void scheduleAllErrataUpdate(User scheduler, Server srvr, Date earliest) { // Do not elaborate, we need only the IDs in here DataResult<Errata> errata = SystemManager.unscheduledErrata(scheduler, srvr.getId(), null); List<Long> errataIds = new ArrayList<Long>(); for (Errata e : errata) { errataIds.add(e.getId()); } List<Long> serverIds = Arrays.asList(srvr.getId()); ErrataManager.applyErrata(scheduler, errataIds, earliest, serverIds); } /** * Schedules an install of a package * @param scheduler The user scheduling the action. * @param srvr The server that this action is for. * @param nameId nameId rhnPackage.name_id * @param evrId evrId of package * @param archId archId of package * @return The action that has been scheduled. */ public static Action schedulePackageInstall(User scheduler, Server srvr, Long nameId, Long evrId, Long archId) { List packages = new LinkedList(); Map row = new HashMap(); row.put("name_id", nameId); row.put("evr_id", evrId); row.put("arch_id", archId); packages.add(row); return schedulePackageInstall(scheduler, srvr, packages, new Date()); } /** * Schedules a package action of the given type for the given server with the * packages given as a list. * @param scheduler The user scheduling the action. * @param pkgs A list of maps containing keys 'name_id', 'evr_id' and * optional 'arch_id' with Long values. * @param type The type of the package action. One of the static types found in * ActionFactory * @param earliestAction The earliest time that this action could happen. * @param servers The server(s) that this action is for. * @return The action that has been scheduled. */ public static Action schedulePackageAction(User scheduler, List pkgs, ActionType type, Date earliestAction, Server...servers) { Set<Long> serverIds = new HashSet<Long>(); for (Server s : servers) { serverIds.add(s.getId()); } return schedulePackageAction(scheduler, pkgs, type, earliestAction, serverIds); } /** * Schedules a package action of the given type for the given server with the * packages given as a list. * @param scheduler The user scheduling the action. * @param pkgs A list of maps containing keys 'name_id', 'evr_id' and * optional 'arch_id' with Long values. * @param type The type of the package action. One of the static types found in * ActionFactory * @param earliestAction The earliest time that this action could happen. * @param serverIds The server ids that this action is for. * @return The action that has been scheduled. */ public static Action schedulePackageAction(User scheduler, List pkgs, ActionType type, Date earliestAction, Set<Long> serverIds) { String name = getActionName(type); Action action = scheduleAction(scheduler, type, name, earliestAction, serverIds); ActionFactory.save(action); addPackageActionDetails(action, pkgs); return action; } /** * Adds package details to an Action * @param action the action * @param packages A list of maps containing keys 'name_id', 'evr_id' and * optional 'arch_id' with Long values. */ public static void addPackageActionDetails(Action action, List packages) { if (packages != null) { // for each item in the set create a package action detail // I'm using datasource to insert the records instead of // hibernate. It seems terribly inefficient to lookup a // packagename and packageevr object to insert the ids into the // correct table if I already have the ids. for (Iterator itr = packages.iterator(); itr.hasNext();) { Map rse = (Map) itr.next(); Map<String, Object> params = new HashMap<String, Object>(); Long nameId = (Long) rse.get("name_id"); Long evrId = (Long) rse.get("evr_id"); Long archId = (Long) rse.get("arch_id"); if (nameId == null || evrId == null) { throw new IllegalArgumentException("name_id or " + "evr_id are not in the Map passed into " + "this method. Please populate the Map " + "with the name_id and evr_id items"); } params.put("action_id", action.getId()); params.put("name_id", nameId); params.put("evr_id", evrId); WriteMode m = null; if (archId == null) { m = ModeFactory.getWriteMode("Action_queries", "schedule_action_no_arch"); } else { params.put("arch_id", archId); m = ModeFactory.getWriteMode("Action_queries", "schedule_action"); } m.executeUpdate(params); } } } /** * Returns a name string from an Action type * @param type the type * @return a name */ public static String getActionName(ActionType type) { String name = ""; if (type.equals(ActionFactory.TYPE_PACKAGES_REMOVE)) { name = "Package Removal"; } else if (type.equals(ActionFactory.TYPE_PACKAGES_UPDATE)) { name = "Package Install/Upgrade"; } else if (type.equals(ActionFactory.TYPE_PACKAGES_VERIFY)) { name = "Package Verify"; } else if (type.equals(ActionFactory.TYPE_PACKAGES_REFRESH_LIST)) { name = "Package List Refresh"; } else if (type.equals(ActionFactory.TYPE_PACKAGES_DELTA)) { name = "Package Synchronization"; } return name; } /** * Schedules the appropriate package action * @param scheduler User scheduling the action. * @param srvr Server for which the action affects. * @param pkgs The set of packages to be removed. * @param type The Action Type * @param earliestAction Date of earliest action to be executed * @return scheduled Package Action */ private static Action schedulePackageAction(User scheduler, Server srvr, RhnSet pkgs, ActionType type, Date earliestAction) { List packages = new LinkedList(); Iterator i = pkgs.getElements().iterator(); while (i.hasNext()) { RhnSetElement rse = (RhnSetElement) i.next(); Map row = new HashMap(); row.put("name_id", rse.getElement()); row.put("evr_id", rse.getElementTwo()); row.put("arch_id", rse.getElementThree()); // bugzilla: 191000, we forgot to populate the damn LinkedList :( packages.add(row); } return schedulePackageAction(scheduler, packages, type, earliestAction, srvr ); } /** * Schedules Xccdf evaluation. * @param scheduler User scheduling the action. * @param srvr Server for which the action affects. * @param path Path for the Xccdf content. * @param parameters Additional parameters for oscap tool. * @param earliestAction Date of earliest action to be executed. * @return scheduled Scap Action */ public static ScapAction scheduleXccdfEval(User scheduler, Server srvr, String path, String parameters, Date earliestAction) { Set<Long> serverIds = new HashSet<Long>(); serverIds.add(srvr.getId()); return scheduleXccdfEval(scheduler, serverIds, path, parameters, earliestAction); } /** * Schedules Xccdf evaluation. * @param scheduler User scheduling the action. * @param serverIds Set of server identifiers for which the action affects. * @param path Path for the Xccdf content. * @param parameters Additional parameters for oscap tool. * @param earliestAction Date of earliest action to be executed. * @return scheduled Scap Action */ public static ScapAction scheduleXccdfEval(User scheduler, Set<Long> serverIds, String path, String parameters, Date earliestAction) { if (serverIds.isEmpty()) { return null; } for (Long serverId : serverIds) { Server server = SystemManager.lookupByIdAndUser(serverId, scheduler); if (!SystemManager.clientCapable(serverId, "scap.xccdf_eval")) { throw new MissingCapabilityException("OpenSCAP", server); } if (!SystemManager.hasEntitlement(serverId, EntitlementManager.MANAGEMENT)) { throw new MissingEntitlementException( EntitlementManager.MANAGEMENT.getHumanReadableLabel()); } } ScapActionDetails scapDetails = new ScapActionDetails(path, parameters); ScapAction action = (ScapAction) scheduleAction(scheduler, ActionFactory.TYPE_SCAP_XCCDF_EVAL, ActionFactory.TYPE_SCAP_XCCDF_EVAL.getName(), earliestAction, serverIds); action.setScapActionDetails(scapDetails); ActionFactory.save(action); return action; } /** * Schedule machine reboot. * * @param scheduler Logged in user * @param server Server, which is going to be rebooted * @param earliestAction Earliest date. If null, then date is current. * @return scheduled reboot action */ public static Action scheduleReboot(User scheduler, Server server, Date earliestAction) { Action action = ActionManager.scheduleAction(scheduler, server, ActionFactory.TYPE_REBOOT, ActionFactory.TYPE_REBOOT.getName(), (earliestAction == null ? new Date() : earliestAction)); ActionFactory.save(action); return action; } /** * scheduleCertificateUpdate * @param scheduler Logged in user * @param server Server, to update the certificate for * @param earliestAction Earliest date. If null, use current date * @return scheduled certificate update action */ public static Action scheduleCertificateUpdate(User scheduler, Server server, Date earliestAction) { if (!SystemManager.clientCapable(server.getId(), "clientcert.update_client_cert")) { throw new MissingCapabilityException("spacewalk-client-cert", server); } Action action = ActionManager.scheduleAction(scheduler, server, ActionFactory.TYPE_CLIENTCERT_UPDATE_CLIENT_CERT, ActionFactory.TYPE_CLIENTCERT_UPDATE_CLIENT_CERT.getName(), (earliestAction == null ? new Date() : earliestAction)); ActionFactory.save(action); return action; } }