summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2015-09-23 16:52:16 +0200
committerSimon Rettberg2015-09-23 16:52:16 +0200
commit8bb1ae726b5108d8ff58dbfd36378fb8319dfa98 (patch)
tree05e0b880c824673bc9d7e0d8bc2c33e8c3630b28
parent[server] Fix race condition on delete; check for vmstore before up/download (diff)
downloadtutor-module-8bb1ae726b5108d8ff58dbfd36378fb8319dfa98.tar.gz
tutor-module-8bb1ae726b5108d8ff58dbfd36378fb8319dfa98.tar.xz
tutor-module-8bb1ae726b5108d8ff58dbfd36378fb8319dfa98.zip
[client] Disable login button while login is running; create legacy vmx if server doesn't supply one
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/App.java4
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/DownloadTask.java5
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java2
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java50
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java49
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/util/VmWrapper.java21
-rw-r--r--[-rwxr-xr-x]dozentenmodul/src/main/resources/txt/vmx_template19
7 files changed, 76 insertions, 74 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/App.java b/dozentenmodul/src/main/java/org/openslx/dozmod/App.java
index d7c9539f..4a1f6fe3 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/App.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/App.java
@@ -200,8 +200,8 @@ public class App {
null,
"Ungefangene Ausnahme in Faden "
+ t.getName()
- + "\n"
- + "Die Anwendung könnte instabil laufen. Zur Sicherheit sollten Sie sie neustarten.",
+ + "\n\n"
+ + "Die Anwendung könnte instabil laufen.\nZur Sicherheit sollten Sie sie neustarten.",
MessageType.WARNING, LOGGER, e);
}
});
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/DownloadTask.java b/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/DownloadTask.java
index 0cd77713..0aa48e8c 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/DownloadTask.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/filetransfer/DownloadTask.java
@@ -103,12 +103,12 @@ public class DownloadTask extends TransferTask {
if (chunk == null)
return;
// TODO: Hash check, async
- chunks.markSuccessful(chunk);
try {
synchronized (fileHandle) {
fileHandle.seek(chunk.range.startOffset);
fileHandle.write(buffer, 0, chunk.range.getLength());
}
+ chunks.markSuccessful(chunk);
} catch (Exception e) {
LOGGER.error("Could not write to file at offset " + chunk.range.startOffset, e);
fileWritable = false;
@@ -166,7 +166,8 @@ public class DownloadTask extends TransferTask {
if (consecutiveInitFails.get() > 20) {
state = TransferState.ERROR;
error = "Cannot talk to server after 20 tries...";
- } else if (chunks.isComplete()) {
+ } else if (chunks.isComplete() && getTransferCount() == 0) {
+ Util.safeClose(fileHandle);
state = TransferState.FINISHED;
error = null;
} else {
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java
index 7a0c1b56..57c825f5 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/MainWindow.java
@@ -236,7 +236,7 @@ public abstract class MainWindow {
public void fire() {
App.waitForInit();
// now try to init the session with the saved configuration (by giving it null)
- if (ThriftActions.initSession(null, SwingUtilities.getWindowAncestor(mainWindow))) {
+ if (ThriftActions.initSession(null, false, SwingUtilities.getWindowAncestor(mainWindow))) {
initWindow();
} else {
// session resume failed, so do the normal login procedure
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java
index 8b16bd2b..342ce9eb 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java
@@ -73,18 +73,21 @@ public class LoginWindow extends LoginWindowLayout {
private final String NO_USERNAME = "Kein Benutzername angegeben!";
private final String NO_PASSWORD = "Kein Passwort angegeben!";
- public static boolean forceCustomSatellite;
+ private boolean forceCustomSatellite = false;
+
private final KeyEventDispatcher satelliteShiftDispatcher = new KeyEventDispatcher() {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
- int type = event.getID();
int code = event.getKeyCode();
if (code == KeyEvent.VK_SHIFT) { // shift key is pressed
+ int type = event.getID();
if (type == KeyEvent.KEY_PRESSED) {
forceCustomSatellite = true;
- } else if (type == KeyEvent.KEY_RELEASED)
+ event.consume();
+ } else if (type == KeyEvent.KEY_RELEASED) {
forceCustomSatellite = false;
- event.consume();
+ event.consume();
+ }
}
return event.isConsumed();
}
@@ -213,8 +216,7 @@ public class LoginWindow extends LoginWindowLayout {
return;
}
- idpCombo.setModel(
- new DefaultComboBoxModel<Organization>(orgs.toArray(new Organization[orgs.size()])));
+ idpCombo.setModel(new DefaultComboBoxModel<Organization>(orgs.toArray(new Organization[orgs.size()])));
// now check if we had a saved identity provider
String savedOrganizationId = Config.getIdentityProvider();
idpCombo.setSelectedItem(OrganizationCache.find(savedOrganizationId));
@@ -292,7 +294,8 @@ public class LoginWindow extends LoginWindowLayout {
// username contains a known organization
if (!selectedOrg.equals(orgInUsername)) {
// but it does not match the one selected in the combobox
- boolean ret = Gui.showMessageBox(this,
+ boolean ret = Gui.showMessageBox(
+ this,
"Der angegebene Benutzername enthält eine Organisation, die nicht mit Ihrer IDP-Auswahl übereinstimmt."
+ "\nWollen Sie die in Ihrem Benutzername gefundene Organisation verwenden?",
MessageType.QUESTION_YESNO, null, null);
@@ -314,11 +317,16 @@ public class LoginWindow extends LoginWindowLayout {
final LoginWindow me = this;
final AuthenticatorCallback authenticatorCallback = new AuthenticatorCallback() {
@Override
- public void postLogin(ReturnCode returnCode, AuthenticationData data, Throwable t) {
+ public void postLogin(ReturnCode returnCode, final AuthenticationData data, Throwable t) {
switch (returnCode) {
case NO_ERROR:
- postSuccessfulLogin(data);
- break;
+ Gui.asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ postSuccessfulLogin(data);
+ }
+ });
+ return;
case IDENTITY_PROVIDER_ERROR:
Gui.showMessageBox(me, "IdP Error", MessageType.ERROR, LOGGER, null);
break;
@@ -329,10 +337,9 @@ public class LoginWindow extends LoginWindowLayout {
LOGGER, t);
break;
case UNREGISTERED_ERROR:
- Gui.showMessageBox(me,
- "You are not registered to bwLehrpool. Please visit "
- + ShibbolethEcp.getRegistrationUrl() + " and register first.",
- MessageType.ERROR, LOGGER, t);
+ Gui.showMessageBox(me, "You are not registered to bwLehrpool. Please visit "
+ + ShibbolethEcp.getRegistrationUrl() + " and register first.", MessageType.ERROR,
+ LOGGER, t);
break;
case INVALID_URL_ERROR:
Gui.showMessageBox(me, "ECP Authenticator says: Invalid URL.", MessageType.ERROR, LOGGER,
@@ -343,6 +350,7 @@ public class LoginWindow extends LoginWindowLayout {
Gui.showMessageBox(me, "Internal error!", MessageType.ERROR, LOGGER, null);
break;
}
+ loginButton.setEnabled(true);
}
};
@@ -363,20 +371,23 @@ public class LoginWindow extends LoginWindowLayout {
return;
}
- // Execute login
- App.waitForInit();
+ loginButton.setEnabled(false);
final String finalUsername = username;
QuickTimer.scheduleOnce(new Task() {
@Override
public void fire() {
+ // Execute login
+ App.waitForInit();
try {
authenticator.login(finalUsername, password, authenticatorCallback);
+ return;
} catch (TException e) {
ThriftError.showMessage(LoginWindow.this, LOGGER, e, "Anmeldung fehlgeschlagen");
} catch (Exception e) {
Gui.showMessageBox(LoginWindow.this, "Anmeldung fehlgeschlagen", MessageType.ERROR,
LOGGER, e);
}
+ loginButton.setEnabled(true);
}
});
}
@@ -391,18 +402,19 @@ public class LoginWindow extends LoginWindowLayout {
// Update known suggested fingerprints
importFingerprints(data.satellites);
// now try to init the session with the data received
- if (ThriftActions.initSession(data, SwingUtilities.getWindowAncestor(this))) {
+ if (ThriftActions.initSession(data, forceCustomSatellite, SwingUtilities.getWindowAncestor(this))) {
if (saveUsernameCheck.isSelected()) {
Config.saveCurrentSession(Session.getSatelliteAddress(), Session.getSatelliteToken(),
Session.getMasterToken());
}
// Remove the listener for the shift key. (For forcing the satellite selection)
- KeyboardFocusManager.getCurrentKeyboardFocusManager()
- .removeKeyEventDispatcher(satelliteShiftDispatcher);
+ KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(
+ satelliteShiftDispatcher);
dispose();
return;
}
+ loginButton.setEnabled(true);
}
/**
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java b/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java
index 5a6f4566..fba3ed2a 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/thrift/ThriftActions.java
@@ -46,7 +46,6 @@ import org.openslx.dozmod.gui.Gui;
import org.openslx.dozmod.gui.MainWindow;
import org.openslx.dozmod.gui.helper.MessageType;
import org.openslx.dozmod.gui.helper.QFileChooser;
-import org.openslx.dozmod.gui.window.LoginWindow;
import org.openslx.dozmod.gui.window.SatelliteListWindow;
import org.openslx.dozmod.thrift.cache.ImageCache;
import org.openslx.dozmod.thrift.cache.LectureCache;
@@ -69,7 +68,6 @@ public class ThriftActions {
private static final long SIZE_CHECK_EXTRA_DL = 50l * 1024l * 1024l;
private static final long SIZE_CHECK_EXTRA_UL = 150l * 1024l * 1024l;
-
/* *******************************************************************************
*
* LOGIN
@@ -83,10 +81,12 @@ public class ThriftActions {
* @param window the parentWindow
* @param data AuthenticationData as received from a successful login, or
* null if trying to resume a saved sessions
- * @param loginWindow
+ * @param forceCustomSatellite show satellite selection dialog even if there
+ * is just one
+ * @param loginWindow
* @return true if initialising the session worked, false otherwise
*/
- public static boolean initSession(AuthenticationData data, Window window) {
+ public static boolean initSession(AuthenticationData data, boolean forceCustomSatellite, Window window) {
Client client = null;
WhoamiInfo whoami = null;
String address = null;
@@ -102,35 +102,23 @@ public class ThriftActions {
masterToken = session.masterToken;
} else {
// after login
- if (data.satellites == null || data.satellites.isEmpty()) {
- // TODO: Ask for manual IP address entry
- Gui.asyncMessageBox(
- "Login erfolgreich, aber für die gewählte Einrichtung ist kein Satellit registriert",
- MessageType.ERROR, LOGGER, null);
- return false;
- }
- // Satellite sat = data.satellites.get(0);
Satellite sat = null;
- if (data.satellites.size() == 1 && !LoginWindow.forceCustomSatellite) {
+ if (data.satellites != null && data.satellites.size() == 1 && !forceCustomSatellite) {
sat = data.satellites.get(0);
} else {
- sat = SatelliteListWindow.open(window , data.satellites);
+ sat = SatelliteListWindow.open(window, data.satellites);
}
if (sat == null || sat.addressList == null) {
// TODO: Ask for manual IP address entry
- Gui.asyncMessageBox(
- "Login erfolgreich, aber es wurde kein Satelliten-Server ausgewählt.\n"
- + "Vorgang abgebrochen.",
- MessageType.ERROR, LOGGER, null);
+ Gui.asyncMessageBox("Login erfolgreich, aber es wurde kein Satelliten-Server ausgewählt.\n"
+ + "Vorgang abgebrochen.", MessageType.ERROR, LOGGER, null);
return false;
}
if (sat.addressList.isEmpty()) {
// TODO: Ask for manual IP address entry
- Gui.asyncMessageBox(
- "Login erfolgreich, aber für den ausgewählten Satelliten-Server ist\n"
- + "keine Adresse hinterlegt. Kann nicht verbinden.",
- MessageType.ERROR, LOGGER, null);
+ Gui.asyncMessageBox("Login erfolgreich, aber für den ausgewählten Satelliten-Server ist\n"
+ + "keine Adresse hinterlegt. Kann nicht verbinden.", MessageType.ERROR, LOGGER, null);
return false;
}
address = sat.addressList.get(0);
@@ -141,8 +129,15 @@ public class ThriftActions {
// try to get a new client
client = ThriftManager.getNewSatelliteClient(GraphicalCertHandler.getSslContext(address), address,
App.THRIFT_SSL_PORT, App.THRIFT_TIMEOUT_MS);
- if (client == null)
+ if (client == null) {
+ if (data != null) {
+ Gui.asyncMessageBox(
+ "Authentifizierung erfolgreich, die Verbindung zum Satelliten-Server ist jedoch nicht möglich.\n\n"
+ + "Möglicherweise ist der Server nicht verfügbar, oder die Netzwerkverbindung gestört.",
+ MessageType.ERROR, null, null);
+ }
return false;
+ }
// check our version
long remoteVersion = 0;
@@ -169,7 +164,7 @@ public class ThriftActions {
Gui.asyncMessageBox(
"Authentifizierung erfolgreich, der Satellit verweigert jedoch die Verbindung.\n\n"
+ "Grund: " + e.number.toString() + " (" + e.message + ")",
- MessageType.ERROR, null, null);
+ MessageType.ERROR, null, null);
}
return false;
} catch (TInvocationException e) {
@@ -371,7 +366,7 @@ public class ThriftActions {
uploadThread.setDaemon(true);
uploadThread.start();
do { // Even more ugly - block the GUI thread so we know whether the
- // upload started, and only then switch to the next page
+ // upload started, and only then switch to the next page
Util.sleep(5);
} while (uploadTask.getFailCount() == 0 && uploadTask.getTransferCount() == 0
&& !uploadTask.isCanceled());
@@ -545,12 +540,12 @@ public class ThriftActions {
}
try {
VmWrapper.wrapVm(destImage, imageName, transInf.getMachineDescription(),
- virtualizerId, osId);
+ virtualizerId, osId, diskImage);
} catch (MetaDataMissingException | IOException e) {
Gui.asyncMessageBox(
"Zur heruntergeladenen VM konnte keine vmx-Datei angelegt werden."
+ "\nSie können versuchen, das Abbild manuell in den VMWare-Player zu importieren.",
- MessageType.WARNING, LOGGER, e);
+ MessageType.WARNING, LOGGER, e);
}
}
});
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/util/VmWrapper.java b/dozentenmodul/src/main/java/org/openslx/dozmod/util/VmWrapper.java
index 2a192171..37bbbc3d 100644
--- a/dozentenmodul/src/main/java/org/openslx/dozmod/util/VmWrapper.java
+++ b/dozentenmodul/src/main/java/org/openslx/dozmod/util/VmWrapper.java
@@ -4,6 +4,7 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.management.ManagementFactory;
+import java.nio.charset.StandardCharsets;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
@@ -17,6 +18,7 @@ import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.openslx.bwlp.thrift.iface.OperatingSystem;
import org.openslx.dozmod.thrift.cache.MetaDataCache;
+import org.openslx.util.vm.DiskImage;
import org.openslx.util.vm.VmwareMetaData;
public class VmWrapper {
@@ -24,19 +26,18 @@ public class VmWrapper {
private static final Logger LOGGER = Logger.getLogger(VmWrapper.class);
public static void wrapVm(File diskFile, String imageName, byte[] machineDescription,
- String virtualizerId, int osId) throws MetaDataMissingException, IOException {
+ String virtualizerId, int osId, DiskImage diskImageInfo) throws MetaDataMissingException,
+ IOException {
// TODO This is very vmware specific, but should support others too some day
if (!diskFile.exists())
throw new FileNotFoundException("Disk file " + diskFile.getAbsolutePath() + " does not exist");
// Handle machine description to generate *.vmx
VmwareMetaData vmwareConfig = null;
- if (machineDescription == null) {
- // TODO: Generate fallback vmx
- return;
- } else {
- vmwareConfig = new VmwareMetaData(MetaDataCache.getOperatingSystems(), machineDescription,
- machineDescription.length);
+ if (machineDescription == null || machineDescription.length < 10) {
+ machineDescription = getFallbackVmx(diskImageInfo);
}
+ vmwareConfig = new VmwareMetaData(MetaDataCache.getOperatingSystems(), machineDescription,
+ machineDescription.length);
// Append disk & NAT
if (!vmwareConfig.addDefaultNat() || !vmwareConfig.addHddTemplate(diskFile.getName(), null, null)) {
throw new MetaDataMissingException();
@@ -71,6 +72,12 @@ public class VmWrapper {
FileUtils.writeByteArrayToFile(vmxFile, vmwareConfig.getFilteredDefinitionArray());
}
+ private static byte[] getFallbackVmx(DiskImage diskImageInfo) throws IOException {
+ String vmx = ResourceLoader.getTextFile("/txt/vmx_template");
+ return vmx.replace("%VM_HW_VERSION%", Integer.toString(diskImageInfo.hwVersion)).getBytes(
+ StandardCharsets.UTF_8);
+ }
+
/**
* Generates a filename based on the given imageName and with the proper
* extension depending on the virtualizer
diff --git a/dozentenmodul/src/main/resources/txt/vmx_template b/dozentenmodul/src/main/resources/txt/vmx_template
index 1b666d2f..87deb84f 100755..100644
--- a/dozentenmodul/src/main/resources/txt/vmx_template
+++ b/dozentenmodul/src/main/resources/txt/vmx_template
@@ -1,10 +1,10 @@
-#!/usr/bin/vmware
.encoding = "UTF-8"
config.version = "8"
+#SLX_HDD_BUS = "IDE"
+
# general hardware (ehci, 3d accel)
ehci.present = "TRUE"
-mks.gl.allowBlacklistedDrivers = "TRUE"
mks.enable3d = "FALSE"
monitor.virtual_mmu = "automatic"
@@ -12,20 +12,10 @@ monitor.virtual_exec = "automatic"
# id
virtualHW.version = "%VM_HW_VERSION%"
-displayName = "%VM_DISPLAY_NAME%"
-guestOS = "%VM_GUEST_OS%"
-
-# CPU/MEM
-numvcpus = "%VM_CPU_COUNT%"
-cpuid.coresPerSocket = "%VM_CPU_COUNT%"
-maxvcpus = "%VM_CPU_COUNT%"
-memsize = "%VM_RAM_SIZE%"
-MemAllowAutoScaleDown = "FALSE"
-MemTrimRate = "-1"
+guestOS = "other"
# ide-disks
ide0:0.present = "TRUE"
-ide0:0.fileName = "%VM_DISK_PATH%"
ide1:0.present = "TRUE"
ide1:0.autodetect = "TRUE"
ide1:0.fileName = "auto detect"
@@ -33,11 +23,8 @@ ide1:0.deviceType = "cdrom-raw"
# nics
ethernet0.present = "TRUE"
-ethernet0.addressType = "static"
ethernet0.virtualDev = "e1000"
ethernet0.connectionType = "nat"
-ethernet0.vnet = "/dev/vmnet1"
-ethernet0.address = "00:50:56:15:00:4E"
ethernet0.wakeOnPcktRcv = "FALSE"
# sound