diff --git a/README.md b/README.md index 5c2cc4f..946273b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,10 @@ # pagure_ynh Pagure, a git centered forge for YunoHost + +Due to the usage of RemoteCollection, Pagure can't be use on Debian 8. + +It needs a libgit2-dev>=0.22: +https://github.com/libgit2/pygit2/blob/62c70e852da23bcb60e64996f6326a3e2a800469/CHANGELOG.rst#0220-2015-01-16 + +Stretch has 0.25, but it will wait for YunoHost to be compatible: +https://packages.debian.org/search?keywords=libgit2&searchon=names&suite=all§ion=all diff --git a/check_process b/check_process new file mode 100644 index 0000000..37eeef5 --- /dev/null +++ b/check_process @@ -0,0 +1,41 @@ +# See here for more informations +# https://github.com/YunoHost/package_check#syntax-check_process-file + +# Move this file from check_process.default to check_process when you have filled it. + +;; Test complet + ; Manifest + domain="domain.tld" (DOMAIN) + path="/path" (PATH) + admin="john" (USER) + is_public=1 (PUBLIC|public=1|private=0) + password="pass" + ; Checks + pkg_linter=0 + setup_sub_dir=1 + setup_root=0 + setup_nourl=0 + setup_private=0 + setup_public=0 + upgrade=0 + backup_restore=0 + multi_instance=0 + incorrect_path=0 + port_already_use=0 + change_url=0 +;;; Levels + Level 1=auto + Level 2=auto + Level 3=auto +# Level 4: + Level 4=0 +# Level 5: + Level 5=auto + Level 6=auto + Level 7=auto + Level 8=0 + Level 9=0 + Level 10=0 +;;; Options +Email=jean-baptiste@holcroft.fr +Notification=all diff --git a/conf/app.src b/conf/app.src new file mode 100644 index 0000000..0c76cec --- /dev/null +++ b/conf/app.src @@ -0,0 +1,5 @@ +SOURCE_URL=https://releases.pagure.org/pagure/pagure-3.8.tar.gz +SOURCE_SUM=ba53d32cac0acb4dc111accb14639939c06927d2cb96245c38ddf631b7d82a4e +SOURCE_SUM_PRG=sha256sum +SOURCE_FORMAT=tar.gz +SOURCE_IN_SUBDIR=false diff --git a/conf/systemd.service b/conf/systemd.service new file mode 100644 index 0000000..1d34019 --- /dev/null +++ b/conf/systemd.service @@ -0,0 +1,13 @@ +[Unit] +Description=Pagure server service +After=network.target + +[Service] +Type=simple +User=__APP__ +Group=__APP__ +WorkingDirectory=__FINALPATH__ +ExecStart=__FINALPATH__/pagure/runworker.py --debug & __FINALPATH__/pagure/runserver.py --debug + +[Install] +WantedBy=multi-user.target diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..01f16c4 --- /dev/null +++ b/manifest.json @@ -0,0 +1,59 @@ +{ + "name": "Pagure", + "id": "pagure", + "packaging_format": 1, + "requirements": { + "yunohost": ">= 2.7.0" + }, + "description": { + "en": "A translation platform using Git and Python" + }, + "version": "3.8.0", + "url": "https://pagure.io/pagure", + "license": "AGPL-3.0", + "maintainer": { + "name": "Jean-Baptiste Holcroft", + "email": "jean-baptiste@holcroft.fr" + }, + "multi_instance": true, + "services": [ + "nginx" + ], + "arguments": { + "install" : [ + { + "name": "domain", + "type": "domain", + "ask": { + "en": "Choose a domain for Pagure:" + }, + "example": "domain.org" + }, + { + "name": "path", + "type": "path", + "ask": { + "en": "Choose a path for Pagure:" + }, + "example": "/pagure", + "default": "/pagure" + }, + { + "name": "is_public", + "type": "boolean", + "ask": { + "en": "Should Pagure be publicly accessible?" + }, + "default": "0" + }, + { + "name": "admin", + "type": "user", + "ask": { + "en": "Choose an admin user for Pagure" + }, + "example": "simon" + } + ] + } +} diff --git a/scripts/_common.sh b/scripts/_common.sh new file mode 100755 index 0000000..4384a8a --- /dev/null +++ b/scripts/_common.sh @@ -0,0 +1,133 @@ +#!/bin/bash + +ynh_psql_test_if_first_run() { + if [ -f /etc/yunohost/psql ]; + then + echo "PostgreSQL is already installed, no need to create master password" + else + pgsql=$(ynh_string_random) + echo "$pgsql" >> /etc/yunohost/psql + systemctl start postgresql + su --command="psql -c\"ALTER user postgres WITH PASSWORD '${pgsql}'\"" postgres + # we can't use peer since YunoHost create users with nologin + sed -i '/local\s*all\s*all\s*peer/i \ + local all all password' /etc/postgresql/9.4/main/pg_hba.conf + systemctl enable postgresql + systemctl reload postgresql + fi +} + +# Open a connection as a user +# +# example: ynh_psql_connect_as 'user' 'pass' <<< "UPDATE ...;" +# example: ynh_psql_connect_as 'user' 'pass' < /path/to/file.sql +# +# usage: ynh_psql_connect_as user pwd [db] +# | arg: user - the user name to connect as +# | arg: pwd - the user password +# | arg: db - the database to connect to +ynh_psql_connect_as() { + user="$1" + pwd="$2" + db="$3" + su --command="PGUSER=\"${user}\" PGPASSWORD=\"${pwd}\" psql \"${db}\"" postgres +} + +# # Execute a command as root user +# +# usage: ynh_psql_execute_as_root sql [db] +# | arg: sql - the SQL command to execute +# | arg: db - the database to connect to +ynh_psql_execute_as_root () { + sql="$1" + su --command="psql" postgres <<< "$sql" +} + +# Execute a command from a file as root user +# +# usage: ynh_psql_execute_file_as_root file [db] +# | arg: file - the file containing SQL commands +# | arg: db - the database to connect to +ynh_psql_execute_file_as_root() { + file="$1" + db="$2" + su -c "psql $db" postgres < "$file" +} + +# Create a database, an user and its password. Then store the password in the app's config +# +# After executing this helper, the password of the created database will be available in $db_pwd +# It will also be stored as "psqlpwd" into the app settings. +# +# usage: ynh_psql_setup_db user name [pwd] +# | arg: user - Owner of the database +# | arg: name - Name of the database +# | arg: pwd - Password of the database. If not given, a password will be generated +ynh_psql_setup_db () { + db_user="$1" + app="$1" + db_name="$2" + new_db_pwd=$(ynh_string_random) # Generate a random password + # If $3 is not given, use new_db_pwd instead for db_pwd. + db_pwd="${3:-$new_db_pwd}" + ynh_psql_create_db "$db_name" "$db_user" "$db_pwd" # Create the database + ynh_app_setting_set "$app" psqlpwd "$db_pwd" # Store the password in the app's config +} + +# Create a database and grant optionnaly privilegies to a user +# +# usage: ynh_psql_create_db db [user [pwd]] +# | arg: db - the database name to create +# | arg: user - the user to grant privilegies +# | arg: pwd - the user password +ynh_psql_create_db() { + db="$1" + user="$2" + pwd="$3" + ynh_psql_create_user "$user" "$pwd" + su --command="createdb --owner=\"${user}\" \"${db}\"" postgres +} + +# Drop a database +# +# usage: ynh_psql_drop_db db +# | arg: db - the database name to drop +# | arg: user - the user to drop +ynh_psql_remove_db() { + db="$1" + user="$2" + su --command="dropdb \"${db}\"" postgres + ynh_psql_drop_user "${user}" +} + +# Dump a database +# +# example: ynh_psql_dump_db 'roundcube' > ./dump.sql +# +# usage: ynh_psql_dump_db db +# | arg: db - the database name to dump +# | ret: the psqldump output +ynh_psql_dump_db() { + db="$1" + su --command="pg_dump \"${db}\"" postgres +} + + +# Create a user +# +# usage: ynh_psql_create_user user pwd [host] +# | arg: user - the user name to create +ynh_psql_create_user() { + user="$1" + pwd="$2" + su --command="psql -c\"CREATE USER ${user} WITH PASSWORD '${pwd}'\"" postgres +} + +# Drop a user +# +# usage: ynh_psql_drop_user user +# | arg: user - the user name to drop +ynh_psql_drop_user() { + user="$1" + su --command="dropuser \"${user}\"" postgres +} diff --git a/scripts/install b/scripts/install new file mode 100755 index 0000000..753afef --- /dev/null +++ b/scripts/install @@ -0,0 +1,168 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= +set -eu +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# MANAGE SCRIPT FAILURE +#================================================= + +# 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 + +# This is 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 you are interested the 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 +#================================================= + +# Normalize the url path syntax +path_url=$(ynh_normalize_url_path "$path_url") + +# Check web path availability +ynh_webpath_available "$domain" "$path_url" +# Register (book) web path +ynh_webpath_register "$app" "$domain" "$path_url" + +final_path=/var/www/$app +test ! -e "$final_path" || ynh_die "This path already contains a folder" + +mkdir -p "$final_path" + +#================================================= +# 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" +ynh_app_setting_set "$app" final_path "$final_path" + +#================================================= +# STANDARD MODIFICATIONS +#================================================= + +#================================================= +# INSTALL DEPENDENCIES +#================================================= + +ynh_install_app_dependencies git python-virtualenv libgit2-dev \ + libjpeg-dev gcc libffi-dev python-dev python-cffi + +#================================================= +# CREATE DEDICATED USER +#================================================= + +ynh_system_user_create "$app" "${final_path}" + +#================================================= +# SPECIFIC SETUP +#================================================= + +#================================================= +# Get Pagure source +#================================================= + +ynh_setup_source "${final_path}" +ln -s "${final_path}/pagure-3.8" "${final_path}/pagure" + +#================================================= +# PIP INSTALLATION +#================================================= +virtualenv "${final_path}/venv" +#run source in a 'sub shell' +( + set +eu + source "${final_path}/venv/bin/activate" + "${final_path}/venv/bin/pip" install cffi + "${final_path}/venv/bin/pip" install pygit2==0.21 + "${final_path}/venv/bin/pip" install -r "${final_path}/pagure/requirements.txt" +) + +#================================================= +# SPECIFIC SETUP Filling up the database +# https://docs.weblate.org/en/latest/admin/install.html#filling-up-the-database +#========================================== + +# Create the folder that will receive the projects, forks, docs, requests and tickets' git repo: +mkdir -p "${final_path}/lcl/{repos,docs,forks,tickets,requests,remotes,attachments,releases}" + +( + set +eu + source "${final_path}/venv/bin/activate" + cd "${final_path}/pagure" + python createdb.py +) + +#================================================= +# Set-up a service +#================================================= +# TODO: add port support for service +# server_port=$(ynh_find_port 8080) +# ynh_app_setting_set "$app" port "$server_port" + +ynh_add_systemd_config + +#================================================= +# GENERIC FINALIZATION +#================================================= +# SECURE FILES AND DIRECTORIES +#================================================= + +# Set permissions to app files +chown -R "$app": "$final_path" + +#================================================= +# SETUP LOGROTATE +#================================================= + +# Use logrotate to manage application logfile(s) +ynh_use_logrotate + +#================================================= +# SETUP SSOWAT +#================================================= + +if [ "$is_public" -eq 0 ] +then # Remove the public access + ynh_app_setting_delete "$app" skipped_uris +fi +# 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 + +#================================================= +# RELOAD NGINX +#================================================= + +systemctl start "$app.service" +systemctl reload nginx diff --git a/scripts/remove b/scripts/remove new file mode 100755 index 0000000..811e39f --- /dev/null +++ b/scripts/remove @@ -0,0 +1,65 @@ +#!/bin/bash + +#================================================= +# GENERIC START +#================================================= +# IMPORT GENERIC HELPERS +#================================================= +set -u +source _common.sh +source /usr/share/yunohost/helpers + +#================================================= +# LOAD SETTINGS +#================================================= + +app=$YNH_APP_INSTANCE_NAME + +db_name=$(ynh_app_setting_get "$app" db_name) + +#================================================= +# REMOVE SERVICE FROM ADMIN PANEL +#================================================= + +if yunohost service status | grep -q "$app" +then + echo "Remove $app service" + systemctl stop "$app.service" + yunohost service remove "$app.service" +fi + +#================================================= +# REMOVE DEPENDENCIES +#================================================= + +# Remove metapackage and its dependencies +ynh_remove_app_dependencies + +#================================================= +# REMOVE APP MAIN DIR +#================================================= + +# Remove the app directory securely +ynh_secure_remove "/var/www/$app" + +#================================================= +# REMOVE LOGROTATE CONFIGURATION +#================================================= + +# Remove the app-specific logrotate config +ynh_remove_logrotate + +#================================================= +# SPECIFIC REMOVE +#================================================= + +ynh_remove_systemd_config + +#================================================= +# GENERIC FINALIZATION +#================================================= +# REMOVE DEDICATED USER +#================================================= + +# Delete a system user +ynh_system_user_delete "$app"