Compare commits
No commits in common. "947bccb6da2fdbe7b8a21b6481d1a34af6a4349d" and "0594a6481288cd858a0df6acc0281a8e6365da69" have entirely different histories.
947bccb6da
...
0594a64812
@ -1,152 +0,0 @@
|
|||||||
package name.nathanmcrae.numbersstation;
|
|
||||||
|
|
||||||
import com.leakyabstractions.result.api.Result;
|
|
||||||
import com.leakyabstractions.result.core.Results;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.io.Writer;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import javafx.util.Pair;
|
|
||||||
|
|
||||||
public class LinuxScheduler {
|
|
||||||
private static final Logger logger = Logger.getLogger(Main.class.getName());
|
|
||||||
|
|
||||||
public static Result<Boolean, String> registerSchedule(StationSettings settings) {
|
|
||||||
try {
|
|
||||||
String taskName = "numbers-station-main_" + settings.getName();
|
|
||||||
|
|
||||||
// TODO: assume it's on the PATH
|
|
||||||
Process listProcess = new ProcessBuilder("/usr/bin/crontab", "-l").start();
|
|
||||||
if (!listProcess.waitFor(5, TimeUnit.SECONDS)) {
|
|
||||||
String message = "Failed to query " + taskName + " task: process timed out";
|
|
||||||
logger.log(Level.SEVERE, message);
|
|
||||||
return Results.failure(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
Pair<String, String> output = WindowsScheduler.captureProcessOutput(listProcess);
|
|
||||||
if(listProcess.exitValue() != 0) {
|
|
||||||
String message = "Failed to get user id. Exit code: " + listProcess.exitValue() + ". stdout: " + output.getKey() + "\n\tstderr: " + output.getValue();
|
|
||||||
logger.log(Level.SEVERE, message);
|
|
||||||
return Results.failure(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
String currentCrontab = output.getKey();
|
|
||||||
|
|
||||||
String cronEntry = "# " + taskName + "\n" + cronExpression(settings) + "\n\n";
|
|
||||||
|
|
||||||
Pattern pattern = Pattern.compile("# " + taskName + "\\n[^\\n]+\\n\\n");
|
|
||||||
|
|
||||||
Matcher matcher = pattern.matcher(currentCrontab);
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
|
|
||||||
if (matcher.find()) {
|
|
||||||
matcher.appendReplacement(sb, cronEntry);
|
|
||||||
|
|
||||||
boolean foundMultiple = false;
|
|
||||||
while (matcher.find()) {
|
|
||||||
foundMultiple = true;
|
|
||||||
matcher.appendReplacement(sb, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
matcher.appendTail(sb);
|
|
||||||
} else {
|
|
||||||
sb.append(currentCrontab);
|
|
||||||
sb.append(cronEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
String newCrontab = sb.toString();
|
|
||||||
|
|
||||||
// TODO: assume it's on the PATH
|
|
||||||
Process addProcess = new ProcessBuilder("/usr/bin/crontab", "-").start();
|
|
||||||
Writer w = new OutputStreamWriter(addProcess.getOutputStream(), "UTF-8");
|
|
||||||
System.out.println(newCrontab);
|
|
||||||
w.write(newCrontab);
|
|
||||||
w.flush();
|
|
||||||
w.close();
|
|
||||||
if (!addProcess.waitFor(5, TimeUnit.SECONDS)) {
|
|
||||||
String message = "Failed to register " + taskName + " task: process timed out";
|
|
||||||
logger.log(Level.SEVERE, message);
|
|
||||||
return Results.failure(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(addProcess.exitValue() != 0) {
|
|
||||||
Pair<String, String> addOutput = WindowsScheduler.captureProcessOutput(addProcess);
|
|
||||||
String message = "Failed to get user id. Exit code: " + addProcess.exitValue() + ". stdout: " + addOutput.getKey() + ". stderr: " + addOutput.getValue();
|
|
||||||
logger.log(Level.SEVERE, message);
|
|
||||||
return Results.failure(message);
|
|
||||||
}
|
|
||||||
} catch (CronExpressionException | IOException | InterruptedException e) {
|
|
||||||
String message = "Exception while registering schedule";
|
|
||||||
logger.log(Level.SEVERE, message, e);
|
|
||||||
return Results.failure(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Path cronDPath = Paths.get("/etc/cron.d");
|
|
||||||
// if (!Files.exists(cronDPath)) {
|
|
||||||
// String message = "/etc/cron.d does not exist, cannot create cron entry. Select 'Manage schedule externally' and set up scheduling as desired.";
|
|
||||||
// logger.log(Level.SEVERE, message);
|
|
||||||
// return Results.failure(message);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Path cronPath = cronDPath.resolve(settings.safeName());
|
|
||||||
|
|
||||||
// try {
|
|
||||||
// Files.write(cronPath, cronEntry(settings).getBytes(StandardCharsets.UTF_8));
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// String message = "Failed to write cron file at '" + cronPath.toString() + "'";
|
|
||||||
// logger.log(Level.SEVERE, message, e);
|
|
||||||
// return Results.failure(message);
|
|
||||||
// }
|
|
||||||
|
|
||||||
return Results.success(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* * * * * * {command to execute}
|
|
||||||
* | | | | |
|
|
||||||
* | | | | day of the week (0–6) (Sunday to Saturday;
|
|
||||||
* | | | month (1–12) 7 is also Sunday on some systems)
|
|
||||||
* | | day of the month (1–31)
|
|
||||||
* | hour (0–23)
|
|
||||||
* minute (0–59)
|
|
||||||
*/
|
|
||||||
public static String cronExpression(StationSettings settings) throws CronExpressionException {
|
|
||||||
String minute = Integer.toString(settings.getScheduleStartTime().getMinute());
|
|
||||||
String hour = Integer.toString(settings.getScheduleStartTime().getHour());
|
|
||||||
String dayOfMonth = Integer.toString(settings.getScheduleStartDate().getDayOfMonth());
|
|
||||||
String dayOfWeek = Integer.toString(settings.getScheduleStartDate().getDayOfMonth());
|
|
||||||
|
|
||||||
String scheduleString = "";
|
|
||||||
switch(settings.getMessagePeriod()) {
|
|
||||||
case DAILY:
|
|
||||||
scheduleString = minute + " " + hour + " * * *";
|
|
||||||
break;
|
|
||||||
case WEEKLY:
|
|
||||||
scheduleString = minute + " " + hour + " * * " + dayOfWeek;
|
|
||||||
break;
|
|
||||||
case MONTHLY:
|
|
||||||
scheduleString = minute + " " + hour + " " + dayOfMonth + " * *";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new CronExpressionException("Message period not implemented: '" + settings.getMessagePeriod() + "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: figure out actual invocation
|
|
||||||
return scheduleString + " /home/nathanmcrae/personal_root/projects/numbers-station/run.sh --station \"" + settings.getName() + "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class CronExpressionException extends Exception {
|
|
||||||
public CronExpressionException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
package name.nathanmcrae.numbersstation;
|
|
||||||
|
|
||||||
public class MainRun {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
Main.main(args);
|
|
||||||
}
|
|
||||||
}
|
|
@ -454,7 +454,7 @@ public class StationSettingsController {
|
|||||||
if (osName.contains("win")) {
|
if (osName.contains("win")) {
|
||||||
WindowsScheduler.registerSchedule(settings);
|
WindowsScheduler.registerSchedule(settings);
|
||||||
} else if (osName.contains("nix") || osName.contains("nux") || osName.contains("aix")) {
|
} else if (osName.contains("nix") || osName.contains("nux") || osName.contains("aix")) {
|
||||||
LinuxScheduler.registerSchedule(settings);
|
logger.log(Level.SEVERE, "Unsupported OS " + osName);
|
||||||
} else {
|
} else {
|
||||||
logger.log(Level.SEVERE, "Unsupported OS " + osName);
|
logger.log(Level.SEVERE, "Unsupported OS " + osName);
|
||||||
// TODO: Alert
|
// TODO: Alert
|
||||||
|
@ -426,7 +426,6 @@ public class WindowsScheduler {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return (stdout contents, stderr contents)
|
* @return (stdout contents, stderr contents)
|
||||||
* TODO: don't assume that process has exited yet. If it does we don't want to hang.
|
|
||||||
*/
|
*/
|
||||||
public static Pair<String, String> captureProcessOutput(Process process) throws IOException {
|
public static Pair<String, String> captureProcessOutput(Process process) throws IOException {
|
||||||
StringBuilder output = new StringBuilder();
|
StringBuilder output = new StringBuilder();
|
||||||
@ -436,10 +435,10 @@ public class WindowsScheduler {
|
|||||||
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
|
BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
|
||||||
String line;
|
String line;
|
||||||
while ((line = reader.readLine()) != null) {
|
while ((line = reader.readLine()) != null) {
|
||||||
output.append(line + "\n");
|
output.append(line);
|
||||||
}
|
}
|
||||||
while ((line = errorReader.readLine()) != null) {
|
while ((line = errorReader.readLine()) != null) {
|
||||||
error.append(line + "\n");
|
error.append(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user