Skip to content

Commit

Permalink
MID-8842 ninja - upgrade command, work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
1azyman committed Aug 31, 2023
1 parent e791310 commit f26d3c1
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,24 @@

package com.evolveum.midpoint.ninja.action;

import com.evolveum.midpoint.ninja.action.upgrade.UpgradeConstants;
import com.evolveum.midpoint.ninja.util.ConsoleFormat;

public abstract class ComplexAction<O, R> extends Action<O, R> {
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;

public abstract class UpgradeBaseAction<O, R> extends Action<O, R> {

protected File createTmpDirectory(File optsTempDirectory) throws IOException {
File tempDirectory = optsTempDirectory != null ?
optsTempDirectory : new File(FileUtils.getTempDirectory(), UpgradeConstants.UPGRADE_TEMP_DIRECTORY);

FileUtils.forceMkdir(tempDirectory);

return tempDirectory;
}

protected <O, T> T executeAction(Action<O, T> action, O options) throws Exception {
action.init(context, options);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,124 @@

package com.evolveum.midpoint.ninja.action.upgrade.action;

import java.io.File;

import org.apache.commons.lang3.StringUtils;

import com.evolveum.midpoint.ninja.action.ActionResult;
import com.evolveum.midpoint.ninja.action.ComplexAction;
import com.evolveum.midpoint.ninja.action.VerifyAction;
import com.evolveum.midpoint.ninja.action.VerifyOptions;
import com.evolveum.midpoint.ninja.action.*;
import com.evolveum.midpoint.ninja.util.NinjaUtils;
import com.evolveum.midpoint.ninja.util.ThrowableSupplier;

public class UpgradeAction extends UpgradeBaseAction<UpgradeOptions, ActionResult<Void>> {

public class UpgradeAction extends ComplexAction<UpgradeOptions, ActionResult<Void>> {
private static final String VERIFY_OUTPUT_FILE = "verify-output.csv";

@Override
public String getOperationName() {
return "upgrade";
}

/**
* Asks for input from user if batch mode is not enabled.
*
* @return If batch mode is not enabled, user input is returned. Otherwise, default value is returned.
*/
private String checkInputOrDefault(ThrowableSupplier<String> inputSupplier, String defaultValue) throws Exception {
BaseOptions baseOptions = context.getOptions(BaseOptions.class);
if (baseOptions.isBatchMode()) {
return defaultValue;
}

return inputSupplier.get();
}

private ActionResult<Void> createCanceledResult() {
return new ActionResult<>(null, 0, "Process cancelled by user");
}

@Override
public ActionResult<Void> execute() throws Exception {
File tempDirectory = createTmpDirectory(null);

// objects verification
log.info("Do you want to run objects verification before upgrade? yes/skip/cancel (y/s/C) [y] ");
String response = NinjaUtils.readInput(log, input -> StringUtils.isEmpty(input) || input.matches("[ysC]"));
String verifyResp = checkInputOrDefault(
() -> NinjaUtils.readInput(log, input -> StringUtils.isEmpty(input) || input.matches("[ysC]")),
"y"
);

if ("C".equals(verifyResp)) {
return createCanceledResult();
}

File verificationFile = null;

if (StringUtils.isEmpty(verifyResp) || "y".equalsIgnoreCase(verifyResp)) {
verificationFile = new File(tempDirectory, VERIFY_OUTPUT_FILE);

if (StringUtils.isEmpty(response) || "y".equalsIgnoreCase(response)) {
VerifyOptions verifyOptions = new VerifyOptions();
// todo options
verifyOptions.setOutput(verificationFile);
verifyOptions.setOverwrite(true);
verifyOptions.setReportStyle(VerifyOptions.ReportStyle.CSV);

executeAction(new VerifyAction(), verifyOptions);
}

if ("s".equalsIgnoreCase(response)) {
// objects upgrade
if ("s".equalsIgnoreCase(verifyResp)) {
log.warn("Skipping objects verification");
}

if ("C".equals(response)) {
return new ActionResult<>(null, 0, "Upgrade cancelled by user");
log.info("");
log.info("Do you want to update objects before upgrade? yes/skip/cancel (y/s/C) [y] ");
String upgradeObjectsResp = checkInputOrDefault(
() -> NinjaUtils.readInput(log, input -> StringUtils.isEmpty(input) || input.matches("[ysC]")),
"y"
);

if ("C".equals(upgradeObjectsResp)) {
return createCanceledResult();
}

if ("s".equals(upgradeObjectsResp)) {
log.warn("Skipping objects upgrade");
}

if (StringUtils.isEmpty(upgradeObjectsResp) || "y".equals(upgradeObjectsResp)) {
if (verificationFile == null) {
log.info("Do you want to provide a file with verification issues? yes/no (y/n) [n] ");
String verifyFileResp = checkInputOrDefault(
() -> NinjaUtils.readInput(log, input -> StringUtils.isEmpty(input) || input.matches("[yn]")),
"n"
);

if ("y".equals(verifyFileResp)) {
// todo maybe more interactive validation? check file existence etc...
String filePath = NinjaUtils.readInput(log, input -> StringUtils.isNotEmpty(input));
verificationFile = new File(filePath);
}
} else {
checkVerificationReviewed();
}

if (verificationFile == null) {
// todo how to report them?
// * we should report separately if there are CRITICAL issues with phase=AFTER - cause they would be updated
// after installation is upgraded before midpoint is started (via ninja)
// * we should report separately if there are CRITICAL issues with type=MANUAL - cause they would not be updated by ninja
// * we should report separately if there are CRITICAL issues with type=PREVIEW - cause they probably should not be
log.info(
"Verification file was not created, nor provided. "
+ "Ninja will try to update all objects that contain verification issues."
+ "Verification issues that were skipped will be reported");
}

UpgradeObjectsOptions upgradeObjectsOptions = new UpgradeObjectsOptions();
upgradeObjectsOptions.setVerification(verificationFile);

// executeAction(new UpgradeObjectsAction(), upgradeObjectsOptions);
}

// UpgradeObjectsOptions upgradeObjectsOptions = new UpgradeObjectsOptions();
// // todo options
// executeAction(new UpgradeObjectsAction(), upgradeObjectsOptions);
//
// PreUpgradeCheckOptions preUpgradeCheckOptions = new PreUpgradeCheckOptions();
// // todo options
// executeAction(new PreUpgradeCheckAction(), preUpgradeCheckOptions);
Expand All @@ -60,4 +140,18 @@ public ActionResult<Void> execute() throws Exception {

return null;
}

private boolean checkVerificationReviewed() throws Exception {
log.info("Have you reviewed verification issues? yes/no (y/n) [y] ");
String reviewedVerificationResp = checkInputOrDefault(
() -> NinjaUtils.readInput(log, input -> StringUtils.isEmpty(input) || input.matches("[yn]")),
"y"
);

if ("n".equals(reviewedVerificationResp)) {
return checkVerificationReviewed();
}

return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
import java.io.File;
import java.util.stream.Collectors;

import org.apache.commons.io.FileUtils;
import org.fusesource.jansi.Ansi;

import com.evolveum.midpoint.ninja.action.*;
import com.evolveum.midpoint.ninja.action.upgrade.UpgradeConstants;

public class UpgradeDistributionAction extends ComplexAction<UpgradeDistributionOptions, ActionResult<Void>> {
public class UpgradeDistributionAction extends UpgradeBaseAction<UpgradeDistributionOptions, ActionResult<Void>> {

@Override
public String getOperationName() {
Expand All @@ -18,10 +16,7 @@ public String getOperationName() {

@Override
public ActionResult<Void> execute() throws Exception {
File tempDirectory = options.getTempDirectory() != null ?
options.getTempDirectory() : new File(FileUtils.getTempDirectory(), UpgradeConstants.UPGRADE_TEMP_DIRECTORY);

FileUtils.forceMkdir(tempDirectory);
File tempDirectory = createTmpDirectory(options.getTempDirectory());
// FIXME: Should we log pre-upgrade checks

// pre-upgrade checks
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@

@Parameters(resourceBundle = "messages", commandDescriptionKey = "upgrade")
public class UpgradeOptions {

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,12 @@

import com.beust.jcommander.IUsageFormatter;
import com.beust.jcommander.JCommander;

import com.evolveum.midpoint.ninja.impl.*;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;

import com.evolveum.midpoint.ninja.action.BaseOptions;
import com.evolveum.midpoint.ninja.action.ConnectionOptions;
import com.evolveum.midpoint.ninja.impl.*;
import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.prism.query.ObjectFilter;
import com.evolveum.midpoint.prism.query.ObjectQuery;
Expand Down Expand Up @@ -282,7 +280,10 @@ public static String readInput(Log log, Function<String, Boolean> inputValidatio
boolean first = true;

String line = null;
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
// we don't want to close this input stream (stdin), we didn't open it.
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

boolean accepted = false;
while (!accepted) {
if (!first) {
Expand All @@ -294,6 +295,8 @@ public static String readInput(Log log, Function<String, Boolean> inputValidatio

accepted = inputValidation.apply(line);
}
} catch (IOException ex) {
log.error("Error occurred while reading input from stdin", ex);
}

return line;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (C) 2010-2023 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.ninja.util;

@FunctionalInterface
public interface ThrowableSupplier<T> {

T get() throws Exception;
}

0 comments on commit f26d3c1

Please sign in to comment.