Skip to content

Commit

Permalink
Merge branch 'master' into feat/preview-col-names
Browse files Browse the repository at this point in the history
  • Loading branch information
timcadman authored Oct 3, 2024
2 parents e2c7a69 + 45b11f5 commit e952aed
Show file tree
Hide file tree
Showing 17 changed files with 362 additions and 169 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ version: 2.1
jobs:
build:
docker:
- image: eclipse-temurin:17.0.10_7-jdk-jammy
- image: eclipse-temurin:17.0.12_7-jdk-jammy

working_directory: ~/repo
resource_class: large
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM --platform=linux/amd64 eclipse-temurin:17.0.10_7-jdk-focal
FROM --platform=linux/amd64 eclipse-temurin:17.0.12_7-jdk-focal
VOLUME /data
VOLUME /config
VOLUME /logs
Expand Down
2 changes: 1 addition & 1 deletion armadillo/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ dependencies {
//other
implementation 'org.rosuda.REngine:REngine:2.1.0'
implementation 'org.rosuda.REngine:Rserve:1.8.1'
implementation 'io.swagger.core.v3:swagger-annotations:2.2.20'
implementation 'io.swagger.core.v3:swagger-annotations:2.2.23'
implementation 'com.google.auto.value:auto-value-annotations:1.10.4'
implementation 'org.obiba.datashield:ds4j-core:2.1.0'
implementation 'org.obiba.datashield:ds4j-r:2.1.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.stereotype.Component;

import static org.molgenis.armadillo.security.RunAs.runAsSystem;

@Component
@Endpoint(id = "rserveProcesses")
public class RProcessEndpoint {
Expand All @@ -41,7 +43,7 @@ public List<REnvironment> getRServeEnvironments() {

<T> T doWithConnection(String environmentName, Function<RServerConnection, T> action) {
var environment =
profileService.getAll().stream()
runAsSystem(profileService::getAll).stream()
.filter(it -> environmentName.equals(it.getName()))
.map(ProfileConfig::toEnvironmentConfigProps)
.findFirst()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ protected SecurityFilterChain oauthAndBasic(HttpSecurity http) throws Exception
"/v3/**",
"/swagger-ui/**",
"/ui/**",
"/actuator/prometheus",
"/swagger-ui.html")
.permitAll()
.requestMatchers(EndpointRequest.to(InfoEndpoint.class, HealthEndpoint.class))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,28 +223,34 @@ private static Workspace toWorkspace(ObjectMetadata item) {
.build();
}

private void trySaveWorkspace (ArmadilloWorkspace workspace, Principal principal, String id) {
try {
storageService.save(
workspace.createInputStream(),
getUserBucketName(principal),
getWorkspaceObjectName(id),
APPLICATION_OCTET_STREAM);
} catch (StorageException e) {
throw new StorageException(e);
}
}
public void saveWorkspace(InputStream is, Principal principal, String id) {
// Load root dir
File drive = new File("/");
long usableSpace = drive.getUsableSpace();

ArmadilloWorkspace workspace = storageService.getWorkSpace(is);
long fileSize = workspace.getSize();
if (usableSpace > fileSize * 2L) {
try {
storageService.save(
workspace.createInputStream(),
getUserBucketName(principal),
getWorkspaceObjectName(id),
APPLICATION_OCTET_STREAM);
} catch (StorageException e) {
throw new StorageException(e);
try {
ArmadilloWorkspace workspace = storageService.getWorkSpace(is);
long fileSize = workspace.getSize();
if (usableSpace > fileSize * 2L) {
trySaveWorkspace(workspace, principal, id);
} else {
throw new StorageException(
format(
"Can't save workspace: workspace too big (%s), not enough space left on device. Try to make your workspace smaller and/or contact the administrator to increase diskspace.",
getHumanReadableByteCount(fileSize)));
}
} else {
throw new StorageException(
format(
"Can't save workspace: workspace too big (%s), not enough space left on device. Try to make your workspace smaller and/or contact the administrator to increase diskspace.",
getHumanReadableByteCount(fileSize)));
} catch (StorageException e) {
throw new StorageException(e.getMessage().replace("load", "save"));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package org.molgenis.armadillo.storage;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.io.IOUtils;
import org.molgenis.armadillo.exceptions.StorageException;

public class ArmadilloWorkspace {
byte[] content;
public static final String WORKSPACE_TOO_BIG_ERROR = "Unable to load workspace. Maximum supported workspace size is 2GB";

public ArmadilloWorkspace(InputStream is) {
content = toByteArray(is);
Expand All @@ -16,8 +16,10 @@ public ArmadilloWorkspace(InputStream is) {
private byte[] toByteArray(InputStream is) {
try {
return IOUtils.toByteArray(is);
} catch (IOException e) {
throw new StorageException("Unable to read workspace");
} catch (OutOfMemoryError e) {
throw new StorageException(WORKSPACE_TOO_BIG_ERROR);
} catch (Exception e) {
throw new StorageException("Unable to load workspace, because: " + e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,16 @@ void testSaveWorkspaceReturnsErrorWhenTooBig() {
StorageException.class, () -> armadilloStorage.saveWorkspace(is, principal, "test"));
}

@Test
void testSaveWorkspaceReturnsErrorWhenBiggerThan2Gbs() {
when(storageService.getWorkSpace(is)).thenThrow(new StorageException(ArmadilloWorkspace.WORKSPACE_TOO_BIG_ERROR));
try {
armadilloStorage.saveWorkspace(is, principal, "test");
} catch (StorageException e) {
assertEquals("Unable to save workspace. Maximum supported workspace size is 2GB", e.getMessage());
}
}

@Test
void testSaveWorkspaceChecksBucketName() {
ArmadilloWorkspace workspaceMock = mock(ArmadilloWorkspace.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,15 @@ void testGetByteOfInputStreamThrowsError() throws IOException {
when(isMock.read(any(byte[].class))).thenThrow(IOException.class);
assertThrows(StorageException.class, () -> new ArmadilloWorkspace(isMock));
}

@Test
void testGetByteOfInputStreamThrowsMemoryError() throws IOException {
InputStream isMock = mock(InputStream.class);
when(isMock.read(any(byte[].class))).thenThrow(OutOfMemoryError.class);
try {
new ArmadilloWorkspace(isMock);
} catch(StorageException e) {
assertEquals(ArmadilloWorkspace.WORKSPACE_TOO_BIG_ERROR, e.getMessage());
}
}
}
140 changes: 140 additions & 0 deletions docs/minor-release-update.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Minor Version Upgrade Manual: Procedures for y.z Releases

> Note: This manual is intended for minor version updates within the latest major release. For example, you can use it to update from version 4.1 to 4.7.1. For upgrading to a new major version, please refer to the specific manuals dedicated to major version upgrades.
## Check latest version

For the latest 4.y.z release check https://github.com/molgenis/molgenis-service-armadillo/releases/latest. This will redirect to a v4.y.z page.

# Updating Armadillo

### 1. Stop docker containers

First, log in to the Armadillo UI and navigate to the Profiles tab. Now, click 'Stop' for each profile listed.

Next, stop any unnecessary containers.

The commands provided are indicative, so adjust them as needed.

```bash
# should return empty list (i.e. default, xenon, rock)
docker container list

# remove containers not needed
docker container stop <id>
```

## 2. Download required files

Make a note of the version number ie. `v4.7.1` as you need to download some files from the terminal using the update script.

### 2.1 Update script

You need to be root user.

```bash
cd /root

# Make sure to change the versions number v4.y.z
mkdir v4.y.z
cd v4.y.z

# Check directory location
pwd
```

```bash
# Change the version number v4.y.z then run command
wget https://raw.githubusercontent.com/molgenis/molgenis-service-armadillo/v4.y.z/scripts/install/armadillo-check-update.sh
```

Make the script runnable
```bash
chmod u+x armadillo-check-update.sh
```

### 2.2 Run update script

You can run the following script to download the new Armadillo version.

> The output could help us to help you fix problems.
```bash
# Change the version number v4.y.z
./armadillo-check-update.sh 4.y.z
```

Once the script has completed, you can verify that the Armadillo JAR file has been downloaded by checking the directory:

```bash
# See all jar files on your system
ls -ltr /usr/share/armadillo/application/
```

### 3. Make backup of system config

```bash
# Still in the correct directory? (`/root/v4.y.z`)
pwd
```

We make a backup into the same `v4.y.z` directory but that is not strictly needed.

```bash
cp -r /usr/share/armadillo/data/system ./
```

should result in:

```bash
ls system/
# access.json profiles.json
```

## 4. Restart application using new version

Armadillo has not yet been updated, follow the following steps to do so:

### 4.1 Stop Armadillo

```bash
systemctl stop armadillo
```

### 4.2 Link new version

```bash
# List application files
ls -l /usr/share/armadillo/application/

# Remove the linked file
rm /usr/share/armadillo/application/armadillo.jar

# Attach new linked file and dont forget to change the version number v4.y.z
ln -s /usr/share/armadillo/application/armadillo-4.y.z.jar /usr/share/armadillo/application/armadillo.jar

# Check result
ls -l /usr/share/armadillo/application/
```

### 4.3 Restart Armadillo

```bash
systemctl start armadillo
systemctl status armadillo
```

## 5. Log on to the UI

Go to your armadillo website. Is the version in the left top corner updated? This means the update was successful. We're
almost finished.

## 6. Start profiles

Login into the website and go to the profiles tab. Now you can start all the profiles again.

Everything should now be working correctly. You can try and login to your server via the central analysis server, using
the `DSMolgenisArmadillo` (2.0.5 or up) package to test.

Enjoy =)
Team Armadillo
8 changes: 7 additions & 1 deletion docs/ops/installing.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ The values needed are:

You need a SSL certificate to configuring the front-end proxy and make the browser use **https** before putting data on the server.

If SELinux is enabled, run the following command to ensure that the application can connect to required services:

```bash
setsebool -P httpd_can_network_connect on
```

## Installing Armadillo as service

We run Armadillo in production as a Linux service on Ubuntu, ensuring it gets restarted when the server is rebooted. You might be able to reproduce also on CentOS (using yum instead of apt).
Expand Down Expand Up @@ -184,4 +190,4 @@ For questions on other linux release you can email molgenis-operations@umcg.nl
## What's next?

* [For the server owner or data manager who need to put data on to the server](https://molgenis.github.io/molgenis-r-armadillo/)
* [For the researcher who want to start analyzing the data on the server](https://molgenis.github.io/molgenis-r-datashield/)
* [For the researcher who want to start analyzing the data on the server](https://molgenis.github.io/molgenis-r-datashield/)
2 changes: 1 addition & 1 deletion docs/ui.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ By default, some fields will be set. Please update them to install the correct p

Possible images can be found on [dockerhub](https://hub.docker.com/search?q=datashield%2Farmadillo-rserver). We
recommend selecting one of the
[DataSHIELD standard profiles](https://www.datashield.org/help/standard-profiles-and-plaforms). The image name of those
[DataSHIELD standard profiles](https://wiki.datashield.org/en/opmanag/standard-profiles-and-platforms). The image name of those
profiles can be found on the dockerhub link above.

Although the default `port` setting should find an available port, please keep in mind that the port has to be unique,
Expand Down
1 change: 1 addition & 0 deletions r/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ dependencies {
implementation 'com.google.auto.value:auto-value-annotations:1.10.4'
implementation 'org.apache.commons:commons-text:1.11.0'
implementation 'org.json:json:20240303'
implementation 'org.apache.httpcomponents.client5:httpclient5:5.3.1'

//test
testImplementation('org.springframework.boot:spring-boot-starter-test') {
Expand Down
Loading

0 comments on commit e952aed

Please sign in to comment.