From 75c0a4e575ffdcf66cec2db85c65b0191966e123 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment?= Date: Sat, 16 Feb 2019 15:00:20 +0100 Subject: [PATCH] First working version --- .gitignore | 2 + LICENSE | 21 ++++ README.md | 45 ++++++++ conf/amd64.src | 6 + conf/config.yml | 25 +++++ conf/nginx.conf | 33 ++++++ conf/systemd.service | 14 +++ manifest.json | 78 +++++++++++++ scripts/_common.sh | 22 ++++ scripts/install | 255 +++++++++++++++++++++++++++++++++++++++++++ scripts/remove | 104 ++++++++++++++++++ 11 files changed, 605 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 conf/amd64.src create mode 100644 conf/config.yml create mode 100644 conf/nginx.conf create mode 100644 conf/systemd.service create mode 100644 manifest.json create mode 100644 scripts/_common.sh create mode 100755 scripts/install create mode 100755 scripts/remove diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..783a4ae --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*~ +*.sw[op] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..4ff0e6c --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 jmattheis + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..84043b4 --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ +# Gitify for YunoHost + +[![Install Gotify with YunoHost](https://install-app.yunohost.org/install-with-yunohost.png)](https://install-app.yunohost.org/?app=Gotify) + +> *This package allow you to install Gotify quickly and simply on a YunoHost server. +If you don't have YunoHost, please see [here](https://yunohost.org/#/install) to know how to install and enjoy it.* + +## Overview +Gotify is a simple server for sending and receiving messages in real-time per web socket. (Includes a sleek web-ui) + +**Shipped version:** 1.2.1 + +## Screenshots + +[![Screenshot](https://raw.githubusercontent.com/gotify/server/master/ui.png)](https://github.com/gotify/server) + + +## Configuration + +How to configure this app: +> Edit config.yml file via SSH. + +## Documentation + + * Official documentation: [here](https://gotify.net/docs/index) + +#### Multi-users support + +LDAP not supported. + +## Limitations + + * Require dedicated domain like gotify.domain.tld. + + * No LDAP support (blocked until Gotify core upstream implements it) + + * is_public is ignored app can't be SSOed + +## Links + + * Report a bug: https://github.com/YunoHost-Apps/gotify_ynh/issues + * App website: https://gotify.net/ + * YunoHost website: https://yunohost.org/ + +--- diff --git a/conf/amd64.src b/conf/amd64.src new file mode 100644 index 0000000..ee0811f --- /dev/null +++ b/conf/amd64.src @@ -0,0 +1,6 @@ +SOURCE_URL=https://github.com/gotify/server/releases/download/v1.2.1/gotify-linux-amd64.zip +SOURCE_SUM=f0702c07716c8a6b27c14f8469771d8f23cc17a9b4e12265e7bef3733a203a59 +SOURCE_SUM_PRG=sha256sum +SOURCE_FORMAT=zip +SOURCE_IN_SUBDIR=false +SOURCE_FILENAME=gotify-linux-amd64 diff --git a/conf/config.yml b/conf/config.yml new file mode 100644 index 0000000..7cff170 --- /dev/null +++ b/conf/config.yml @@ -0,0 +1,25 @@ +server: + port: __PORT__ # the port the HTTP server will listen on + + ssl: + enabled: false # if https should be enabled + redirecttohttps: false # redirect to https if site is accessed by http + + responseheaders: # response headers are added to every response (default: none) + Access-Control-Allow-Origin: "*" + Access-Control-Allow-Methods: "GET,POST" + + stream: + allowedorigins: # allowed origins for websocket connections (same origin is always allowed) + - ".+.__DOMAIN__" + +database: # for database see (configure database section) + dialect: mysql + connection: gotify:__DBPASS__@/__DBNAME__?charset=utf8&parseTime=True&loc=Local + +defaultuser: # on database creation, gotify creates an admin user + name: __ADMINUSER__ # the username of the default user + pass: __ADMINPASS__ # the password of the default user +passstrength: 10 # the bcrypt password strength (higher = better but also slower) +uploadedimagesdir: data/images # the directory for storing uploaded images +pluginsdir: data/plugins # the directory where plugin resides diff --git a/conf/nginx.conf b/conf/nginx.conf new file mode 100644 index 0000000..b003c38 --- /dev/null +++ b/conf/nginx.conf @@ -0,0 +1,33 @@ +#sub_path_only rewrite ^__PATH__$ __PATH__/ permanent; +location __PATH__/stream { + proxy_pass http://localhost:__PORT__/stream; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_connect_timeout 7m; + proxy_send_timeout 7m; + proxy_read_timeout 7m; + + if ($scheme = http) { + rewrite ^ https://$server_name$request_uri? permanent; + } +} + +location __PATH__/ { + proxy_pass http://localhost:__PORT__/; + proxy_set_header Host $host; + proxy_buffering off; + fastcgi_param REMOTE_USER $remote_user; + client_max_body_size 50M; + + # Force https + if ($scheme = http) { + rewrite ^ https://$server_name$request_uri? permanent; + } + + # Include SSOWAT user panel. + include conf.d/yunohost_panel.conf.inc; +} diff --git a/conf/systemd.service b/conf/systemd.service new file mode 100644 index 0000000..6247898 --- /dev/null +++ b/conf/systemd.service @@ -0,0 +1,14 @@ +[Unit] +Description=Gotify +After=network.target +After=mysql.service + +[Service] +Type=simple +User=__APP__ +Group=__APP__ +WorkingDirectory=__FINALPATH__/ +ExecStart=__FINALPATH__/gotify-linux-amd64 + +[Install] +WantedBy=multi-user.target diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..0d6412b --- /dev/null +++ b/manifest.json @@ -0,0 +1,78 @@ +{ + "name": "Gotify", + "id": "gotify", + "packaging_format": 1, + "description": { + "en": "Gotify package for YunoHost.", + "fr": "Package Gotify pour YunoHost." + }, + "version": "1.2.1", + "url": "http://gotify.net", + "license": "MIT", + "maintainer": { + "name": "plopoyop", + "email": "plopoyop@gmail.com" + }, + "requirements": { + "yunohost": ">= 2.7.14" + }, + "multi_instance": true, + "services": [ + "nginx", + "mysql" + ], + "arguments": { + "install" : [ + { + "name": "domain", + "type": "domain", + "ask": { + "en": "Choose a domain name for gotify", + "fr": "Choisissez un nom de domaine pour gotify" + }, + "example": "example.com" + }, + { + "name": "path", + "type": "path", + "ask": { + "en": "Choose a path for gotify", + "fr": "Choisissez un chemin pour gotify" + }, + "example": "/gotify", + "default": "/gotify" + }, + { + "name": "admin", + "type": "user", + "ask": { + "en": "Choose an admin user", + "fr": "Choisissez l’administrateur" + }, + "example": "johndoe" + }, + { + "name": "is_public", + "type": "boolean", + "ask": { + "en": "Is it a public application?", + "fr": "Est-ce une application publique ?" + }, + "default": true + }, + { + "name": "password", + "type": "password", + "ask": { + "en": "Set the administrator password", + "fr": "Définissez le mot de passe administrateur" + }, + "help": { + "en": "Use the help field to add an information for the admin about this question.", + "fr": "Utilisez le champ aide pour ajouter une information à l'intention de l'administrateur à propos de cette question." + }, + "example": "Choose a password" + } + ] + } +} diff --git a/scripts/_common.sh b/scripts/_common.sh new file mode 100644 index 0000000..c104bf7 --- /dev/null +++ b/scripts/_common.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# ============= FUTURE YUNOHOST HELPER ============= +# Delete a file checksum from the app settings +# +# $app should be defined when calling this helper +# +# usage: ynh_remove_file_checksum file +# | arg: file - The file for which the checksum will be deleted +ynh_delete_file_checksum () { + local checksum_setting_name=checksum_${1//[\/ ]/_} # Replace all '/' and ' ' by '_' + ynh_app_setting_delete $app $checksum_setting_name +} + +if [ -n "$(uname -m | grep 64)" ]; then + architecture="amd64" +elif [ -n "$(uname -m | grep arm)" ]; then + architecture="arm" +else + ynh_die "Unable to detect your achitecture, please open a bug describing \ + your hardware and the result of the command \"uname -m\"." 1 +fi diff --git a/scripts/install b/scripts/install new file mode 100755 index 0000000..ea30aac --- /dev/null +++ b/scripts/install @@ -0,0 +1,255 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +ynh_clean_setup () { + ### Remove this function if there's nothing to clean before calling the remove script. + true +} +# Exit if an error occurs during the execution of the script +ynh_abort_if_errors + + +#================================================= +# RETRIEVE ARGUMENTS FROM THE MANIFEST +#================================================= + +domain=$YNH_APP_ARG_DOMAIN +path_url=$YNH_APP_ARG_PATH +admin=$YNH_APP_ARG_ADMIN +is_public=$YNH_APP_ARG_IS_PUBLIC +password=$YNH_APP_ARG_PASSWORD + +### If it's a multi-instance app, meaning it can be installed several times independently +### The id of the app as stated in the manifest is available as $YNH_APP_ID +### The instance number is available as $YNH_APP_INSTANCE_NUMBER (equals "1", "2", ...) +### The app instance name is available as $YNH_APP_INSTANCE_NAME +### - the first time the app is installed, YNH_APP_INSTANCE_NAME = ynhexample +### - the second time the app is installed, YNH_APP_INSTANCE_NAME = ynhexample__2 +### - ynhexample__{N} for the subsequent installations, with N=3,4, ... +### The app instance name is probably what interests you most, since this is +### guaranteed to be unique. This is a good unique identifier to define installation path, +### db names, ... +app=$YNH_APP_INSTANCE_NAME + +#================================================= +# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS +#================================================= + +final_path=/opt/yunohost/$app +test ! -e "$final_path" || ynh_die "This path already contains a folder" + +# Normalize the url path syntax +path_url=$(ynh_normalize_url_path $path_url) + +# Does not work in subpath +if [ "$path_url" != "/" ] +then + ynh_die "Cannot be installed in subpath" +fi + +# Check web path availability +ynh_webpath_available $domain $path_url +# Register (book) web path +ynh_webpath_register $app $domain $path_url + +#================================================= +# STORE SETTINGS FROM MANIFEST +#================================================= + +ynh_app_setting_set $app domain $domain +ynh_app_setting_set $app path $path_url +ynh_app_setting_set $app admin $admin +ynh_app_setting_set $app is_public $is_public + +#================================================= +# STANDARD MODIFICATIONS +#================================================= +# FIND AND OPEN A PORT +#================================================= + +### Use these lines if you have to open a port for the application +### `ynh_find_port` will find the first available port starting from the given port. +### If you're not using these lines: +### - Remove the section "CLOSE A PORT" in the remove script + +# Find a free port +port=$(ynh_find_port 8080) +# Open this port +# yunohost firewall allow --no-upnp TCP $port 2>&1 +ynh_app_setting_set $app port $port + +#================================================= +# CREATE A MYSQL DATABASE +#================================================= + +### Use these lines if you need a database for the application. +### `ynh_mysql_setup_db` will create a database, an associated user and a ramdom password. +### The password will be stored as 'mysqlpwd' into the app settings, +### and will be available as $db_pwd +### If you're not using these lines: +### - Remove the section "BACKUP THE MYSQL DATABASE" in the backup script +### - Remove also the section "REMOVE THE MYSQL DATABASE" in the remove script +### - As well as the section "RESTORE THE MYSQL DATABASE" in the restore script + +db_name=$(ynh_sanitize_dbid $app) +ynh_app_setting_set $app db_name $db_name +ynh_mysql_setup_db $db_name $db_name + +#================================================= +# DOWNLOAD, CHECK AND UNPACK SOURCE +#================================================= + +### `ynh_setup_source` is used to install an app from a zip or tar.gz file, +### downloaded from an upstream source, like a git repository. +### `ynh_setup_source` use the file conf/app.src + +ynh_app_setting_set $app final_path $final_path +# Download, check integrity, uncompress and patch the source from app.src +ynh_setup_source "$final_path" $architecture + +#================================================= +# NGINX CONFIGURATION +#================================================= + +### `ynh_add_nginx_config` will use the file conf/nginx.conf + +# Create a dedicated nginx config +if [ "$path_url" != "/" ] +then + ynh_replace_string "^#sub_path_only" "" "../conf/nginx.conf" +fi + +ynh_add_nginx_config + +#================================================= +# CREATE DEDICATED USER +#================================================= + +# Create a system user +ynh_system_user_create $app + + +#================================================= +# SETUP SYSTEMD +#================================================= + +### `ynh_systemd_config` is used to configure a systemd script for an app. +### It can be used for apps that use sysvinit (with adaptation) or systemd. +### Have a look at the app to be sure this app needs a systemd script. +### `ynh_systemd_config` will use the file conf/systemd.service +### If you're not using these lines: +### - You can remove those files in conf/. +### - Remove the section "BACKUP SYSTEMD" in the backup script +### - Remove also the section "STOP AND REMOVE SERVICE" in the remove script +### - As well as the section "RESTORE SYSTEMD" in the restore script +### - And the section "SETUP SYSTEMD" in the upgrade script + +# Create a dedicated systemd config +ynh_add_systemd_config + +#================================================= +# MODIFY A CONFIG FILE +#================================================= + +### `ynh_replace_string` is used to replace a string in a file. +### (It's compatible with sed regular expressions syntax) +cp ../conf/config.yml "$final_path/config.yml" +ynh_replace_string "__PORT__" $port "$final_path/config.yml" +ynh_replace_string "__DBNAME__" $db_name "$final_path/config.yml" +ynh_replace_string "__DBPASS__" $db_pwd "$final_path/config.yml" +ynh_replace_string "__ADMINUSER__" $admin "$final_path/config.yml" +ynh_replace_string "__ADMINPASS__" $password "$final_path/config.yml" +ynh_replace_string "__DOMAIN__" $domain "$final_path/config.yml" + +#================================================= +# STORE THE CONFIG FILE CHECKSUM +#================================================= + +### `ynh_store_file_checksum` is used to store the checksum of a file. +### That way, during the upgrade script, by using `ynh_backup_if_checksum_is_different`, +### you can make a backup of this file before modifying it again if the admin had modified it. + +# Calculate and store the config file checksum into the app settings +ynh_store_file_checksum "$final_path/config.yml" + +#================================================= +# GENERIC FINALIZATION +#================================================= +# SECURE FILES AND DIRECTORIES +#================================================= + +### For security reason, any app should set the permissions to root: before anything else. +### Then, if write authorization is needed, any access should be given only to directories +### that really need such authorization. + +# Set permissions to app files +chown -R root: $final_path +mkdir $final_path/data +chown $app $final_path/data + +#================================================= +# SETUP LOGROTATE +#================================================= + +### `ynh_use_logrotate` is used to configure a logrotate configuration for the logs of this app. +### Use this helper only if there is effectively a log file for this app. +### If you're not using this helper: +### - Remove the section "BACKUP LOGROTATE" in the backup script +### - Remove also the section "REMOVE LOGROTATE CONFIGURATION" in the remove script +### - As well as the section "RESTORE THE LOGROTATE CONFIGURATION" in the restore script +### - And the section "SETUP LOGROTATE" in the upgrade script + +# Use logrotate to manage application logfile(s) +# ynh_use_logrotate + +#================================================= +# ADVERTISE SERVICE IN ADMIN PANEL +#================================================= + +### `yunohost service add` is a CLI yunohost command to add a service in the admin panel. +### You'll find the service in the 'services' section of YunoHost admin panel. +### This CLI command would be useless if the app does not have any services (systemd or sysvinit) +### If you're not using these lines: +### - You can remove these files in conf/. +### - Remove the section "REMOVE SERVICE FROM ADMIN PANEL" in the remove script +### - As well as the section ADVERTISE SERVICE IN ADMIN PANEL" in the restore script + +yunohost service add $app +#--log "/var/log/FILE.log" + +#================================================= +# SETUP SSOWAT +#================================================= + +# Make app public if necessary +# if [ $is_public -eq 1 ] +# then +# # unprotected_uris allows SSO credentials to be passed anyway. +# ynh_app_setting_set $app unprotected_uris "/" +# fi + +# websocket must be open +# ynh_app_setting_set $app unprotected_uris "/stream" + +ynh_app_setting_set $app unprotected_uris "/" + +#================================================= +# RELOAD NGINX +#================================================= + +systemctl reload nginx + +systemctl start $app +# yunohost firewall allow --no-upnp TCP $port 2>&1 diff --git a/scripts/remove b/scripts/remove new file mode 100755 index 0000000..6fda864 --- /dev/null +++ b/scripts/remove @@ -0,0 +1,104 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= + +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# LOAD SETTINGS +#================================================= + +app=$YNH_APP_INSTANCE_NAME + +domain=$(ynh_app_setting_get $app domain) +port=$(ynh_app_setting_get $app port) +db_name=$(ynh_app_setting_get $app db_name) +db_user=$app +final_path=$(ynh_app_setting_get $app final_path) + +#================================================= +# STANDARD REMOVE +#================================================= +# STOP AND REMOVE SERVICE +#================================================= + +# Remove the dedicated systemd config +ynh_remove_systemd_config + +#================================================= +# REMOVE SERVICE FROM ADMIN PANEL +#================================================= + +# Remove a service from the admin panel, added by `yunohost service add` +if yunohost service status | grep -q $app +then + echo "Remove $app service" + yunohost service remove $app +fi + +#================================================= +# REMOVE THE MYSQL DATABASE +#================================================= + +# Remove a database if it exists, along with the associated user +ynh_mysql_remove_db $db_user $db_name + +#================================================= +# REMOVE APP MAIN DIR +#================================================= + +# Remove the app directory securely +ynh_secure_remove "$final_path" + +#================================================= +# REMOVE NGINX CONFIGURATION +#================================================= + +# Remove the dedicated nginx config +ynh_remove_nginx_config + +#================================================= +# REMOVE LOGROTATE CONFIGURATION +#================================================= + +# Remove the app-specific logrotate config +# ynh_remove_logrotate + +#================================================= +# CLOSE A PORT +#================================================= + +# if yunohost firewall list | grep -q "\- $port$" +# then +# echo "Close port $port" >&2 +# yunohost firewall disallow TCP $port 2>&1 +# fi + +#================================================= +# SPECIFIC REMOVE +#================================================= +# REMOVE THE CRON FILE +#================================================= + +# Remove a cron file +# ynh_secure_remove "/etc/cron.d/$app" + +# Remove a directory securely +# ynh_secure_remove "/etc/$app/" + +# Remove the log files +# ynh_secure_remove "/var/log/$app/" + +#================================================= +# GENERIC FINALIZATION +#================================================= +# REMOVE DEDICATED USER +#================================================= + +# Delete a system user +ynh_system_user_delete $app