Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set package refresh scheduler if possible #6969

Merged
merged 3 commits into from
Aug 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ SELECT EVENT_ID as ID,
WHERE SH.server_id = :sid
UNION
SELECT SA.action_id EVENT_ID,
AType.name || ' scheduled by ' || NVL(U.login, '(none)') AS SUMMARY,
AType.name || ' scheduled by ' || NVL(U.login, '(system)') AS SUMMARY,
SA.created,
SA.pickup_time AS picked_up,
SA.completion_time AS completed,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1798,7 +1798,7 @@ select event_id as id,
where SH.server_id = :sid
union
select SA.action_id event_id,
COALESCE(A.name, AType.name) || ' scheduled by ' || NVL(U.login, '(none)') as summary,
COALESCE(A.name, AType.name) || ' scheduled by ' || NVL(U.login, '(system)') as summary,
SA.created,
SA.pickup_time as picked_up,
SA.completion_time as completed,
Expand Down Expand Up @@ -1852,7 +1852,7 @@ order by completed desc, picked_up desc, all_events.created desc, event_id desc
AND SH.id = :eid
union
select SA.action_id event_id,
COALESCE(A.name, AType.name) || ' scheduled by ' || NVL(U.login, '(none)') as summary,
COALESCE(A.name, AType.name) || ' scheduled by ' || NVL(U.login, '(system)') as summary,
SA.created,
SA.pickup_time as picked_up,
SA.completion_time as completed,
Expand Down Expand Up @@ -1888,7 +1888,7 @@ select count(action_id) as count
class="com.redhat.rhn.frontend.dto.SystemPendingEventDto">
<query params="sid">
SELECT SA.action_id AS id
, COALESCE(A.name, AType.name) || ' scheduled by ' || NVL(U.login, '(none)') AS summary
, COALESCE(A.name, AType.name) || ' scheduled by ' || NVL(U.login, '(system)') AS summary
, A.earliest_action AS scheduled_for
, AType.label AS history_type
, AType.name AS history_type_name
Expand All @@ -1910,7 +1910,7 @@ ORDER BY scheduled_for DESC, prereq_aid NULLS FIRST
class="com.redhat.rhn.frontend.dto.SystemPendingEventDto">
<query params="sid, user_id, set_label">
SELECT SA.action_id AS ID
, COALESCE(A.name, AType.name) || ' scheduled by ' || NVL(U.login, '(none)') AS summary
, COALESCE(A.name, AType.name) || ' scheduled by ' || NVL(U.login, '(system)') AS summary
, A.earliest_action AS scheduled_for
, AType.label AS history_type
, AType.name AS history_type_name
Expand Down
14 changes: 7 additions & 7 deletions java/code/src/com/redhat/rhn/manager/action/ActionManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -1188,37 +1188,37 @@ public static PackageAction schedulePackageRefresh(User scheduler, Server server
/**
* Schedule a package list refresh without a user.
*
* @param schedulerOrg the organization the server belongs to
* @param user the user that scheduled the action
* @param server the server
* @return the scheduled PackageRefreshListAction
* @throws TaskomaticApiException if there was a Taskomatic error
* (typically: Taskomatic is down)
*/
public static PackageAction schedulePackageRefresh(Org schedulerOrg, Server server)
public static PackageAction schedulePackageRefresh(Optional<User> user, Server server)
throws TaskomaticApiException {
Date earliest = new Date();
return schedulePackageRefresh(schedulerOrg, server, earliest);
return schedulePackageRefresh(user, server, earliest);
}

/**
* Schedule a package list refresh without a user.
*
* @param schedulerOrg the organization the server belongs to
* @param user the organization the server belongs to
* @param server the server
* @param earliest The earliest time this action should be run.
* @return the scheduled PackageRefreshListAction
* @throws TaskomaticApiException if there was a Taskomatic error
* (typically: Taskomatic is down)
*/
public static PackageAction schedulePackageRefresh(Org schedulerOrg, Server server,
public static PackageAction schedulePackageRefresh(Optional<User> user, Server server,
Date earliest) throws TaskomaticApiException {
checkSaltOrManagementEntitlement(server.getId());

Action action = ActionFactory.createAction(
ActionFactory.TYPE_PACKAGES_REFRESH_LIST);
action.setName(ActionFactory.TYPE_PACKAGES_REFRESH_LIST.getName());
action.setOrg(schedulerOrg);
action.setSchedulerUser(null);
action.setOrg(server.getOrg());
action.setSchedulerUser(user.orElse(null));
action.setEarliestAction(earliest);

ServerAction sa = new ServerAction();
Expand Down
2 changes: 1 addition & 1 deletion java/code/src/com/suse/manager/reactor/SaltReactor.java
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ public Stream<EventMessage> eventToMessages(BeaconEvent beaconEvent) {
() -> MinionServerFactory.findByMinionId(beaconEvent.getMinionId())
.ifPresent(minionServer -> {
try {
ActionManager.schedulePackageRefresh(minionServer.getOrg(), minionServer);
ActionManager.schedulePackageRefresh(Optional.empty(), minionServer);
}
catch (TaskomaticApiException e) {
LOG.error("Could not schedule package refresh for minion: {}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.redhat.rhn.domain.server.MinionServer;
import com.redhat.rhn.domain.server.MinionServerFactory;
import com.redhat.rhn.domain.server.VirtualInstance;
import com.redhat.rhn.domain.user.User;
import com.redhat.rhn.manager.action.ActionManager;
import com.redhat.rhn.manager.system.SystemManager;
import com.redhat.rhn.taskomatic.TaskomaticApiException;
Expand Down Expand Up @@ -56,6 +57,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;


Expand Down Expand Up @@ -146,6 +148,7 @@ public void execute(EventMessage msg) {
if (!jobResult.isPresent()) {
return;
}
AtomicReference<Optional<User>> scheduler = new AtomicReference<>(Optional.empty());
JsonElement jsonResult = jobResult.get();
// The Salt reactor triggers a "suma-action-chain" job (mgractionchains.resume) at
// 'minion/startup/event/'. This means the result might not be a JSON in case of
Expand All @@ -162,6 +165,7 @@ public void execute(EventMessage msg) {
.flatMap(ActionChainFactory::getActionChain);

actionChain.ifPresent(ac -> {
scheduler.set(Optional.ofNullable(ac.getUser()));
ac.getEntries().stream()
.flatMap(ace -> ace.getAction().getServerActions().stream())
.filter(sa -> sa.getServer().asMinionServer()
Expand Down Expand Up @@ -204,23 +208,27 @@ public void execute(EventMessage msg) {
.stream() // handlePackageChange for all the results in actions chain result.
.anyMatch(Boolean.TRUE::equals);
if (packageRefreshNeeded) {
schedulePackageRefresh(jobReturnEvent.getMinionId());
schedulePackageRefresh(scheduler.get(), jobReturnEvent.getMinionId());
}
});

//For all jobs except when action chains are involved or the action was in test mode
if (!isActionChainInvolved && !isFunctionTestMode && handlePackageChanges(jobReturnEvent,
Optional.ofNullable(function).map(Xor::right), jobResult)) {
Date earliest = new Date();
Optional<User> scheduler = Optional.empty();
if (actionId.isPresent()) {
Optional<Action> action = Optional.ofNullable(ActionFactory.lookupById(actionId.get()));
if (action.isPresent() && action.get().getActionType().equals(ActionFactory.TYPE_DIST_UPGRADE)) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, 30);
earliest = calendar.getTime();
if (action.isPresent()) {
scheduler = Optional.ofNullable(action.get().getSchedulerUser());
if (action.get().getActionType().equals(ActionFactory.TYPE_DIST_UPGRADE)) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, 30);
earliest = calendar.getTime();
}
}
}
schedulePackageRefresh(jobReturnEvent.getMinionId(), earliest);
schedulePackageRefresh(scheduler, jobReturnEvent.getMinionId(), earliest);
}

// Check if event was triggered in response to state scheduled at minion start-up event
Expand Down Expand Up @@ -317,19 +325,19 @@ private boolean handlePackageChanges(JobReturnEvent jobReturnEvent, Optional<Xor
* Schedule package refresh on the minion
* @param minionId ID of the minion for which package refresh should be scheduled
*/
private void schedulePackageRefresh(String minionId) {
schedulePackageRefresh(minionId, new Date());
private void schedulePackageRefresh(Optional<User> user, String minionId) {
schedulePackageRefresh(user, minionId, new Date());
}

/**
* Schedule package refresh on the minion
* @param minionId ID of the minion for which package refresh should be scheduled
* @param earliest The earliest time this action should be run.
*/
private void schedulePackageRefresh(String minionId, Date earliest) {
private void schedulePackageRefresh(Optional<User> user, String minionId, Date earliest) {
MinionServerFactory.findByMinionId(minionId).ifPresent(minionServer -> {
try {
ActionManager.schedulePackageRefresh(minionServer.getOrg(), minionServer, earliest);
ActionManager.schedulePackageRefresh(user, minionServer, earliest);
}
catch (TaskomaticApiException e) {
LOG.error(e.getMessage(), e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
import com.redhat.rhn.domain.server.VirtualInstanceFactory;
import com.redhat.rhn.domain.token.ActivationKey;
import com.redhat.rhn.domain.token.ActivationKeyFactory;
import com.redhat.rhn.domain.user.User;
import com.redhat.rhn.frontend.dto.PackageListItem;
import com.redhat.rhn.manager.action.ActionManager;
import com.redhat.rhn.manager.kickstart.cobbler.CobblerXMLRPCHelper;
Expand Down Expand Up @@ -729,6 +730,7 @@ else if (stateApplyResult.getChanges() != null) {
.contains(SYSTEM_REBOOT)).orElse(false));

boolean refreshPkg = false;
Optional<User> scheduler = Optional.empty();
for (Map.Entry<String, StateApplyResult<Ret<JsonElement>>> entry : actionChainResult.entrySet()) {
String stateIdKey = entry.getKey();
StateApplyResult<Ret<JsonElement>> stateResult = entry.getValue();
Expand All @@ -740,13 +742,13 @@ else if (stateApplyResult.getChanges() != null) {
// only reboot needs special handling,
// for salt pkg update there's no need to split the sls in case of salt-ssh minions

Action action = ActionFactory.lookupById(stateId.getActionId());
if (stateResult.getName().map(x -> x.fold(Arrays::asList, List::of)
.contains(SYSTEM_REBOOT)).orElse(false) && stateResult.isResult()) {
Action rebootAction = ActionFactory.lookupById(stateId.getActionId());

if (rebootAction.getActionType().equals(ActionFactory.TYPE_REBOOT)) {
if (action.getActionType().equals(ActionFactory.TYPE_REBOOT)) {
Optional<ServerAction> rebootServerAction =
rebootAction.getServerActions().stream()
action.getServerActions().stream()
.filter(sa -> sa.getServer().asMinionServer().isPresent() &&
sa.getServer().asMinionServer().get()
.getMinionId().equals(minionId))
Expand All @@ -765,16 +767,18 @@ else if (stateApplyResult.getChanges() != null) {
if (stateResult.isResult() &&
saltUtils.shouldRefreshPackageList(stateResult.getName(),
Optional.of(stateResult.getChanges().getRet()))) {
scheduler = Optional.ofNullable(action.getSchedulerUser());
refreshPkg = true;
}
}
}
Optional<MinionServer> minionServer = MinionServerFactory.findByMinionId(minionId);
if (refreshPkg) {
Optional<User> finalScheduler = scheduler;
minionServer.ifPresent(minion -> {
LOG.info("Scheduling a package profile update for minion {}", minionId);
try {
ActionManager.schedulePackageRefresh(minion.getOrg(), minion);
ActionManager.schedulePackageRefresh(finalScheduler, minion);
}
catch (TaskomaticApiException e) {
LOG.error("Could not schedule package refresh for minion: {}", minion.getMinionId(), e);
Expand Down Expand Up @@ -2513,7 +2517,8 @@ else if (sa.getStatus().equals(ActionFactory.STATUS_QUEUED)) {
LOG.info("Scheduling a package profile update");

try {
ActionManager.schedulePackageRefresh(minion.getOrg(), minion);
ActionManager.schedulePackageRefresh(
Optional.ofNullable(action.getSchedulerUser()), minion);
}
catch (TaskomaticApiException e) {
LOG.error("Could not schedule package refresh for minion: {}", minion.getMinionId(), e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void testSerializeSystemEventDetailDto() {
dto.setHistoryType(ActionFactory.TYPE_HARDWARE_REFRESH_LIST.getLabel());
dto.setHistoryTypeName(ActionFactory.TYPE_HARDWARE_REFRESH_LIST.getName());
dto.setHistoryStatus(ActionFactory.STATUS_COMPLETED.getName());
dto.setSummary("Hardware List Refresh scheduled by (none)");
dto.setSummary("Hardware List Refresh scheduled by (system)");
dto.setCreated(Date.from(LocalDateTime.of(2021, 10, 5, 16, 55)
.atZone(ZoneOffset.systemDefault())
.toInstant()));
Expand Down Expand Up @@ -81,7 +81,7 @@ public void testSerializeSystemEventDetailDto() {
assertTrue(xml.contains("<string>Completed</string>"));

assertTrue(xml.contains("<name>summary</name>"));
assertTrue(xml.contains("<string>Hardware List Refresh scheduled by (none)</string>"));
assertTrue(xml.contains("<string>Hardware List Refresh scheduled by (system)</string>"));

assertTrue(xml.contains("<name>created</name>"));
assertTrue(xml.contains("<dateTime.iso8601>20211005T16:55:00</dateTime.iso8601>"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public void testSerializeSystemEventDto() {
dto.setHistoryType(ActionFactory.TYPE_HARDWARE_REFRESH_LIST.getLabel());
dto.setHistoryTypeName(ActionFactory.TYPE_HARDWARE_REFRESH_LIST.getName());
dto.setHistoryStatus(ActionFactory.STATUS_COMPLETED.getName());
dto.setSummary("Hardware List Refresh scheduled by (none)");
dto.setSummary("Hardware List Refresh scheduled by (system)");
dto.setCompleted(Date.from(LocalDateTime.of(2021, 10, 5, 17, 0)
.atZone(ZoneOffset.systemDefault())
.toInstant()));
Expand All @@ -65,7 +65,7 @@ public void testSerializeSystemEventDto() {
assertTrue(xml.contains("<string>Completed</string>"));

assertTrue(xml.contains("<name>summary</name>"));
assertTrue(xml.contains("<string>Hardware List Refresh scheduled by (none)</string>"));
assertTrue(xml.contains("<string>Hardware List Refresh scheduled by (system)</string>"));

assertTrue(xml.contains("<name>completed</name>"));
assertTrue(xml.contains("<dateTime.iso8601>20211005T17:00:00</dateTime.iso8601>"));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Change default scheduler from (none) to (system)
- Set user for package list refresh action if possible
8 changes: 4 additions & 4 deletions spacecmd/tests/test_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ def test_do_system_listeventhistory_output(self, shell):
shell.help_system_listeventhistory = MagicMock()
shell.client.system.getEventHistory = MagicMock(return_value=[{
"id": 3, "history_type": "Apply states", "status": "Completed",
"summary": "Apply states [certs, channels] scheduled by (none)", "completed": "20211015T16:56:27",
"summary": "Apply states [certs, channels] scheduled by (system)", "completed": "20211015T16:56:27",
}, {
"id": 1, "history_type": "History Event", "status": "(n/a)",
"summary": "added system entitlement", "completed": "20211015T16:56:14",
Expand All @@ -302,7 +302,7 @@ def test_do_system_listeventhistory_output(self, shell):
'Id: 3',
'History type: Apply states',
'Status: Completed',
'Summary: Apply states [certs, channels] scheduled by (none)',
'Summary: Apply states [certs, channels] scheduled by (system)',
'Completed: 20211015T16:56:27',
'',
'Id: 1',
Expand Down Expand Up @@ -422,7 +422,7 @@ def test_do_system_event_details_action_output(self, shell):
shell.get_system_id = MagicMock(side_effect=[1000010000])
shell.client.system.getEventDetails = MagicMock(return_value={
"id": 1, "history_type": "Apply states", "status": "Completed",
"summary": "Apply states [certs] scheduled by (none)",
"summary": "Apply states [certs] scheduled by (system)",
"created": "20211005T09:47:53", "picked_up": "20211005T09:48:03",
"completed": "20211005T09:48:18", "earliest_action": "20211005T09:47:53",
"result_msg": "Successfully applied state(s): [certs]",
Expand Down Expand Up @@ -460,7 +460,7 @@ def test_do_system_event_details_action_output(self, shell):
'',
'History type: Apply states',
'Status: Completed',
'Summary: Apply states [certs] scheduled by (none)',
'Summary: Apply states [certs] scheduled by (system)',
'',
'Created: 20211005T09:47:53',
'Picked up: 20211005T09:48:03',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ Feature: Setup Uyuni for Retail branch network
Scenario: Disable repositories after installing branch services
When I disable repositories after installing branch server
# WORKAROUND: the following event fails because the proxy needs 10 minutes to become responsive again
# And I wait until event "Package List Refresh scheduled by (none)" is completed
# And I wait until event "Package List Refresh scheduled by (system)" is completed
And I wait for "700" seconds

@proxy
Expand Down
Loading
Loading