From ce58bfe0a7c0496d95c40f0bd859b41c669bc0bb Mon Sep 17 00:00:00 2001 From: Dominic Wienzek Date: Wed, 29 Apr 2020 10:05:46 +0200 Subject: [PATCH] First commit --- .gitignore | 135 ++++++++++++++++++ README.md | 18 +++ pom.xml | 121 ++++++++++++++++ .../DockerProcessWrapper.java | 85 +++++++++++ 4 files changed, 359 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 pom.xml create mode 100644 src/main/java/de/dwienzek/dockerprocesswrapper/DockerProcessWrapper.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2b4357e --- /dev/null +++ b/.gitignore @@ -0,0 +1,135 @@ +# Created by .ignore support plugin (hsz.mobi) +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea + +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/dictionaries + +# Sensitive or high-churn files: +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.xml +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml + +# Gradle: +.idea/**/gradle.xml +.idea/**/libraries + +# CMake +cmake-build-debug/ + +# Mongo Explorer plugin: +.idea/**/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +### NotepadPP template +# Notepad++ backups # +*.bak +### Linux template +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* +### LibreOffice template +# LibreOffice locks +.~lock.*# +### macOS template +# General +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk +### Windows template +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# IntelliJ Project File +*.iml + +#Maven +target/ +*.versionsBackup +dependency-reduced-pom.xml + +#JavaDocs +javadoc/ + diff --git a/README.md b/README.md new file mode 100644 index 0000000..517d47f --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# DockerProcessWrapper + +A simple process wrapper which runs the process as it self but sends a command to it, if the TERM signal will be received. This is useful for applications in docker containers. It is written with Java 8. + +## Table of Contents + +* [Authors](#authors--contributors) +* [License](#license) + +## Authors & Contributors + +* **Dominic Wienzek** - *Development* - [Skyleiger](https://github.com/skyleiger) + +See also the list of [contributors](https://github.com/Skyleiger/RadioBots-GameCloud/contributors) who participated in this project. + +## License + +This project is is the property of the author(s) and may only be used with the consent of the author(s). Other uses are not permitted. diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..36b3f2a --- /dev/null +++ b/pom.xml @@ -0,0 +1,121 @@ + + + 4.0.0 + + de.dwienzek + docker-process-wrapper + 0.0.1-SNAPSHOT + + + 11 + 11 + 11 + UTF-8 + UTF-8 + + + + + Dominic Wienzek + dominic.wienzek@gmail.com + https://dominicwienzek.de + + + + + + net.sf.jopt-simple + jopt-simple + 5.0.4 + compile + + + + + DockerProcessWrapper + clean install + + + + org.apache.maven.plugins + maven-clean-plugin + 3.1.0 + + + + * + + *.versionsBackup + + + + javadoc + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + + true + true + + + de.dwienzek.dockerprocesswrapper.DockerProcessWrapper + DockerProcessWrapper + DockerProcessWrapper + ${project.version} + ${project.version} + ${project.version} + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.3 + + + package + + shade + + + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + attach-sources + + jar + + + + + + + + \ No newline at end of file diff --git a/src/main/java/de/dwienzek/dockerprocesswrapper/DockerProcessWrapper.java b/src/main/java/de/dwienzek/dockerprocesswrapper/DockerProcessWrapper.java new file mode 100644 index 0000000..4e694dd --- /dev/null +++ b/src/main/java/de/dwienzek/dockerprocesswrapper/DockerProcessWrapper.java @@ -0,0 +1,85 @@ +package de.dwienzek.dockerprocesswrapper; + +import joptsimple.OptionParser; +import joptsimple.OptionSet; +import sun.misc.Signal; + +import java.io.Console; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class DockerProcessWrapper { + + public static void main(String[] args) throws IOException { + OptionParser optionParser = new OptionParser(); + optionParser.accepts("help", "Show the help"); + optionParser.accepts("execute", "The command to execute").withRequiredArg(); + optionParser.accepts("directory", "The execute directory").withOptionalArg(); + optionParser.accepts("shutdown-command", "The shutdown command sent to the process").withRequiredArg(); + + OptionSet optionSet = optionParser.parse(args); + + if (optionSet.has("help")) { + optionParser.printHelpOn(System.out); + return; + } + + if (!optionSet.has("execute") || !optionSet.has("shutdown-command")) { + System.out.println("Please enter the correct arguments."); + System.out.println("Example: DockerProcessWrapper.jar --execute --shutdown-command (--directory )"); + System.out.println("Use --help for help."); + } + + String commandString = (String) optionSet.valueOf("execute"); + List command = new ArrayList<>(); + if (commandString.contains(" ")) { + command.addAll(Arrays.asList(commandString.split(" "))); + } else { + command.add(commandString); + } + + Process process; + ProcessBuilder processBuilder = new ProcessBuilder().redirectOutput(ProcessBuilder.Redirect.INHERIT).redirectError(ProcessBuilder.Redirect.INHERIT).command(command); + if (optionSet.has("directory")) { + processBuilder.directory(new File((String) optionSet.valueOf("directory"))); + } + process = processBuilder.start(); + + Thread thread = new Thread() { + @Override + public void run() { + Console console = System.console(); + String line; + while (!isInterrupted() && (line = console.readLine()) != null) { + try { + process.getOutputStream().write((line + "\n").getBytes()); + process.getOutputStream().flush(); + } catch (IOException exception) { + exception.printStackTrace(); + } + } + } + }; + thread.setDaemon(true); + thread.start(); + + Signal.handle(new Signal("TERM"), signal -> { + try { + process.getOutputStream().write((optionSet.valueOf("shutdown-command") + "\n").getBytes()); + process.getOutputStream().flush(); + } catch (IOException exception) { + exception.printStackTrace(); + } + }); + + try { + process.waitFor(); + } catch (InterruptedException exception) { + exception.printStackTrace(); + } + } + +}