From ec95e5829cdf179be145b229eb3e92178d0e92b8 Mon Sep 17 00:00:00 2001 From: Sacha Chua Date: Wed, 19 Oct 2022 09:22:10 -0400 Subject: Add upload --- README.org | 4 ++ common-playbook.yml | 6 ++ inventory.yml | 6 ++ roles/pad-proxy/tasks/main.yml | 3 - roles/upload/defaults/main.yml | 2 + roles/upload/tasks/main.yml | 107 ++++++++++++++++++++++++++++ roles/upload/templates/config.production.js | 106 +++++++++++++++++++++++++++ roles/upload/templates/head.pug | 22 ++++++ roles/upload/templates/upload.service | 16 +++++ 9 files changed, 269 insertions(+), 3 deletions(-) create mode 100644 roles/upload/defaults/main.yml create mode 100644 roles/upload/tasks/main.yml create mode 100644 roles/upload/templates/config.production.js create mode 100644 roles/upload/templates/head.pug create mode 100644 roles/upload/templates/upload.service diff --git a/README.org b/README.org index 76c082f..31c926b 100644 --- a/README.org +++ b/README.org @@ -138,3 +138,7 @@ https://gist.github.com/aaronpk/7307172 ansible-playbook -i inventory.yml prod-playbook.yml --tags proxy --extra-vars='{"use_wikimedia": false}' ansible-playbook -i inventory.yml prod-playbook.yml --tags proxy --extra-vars='{"use_wikimedia": true}' +* Upload + +/ssh:media|sudo:upload@media:~upload +/ssh:media|sudo::/etc/nginx/sites-available diff --git a/common-playbook.yml b/common-playbook.yml index 06b8d08..815aac4 100644 --- a/common-playbook.yml +++ b/common-playbook.yml @@ -23,3 +23,9 @@ tags: proxy roles: - pad-proxy +- name: Set up upload container + hosts: upload + tags: upload + roles: + - upload + diff --git a/inventory.yml b/inventory.yml index 3124fb5..7f80dae 100644 --- a/inventory.yml +++ b/inventory.yml @@ -18,6 +18,12 @@ prod: ansible_ssh_user: orga ansible_python_interpreter: /usr/bin/python3 ansible_become: true + upload: + ansible_host: media.emacsconf.org + remote_user: orga + ansible_ssh_user: orga + ansible_python_interpreter: /usr/bin/python3 + ansible_become: true all: hosts: localhost: diff --git a/roles/pad-proxy/tasks/main.yml b/roles/pad-proxy/tasks/main.yml index b8cfdf3..8de72df 100644 --- a/roles/pad-proxy/tasks/main.yml +++ b/roles/pad-proxy/tasks/main.yml @@ -6,9 +6,6 @@ apt: name: nginx state: present - - debug: - var: ansible_managed - tags: wip - name: Add proxy configuration template: src: etherpad.nginx.conf diff --git a/roles/upload/defaults/main.yml b/roles/upload/defaults/main.yml new file mode 100644 index 0000000..188420c --- /dev/null +++ b/roles/upload/defaults/main.yml @@ -0,0 +1,2 @@ +upload_user: upload +upload_dir: /home/upload/files diff --git a/roles/upload/tasks/main.yml b/roles/upload/tasks/main.yml new file mode 100644 index 0000000..843b4be --- /dev/null +++ b/roles/upload/tasks/main.yml @@ -0,0 +1,107 @@ +- name: Set up packages as root + block: + - name: Add GPG + apt: + update_cache: yes + name: + - gpg + - sudo + - name: Add nodesource key + apt_key: + url: https://deb.nodesource.com/gpgkey/nodesource.gpg.key + state: present + - name: Add nodesource repository + ansible.builtin.apt_repository: + repo: deb https://deb.nodesource.com/node_13.x buster main + update_cache: yes + - name: Install packages + apt: + update_cache: yes + name: + - nodejs + state: present +- name: Create upload user + become: true + user: + name: "{{ upload_user }}" + shell: /bin/bash + state: present +- name: Ensure upload directory exists + file: + path: "{{ upload_dir }}" + owner: "{{ upload_user }}" + state: directory +- name: Install precompiled version + unarchive: + src: https://github.com/psi-4ward/psitransfer/releases/download/v2.1.1/psitransfer-v2.1.1.tar.gz + dest: "/home/{{ upload_user }}" + remote_src: yes +- name: Create link + file: + src: "/home/{{ upload_user }}/psitransfer-v2.1.1" + dest: "/home/{{ upload_user }}/psitransfer" + state: link +- name: Upload production config + tags: wip + become: true + template: + src: config.production.js + dest: "/home/{{ upload_user }}/psitransfer/config.production.js" +- name: Install dependencies + npm: + path: "/home/{{ upload_user }}/psitransfer" + production: yes + ci: yes +- name: Add LibreJS tag start + tags: wip + lineinfile: + path: /home/{{ upload_user }}/psitransfer/public/app/{{ item.path }} + line: // @license {{ item.license }} + insertbefore: BOF + loop: + - path: common.js + license: magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat + - path: upload.js + license: magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat + - path: admin.js + license: magnet:?xt=urn:btih:87f119ba0b429ba17a44b4bffcab33165ebdacc0&dn=freebsd.txt BSD-2-Clause + - path: download.js + license: magnet:?xt=urn:btih:87f119ba0b429ba17a44b4bffcab33165ebdacc0&dn=freebsd.txt BSD-2-Clause +- name: Add license tag end + tags: wip + lineinfile: + path: /home/{{ upload_user }}/psitransfer/public/app/{{ item.path }} + line: // @license-end + loop: + - path: common.js + - path: upload.js + - path: admin.js + - path: download.js +- name: Update head template + tags: wip + template: + src: head.pug + dest: /home/{{ upload_user }}/psitransfer/public/pug/partials/head.pug +- name: Change ownership + file: + path: "/home/{{ upload_user }}" + owner: "{{ upload_user }}" + group: "{{ upload_group }}" + recurse: true +- name: Install systemd configuration + tags: system + become: true + template: + src: upload.service + dest: /etc/systemd/system/upload.service + owner: root + group: root + mode: 0755 + when: not use_initd +- name: Restart Upload + tags: wip + become: true + service: + name: upload + state: restarted + enabled: yes diff --git a/roles/upload/templates/config.production.js b/roles/upload/templates/config.production.js new file mode 100644 index 0000000..b3b1e4b --- /dev/null +++ b/roles/upload/templates/config.production.js @@ -0,0 +1,106 @@ +const path = require('path'); +const fs = require('fs'); +const fsp = require('fs-promise'); + +// Default Config +// Do not edit this, generate a config..js for your NODE_ENV +// or use ENV-VARS like PSITRANSFER_PORT=8000 +const config = { + "uploadDir": path.resolve(__dirname + '/data'), + // set to serve PsiTransfer from a sub-path + "baseUrl": '/', + // use to set custom upload url (subfolder to baseUrl) + "uploadAppPath": '/', + "iface": '127.0.0.1', + // set to false to disable HTTP + "port": 3000, + // HTTPS, set all 3 values to enable + "sslPort": "{{ upload_ssl_port }}", + "sslKeyFile": "{{ upload_ssl_key }}", + "sslCertFile": "{{ upload_ssl_cert }}", + // Force redirect to https + // can be true or a specific url like https://example.com:8443 + // keep empty to disable + "forceHttps": '', + // retention options in seconds:label + "retentions": { + // "one-time": "one time download", + // "3600": "1 Hour", + // "21600": "6 Hours", + // "86400": "1 Day", + // "259200": "3 Days", + // "604800": "1 Week", + // "1209600": "2 Weeks", + // "2419200": "4 Weeks", + "4838400": "8 Weeks" + }, + // admin password, set to false to disable /admin page + "adminPass": false, + // upload password, set to false to disable + "uploadPass": false, + // make the bucket-password field mandatory + "requireBucketPassword": false, + "defaultRetention": "4838400", + // expire every file after maxAge (eg never downloaded one-time files) + "maxAge": 3600 * 24 * 75, // 75 days + // maximum file-size for previews in byte + "maxPreviewSize": Math.pow(2, 20) * 2, // 2MB + "mailTemplate": 'mailto:?subject=File Transfer&body=You can download the files here: %%URL%%', + // see https://github.com/expressjs/morgan + // set to false to disable logging + "accessLog": ':date[iso] :method :url :status :response-time :remote-addr', + // event webhooks + // invokes an HTTP POST to a url whenever a file is downloaded + // for more info, see the webhooks section of docs/configuration.md + "fileDownloadedWebhook": null, + "fileUploadedWebhook": null, + // Fallback language + "defaultLanguage": "en", + // Limit upload size + "maxFileSize": null, // Math.pow(2, 30) * 2, // 2GB + "maxBucketSize": null, // Math.pow(2, 30) * 2, // 10GB + "plugins": ['file-downloaded-webhook', 'file-uploaded-webhook'], +}; + +// Load NODE_ENV specific config +const envConfFile = path.resolve(__dirname, `config.${ process.env.NODE_ENV }.js`); +if (process.env.NODE_ENV && fsp.existsSync(envConfFile)) { + Object.assign(config, require(envConfFile)); +} + +// Load config from ENV VARS +let envName; +for (let k in config) { + envName = 'PSITRANSFER_' + k.replace(/([A-Z])/g, $1 => "_" + $1).toUpperCase(); + if (process.env[envName]) { + if (typeof config[k] === 'number') { + config[k] = parseInt(process.env[envName], 10); + } else if (Array.isArray(config[k])) { + config[k] = process.env[envName].split(','); + } else if (typeof config[k] === 'object') { + config[k] = JSON.parse(process.env[envName]); + } else { + config[k] = process.env[envName]; + } + } +} + +if (!config.baseUrl.endsWith('/')) config.baseUrl = config.baseUrl + '/'; +if (!config.uploadAppPath.endsWith('/')) config.uploadAppPath = config.uploadAppPath + '/'; + +config.uploadAppPath = config.baseUrl.substr(0, config.baseUrl.length - 1) + config.uploadAppPath; + +// Load language files +config.languages = { + [config.defaultLanguage]: require(`./lang/${ config.defaultLanguage }`) // default language +}; +fs.readdirSync(path.resolve(__dirname, 'lang')).forEach(lang => { + lang = lang.replace('.js', ''); + if (lang === config.defaultLanguage) return; + config.languages[lang] = { + ...config.languages[config.defaultLanguage], + ...require(`./lang/${ lang }`) + }; +}); + +module.exports = config; diff --git a/roles/upload/templates/head.pug b/roles/upload/templates/head.pug new file mode 100644 index 0000000..fbc16f5 --- /dev/null +++ b/roles/upload/templates/head.pug @@ -0,0 +1,22 @@ +base(href=baseUrl) +meta(charset='utf-8') +title EmacsConf upload +link(href='assets/favicon.ico' rel='icon' type='image/x-icon') +meta(name='viewport' content='width=device-width, initial-scale=1') +meta(name='robots' content='noindex,nofollow') +meta(http-equiv='x-ua-compatible' content='IE=edge') +link(href='assets/styles.css' rel='stylesheet') +script. + // {{ ansible_managed }} + // @license magnet:?xt=urn:btih:87f119ba0b429ba17a44b4bffcab33165ebdacc0&dn=freebsd.txt BSD-2-Clause + // Add ployfills for stupid IE + if (document.documentMode || /Edge/.test(navigator.userAgent)) { + (function(d, script) { + script = d.createElement('script'); + script.type = 'text/javascript'; + script.async = false; + script.src = 'assets/babel-polyfill.js'; + d.getElementsByTagName('head')[0].appendChild(script); + }(document)); + } + // @license-end \ No newline at end of file diff --git a/roles/upload/templates/upload.service b/roles/upload/templates/upload.service new file mode 100644 index 0000000..2d65a74 --- /dev/null +++ b/roles/upload/templates/upload.service @@ -0,0 +1,16 @@ +# {{ ansible_managed }} + +[Unit] +Description=PsiTransfer +After=syslog.target network.target + +[Service] +Type=simple +User={{ upload_user }} +WorkingDirectory=/home/{{ upload_user }}/psitransfer +ExecStart=/usr/bin/node app.js +Environment=NODE_ENV=production PSITRANSFER_ADMIN_PASS="{{ upload_admin_password }}" PSITRANSFER_UPLOAD_PASS="{{ upload_password }}" PSITRANSFER_UPLOAD_DIR="{{ upload_dir }}" +Restart=always + +[Install] +WantedBy=multi-user.target -- cgit v1.2.3