diff --git a/check_process b/check_process deleted file mode 100644 index 2b1a527..0000000 --- a/check_process +++ /dev/null @@ -1,31 +0,0 @@ -# See here for more information -# 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) - admin="john" (USER) - is_public=1 (PUBLIC|public=1|private=0) - allow_multimedia_write=1 - ; Checks - pkg_linter=1 - setup_sub_dir=0 - setup_root=1 - setup_nourl=0 - setup_private=1 - setup_public=1 - upgrade=1 - upgrade=1 from_commit=3b5b527e26cb6b530bd51f14c791d1dc15757af4 - backup_restore=1 - multi_instance=0 - port_already_use=0 - change_url=1 -;;; Options -Email= -Notification=none -;;; Upgrade options - ; commit=3b5b527e26cb6b530bd51f14c791d1dc15757af4 - name=Upgrade from March 29 - manifest_arg=domain=domain.tld&admin=john&is_public=1&allow_multimedia_write=1& diff --git a/conf/backend.service b/conf/backend.service index 79557bc..550d25d 100644 --- a/conf/backend.service +++ b/conf/backend.service @@ -8,9 +8,9 @@ Requires=postgresql.service [Service] User=__APP__ Group=__APP__ -EnvironmentFile=__FINALPATH__/librephotos.env +EnvironmentFile=__INSTALL_DIR__/librephotos.env ExecStart=/usr/bin/env bash -c "PATH=__PATH_PREFIX__:$PATH gunicorn --worker-class=gevent --timeout 3600 --bind 127.0.0.1:$BACKEND_PORT --log-level=info ownphotos.wsgi" -WorkingDirectory=__FINALPATH__/backend +WorkingDirectory=__INSTALL_DIR__/backend StandardOutput=append:/var/log/__APP__/__APP__-backend.log StandardError=inherit diff --git a/conf/backend.src b/conf/backend.src deleted file mode 100644 index 4291c05..0000000 --- a/conf/backend.src +++ /dev/null @@ -1,7 +0,0 @@ -SOURCE_URL=https://github.com/LibrePhotos/librephotos/tarball/11c6994d3c506d835335f596090a13545d72713a -SOURCE_SUM=0e588d7ed34fa826e8beba3894586b16bb247b00548215190732a1cbec57167b -SOURCE_SUM_PRG=sha256sum -SOURCE_FORMAT=tar.gz -SOURCE_IN_SUBDIR=true -SOURCE_FILENAME=11c6994d3c506d835335f596090a13545d72713a -SOURCE_EXTRACT=true diff --git a/conf/cmake.src b/conf/cmake.src deleted file mode 100644 index b02ef3f..0000000 --- a/conf/cmake.src +++ /dev/null @@ -1,7 +0,0 @@ -SOURCE_URL=https://github.com/Kitware/CMake/releases/download/v3.20.3/cmake-3.20.3-linux-aarch64.tar.gz -SOURCE_SUM=77620f99e9d5f39cf4a49294c6a68c89a978ecef144894618974b9958efe3c2a -SOURCE_SUM_PRG=sha256sum -SOURCE_FORMAT=tar.gz -SOURCE_IN_SUBDIR=true -SOURCE_FILENAME=cmake-3.20.3-linux-aarch64.tar.gz -SOURCE_EXTRACT=true diff --git a/conf/cmake_amd64.src b/conf/cmake_amd64.src deleted file mode 100644 index 904d4b5..0000000 --- a/conf/cmake_amd64.src +++ /dev/null @@ -1,7 +0,0 @@ -SOURCE_URL=https://github.com/Kitware/CMake/releases/download/v3.20.3/cmake-3.20.3-linux-x86_64.tar.gz -SOURCE_SUM=97bf730372f9900b2dfb9206fccbcf92f5c7f3b502148b832e77451aa0f9e0e6 -SOURCE_SUM_PRG=sha256sum -SOURCE_FORMAT=tar.gz -SOURCE_IN_SUBDIR=true -SOURCE_FILENAME=cmake-3.20.3-linux-x86_64.tar.gz -SOURCE_EXTRACT=true diff --git a/conf/dlib.src b/conf/dlib.src deleted file mode 100644 index 8c2eeea..0000000 --- a/conf/dlib.src +++ /dev/null @@ -1,7 +0,0 @@ -SOURCE_URL=https://github.com/davisking/dlib/archive/refs/tags/v19.22.tar.gz -SOURCE_SUM=5f44b67f762691b92f3e41dcf9c95dd0f4525b59cacb478094e511fdacb5c096 -SOURCE_SUM_PRG=sha256sum -SOURCE_FORMAT=tar.gz -SOURCE_IN_SUBDIR=true -SOURCE_FILENAME=v19.22.tar.gz -SOURCE_EXTRACT=true diff --git a/conf/faiss.src b/conf/faiss.src deleted file mode 100644 index bff08fb..0000000 --- a/conf/faiss.src +++ /dev/null @@ -1,7 +0,0 @@ -SOURCE_URL=https://github.com/facebookresearch/faiss/archive/refs/tags/v1.7.1.tar.gz -SOURCE_SUM=d676d3107ad41203a49e0afda2630519299dc8666f8d23322cbe1eac0c431871 -SOURCE_SUM_PRG=sha256sum -SOURCE_FORMAT=tar.gz -SOURCE_IN_SUBDIR=true -SOURCE_FILENAME=v1.7.1.tar.gz -SOURCE_EXTRACT=true diff --git a/conf/frontend.service b/conf/frontend.service index dd8a8a9..f7e455a 100644 --- a/conf/frontend.service +++ b/conf/frontend.service @@ -5,9 +5,9 @@ Documentation=https://github.com/LibrePhotos/librephotos [Service] User=__APP__ Group=__APP__ -EnvironmentFile=__FINALPATH__/librephotos.env +EnvironmentFile=__INSTALL_DIR__/librephotos.env ExecStart=/usr/bin/env bash -c "PATH=__PATH_PREFIX__:$PATH ./node_modules/.bin/serve build -d -l $httpPort" -WorkingDirectory=__FINALPATH__/frontend +WorkingDirectory=__INSTALL_DIR__/frontend StandardOutput=append:/var/log/__APP__/__APP__-frontend.log StandardError=inherit diff --git a/conf/frontend.src b/conf/frontend.src deleted file mode 100644 index 66e0bad..0000000 --- a/conf/frontend.src +++ /dev/null @@ -1,7 +0,0 @@ -SOURCE_URL=https://github.com/LibrePhotos/librephotos-frontend/tarball/37963756369f11617c456a56f6850b2e8aaf8358 -SOURCE_SUM=085b62550214bd9ffecfefde802b96f3542e6867bb25ff1a830623b598e4c61d -SOURCE_SUM_PRG=sha256sum -SOURCE_FORMAT=tar.gz -SOURCE_IN_SUBDIR=true -SOURCE_FILENAME=37963756369f11617c456a56f6850b2e8aaf8358 -SOURCE_EXTRACT=true diff --git a/conf/im2txt.src b/conf/im2txt.src deleted file mode 100644 index 4052617..0000000 --- a/conf/im2txt.src +++ /dev/null @@ -1,7 +0,0 @@ -SOURCE_URL=https://github.com/LibrePhotos/librephotos-docker/releases/download/0.1/im2txt.tar.gz -SOURCE_SUM=980670c0365c0e32b5fecfc0907bfee4742bcd6a40e0d6ac5692c69bbd49ccc4 -SOURCE_SUM_PRG=sha256sum -SOURCE_FORMAT=tar.gz -SOURCE_IN_SUBDIR=true -SOURCE_FILENAME=im2txt.tar.gz -SOURCE_EXTRACT=true diff --git a/conf/image-similarity.service b/conf/image-similarity.service index 399b1b3..8d91973 100644 --- a/conf/image-similarity.service +++ b/conf/image-similarity.service @@ -7,9 +7,9 @@ After=network.target [Service] User=__APP__ Group=__APP__ -EnvironmentFile=__FINALPATH__/librephotos.env +EnvironmentFile=__INSTALL_DIR__/librephotos.env ExecStart=/usr/bin/env bash -c "PATH=__PATH_PREFIX__:$PATH python3 image_similarity/main.py" -WorkingDirectory=__FINALPATH__/backend +WorkingDirectory=__INSTALL_DIR__/backend StandardOutput=append:/var/log/__APP__/__APP__-image-similarity.log StandardError=inherit diff --git a/conf/miniforge3.src b/conf/miniforge3.src deleted file mode 100644 index a3fb707..0000000 --- a/conf/miniforge3.src +++ /dev/null @@ -1,7 +0,0 @@ -SOURCE_URL=https://github.com/conda-forge/miniforge/releases/download/4.10.1-4/Miniforge3-4.10.1-4-Linux-aarch64.sh -SOURCE_SUM=68f11be0b8272b9218f62fa3ba1b7c58783427e65db7b7ba77e7cdf91f099540 -SOURCE_SUM_PRG=sha256sum -SOURCE_FORMAT=sh -SOURCE_IN_SUBDIR=false -SOURCE_FILENAME=Miniforge3-4.10.1-4-Linux-aarch64.sh -SOURCE_EXTRACT=false diff --git a/conf/places365.src b/conf/places365.src deleted file mode 100644 index 5e4bebb..0000000 --- a/conf/places365.src +++ /dev/null @@ -1,7 +0,0 @@ -SOURCE_URL=https://github.com/LibrePhotos/librephotos-docker/releases/download/0.1/places365.tar.gz -SOURCE_SUM=27792ffcd1f6a4de7abebdea046dda0916f9cd12eba7bed7b5f51f120f91f0d8 -SOURCE_SUM_PRG=sha256sum -SOURCE_FORMAT=tar.gz -SOURCE_IN_SUBDIR=true -SOURCE_FILENAME=places365.tar.gz -SOURCE_EXTRACT=true diff --git a/conf/resnet152-b121ed2d.src b/conf/resnet152-b121ed2d.src deleted file mode 100644 index e056c8f..0000000 --- a/conf/resnet152-b121ed2d.src +++ /dev/null @@ -1,7 +0,0 @@ -SOURCE_URL=https://download.pytorch.org/models/resnet152-b121ed2d.pth -SOURCE_SUM=b121ed2db97ec7e9f55a91300ceaf85a326de955e8a4ae09e3a0c8170d27f14f -SOURCE_SUM_PRG=sha256sum -SOURCE_FORMAT=tar -SOURCE_IN_SUBDIR=false -SOURCE_FILENAME=resnet152-b121ed2d.pth -SOURCE_EXTRACT=false diff --git a/conf/worker.service b/conf/worker.service index 6793f7d..255cc84 100644 --- a/conf/worker.service +++ b/conf/worker.service @@ -8,9 +8,9 @@ Requires=postgresql.service [Service] User=__APP__ Group=__APP__ -EnvironmentFile=__FINALPATH__/librephotos.env +EnvironmentFile=__INSTALL_DIR__/librephotos.env ExecStart=/usr/bin/env bash -c "PATH=__PATH_PREFIX__:$PATH python manage.py rqworker default" -WorkingDirectory=__FINALPATH__/backend +WorkingDirectory=__INSTALL_DIR__/backend StandardOutput=append:/var/log/__APP__/__APP__-worker.log StandardError=inherit diff --git a/doc/DESCRIPTION.md b/doc/DESCRIPTION.md new file mode 100644 index 0000000..76700ab --- /dev/null +++ b/doc/DESCRIPTION.md @@ -0,0 +1 @@ +A photo viewer and manager similar to Google Photos diff --git a/doc/DESCRIPTION_fr.md b/doc/DESCRIPTION_fr.md new file mode 100644 index 0000000..3ebfaff --- /dev/null +++ b/doc/DESCRIPTION_fr.md @@ -0,0 +1 @@ +Un gestionnaire de photos semblable à Google Photos diff --git a/manifest.json b/manifest.json deleted file mode 100644 index dac86b1..0000000 --- a/manifest.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "name": "Librephotos", - "id": "librephotos", - "packaging_format": 1, - "description": { - "en": "A photo viewer and manager similar to Google Photos", - "fr": "Un gestionnaire de photos semblable à Google Photos" - }, - "version": "0.2021.36~ynh1", - "url": "https://github.com/LibrePhotos/librephotos", - "upstream": { - "license": "MIT", - "website": "https://librephotos.com/", - "demo": "https://demo2.librephotos.com/ (user: demo, password: demo1234)", - "admindoc": "https://docs.librephotos.com/", - "userdoc": "https://github.com/LibrePhotos/librephotos", - "code": "https://github.com/LibrePhotos/librephotos" - }, - "license": "MIT", - "maintainer": { - "name": "Jules Bertholet", - "email": "jules.berthlet@quoi.xyz" - }, - "requirements": { - "yunohost": ">= 4.2.4" - }, - "multi_instance": false, - "services": [ - "nginx", - "redis-server", - "postgresql" - ], - "arguments": { - "install" : [ - { - "name": "domain", - "type": "domain", - "example": "example.com" - }, - { - "name": "admin", - "type": "user", - "example": "johndoe" - }, - { - "name": "is_public", - "type": "boolean", - "default": true - }, - { - "name": "allow_multimedia_write", - "type": "boolean", - "default": false, - "ask": { - "en": "Allow write access to multimedia directories?", - "fr": "Autoriser la modification des fichiers dans les dossiers multimédia ?" - } - } - ] - } -} diff --git a/manifest.toml b/manifest.toml new file mode 100644 index 0000000..2241a13 --- /dev/null +++ b/manifest.toml @@ -0,0 +1,162 @@ +packaging_format = 2 + +id = "librephotos" +name = "Librephotos" +description.en = "A photo viewer and manager similar to Google Photos" +description.fr = "Un gestionnaire de photos semblable à Google Photos" + +version = "0.2021.36~ynh1" + +maintainers = ["Jules Bertholet"] + +[upstream] +license = "MIT" +website = "https://librephotos.com" +demo = "https://demo2.librephotos.com (user: demo, password: demo1234)" +admindoc = "https://docs.librephotos.com" +userdoc = "https://github.com/LibrePhotos/librephotos" +code = "https://github.com/LibrePhotos/librephotos" +fund = "https://www.paypal.com/donate/?hosted_button_id=5JWVM2UR4LM96" + +[integration] +yunohost = ">= 4.2.4" +architectures = "all" +multi_instance = false +ldap = "false" +sso = "false" +disk = "50M" # FIXME: replace with an **estimate** minimum disk requirement. e.g. 20M, 400M, 1G, ... +ram.build = "50M" # FIXME: replace with an **estimate** minimum ram requirement. e.g. 50M, 400M, 1G, ... +ram.runtime = "50M" # FIXME: replace with an **estimate** minimum ram requirement. e.g. 50M, 400M, 1G, ... + +[install] + [install.domain] + type = "domain" + + [install.admin] + type = "user" + + [install.init_main_permission] + type = "group" + default = "visitors" + + [install.allow_multimedia_write] + ask.en = "Allow write access to multimedia directories?" + ask.fr = "Autoriser la modification des fichiers dans les dossiers multimédia ?" + type = "boolean" + default = false + +[resources] + [resources.sources] + [resources.sources.cmake] + url = "https://github.com/Kitware/CMake/releases/download/v3.20.3/cmake-3.20.3-linux-aarch64.tar.gz" + sha256 = "77620f99e9d5f39cf4a49294c6a68c89a978ecef144894618974b9958efe3c2a" + + [resources.sources.im2txt] + url = "https://github.com/LibrePhotos/librephotos-docker/releases/download/0.1/im2txt.tar.gz" + sha256 = "980670c0365c0e32b5fecfc0907bfee4742bcd6a40e0d6ac5692c69bbd49ccc4" + + [resources.sources.resnet152-b121ed2d] + url = "https://download.pytorch.org/models/resnet152-b121ed2d.pth" + sha256 = "b121ed2db97ec7e9f55a91300ceaf85a326de955e8a4ae09e3a0c8170d27f14f" + format = "tar" + rename = "resnet152-b121ed2d.pth" + + [resources.sources.backend] + url = "https://github.com/LibrePhotos/librephotos/tarball/11c6994d3c506d835335f596090a13545d72713a" + sha256 = "0e588d7ed34fa826e8beba3894586b16bb247b00548215190732a1cbec57167b" + + [resources.sources.frontend] + url = "https://github.com/LibrePhotos/librephotos-frontend/tarball/37963756369f11617c456a56f6850b2e8aaf8358" + sha256 = "085b62550214bd9ffecfefde802b96f3542e6867bb25ff1a830623b598e4c61d" + + [resources.sources.dlib] + url = "https://github.com/davisking/dlib/archive/refs/tags/v19.22.tar.gz" + sha256 = "5f44b67f762691b92f3e41dcf9c95dd0f4525b59cacb478094e511fdacb5c096" + + [resources.sources.places365] + url = "https://github.com/LibrePhotos/librephotos-docker/releases/download/0.1/places365.tar.gz" + sha256 = "27792ffcd1f6a4de7abebdea046dda0916f9cd12eba7bed7b5f51f120f91f0d8" + + [resources.sources.faiss] + url = "https://github.com/facebookresearch/faiss/archive/refs/tags/v1.7.1.tar.gz" + sha256 = "d676d3107ad41203a49e0afda2630519299dc8666f8d23322cbe1eac0c431871" + + [resources.sources.cmake_amd64] + url = "https://github.com/Kitware/CMake/releases/download/v3.20.3/cmake-3.20.3-linux-x86_64.tar.gz" + sha256 = "97bf730372f9900b2dfb9206fccbcf92f5c7f3b502148b832e77451aa0f9e0e6" + + [resources.sources.miniforge3] + url = "https://github.com/conda-forge/miniforge/releases/download/4.10.1-4/Miniforge3-4.10.1-4-Linux-aarch64.sh" + sha256 = "68f11be0b8272b9218f62fa3ba1b7c58783427e65db7b7ba77e7cdf91f099540" + format = "sh" + rename = "Miniforge3-4.10.1-4-Linux-aarch64.sh" + + + [resources.system_user] + + [resources.install_dir] + + [resources.data_dir] + + [resources.permissions] + main.url = "/" + + [resources.ports] + main.default = 3000 + backend.default = 8001 + similarity.default = 8002 + + [resources.database] + type = "postgresql" + + [resources.apt] + packages = [ + "curl", "unzip", + "git", + "bzip2", + "build-essential", + "libtinfo5", + "ca-certificates", + "swig", + "libpq-dev", + "postgresql", "postgresql-contrib", "postgresql-common", + "ffmpeg", + "libimage-exiftool-perl", + "libopenblas-dev", + "libmagic1", + "libboost-all-dev", + "libxrender-dev", + "liblapack-dev", + "cmake", + "libsm6", + "libglib2.0-0", + "libgl1-mesa-glx", + "gfortran", + "gunicorn", + "libheif-dev", + "libssl-dev", + "rustc", + "liblzma-dev", + "python3", + "python3-pip", + "python3-venv", + "imagemagick", + "xsel", + "nodejs", + "npm", + "redis-server", + "libmagickwand-dev", + "libldap2-dev", + "libsasl2-dev", + ] + + packages_from_raw_bash = """ + if ! (apt-cache -q=0 show ufraw-batch |& grep ': No packages found' &>/dev/null); then + echo ufraw-batch + fi + """ + + [[resources.apt.extras]] + repo = "deb https://dl.yarnpkg.com/debian/ stable main" + key = "https://dl.yarnpkg.com/debian/pubkey.gpg" + packages = "yarn" diff --git a/scripts/_common.sh b/scripts/_common.sh index 5c65278..7bbfa89 100644 --- a/scripts/_common.sh +++ b/scripts/_common.sh @@ -4,27 +4,20 @@ # COMMON VARIABLES #================================================= -# dependencies used by the app -pkg_dependencies="libtinfo5 unzip ca-certificates swig libpq-dev postgresql postgresql-contrib postgresql-common ffmpeg libimage-exiftool-perl curl libopenblas-dev libmagic1 libboost-all-dev libxrender-dev liblapack-dev git bzip2 cmake build-essential libsm6 libglib2.0-0 libgl1-mesa-glx gfortran gunicorn libheif-dev libssl-dev rustc liblzma-dev python3 python3-pip python3-venv imagemagick xsel nodejs npm redis-server libmagickwand-dev libldap2-dev libsasl2-dev" - arch="$(dpkg --print-architecture)" arm64_test=0 -if ! (apt-cache -q=0 show ufraw-batch |& grep ': No packages found' &>/dev/null); then - pkg_dependencies="$pkg_dependencies ufraw-batch" -fi - #================================================= # PERSONAL HELPERS #================================================= function unpack_source { - ynh_secure_remove "$final_path" - mkdir -p "$final_path/data_models/"{places365,im2txt} - ynh_setup_source --source_id="places365" --dest_dir="$final_path/data_models/places365/" - ynh_setup_source --source_id="im2txt" --dest_dir="$final_path/data_models/im2txt/" + ynh_secure_remove "$install_dir" + mkdir -p "$install_dir/data_models/"{places365,im2txt} + ynh_setup_source --source_id="places365" --dest_dir="$install_dir/data_models/places365/" + ynh_setup_source --source_id="im2txt" --dest_dir="$install_dir/data_models/im2txt/" mkdir -p "$data_path" - ln -sf "$final_path/data_models" "$data_path/data_models" + ln -sf "$install_dir/data_models" "$data_path/data_models" mkdir -p "$data_path/protected_media/"{thumbnails_big,square_thumbnails,square_thumbnails_small,faces} mkdir -p "$data_path/data/nextcloud_media" mkdir -p "$data_path/matplotlib" @@ -32,27 +25,27 @@ function unpack_source { mkdir -p ~/.cache/torch/hub/checkpoints/ ynh_setup_source --source_id="resnet152-b121ed2d" --dest_dir="/root/.cache/torch/hub/checkpoints/" - ynh_setup_source --source_id="backend" --dest_dir="$final_path/backend/" - ynh_setup_source --source_id="frontend" --dest_dir="$final_path/frontend/" - ynh_setup_source --source_id="dlib" --dest_dir="$final_path/backend/dlib/" + ynh_setup_source --source_id="backend" --dest_dir="$install_dir/backend/" + ynh_setup_source --source_id="frontend" --dest_dir="$install_dir/frontend/" + ynh_setup_source --source_id="dlib" --dest_dir="$install_dir/backend/dlib/" if [ "$arch" = "arm64" ] || [ "$arm64_test" -eq 1 ]; then - export CONDA_DIR="$final_path/backend/conda" + export CONDA_DIR="$install_dir/backend/conda" mkdir -p "$CONDA_DIR" if [ "$arch" = "arm64" ]; then ynh_setup_source --source_id="miniforge3" --dest_dir="$CONDA_DIR" - ynh_setup_source --source_id="cmake" --dest_dir="$final_path/backend/cmake/" + ynh_setup_source --source_id="cmake" --dest_dir="$install_dir/backend/cmake/" else wget -O "${CONDA_DIR}/Miniforge3-4.10.1-4-Linux-aarch64.sh" https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh 2>&1 - ynh_setup_source --source_id="cmake_amd64" --dest_dir="$final_path/backend/cmake/" + ynh_setup_source --source_id="cmake_amd64" --dest_dir="$install_dir/backend/cmake/" fi - #ynh_setup_source --source_id="faiss" --dest_dir="$final_path/backend/faiss/" + #ynh_setup_source --source_id="faiss" --dest_dir="$install_dir/backend/faiss/" fi mkdir -p "/var/log/$app" } function set_up_backend { - backend_path="$final_path/backend" + backend_path="$install_dir/backend" pushd "$backend_path" chown -R $app:$app "$backend_path" sudo -u $app python3 -m venv $backend_path/venv @@ -111,8 +104,8 @@ function set_node_vars { function set_up_frontend { set_node_vars - frontend_path=$final_path/frontend - pushd $final_path/frontend + frontend_path=$install_dir/frontend + pushd $install_dir/frontend chown -R $app:$app $frontend_path sudo -u $app touch $frontend_path/.yarnrc sudo -u $app env "PATH=$node_PATH" yarn --cache-folder $frontend_path/yarn-cache --use-yarnrc $frontend_path/.yarnrc install 2>&1 @@ -122,7 +115,7 @@ function set_up_frontend { popd } -function add_configuations { +function add_configurations { secret_key=$(ynh_app_setting_get --app=$app --key=secret_key) if [ -z $secret_key ]; then @@ -130,19 +123,19 @@ function add_configuations { ynh_app_setting_set --app=$app --key=secret_key --value=$secret_key fi - ynh_add_config --template="librephotos.env" --destination="$final_path/librephotos.env" + ynh_add_config --template="librephotos.env" --destination="$install_dir/librephotos.env" } function upgrade_db { - pushd "$final_path/backend" - chown -R $app:$app "$final_path/backend" + pushd "$install_dir/backend" + chown -R $app:$app "$install_dir/backend" chown -R $app:$app "/var/log/$app" sudo -u $app bash -c " set -a export PATH=\"$path_prefix:"'$PATH'"\" - source \"$final_path\"/librephotos.env + source \"$install_dir\"/librephotos.env python3 manage.py showmigrations - python3 manage.py migrate + python3 manage.py migrate python3 manage.py showmigrations " 2>&1 popd @@ -150,11 +143,11 @@ function upgrade_db { } function set_permissions { - chown -R root:$app "$final_path" - chmod -R g=u,g-w,o-rwx "$final_path" + chown -R root:$app "$install_dir" + chmod -R g=u,g-w,o-rwx "$install_dir" chown -R $app:$app "$data_path" chmod -R g=u,g-w,o-rwx "$data_path" - chown -R $app:$app "$final_path/data_models" + chown -R $app:$app "$install_dir/data_models" chown -R $app:$app "/var/log/$app" chmod -R g-w,o-rwx "/var/log/$app" setfacl -n -m user:www-data:rx "$data_path" diff --git a/scripts/backup b/scripts/backup index 15f5000..5ead846 100755 --- a/scripts/backup +++ b/scripts/backup @@ -10,28 +10,6 @@ source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers -#================================================= -# MANAGE SCRIPT FAILURE -#================================================= - -ynh_clean_setup () { - ynh_clean_check_starting -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors - -#================================================= -# LOAD SETTINGS -#================================================= -ynh_print_info --message="Loading installation settings..." - -app=$YNH_APP_INSTANCE_NAME - -final_path=$(ynh_app_setting_get --app=$app --key=final_path) -domain=$(ynh_app_setting_get --app=$app --key=domain) -db_name=$(ynh_app_setting_get --app=$app --key=db_name) -data_path=$(ynh_app_setting_get --app=$app --key=data_path) - #================================================= # DECLARE DATA AND CONF FILES TO BACKUP #================================================= @@ -41,7 +19,7 @@ ynh_print_info --message="Declaring files to be backed up..." # BACKUP THE APP MAIN DIR #================================================= -ynh_backup --src_path="$final_path" +ynh_backup --src_path="$install_dir" #================================================= # BACKUP THE NGINX CONFIGURATION diff --git a/scripts/change_url b/scripts/change_url index b2db8be..6af5c69 100644 --- a/scripts/change_url +++ b/scripts/change_url @@ -9,55 +9,6 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# RETRIEVE ARGUMENTS -#================================================= - -old_domain=$YNH_APP_OLD_DOMAIN -old_path=$YNH_APP_OLD_PATH - -new_domain=$YNH_APP_NEW_DOMAIN -new_path="/" - -app=$YNH_APP_INSTANCE_NAME - -#================================================= -# LOAD SETTINGS -#================================================= -ynh_script_progression --message="Loading installation settings..." --weight=1 - -# Needed for helper "ynh_add_nginx_config" -final_path=$(ynh_app_setting_get --app=$app --key=final_path) - -#================================================= -# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP -#================================================= -ynh_script_progression --message="Backing up the app before changing its URL (may take a while)..." --weight=30 - -# Backup the current version of the app -ynh_backup_before_upgrade -ynh_clean_setup () { - # Remove the new domain config file, the remove script won't do it as it doesn't know yet its location. - ynh_secure_remove --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" - - # Restore it if the upgrade fails - ynh_restore_upgradebackup -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors - -#================================================= -# CHECK WHICH PARTS SHOULD BE CHANGED -#================================================= - -change_domain=0 -if [ "$old_domain" != "$new_domain" ] -then - change_domain=1 -fi - -change_path=0 - #================================================= # STANDARD MODIFICATIONS #================================================= @@ -75,17 +26,7 @@ ynh_systemd_action --service_name=$app-worker --action="stop" --log_path="/var/l #================================================= ynh_script_progression --message="Updating NGINX web server configuration..." --weight=1 -nginx_conf_path=/etc/nginx/conf.d/$old_domain.d/$app.conf - -# Change the domain for NGINX -if [ $change_domain -eq 1 ] -then - # Delete file checksum for the old conf file location - ynh_delete_file_checksum --file="$nginx_conf_path" - mv $nginx_conf_path /etc/nginx/conf.d/$new_domain.d/$app.conf - # Store file checksum for the new config file location - ynh_store_file_checksum --file="/etc/nginx/conf.d/$new_domain.d/$app.conf" -fi +ynh_change_url_nginx_config #================================================= # GENERIC FINALISATION @@ -99,13 +40,6 @@ ynh_systemd_action --service_name=$app-frontend --action="start" --log_path="sys ynh_systemd_action --service_name=$app-image-similarity --action="start" --log_path="/var/log/$app/image_similarity.log" ynh_systemd_action --service_name=$app-worker --action="start" --log_path="/var/log/$app/$app-worker.log" -#================================================= -# RELOAD NGINX -#================================================= -ynh_script_progression --message="Reloading NGINX web server..." --weight=1 - -ynh_systemd_action --service_name=nginx --action=reload - #================================================= # END OF SCRIPT #================================================= diff --git a/scripts/install b/scripts/install index 8603703..4eda21b 100755 --- a/scripts/install +++ b/scripts/install @@ -9,85 +9,13 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# MANAGE SCRIPT FAILURE -#================================================= -ynh_clean_setup () { - ynh_clean_check_starting -} -# 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="/" -admin=$YNH_APP_ARG_ADMIN -is_public=$YNH_APP_ARG_IS_PUBLIC -allow_multimedia_write=$YNH_APP_ARG_ALLOW_MULTIMEDIA_WRITE -app=$YNH_APP_INSTANCE_NAME - -#================================================= -# CHECK IF THE APP CAN BE INSTALLED WITH THESE ARGS -#================================================= -ynh_script_progression --message="Validating installation parameters..." --weight=1 - -final_path=/opt/yunohost/$app -test ! -e "$final_path" || ynh_die --message="This path already contains a folder" -ynh_app_setting_set --app=$app --key=final_path --value="$final_path" - -data_path=/home/yunohost.app/$app -test ! -e "$data_path" || ynh_die --message="This path already contains a folder" -ynh_app_setting_set --app=$app --key=data_path --value="$data_path" - -# Register (book) web path -ynh_webpath_register --app=$app --domain=$domain --path_url=$path_url - -#================================================= -# STORE SETTINGS FROM MANIFEST -#================================================= -ynh_script_progression --message="Storing installation settings..." --weight=1 - -ynh_app_setting_set --app=$app --key=domain --value=$domain -ynh_app_setting_set --app=$app --key=path --value=$path_url -ynh_app_setting_set --app=$app --key=admin --value=$admin -ynh_app_setting_set --app=$app --key=allow_multimedia_write --value=$allow_multimedia_write +# Might not be required +path="/" #================================================= # STANDARD MODIFICATIONS #================================================= -# FIND PORTS -#================================================= -ynh_script_progression --message="Finding available ports..." --weight=1 - -# Find an available port -port=$(ynh_find_port --port=3000) -ynh_app_setting_set --app=$app --key=port --value=$port -backend_port=$(ynh_find_port --port=8001) -ynh_app_setting_set --app=$app --key=backend_port --value=$backend_port -similarity_port=$(ynh_find_port --port=$(expr $backend_port + 1)) -ynh_app_setting_set --app=$app --key=similarity_port --value=$similarity_port - -#================================================= -# INSTALL DEPENDENCIES -#================================================= -ynh_script_progression --message="Installing dependencies..." --weight=5 - -ynh_install_app_dependencies $pkg_dependencies -ynh_install_extra_app_dependencies --repo="deb https://dl.yarnpkg.com/debian/ stable main" --package="yarn" --key="https://dl.yarnpkg.com/debian/pubkey.gpg" - -#================================================= -# CREATE A POSTGRESQL DATABASE -#================================================= -ynh_script_progression --message="Creating a PostgreSQL database..." --weight=1 - -db_name=$(ynh_sanitize_dbid --db_name=$app) -db_user=$db_name -ynh_psql_test_if_first_run -ynh_app_setting_set --app=$app --key=db_name --value=$db_name -ynh_psql_setup_db --db_user=$db_user --db_name=$db_name #================================================= # DOWNLOAD, CHECK AND UNPACK SOURCE @@ -104,14 +32,6 @@ ynh_script_progression --message="Configuring NGINX web server..." --weight=1 # Create a dedicated NGINX config ynh_add_nginx_config backend_port -#================================================= -# CREATE DEDICATED USER -#================================================= -ynh_script_progression --message="Configuring system user..." --weight=1 - -# Create a system user -ynh_system_user_create --username=$app --home_dir=$data_path - #================================================= # SPECIFIC SETUP #================================================= @@ -134,17 +54,17 @@ set_up_frontend ynh_script_progression --message="Configuring systemd services..." --weight=1 # Create dedicated systemd configs -ynh_add_systemd_config --service=$app-backend --template=backend.service -ynh_add_systemd_config --service=$app-frontend --template=frontend.service -ynh_add_systemd_config --service=$app-image-similarity --template=image-similarity.service -ynh_add_systemd_config --service=$app-worker --template=worker.service +ynh_add_systemd_config --service="$app-backend" --template=backend.service +ynh_add_systemd_config --service="$app-frontend" --template=frontend.service +ynh_add_systemd_config --service="$app-image-similarity" --template=image-similarity.service +ynh_add_systemd_config --service="$app-worker" --template=worker.service #================================================= # ADD CONFIGURATIONS #================================================= ynh_script_progression --message="Generating configuration files..." --weight=1 -add_configuations +add_configurations #================================================= # FINALIZE DATABASE @@ -153,22 +73,22 @@ ynh_script_progression --message="Finalizing database..." --weight=1 upgrade_db -pushd "$final_path/backend" - admin_mail="$(ynh_user_get_info $admin 'mail')" - sudo -u $app bash -c " - set -a - export PATH=\"$path_prefix:"'$PATH'"\" - source \"$final_path\"/librephotos.env - python3 manage.py createsuperuser --noinput --username \"$admin\" --email \"$admin_mail\" - " 2>&1 - for user in $(ynh_user_list); do - mail=$(ynh_user_get_info --username="$user" --key=mail) - sudo -u $app bash -c " - set -a - export PATH=\"$path_prefix:"'$PATH'"\" - source \"$final_path\"/librephotos.env - python3 manage.py shell - " <<< " +pushd "$install_dir/backend" + admin_mail="$(ynh_user_get_info $admin 'mail')" + sudo -u $app bash -c " + set -a + export PATH=\"$path_prefix:"'$PATH'"\" + source \"$install_dir\"/librephotos.env + python3 manage.py createsuperuser --noinput --username \"$admin\" --email \"$admin_mail\" + " 2>&1 + for user in $(ynh_user_list); do + mail=$(ynh_user_get_info --username="$user" --key=mail) + sudo -u $app bash -c " + set -a + export PATH=\"$path_prefix:"'$PATH'"\" + source \"$install_dir\"/librephotos.env + python3 manage.py shell + " <<< " from django.contrib.auth import get_user_model User = get_user_model() try: @@ -178,7 +98,7 @@ try: except User.DoesNotExist: User.objects.create_user('$user', email='$mail', scan_directory='/home/yunohost.multimedia/$user/Picture') " 2>&1 - done + done popd #================================================= @@ -188,8 +108,8 @@ ynh_script_progression --message="Adding multimedia directories..." --weight=1 # Build YunoHost multimedia directories ynh_multimedia_build_main_dir -if [ $allow_multimedia_write -eq 1 ]; then - ynh_multimedia_addaccess $app +if [ "$allow_multimedia_write" -eq 1 ]; then + ynh_multimedia_addaccess $app fi #================================================= @@ -231,26 +151,6 @@ ynh_systemd_action --service_name=$app-image-similarity --action="start" --log_p ynh_systemd_action --service_name=$app-worker --action="start" --log_path="/var/log/$app/$app-worker.log" -#================================================= -# SETUP SSOWAT -#================================================= -ynh_script_progression --message="Configuring permissions..." --weight=1 - -# Make app public if necessary -if [ $is_public -eq 1 ] -then - # Everyone can access the app. - # The "main" permission is automatically created before the install script. - ynh_permission_update --permission="main" --add="visitors" -fi - -#================================================= -# RELOAD NGINX -#================================================= -ynh_script_progression --message="Reloading NGINX web server..." --weight=1 - -ynh_systemd_action --service_name=nginx --action=reload - #================================================= # END OF SCRIPT #================================================= diff --git a/scripts/remove b/scripts/remove index e2cbdf3..a29e470 100755 --- a/scripts/remove +++ b/scripts/remove @@ -9,20 +9,6 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# LOAD SETTINGS -#================================================= -ynh_script_progression --message="Loading installation settings..." --weight=1 - -app=$YNH_APP_INSTANCE_NAME - -domain=$(ynh_app_setting_get --app=$app --key=domain) -port=$(ynh_app_setting_get --app=$app --key=port) -db_name=$(ynh_app_setting_get --app=$app --key=db_name) -db_user=$db_name -final_path=$(ynh_app_setting_get --app=$app --key=final_path) -data_path=$(ynh_app_setting_get --app=$app --key=data_path) - #================================================= # STANDARD REMOVE #================================================= @@ -32,22 +18,10 @@ data_path=$(ynh_app_setting_get --app=$app --key=data_path) ynh_script_progression --message="Removing $app services integration..." --weight=1 # Remove the service from the list of services known by YunoHost (added from `yunohost service add`) -if ynh_exec_warn_less yunohost service status $app-backend >/dev/null ; then - yunohost service remove $app-backend -fi - -if ynh_exec_warn_less yunohost service status $app-frontend >/dev/null ; then - yunohost service remove $app-frontend -fi - -if ynh_exec_warn_less yunohost service status $app-image-similarity >/dev/null ; then - yunohost service remove $app-image-similarity -fi - -if ynh_exec_warn_less yunohost service status $app-worker >/dev/null ; then - yunohost service remove $app-worker -fi - +yunohost service remove $app-backend +yunohost service remove $app-frontend +yunohost service remove $app-image-similarity +yunohost service remove $app-worker #================================================= # STOP AND REMOVE SERVICE #================================================= @@ -59,38 +33,6 @@ ynh_remove_systemd_config --service="$app-frontend" ynh_remove_systemd_config --service="$app-image-similarity" ynh_remove_systemd_config --service="$app-worker" -#================================================= -# REMOVE THE POSTGRESQL DATABASE -#================================================= -ynh_script_progression --message="Removing the PostgreSQL database..." --weight=1 - -# Remove a database if it exists, along with the associated user -ynh_psql_remove_db --db_user=$db_user --db_name=$db_name - -#================================================= -# REMOVE DEPENDENCIES -#================================================= -ynh_script_progression --message="Removing dependencies..." --weight=30 - -# Remove metapackage and its dependencies -ynh_remove_app_dependencies - -#================================================= -# REMOVE APP MAIN DIR -#================================================= -ynh_script_progression --message="Removing app main directory..." --weight=2 - -# Remove the app directory securely -ynh_secure_remove --file="$final_path" - -#================================================= -# REMOVE APP DATA DIR -#================================================= -ynh_script_progression --message="Removing app data directory..." --weight=1 - -# Remove the app directory securely -ynh_secure_remove --file="$data_path" - #================================================= # REMOVE NGINX CONFIGURATION #================================================= @@ -123,16 +65,6 @@ ynh_remove_nodejs # Remove the log files ynh_secure_remove --file="/var/log/$app" -#================================================= -# GENERIC FINALIZATION -#================================================= -# REMOVE DEDICATED USER -#================================================= -ynh_script_progression --message="Removing the dedicated system user..." --weight=1 - -# Delete a system user -ynh_system_user_delete --username=$app - #================================================= # END OF SCRIPT #================================================= diff --git a/scripts/restore b/scripts/restore index 6c6e656..cb5489d 100755 --- a/scripts/restore +++ b/scripts/restore @@ -10,49 +10,6 @@ source ../settings/scripts/_common.sh source /usr/share/yunohost/helpers -#================================================= -# MANAGE SCRIPT FAILURE -#================================================= - -ynh_clean_setup () { - ynh_clean_check_starting -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors - -#================================================= -# LOAD SETTINGS -#================================================= -ynh_script_progression --message="Loading installation settings..." --weight=1 - -app=$YNH_APP_INSTANCE_NAME - -domain=$(ynh_app_setting_get --app=$app --key=domain) -path_url=$(ynh_app_setting_get --app=$app --key=path) -final_path=$(ynh_app_setting_get --app=$app --key=final_path) -db_name=$(ynh_app_setting_get --app=$app --key=db_name) -db_user=$db_name -db_pwd=$(ynh_app_setting_get --app=$app --key=psqlpwd) -data_path=$(ynh_app_setting_get --app=$app --key=data_path) -allow_multimedia_write=$(ynh_app_setting_get --app=$app --key=allow_multimedia_write) -port=$(ynh_app_setting_get --app=$app --key=port) -backend_port=$(ynh_app_setting_get --app=$app --key=port) -similarity_port=$(ynh_app_setting_get --app=$app --key=similarity_port) - - -#================================================= -# CHECK IF THE APP CAN BE RESTORED -#================================================= -ynh_script_progression --message="Validating restoration parameters..." --weight=1 - -ynh_webpath_available --domain=$domain --path_url=$path_url \ - || ynh_die --message="Path not available: ${domain}${path_url}" -test ! -d $final_path \ - || ynh_die --message="There is already a directory: $final_path " - -test ! -d $data_path \ - || ynh_die --message="There is already a directory: $data_path " - #================================================= # STANDARD RESTORATION STEPS #================================================= @@ -66,7 +23,7 @@ ynh_restore_file --origin_path="/etc/nginx/conf.d/$domain.d/$app.conf" #================================================= ynh_script_progression --message="Restoring the app main directory..." --weight=1 -ynh_restore_file --origin_path="$final_path" +ynh_restore_file --origin_path="$install_dir" #================================================= # RESTORE THE APP DATA DIR @@ -77,15 +34,7 @@ ynh_restore_file --origin_path="$data_path" --not_mandatory mkdir -p $data_path/protected_media/{thumbnails_big,square_thumbnails,square_thumbnails_small,faces} mkdir -p $data_path/data/nextcloud_media mkdir -p $data_path/matplotlib -ln -s $final_path/data_models $data_path/data_models - -#================================================= -# RECREATE THE DEDICATED USER -#================================================= -ynh_script_progression --message="Recreating the dedicated system user..." --weight=1 - -# Create the dedicated user (if not existing) -ynh_system_user_create --username=$app --home_dir=$data_path +ln -s $install_dir/data_models $data_path/data_models #================================================= # RESTORE VARIOUS FILES @@ -99,15 +48,6 @@ ynh_restore_file --origin_path="/var/log/$app" ynh_restore_file --origin_path="/etc/logrotate.d/$app" -#================================================= -# REINSTALL DEPENDENCIES -#================================================= -ynh_script_progression --message="Reinstalling dependencies..." --weight=60 - -# Define and install dependencies -ynh_install_app_dependencies $pkg_dependencies -ynh_install_extra_app_dependencies --repo="deb https://dl.yarnpkg.com/debian/ stable main" --package="yarn" --key="https://dl.yarnpkg.com/debian/pubkey.gpg" - #================================================= # RESTORE USER RIGHTS #================================================= diff --git a/scripts/upgrade b/scripts/upgrade index 3339bde..585d87d 100644 --- a/scripts/upgrade +++ b/scripts/upgrade @@ -9,47 +9,6 @@ source _common.sh source /usr/share/yunohost/helpers -#================================================= -# LOAD SETTINGS -#================================================= -ynh_script_progression --message="Loading installation settings..." --weight=1 - -app=$YNH_APP_INSTANCE_NAME - -domain=$(ynh_app_setting_get --app=$app --key=domain) -path_url=$(ynh_app_setting_get --app=$app --key=path) -admin=$(ynh_app_setting_get --app=$app --key=admin) -final_path=$(ynh_app_setting_get --app=$app --key=final_path) -language=$(ynh_app_setting_get --app=$app --key=language) -db_name=$(ynh_app_setting_get --app=$app --key=db_name) -db_user=$db_name -db_pwd=$(ynh_app_setting_get --app=$app --key=psqlpwd) -port=$(ynh_app_setting_get --app=$app --key=port) -backend_port=$(ynh_app_setting_get --app=$app --key=backend_port) -similarity_port=$(ynh_app_setting_get --app=$app --key=similarity_port) -data_path=$(ynh_app_setting_get --app=$app --key=data_path) -allow_multimedia_write=$(ynh_app_setting_get --app=$app --key=allow_multimedia_write) - -#================================================= -# CHECK VERSION -#================================================= - -upgrade_type=$(ynh_check_app_version_changed) - -#================================================= -# BACKUP BEFORE UPGRADE THEN ACTIVE TRAP -#================================================= -ynh_script_progression --message="Backing up the app before upgrading (may take a while)..." --weight=30 - -# Backup the current version of the app -ynh_backup_before_upgrade -ynh_clean_setup () { - # Restore it if the upgrade fails - ynh_restore_upgradebackup -} -# Exit if an error occurs during the execution of the script -ynh_abort_if_errors - #================================================= # STANDARD UPGRADE STEPS #================================================= @@ -77,7 +36,7 @@ fi # DOWNLOAD, CHECK AND UNPACK SOURCE #================================================= -if [ "$upgrade_type" == "UPGRADE_APP" ] +if [ "$(ynh_check_app_version_changed)" == "UPGRADE_APP" ] then unpack_source fi @@ -90,22 +49,6 @@ ynh_script_progression --message="Upgrading NGINX web server configuration..." - # Create a dedicated NGINX config ynh_add_nginx_config backend_port -#================================================= -# UPGRADE DEPENDENCIES -#================================================= -ynh_script_progression --message="Upgrading dependencies..." --weight=1 - -ynh_install_app_dependencies $pkg_dependencies -ynh_install_extra_app_dependencies --repo="deb https://dl.yarnpkg.com/debian/ stable main" --package="yarn" --key="https://dl.yarnpkg.com/debian/pubkey.gpg" - -#================================================= -# CREATE DEDICATED USER -#================================================= -ynh_script_progression --message="Making sure dedicated system user exists..." --weight=1 - -# Create a dedicated user (if not existing) -ynh_system_user_create --username=$app --home_dir=$data_path - #================================================= # SPECIFIC UPGRADE #================================================= @@ -138,7 +81,7 @@ ynh_add_systemd_config --service=$app-worker --template=worker.service #================================================= ynh_script_progression --message="Generating configuration files..." --weight=1 -add_configuations +add_configurations #================================================= # FINALIZE DATABASE @@ -196,13 +139,6 @@ ynh_systemd_action --service_name=$app-frontend --action="start" --log_path="sys ynh_systemd_action --service_name=$app-image-similarity --action="start" --log_path="/var/log/$app/image_similarity.log" ynh_systemd_action --service_name=$app-worker --action="start" --log_path="/var/log/$app/$app-worker.log" -#================================================= -# RELOAD NGINX -#================================================= -ynh_script_progression --message="Reloading NGINX web server..." --weight=1 - -ynh_systemd_action --service_name=nginx --action=reload - #================================================= # END OF SCRIPT #================================================= diff --git a/tests.toml b/tests.toml new file mode 100644 index 0000000..d405a97 --- /dev/null +++ b/tests.toml @@ -0,0 +1,34 @@ +#:schema https://raw.githubusercontent.com/YunoHost/apps/master/schemas/tests.v1.schema.json + +test_format = 1.0 + +[default] + + # ------------ + # Tests to run + # ------------ + + exclude = ["install.subdir", "install.multi"] + # The test IDs to be used in only/exclude statements are: + # * install.root + # * install.subdir + # * install.nourl + # * install.multi + # * backup_restore + # * upgrade + # * upgrade.someCommitId + # * change_url + # NB: you should NOT need this except if you really have a good reason... + + # ------------------------------- + # Default args to use for install + # ------------------------------- + + args.allow_multimedia_write = 1 + + # ------------------------------- + # Commits to test upgrade from + # ------------------------------- + + test_upgrade_from.3b5b527e.name = "Upgrade from March 29" + test_upgrade_from.3b5b527e.args.foo = "bar"