aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/io/github
diff options
context:
space:
mode:
authoraxtloss <axtlos@getcryst.al>2023-05-31 20:54:55 +0200
committeraxtloss <axtlos@getcryst.al>2023-05-31 20:54:55 +0200
commit3999be65f43c30d22c93e28c8f1554c923973d23 (patch)
tree884c99b032e2fcd66960cc6c10395ae08e5ee7cf /src/main/java/io/github
parent3bfe8ba05a429e726001b88c63f736f1bbed3509 (diff)
downloadjshipit-3999be65f43c30d22c93e28c8f1554c923973d23.tar.gz
jshipit-3999be65f43c30d22c93e28c8f1554c923973d23.tar.bz2
Add permissions configuration file
Diffstat (limited to 'src/main/java/io/github')
-rw-r--r--src/main/java/io/github/jshipit/Commands.java3
-rw-r--r--src/main/java/io/github/jshipit/ConfigParser.java45
-rw-r--r--src/main/java/io/github/jshipit/ContainerManager.java116
-rwxr-xr-xsrc/main/java/io/github/jshipit/JshipIT.java43
-rw-r--r--src/main/java/io/github/jshipit/Main.java2
5 files changed, 191 insertions, 18 deletions
diff --git a/src/main/java/io/github/jshipit/Commands.java b/src/main/java/io/github/jshipit/Commands.java
index 1b4b913..e4ed5ec 100644
--- a/src/main/java/io/github/jshipit/Commands.java
+++ b/src/main/java/io/github/jshipit/Commands.java
@@ -41,6 +41,9 @@ class CommandCreate {
@Parameter(names = {"--image", "-i"}, description = "Image of the container")
public String containerImage;
+ @Parameter(names = {"--isolated", "-a"}, description = "If the container should be isolated from the host", required = false)
+ public boolean containerIsolated = true;
+
@Parameter(names = "--help", help = true)
private boolean help;
}
diff --git a/src/main/java/io/github/jshipit/ConfigParser.java b/src/main/java/io/github/jshipit/ConfigParser.java
new file mode 100644
index 0000000..0b19acd
--- /dev/null
+++ b/src/main/java/io/github/jshipit/ConfigParser.java
@@ -0,0 +1,45 @@
+package io.github.jshipit;
+
+import com.moandjiezana.toml.Toml;
+
+import java.io.File;
+import java.util.List;
+
+public class ConfigParser {
+ public String configPath;
+
+ public ConfigParser(String configPath) {
+ this.configPath = configPath;
+ }
+
+ public void parseConfig() {
+ System.out.println("Parsing config");
+ Toml toml = new Toml().read(new File(this.configPath));
+ }
+
+ public String getString(String key) {
+ Toml toml = new Toml().read(new File(this.configPath));
+ return toml.getString(key);
+ }
+
+ public boolean getBoolean(String key) {
+ Toml toml = new Toml().read(new File(this.configPath));
+ return toml.getBoolean(key);
+ }
+
+ public List<String> getList(String key) {
+ Toml toml = new Toml().read(new File(this.configPath));
+ return toml.getList(key);
+ }
+
+ public long getLong(String key) {
+ Toml toml = new Toml().read(new File(this.configPath));
+ return toml.getLong(key);
+ }
+
+ public double getDouble(String key) {
+ Toml toml = new Toml().read(new File(this.configPath));
+ return toml.getDouble(key);
+ }
+
+}
diff --git a/src/main/java/io/github/jshipit/ContainerManager.java b/src/main/java/io/github/jshipit/ContainerManager.java
index d276f75..4428465 100644
--- a/src/main/java/io/github/jshipit/ContainerManager.java
+++ b/src/main/java/io/github/jshipit/ContainerManager.java
@@ -17,18 +17,19 @@ public class ContainerManager {
private String containerImage;
private String containerTag;
private String containerApiRepo;
-
private String containerCommand;
private List<String> containerMounts;
+ private boolean containerIsolated;
private OCIDataStore dataStore;
- public ContainerManager(String containerName, String containerImage, String containerTag, String containerApiRepo, String containerRepo, List<String> containerMounts, OCIDataStore dataStore) {
+ public ContainerManager(String containerName, String containerImage, String containerTag, String containerApiRepo, String containerRepo, boolean containerIsolated, OCIDataStore dataStore) {
this.containerName = containerName;
this.containerImage = containerImage;
this.containerTag = containerTag;
this.containerApiRepo = containerApiRepo;
this.containerRepo = containerRepo;
- this.containerMounts = containerMounts;
+ this.containerMounts = null;
+ this.containerIsolated = containerIsolated;
this.dataStore = dataStore;
}
@@ -64,6 +65,36 @@ public class ContainerManager {
new File(containerDirectory + "/containerOverlay").mkdirs(); // The upper directory of the overlay mount, user data and any changes to root will be stored here
new File(containerDirectory + "/root").mkdirs(); // The root directory of the overlay mount
new File(containerDirectory+"/work").mkdirs(); // The work directory of the overlay mount
+
+ // Create the container TOML config file
+ try {
+ new File(containerDirectory + "/config.toml").createNewFile();
+ FileOutputStream fos = new FileOutputStream(containerDirectory + "/config.toml");
+
+ String str = "[container]\n";
+ str += "command = \"" + this.containerCommand + "\"\n";
+ str += "hostname = \"" + this.containerName + "\"\n\n";
+ str += "[permissions]\n";
+ str += "unshare-all = false\n";
+ str += "unshare-net = false\n";
+ str += "unshare-user = false\n";
+ str += "unshare-ipc = false\n";
+ str += "unshare-pid = false\n";
+ str += "unshare-uts = true\n";
+ str += "unshare-cgroup = false\n";
+ str += "mount-dev = true\n";
+ str += "mount-proc = true\n";
+ str += "mount-bind = []\n";
+
+ byte[] b = str.getBytes();
+ fos.write(b);
+ fos.close();
+ } catch (FileNotFoundException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
}
/*
@@ -104,6 +135,7 @@ public class ContainerManager {
public void runCommand() {
String containerDirectory = dataStore.getContainerPath(this.containerName);
String dataStorePath = dataStore.getPath();
+ ConfigParser configParser = new ConfigParser(containerDirectory+"/config.toml");
File configPath = new File(dataStorePath + "/" + this.containerImage + "/" + this.containerTag + "/config"); // Path to the config file of the image
String content = null;
@@ -122,8 +154,8 @@ public class ContainerManager {
config.get("Env").forEach((JsonNode envVar) -> { // Get the environment variables specified in the config file
env.add(envVar.asText());
});
- cmd = config.get("Cmd").get(0).asText(); // Get the command specified in the config file
- hostname = config.get("Hostname").asText(); // Get the hostname specified in the config file
+ cmd = configParser.getString("container.command").equals("null") ? config.get("Cmd").get(0).asText() : configParser.getString("container.command"); // Get the command specified in the config file
+ hostname = configParser.getString("container.hostname").equals("null") ? config.get("Hostname").asText() : configParser.getString("container.hostname"); // Get the hostname specified in the config file
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
@@ -140,16 +172,12 @@ public class ContainerManager {
bwrapCommand.add("--bind "+containerDirectory+"/root / --chdir /"); // Bind the root to / inside the bwrap namespace
- if (this.containerMounts != null) {
- for (String mount : containerMounts) {
- bwrapCommand.add("--bind "+mount.split(":")[0]+" "+mount.split(":")[1]); // Bind the mount to the destination specified in the config file
- }
+ if (!configParser.getBoolean("permissions.unshare-all")) {
+ processBwrapPermissions(bwrapCommand);// Process the permissions specified in the config file
}
- bwrapCommand.add("--ro-bind /etc/resolv.conf /etc/resolv.conf"); // Bind the host resolv.conf to the container
- bwrapCommand.add("--share-net"); // Share the network namespace
- bwrapCommand.add("--unshare-uts --hostname "+ (!hostname.isBlank() ? hostname : this.containerName+"-"+this.containerImage)); // Unshare the UTS namespace and set the hostname
bwrapCommand.add("/bin/sh -c '"+(this.containerCommand != null ? this.containerCommand : cmd)+"'"); // Run the command specified in the config file or the command specified in the constructor
+
SysUtils sysUtils = new SysUtils();
String bwrapCMD = sysUtils.execInBwrap(bwrapCommand.toArray(new String[0]), false);
String mountCMD = startContainer(true);
@@ -165,6 +193,70 @@ public class ContainerManager {
}
}
+ private void processBwrapPermissions(List<String> bwrapCommand) {
+ ConfigParser configParser = new ConfigParser(dataStore.getContainerPath(this.containerName)+"/config.toml");
+ List<String> configMounts = configParser.getList("permissions.mount-bind");
+ if (configMounts.size() > 0) {
+ for (String mount : configMounts) {
+ bwrapCommand.add("--bind "+mount.split(":")[0]+" "+mount.split(":")[1]); // Bind the mount to the destination specified in the config file
+ }
+ }
+ if (this.containerMounts != null) {
+ for (String mount : containerMounts) {
+ bwrapCommand.add("--bind "+mount.split(":")[0]+" "+mount.split(":")[1]); // Bind the mount to the destination specified by the user
+ }
+ }
+
+ if (configParser.getBoolean("permissions.mount-dev")) {
+ bwrapCommand.add("--dev /dev"); // Mount /dev
+ }
+
+ if (configParser.getBoolean("permissions.mount-proc")) {
+ bwrapCommand.add("--proc /proc"); // Mount /proc
+ }
+
+ if (!configParser.getBoolean("permissions.unshare-net")) {
+ bwrapCommand.add("--ro-bind /etc/resolv.conf /etc/resolv.conf"); // Bind the host resolv.conf to the container
+ bwrapCommand.add("--share-net"); // Share the network namespace
+ } else {
+ bwrapCommand.add("--unshare-net"); // Unshare the network namespace
+ }
+
+ if (configParser.getBoolean("permissions.unshare-uts")) {
+ bwrapCommand.add("--unshare-uts"); // Unshare the UTS namespace
+
+ bwrapCommand.add("--hostname "+(configParser.getString("container.hostname").equals("null") ? this.containerName : configParser.getString("container.hostname"))); // Set the hostname
+ }
+
+ if (configParser.getBoolean("permissions.unshare-user")) {
+ bwrapCommand.add("--unshare-user"); // Unshare the user namespace
+ }
+
+ if (configParser.getBoolean("permissions.unshare-ipc")) {
+ bwrapCommand.add("--unshare-ipc"); // Unshare the IPC namespace
+ }
+
+ if (configParser.getBoolean("permissions.unshare-pid")) {
+ bwrapCommand.add("--unshare-pid"); // Unshare the PID namespace
+ }
+
+ if (configParser.getBoolean("permissions.unshare-uts")) {
+ bwrapCommand.add("--unshare-uts"); // Unshare the UTS namespace
+ }
+
+ if (configParser.getBoolean("permissions.unshare-cgroup")) {
+ bwrapCommand.add("--unshare-cgroup"); // Unshare the cgroup namespace
+ }
+
+ if (configParser.getBoolean("permissions.mount-dev")) {
+ bwrapCommand.add("--dev /dev"); // Mount /dev
+ }
+
+ if (configParser.getBoolean("permissions.mount-proc")) {
+ bwrapCommand.add("--proc /proc"); // Mount /proc
+ }
+ }
+
/*
* Delete a container
*/
diff --git a/src/main/java/io/github/jshipit/JshipIT.java b/src/main/java/io/github/jshipit/JshipIT.java
index 4304051..a48fc8e 100755
--- a/src/main/java/io/github/jshipit/JshipIT.java
+++ b/src/main/java/io/github/jshipit/JshipIT.java
@@ -49,7 +49,16 @@ public class JshipIT {
apiRepo = "registry.docker.io";
}
- ContainerManager containerManager = new ContainerManager(commandCreate.containerName, containerImage, commandCreate.containerImage.split(":")[1], apiRepo, containerRepo, null, dataStore);
+ ContainerManager containerManager = new ContainerManager(
+ commandCreate.containerName,
+ containerImage,
+ commandCreate.containerImage.split(":")[1],
+ apiRepo,
+ containerRepo,
+ commandCreate.containerIsolated,
+ dataStore
+ );
+
containerManager.createContainer();
} else if (commands.getParsedCommand().equals("pull")) {
@@ -67,15 +76,39 @@ public class JshipIT {
}
System.out.println("Pulling image " + containerImage + " from " + apiRepo + "/" + containerRepo);
- dataStore.createImage(apiRepo, containerRepo, containerImage, commandPull.containerImage.split(":")[1]);
+ dataStore.createImage(
+ apiRepo,
+ containerRepo,
+ containerImage,
+ commandPull.containerImage.split(":")[1]
+ );
+
} else if (commands.getParsedCommand().equals("start")) {
- ContainerManager containerManager = new ContainerManager(commandStart.containerName, commandStart.containerCommand, commandStart.containerMount, dataStore);
+ ContainerManager containerManager = new ContainerManager(
+ commandStart.containerName,
+ commandStart.containerCommand,
+ commandStart.containerMount,
+ dataStore
+ );
+
containerManager.runCommand();
} else if (commands.getParsedCommand().equals("shell")) {
- ContainerManager containerManager = new ContainerManager(commandShell.containerName, "/bin/sh", commandShell.containerMount, dataStore); // A proper linux system should always have /bin/sh, skill issue if it doesn't
+ ContainerManager containerManager = new ContainerManager(
+ commandShell.containerName,
+ "/bin/sh", // A proper linux system should always have /bin/sh, skill issue if it doesn't
+ commandShell.containerMount,
+ dataStore
+ );
+
containerManager.runCommand();
} else if (commands.getParsedCommand().equals("delete")) {
- ContainerManager containerManager = new ContainerManager(commandDelete.containerName, null, null, dataStore);
+ ContainerManager containerManager = new ContainerManager(
+ commandDelete.containerName,
+ null,
+ null,
+ dataStore
+ );
+
containerManager.deleteContainer();
}
}
diff --git a/src/main/java/io/github/jshipit/Main.java b/src/main/java/io/github/jshipit/Main.java
index 51a88a7..1bac127 100644
--- a/src/main/java/io/github/jshipit/Main.java
+++ b/src/main/java/io/github/jshipit/Main.java
@@ -3,7 +3,7 @@ package io.github.jshipit;
public class Main {
public static void main(String[] args) {
- new JshipIT(args); // I HATE STATIC FUNCTIONS
+ new JshipIT(args);
}
}