summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUdo Walter2017-02-14 15:52:30 +0100
committerUdo Walter2017-02-14 15:52:30 +0100
commit20350a2b7e5cfa13263b9ce41f48d9e988682909 (patch)
tree8426affc9c098302ca0d6c73113e65f3aac753e8
parentFix mltk repo definition (so svg-salamander is found) (diff)
downloadtmlite-bwlp-20350a2b7e5cfa13263b9ce41f48d9e988682909.tar.gz
tmlite-bwlp-20350a2b7e5cfa13263b9ce41f48d9e988682909.tar.xz
tmlite-bwlp-20350a2b7e5cfa13263b9ce41f48d9e988682909.zip
Add RemoteReboot task
-rw-r--r--pom.xml5
-rw-r--r--src/main/java/org/openslx/taskmanager/tasks/RemoteReboot.java162
2 files changed, 167 insertions, 0 deletions
diff --git a/pom.xml b/pom.xml
index 324c2a3..ce899cc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -110,5 +110,10 @@
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
+ <dependency>
+ <groupId>com.jcabi</groupId>
+ <artifactId>jcabi-ssh</artifactId>
+ <version>1.5.2</version>
+ </dependency>
</dependencies>
</project>
diff --git a/src/main/java/org/openslx/taskmanager/tasks/RemoteReboot.java b/src/main/java/org/openslx/taskmanager/tasks/RemoteReboot.java
new file mode 100644
index 0000000..7e1b228
--- /dev/null
+++ b/src/main/java/org/openslx/taskmanager/tasks/RemoteReboot.java
@@ -0,0 +1,162 @@
+package org.openslx.taskmanager.tasks;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import org.openslx.taskmanager.api.AbstractTask;
+
+import com.jcabi.ssh.Shell;
+import com.google.gson.annotations.Expose;
+import com.jcabi.ssh.SSH;
+
+public class RemoteReboot extends AbstractTask
+{
+ @Expose
+ private HashMap<String, String>[] clients;
+
+ @Expose
+ private boolean shutdown = false;
+
+ @Expose
+ private int minutes = 0;
+
+ @Expose
+ private String locationId;
+
+ @Expose
+ private String locationName;
+
+ @Expose
+ private String sshkey;
+
+ @Expose
+ private int port = 22;
+
+ private Output status = new Output();
+
+ @Override
+ protected boolean initTask()
+ {
+ this.setStatusObject( this.status );
+
+ status.clients = clients;
+ Date shutdownTime = new Date(System.currentTimeMillis()+minutes*60*1000);
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
+ status.time = sdf.format(shutdownTime);
+ status.locationId = locationId;
+ status.locationName = locationName;
+ return true;
+ }
+
+ @Override
+ protected boolean execute()
+ {
+ // try to connect to every client and start the reboot/shutdown process
+ ExecutorService tp = Executors.newFixedThreadPool( clients.length > 4 ? 4 : clients.length );
+ for (HashMap<String, String> client : clients) {
+ final String ip = client.get("ip");
+ status.clientStatus.put(ip, "connecting");
+ tp.submit(new Runnable() {
+ public void run() {
+ try {
+ Shell shell = new SSH(ip, port, "root", sshkey);
+ if (shutdown) {
+ new Shell.Empty(shell).exec("/sbin/shutdown +" + minutes);
+ status.clientStatus.put(ip, minutes == 0 ? "shutdown" : "shutdownat");
+ } else {
+ new Shell.Empty(shell).exec("/sbin/reboot");
+ status.clientStatus.put(ip, "rebooting");
+ }
+ } catch (IOException e) {
+ status.clientStatus.put(ip, "error");
+ }
+ }
+ });
+ }
+ tp.shutdown();
+
+ try {
+ tp.awaitTermination( clients.length * 5, TimeUnit.SECONDS );
+ } catch ( InterruptedException e ) {
+ // ...
+ }
+
+ // wait for rebooting clients to finish rebooting
+ ArrayList<String> rebootingClients = new ArrayList<String>();
+ for (Map.Entry<String, String> entry : status.clientStatus.entrySet()) {
+ if (entry.getValue() == "rebooting") {
+ rebootingClients.add(entry.getKey());
+ }
+ }
+
+ if (rebootingClients.size() > 0) {
+ ExecutorService statusTP = Executors.newFixedThreadPool( rebootingClients.size() > 4 ? 4 : rebootingClients.size() );
+ for (final String ip : rebootingClients) {
+ statusTP.submit(new Runnable() {
+ public void run() {
+ while (!isOnline(ip)) {
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ }
+ }
+ status.clientStatus.put(ip, "online");
+ }
+ });
+ }
+ statusTP.shutdown();
+
+ try {
+ statusTP.awaitTermination( 180, TimeUnit.SECONDS );
+ } catch ( InterruptedException e ) {
+ // ...
+ }
+ }
+
+ // change status of clients that got stuck because of timeouts
+ for (Map.Entry<String, String> entry : status.clientStatus.entrySet()) {
+ String value = entry.getValue();
+ if (value == "connecting" || value == "rebooting") {
+ entry.setValue("error");
+ }
+ }
+
+ return true;
+ }
+
+
+ private boolean isOnline(String address)
+ {
+ try (Socket s = new Socket(address, port)) {
+ return true;
+ } catch (IOException ex) {
+ }
+ return false;
+ }
+
+
+ /**
+ * Output - contains additional status data of this task
+ */
+ class Output
+ {
+ private ConcurrentHashMap<String, String> clientStatus = new ConcurrentHashMap<String, String>();
+ private HashMap<String, String>[] clients;
+ private String time;
+ private String locationId;
+ private String locationName;
+ }
+}