Compare commits
28 Commits
plugin-mvp
...
docker-0.6
Author | SHA1 | Date | |
---|---|---|---|
![]() |
9e451460da | ||
![]() |
ffa52c129a | ||
b779fb75a0 | |||
fbe6b53278 | |||
b2bd95788d | |||
83d4a2624b | |||
03e20e21aa | |||
8a08955675 | |||
4ec54ebe54 | |||
758af6f48e | |||
a7bdd47fcd | |||
f7caa77a18 | |||
7641f64536 | |||
02baaace48 | |||
![]() |
d90067ff39 | ||
c910a215f5 | |||
65e073b1b9 | |||
489a7518c3 | |||
3733e48bbd | |||
c3723a1348 | |||
0e0f52bc77 | |||
60b9e990cf | |||
28ad0ae30f | |||
9142de85cd | |||
4eb31c11e3 | |||
e8afe358a5 | |||
![]() |
3db4317fc1 | ||
![]() |
5ad2b28527 |
12
.dockerignore
Normal file
12
.dockerignore
Normal file
@@ -0,0 +1,12 @@
|
||||
# Dot directories
|
||||
.gradle/
|
||||
.idea/
|
||||
.git/
|
||||
|
||||
# Build directories
|
||||
build/
|
||||
**/build/
|
||||
|
||||
# We execute COPY . .
|
||||
# Modifying these files would unnecessarily invalidate the build context
|
||||
Dockerfile
|
64
Dockerfile
Normal file
64
Dockerfile
Normal file
@@ -0,0 +1,64 @@
|
||||
FROM jlesage/baseimage-gui:alpine-3.10-glibc
|
||||
|
||||
# Docker image version is provided via build arg.
|
||||
ARG DOCKER_IMAGE_VERSION=unknown
|
||||
|
||||
# JDK version
|
||||
ARG JDK=9
|
||||
|
||||
# Important directories
|
||||
ARG TMP_DIR=/muwire-tmp
|
||||
ENV APP_HOME=/muwire
|
||||
|
||||
# Define working directory.
|
||||
WORKDIR $TMP_DIR
|
||||
|
||||
# Put sources into dir
|
||||
COPY . .
|
||||
|
||||
# Install final dependencies
|
||||
RUN add-pkg openjdk${JDK}-jre
|
||||
|
||||
# Build and untar in future distribution dir
|
||||
RUN add-pkg --virtual openjdk${JDK}-jdk \
|
||||
&& ./gradlew --no-daemon clean assemble \
|
||||
&& mkdir -p ${APP_HOME} \
|
||||
# Extract to ${APP_HOME and ignore the first dir
|
||||
# First dir in tar is the "MuWire-<version>"
|
||||
&& tar -C ${APP_HOME} --strip 1 -xvf gui/build/distributions/MuWire*.tar \
|
||||
# Cleanup
|
||||
&& rm -rf "${TMP_DIR}" /root/.gradle /root/.java \
|
||||
&& del-pkg openjdk${JDK}-jdk
|
||||
|
||||
WORKDIR ${APP_HOME}
|
||||
|
||||
# Maximize only the main/initial window.
|
||||
RUN \
|
||||
sed-patch 's/<application type="normal">/<application type="normal" title="MuWire">/' \
|
||||
/etc/xdg/openbox/rc.xml
|
||||
|
||||
# Generate and install favicons.
|
||||
RUN \
|
||||
APP_ICON_URL=https://github.com/zlatinb/muwire/raw/master/gui/griffon-app/resources/MuWire-128x128.png && \
|
||||
install_app_icon.sh "$APP_ICON_URL"
|
||||
|
||||
# Add files.
|
||||
COPY docker/rootfs/ /
|
||||
|
||||
# Set environment variables.
|
||||
ENV APP_NAME="MuWire" \
|
||||
S6_KILL_GRACETIME=8000
|
||||
|
||||
# Define mountable directories.
|
||||
VOLUME ["$APP_HOME/.MuWire"]
|
||||
VOLUME ["/incompletes"]
|
||||
VOLUME ["/output"]
|
||||
|
||||
|
||||
# Metadata.
|
||||
LABEL \
|
||||
org.label-schema.name="muwire" \
|
||||
org.label-schema.description="Docker container for MuWire" \
|
||||
org.label-schema.version="$DOCKER_IMAGE_VERSION" \
|
||||
org.label-schema.vcs-url="https://github.com/zlatinb/muwire" \
|
||||
org.label-schema.schema-version="1.0"
|
65
README.md
65
README.md
@@ -6,7 +6,7 @@ The current stable release - 0.6.8 is avaiable for download at https://muwire.co
|
||||
|
||||
You can find technical documentation in the [doc] folder. Also check out the [Wiki] for various other documentation.
|
||||
|
||||
### Building
|
||||
## Building
|
||||
|
||||
You need JDK 9 or newer. After installing that and setting up the appropriate paths, just type
|
||||
|
||||
@@ -21,7 +21,7 @@ If you want to run the unit tests, type
|
||||
|
||||
If you want to build binary bundles that do not depend on Java or I2P, see the [muwire-pkg] project
|
||||
|
||||
### Running the GUI
|
||||
## Running the GUI
|
||||
|
||||
Type
|
||||
```
|
||||
@@ -32,20 +32,70 @@ If you have an I2P router running on the same machine that is all you need to do
|
||||
|
||||
[Default I2CP port]\: `7654`
|
||||
|
||||
### Running the CLI
|
||||
## Running the CLI
|
||||
|
||||
Look inside `cli-lanterna/build/distributions`. Untar/unzip one of the `shadow` files and then run the jar contained inside by typing `java -jar cli-lanterna-x.y.z-all.jar` in a terminal. The CLI will ask you about the router host and port on startup, no need to edit any files. However, the CLI does not have an options window yet, so if you need to change any options you will need to edit the configuration files. The CLI options are documented here [cli options]
|
||||
|
||||
The CLI is under active development and doesn't have all the features of the GUI.
|
||||
|
||||
### Running the Web UI / Plugin
|
||||
## Running the Web UI / Plugin
|
||||
|
||||
There is a Web-based UI under development. It is intended to be run as a plugin to the Java I2P router. Instructions how to build it are available at the wiki [Plugin] page.
|
||||
|
||||
### Translations
|
||||
## Docker
|
||||
|
||||
The Docker image is based on the wonderful work in [jlesage/docker-baseimage-gui].
|
||||
You can refer to it for environment variables to pass to the container.
|
||||
|
||||
If you don't want to use the image on dockerhub, build an image yourself.
|
||||
```bash
|
||||
MUWIRE_VERSION=`awk -F "=" '/^version/ { gsub(" ","") ; print $2}' gradle.properties`
|
||||
docker build -t muwire:latest,muwire:${MUWIRE_VERSION} .
|
||||
```
|
||||
|
||||
**Necessary configuration**
|
||||
|
||||
Since MuWire will be running in a container, it won't have direct access to the host's localhost.
|
||||
By default, it will be configured to use `172.17.0.1` as the target host.
|
||||
You'll need to open the I2CP port on that interface.
|
||||
If you're running I2P on the localhost, navigate to http://localhost:7657/configi2cp and make the necessary changes.
|
||||
|
||||
![i2cp_config.png]
|
||||
|
||||
Should you be using a different interface write an `i2p.properties` and then put that into the shared docker volume.
|
||||
|
||||
Example configuration file:
|
||||
```properties
|
||||
i2cp.tcp.host=112.13.0.1
|
||||
```
|
||||
|
||||
**Running**
|
||||
|
||||
```bash
|
||||
docker run \
|
||||
-p 5800:5800 \
|
||||
-v config:/muwire/.MuWire \
|
||||
-v incompletes:/incompletes \
|
||||
-v output:/output \
|
||||
--name muwire \
|
||||
zlatinb/muwire
|
||||
```
|
||||
|
||||
You will then be able to access the muwire GUI over a browser at http://localhost:5800
|
||||
|
||||
**Options**
|
||||
|
||||
|
||||
| Option | Description |
|
||||
|--------------|--------------------------------------------|
|
||||
|`-v config:/muwire/.MuWire`| This is where the `i2p.properties` and possibly other config should go |
|
||||
|`-v incompletes:/incompletes`| The `/incompletes` volume should be used to store MuWire's **incomplete** download/upload data \*|
|
||||
|`-v output:/output`| The `/output` volume should be used to store MuWire's download/upload data |
|
||||
|
||||
## Translations
|
||||
If you want to help translate MuWire, instructions are on the wiki https://github.com/zlatinb/muwire/wiki/Translate
|
||||
|
||||
### GPG Fingerprint
|
||||
## GPG Fingerprint
|
||||
|
||||
```
|
||||
471B 9FD4 5517 A5ED 101F C57D A728 3207 2D52 5E41
|
||||
@@ -61,3 +111,6 @@ You can find the full key at https://keybase.io/zlatinb
|
||||
[cli options]: https://github.com/zlatinb/muwire/wiki/CLI-Configuration-Options
|
||||
[I2P Github]: https://github.com/i2p/i2p.i2p
|
||||
[Plugin]: https://github.com/zlatinb/muwire/wiki/Plugin
|
||||
[i2cp_config.png]: ./images/i2cp_config.png
|
||||
[muwire_incompletes.png]: ./images/muwire_incompletes.png
|
||||
[jlesage/docker-baseimage-gui]: https://github.com/jlesage/docker-baseimage-gui
|
||||
|
4
TODO.md
4
TODO.md
@@ -17,6 +17,9 @@ This helps with scalability
|
||||
* Persist trust immediately
|
||||
* Check if user-selected download and incomplete locations exist and are writeable
|
||||
* Enum i18n
|
||||
* Ability to share trust list only with trusted users
|
||||
* Confidential files visible only to certain users
|
||||
* Public Feed feature
|
||||
|
||||
### Chat
|
||||
* echo "unknown/innappropriate command" in the console
|
||||
@@ -24,6 +27,7 @@ This helps with scalability
|
||||
* Style timestamps and persona names
|
||||
* enforce # in room names or ignore it
|
||||
* auto-create/join channel on server start
|
||||
* jump from notification window to room with message
|
||||
|
||||
### Swing GUI
|
||||
* I2P Status panel - display message when connected to external router
|
||||
|
@@ -128,7 +128,12 @@ public class Core {
|
||||
this.muOptions = props
|
||||
|
||||
i2pOptions = new Properties()
|
||||
def i2pOptionsFile = new File(home,"i2p.properties")
|
||||
// Read defaults
|
||||
def defaultI2PFile = getClass()
|
||||
.getClassLoader().getResource("defaults/i2p.properties");
|
||||
defaultI2PFile.withInputStream { i2pOptions.load(it) }
|
||||
|
||||
def i2pOptionsFile = new File(home, "i2p.properties")
|
||||
if (i2pOptionsFile.exists()) {
|
||||
i2pOptionsFile.withInputStream { i2pOptions.load(it) }
|
||||
|
||||
@@ -136,15 +141,10 @@ public class Core {
|
||||
i2pOptions["inbound.nickname"] = "MuWire"
|
||||
if (!i2pOptions.containsKey("outbound.nickname"))
|
||||
i2pOptions["outbound.nickname"] = "MuWire"
|
||||
} else {
|
||||
i2pOptions["inbound.nickname"] = "MuWire"
|
||||
i2pOptions["outbound.nickname"] = "MuWire"
|
||||
i2pOptions["inbound.length"] = "3"
|
||||
i2pOptions["inbound.quantity"] = "4"
|
||||
i2pOptions["outbound.length"] = "3"
|
||||
i2pOptions["outbound.quantity"] = "4"
|
||||
i2pOptions["i2cp.tcp.host"] = "127.0.0.1"
|
||||
i2pOptions["i2cp.tcp.port"] = "7654"
|
||||
}
|
||||
if (!(i2pOptions.hasProperty("i2np.ntcp.port")
|
||||
&& i2pOptions.hasProperty("i2np.udp.port")
|
||||
)) {
|
||||
Random r = new Random()
|
||||
int port = r.nextInt(60000) + 4000
|
||||
i2pOptions["i2np.ntcp.port"] = String.valueOf(port)
|
||||
|
8
core/src/main/resources/defaults/i2p.properties
Normal file
8
core/src/main/resources/defaults/i2p.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
inbound.nickname=MuWire
|
||||
outbound.nickname=MuWire
|
||||
inbound.length=3
|
||||
inbound.quantity=4
|
||||
outbound.length=3
|
||||
outbound.quantity=4
|
||||
i2cp.tcp.host=127.0.0.1
|
||||
i2cp.tcp.port=7654
|
26
docker/rootfs/etc/cont-init.d/00-app-user-map.sh
Executable file
26
docker/rootfs/etc/cont-init.d/00-app-user-map.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/with-contenv sh
|
||||
|
||||
#
|
||||
# Add the app user to the password and group databases. This is needed just to
|
||||
# make sure that mapping between the user/group ID and its name is possible.
|
||||
#
|
||||
|
||||
set -e # Exit immediately if a command exits with a non-zero status.
|
||||
set -u # Treat unset variables as an error.
|
||||
|
||||
cp /defaults/passwd /etc/passwd
|
||||
cp /defaults/group /etc/group
|
||||
cp /defaults/shadow /etc/shadow
|
||||
chown root:shadow /etc/shadow
|
||||
chmod 640 /etc/shadow
|
||||
|
||||
echo "$APP_USER:x:$USER_ID:$GROUP_ID::${APP_HOME:-/dev/null}:/sbin/nologin" >> /etc/passwd
|
||||
echo "$APP_USER:x:$GROUP_ID:" >> /etc/group
|
||||
|
||||
# Make sure APP_HOME is editable by the user
|
||||
if [[ -n "$APP_HOME" ]] ; then
|
||||
chown -R "$APP_USER" "$APP_HOME"
|
||||
chmod -R u+rw "$APP_HOME"
|
||||
fi
|
||||
|
||||
# vim:ft=sh:ts=4:sw=4:et:sts=4
|
34
docker/rootfs/muwire/.MuWire/MuWire.properties
Normal file
34
docker/rootfs/muwire/.MuWire/MuWire.properties
Normal file
@@ -0,0 +1,34 @@
|
||||
#This file is UTF-8
|
||||
#Tue Jan 14 12:08:47 GMT 2020
|
||||
meshExpiration=60
|
||||
autoDownloadUpdate=true
|
||||
hostHopelessInterval=1440
|
||||
uploadSlotsPerUser=-1
|
||||
downloadLocation=/output
|
||||
allowTrustLists=true
|
||||
embeddedRouter=false
|
||||
incompleteLocation=/incompletes
|
||||
outBw=128
|
||||
searchExtraHop=false
|
||||
shareHiddenFiles=false
|
||||
advertiseChat=true
|
||||
totalUploadSlots=-1
|
||||
hostClearInterval=15
|
||||
searchComments=true
|
||||
downloadSequentialRatio=0.8
|
||||
maxChatConnectios=-1
|
||||
trustListInterval=1
|
||||
crawlerResponse=REGISTERED
|
||||
browseFiles=true
|
||||
lastUpdateCheck=1579003533112
|
||||
hostRejectInterval=1
|
||||
inBw=256
|
||||
leaf=false
|
||||
updateCheckInterval=24
|
||||
plugin=false
|
||||
downloadRetryInterval=60
|
||||
speedSmoothSeconds=60
|
||||
allowUntrusted=true
|
||||
shareDownloadedFiles=true
|
||||
startChatServer=false
|
||||
updateType=jar
|
1
docker/rootfs/muwire/.MuWire/i2p.properties
Normal file
1
docker/rootfs/muwire/.MuWire/i2p.properties
Normal file
@@ -0,0 +1 @@
|
||||
i2cp.tcp.host=172.17.0.1
|
7
docker/rootfs/startapp.sh
Normal file
7
docker/rootfs/startapp.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Explicitly define HOME otherwise it might not have been set
|
||||
export HOME=/muwire
|
||||
|
||||
echo "Starting MuWire"
|
||||
exec /muwire/bin/MuWire
|
@@ -44,6 +44,8 @@ class Ready extends AbstractLifecycleHandler {
|
||||
propsFile.withReader("UTF-8", {
|
||||
props.load(it)
|
||||
})
|
||||
if (!props.containsKey("nickname"))
|
||||
props.setProperty("nickname", selectNickname())
|
||||
props = new MuWireSettings(props)
|
||||
if (props.incompleteLocation == null)
|
||||
props.incompleteLocation = new File(home, "incompletes")
|
||||
@@ -53,29 +55,7 @@ class Ready extends AbstractLifecycleHandler {
|
||||
props.incompleteLocation = new File(home, "incompletes")
|
||||
props.embeddedRouter = Boolean.parseBoolean(System.getProperties().getProperty("embeddedRouter"))
|
||||
props.updateType = System.getProperty("updateType","jar")
|
||||
def nickname
|
||||
while (true) {
|
||||
nickname = JOptionPane.showInputDialog(null,
|
||||
"Your nickname is displayed when you send search results so other MuWire users can choose to trust you",
|
||||
"Please choose a nickname", JOptionPane.PLAIN_MESSAGE)
|
||||
if (nickname == null) {
|
||||
JOptionPane.showMessageDialog(null, "MuWire cannot start without a nickname and will now exit", JOptionPane.PLAIN_MESSAGE)
|
||||
System.exit(0)
|
||||
}
|
||||
if (nickname.trim().length() == 0) {
|
||||
JOptionPane.showMessageDialog(null, "Nickname cannot be empty", "Select another nickname",
|
||||
JOptionPane.WARNING_MESSAGE)
|
||||
continue
|
||||
}
|
||||
if (nickname.contains("@")) {
|
||||
JOptionPane.showMessageDialog(null, "Nickname cannot contain @, choose another",
|
||||
"Select another nickname", JOptionPane.WARNING_MESSAGE)
|
||||
continue
|
||||
}
|
||||
nickname = nickname.trim()
|
||||
break
|
||||
}
|
||||
props.setNickname(nickname)
|
||||
props.setNickname(selectNickname())
|
||||
|
||||
|
||||
def portableDownloads = System.getProperty("portable.downloads")
|
||||
@@ -120,5 +100,31 @@ class Ready extends AbstractLifecycleHandler {
|
||||
|
||||
core.eventBus.publish(new UILoadedEvent())
|
||||
}
|
||||
|
||||
private String selectNickname() {
|
||||
String nickname
|
||||
while (true) {
|
||||
nickname = JOptionPane.showInputDialog(null,
|
||||
"Your nickname is displayed when you send search results so other MuWire users can choose to trust you",
|
||||
"Please choose a nickname", JOptionPane.PLAIN_MESSAGE)
|
||||
if (nickname == null) {
|
||||
JOptionPane.showMessageDialog(null, "MuWire cannot start without a nickname and will now exit", JOptionPane.PLAIN_MESSAGE)
|
||||
System.exit(0)
|
||||
}
|
||||
if (nickname.trim().length() == 0) {
|
||||
JOptionPane.showMessageDialog(null, "Nickname cannot be empty", "Select another nickname",
|
||||
JOptionPane.WARNING_MESSAGE)
|
||||
continue
|
||||
}
|
||||
if (nickname.contains("@")) {
|
||||
JOptionPane.showMessageDialog(null, "Nickname cannot contain @, choose another",
|
||||
"Select another nickname", JOptionPane.WARNING_MESSAGE)
|
||||
continue
|
||||
}
|
||||
nickname = nickname.trim()
|
||||
break
|
||||
}
|
||||
nickname
|
||||
}
|
||||
}
|
||||
|
||||
|
BIN
images/i2cp_config.png
Normal file
BIN
images/i2cp_config.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
Reference in New Issue
Block a user