.gitignore000066400000000000000000000003721516100566200130520ustar00rootroot00000000000000/build /node_modules /*.log /generated /ramdisk-settings.json .idea/workspace.xml .idea/tasks.xml .idea/profiles_settings.xml .idea/inspectionProfiles/Project_Default.xml .idea/inspectionProfiles/profiles_settings.xml node_modules/.yarn-integrity .idea/000077500000000000000000000000001516100566200120405ustar00rootroot00000000000000.idea/codeStyleSettings.xml000066400000000000000000000004251516100566200162370ustar00rootroot00000000000000 .idea/modules.xml000066400000000000000000000004121516100566200142270ustar00rootroot00000000000000 .idea/ramdisk.iml000066400000000000000000000005201516100566200141720ustar00rootroot00000000000000 .idea/vcs.xml000066400000000000000000000002471516100566200133600ustar00rootroot00000000000000 .npmignore000066400000000000000000000002221516100566200130530ustar00rootroot00000000000000/.idea /artifacts /build /test /node_modules /*.iml /*.ipr /*.iws /.travis.yml /.scrutinizer.yml /Gruntfile.js /*.lock *.log /corifeus-boot.json .travis.yml000066400000000000000000000017371516100566200132010ustar00rootroot00000000000000language: node_js sudo: required node_js: - node env: matrix: - CXX=g++-4.8 global: secure: 0K7XKLpX0QWoI+dTey16SGssHaX55WWz6twIF4VxOmqenRzRjXyU1lgI8RTLnjwBm7rHRfabzTVs0DosbEvCnleGc6t/FiC3otG7zY/MaX/Ak4UGWY6GpRrne3iBtrRVN+2i3h0OHf/wiFhIik4Yo5iRWiTVRGxULKKkQBFKYuipLqAviN6NIUjdMX92Rz53GEPv8gNgh0ezl8u1MAeR8fQL+hrQLelvuckffpR8bRDXSnwTnblnuKm50/5b1Eq/ap+e7s+C2coJYlL+yCmqcW2KZOI5kmEmahVgS2DDzswzMTN4QJxkiJqOKaCyfCcaMsgl/jnPBBlS8sysHmhWJvZrS7oocfA8a3FjW0C9yc8f9V9zR5XssV3/LAgpqUK9URie8l/G4qU/vFFHp/f7FOBLpTp8BsqZ5HsIIaVO0CFHoxJ69B0rWzaxbNhteNqcmisJbJRZdQYHQq1ZSnjBi60Yrds2nCzQwI7odQA9Arx9SdqH96A3qS4UMQ4SCbHMG+2NXfY21JZA1fzdAb8nuCRcq/Q6KYBujYz9QVUsYwP5k7Mr/7+5Zx2ySVMSyfD9dxnb1bqa+4ZeuzY7gAUx/ORKVMZ8WM9ct2Ytrccyc6KQHmkfxInnJqZlR77CdJU7JPMlhSGPQJx3Euybd5PgFWcDAQuB51oMSw9Dl6yFTVU= addons: apt: sources: - ubuntu-toolchain-r-test packages: - dbus - gcc-4.8 - g++-4.8 - libglib2.0-dev before_script: - npm install -g node-gyp - npm install -g grunt-cli npm Gruntfile.js000066400000000000000000000007471516100566200133650ustar00rootroot00000000000000module.exports = (grunt) => { const builder = require(`corifeus-builder`); const loader = new builder.loader(grunt); loader.js({ replacer: { type: 'p3x', npmio: true, }, config: { 'clean': { 'generated': [ 'generated' ] } } }); const defaults = [] grunt.registerTask('default', defaults.concat(builder.config.task.build.js)); } LICENSE000066400000000000000000000023411516100566200120650ustar00rootroot00000000000000 @license p3x-ramdisk v2019.1.29-2 💾 RAM disk persistent with Systemd timer, service and suspend https://pages.corifeus.com/ramdisk Copyright (c) 2019 Patrik Laszlo / P3X / Corifeus and contributors. MIT License 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. README.md000066400000000000000000000277561516100566200123600ustar00rootroot00000000000000[//]: #@corifeus-header [![NPM](https://nodei.co/npm/p3x-ramdisk.png?downloads=true&downloadRank=true&stars=true)](https://www.npmjs.com/package/p3x-ramdisk/) [![Like Corifeus @ Facebook](https://img.shields.io/badge/LIKE-Corifeus-3b5998.svg)](https://www.facebook.com/corifeus.software) [![Donate for Corifeus / P3X](https://img.shields.io/badge/Donate-Corifeus-003087.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QZVM4V6HVZJW6) [![Contact Corifeus / P3X](https://img.shields.io/badge/Contact-P3X-ff9900.svg)](https://www.patrikx3.com/en/front/contact) [![Build Status](https://api.travis-ci.com/patrikx3/ramdisk.svg?branch=master)](https://travis-ci.com/patrikx3/ramdisk) [![Uptime Robot ratio (30 days)](https://img.shields.io/uptimerobot/ratio/m780749701-41bcade28c1ea8154eda7cca.svg)](https://uptimerobot.patrikx3.com/) # 💾 RAM disk persistent with Systemd timer, service and suspend v2019.2.1-0 🙏 This is an open-source project. Star this repository, if you like it, or even donate to maintain the servers and the development. Thank you so much! Possible, this mini server, rarely, is down, please hang on for 15-30 minutes and the server will be back up. All my domains ([patrikx3.com](https://patrikx3.com) and [corifeus.com](https://corifeus.com)) could have minor errors, since I am developing in my free time. However, it is usually stable. **Bugs are evident™ - MATRIX️** ### Node Version Requirement ``` >=10.13.0 ``` ### Built on Node ``` v11.9.0 ``` The ```async``` and ```await``` keywords are required. Install NodeJs: https://nodejs.org/en/download/package-manager/ # Description [//]: #@corifeus-header:end # Breaking change [readme](artifacts/readme/breaking-change.md) # Install ```bash sudo npm install -g p3x-ramdisk --unsafe-perm=true --allow-root ``` ## IntelliJ Speed Based on: http://sheroz.com/pages/blog/improving-development-performance-moving-intellij-idea-cache-ramdisk.html ```text After all these tricks I tried to open my current project with IntelliJ IDEA 12 … Wow!!! It is fantastic! Works like a … sword!!! Why sword?! I don’t know exactly. May be because of Darcula theme. This is just first thought what came to my mind seeing the overall results. The Intellij IDEA 12 now works as a lightsaber sword, as a weapon of a Jedi Knight, which you can trust in Java world! ``` * Requires tmpfs, bash, fstab, rsync, memory :) * Usually, all requirements of every Unix flavor are installed by default * If you can't install it, you probably need to install the `build-essential` * See * https://nodejs.org/en/download/package-manager/ * SystemD * Service * Timer * Suspend * RAM disk to HDD * Linux for sure, easy to extend for Unix, BSD, macOS * Should might need some tuning, but the functions are there, I just only tested in Linux. ## Intel Optane I think my ramdisk is faster. :) Ciao!!! # Use case Speed up IntelliJ and development Node. (Tons of files.) The result is that the development is many folds faster. No waiting at all. # Changelog * Since **v2019.2.1** * The ramdisk works with different users * Migration * `sudo p3x-ramdisk stop` * Install the latest version * `sudo p3x-ramdisk install $USER` * `sudo p3x-ramdisk start $USER` * What actually changed, is that every command has a parameter `` eg. * `sudo p3x-ramdisk install $USER` * `sudo p3x-ramdisk start $USER` * `sudo p3x-ramdisk stop $USER` * `sudo p3x-ramdisk link $USER` * `sudo p3x-ramdisk load $USER` * `sudo p3x-ramdisk save $USER` * `sudo p3x-ramdisk status $USER` * `sudo p3x-ramdisk watch $USER` # Install ## Warning Do not use the ```$USER``` variable, use the actual username, like ```p3x-robot```. ## So actual install ```text patrikx3@workstation ~ $ p3x-ramdisk install --help Usage: install [options] Install a p3x-ramdisk Options: -h, --help output usage information -r, --rampath [path] The path of the ram disk, default /home/$USER/ramdisk -p, --persistent [path] The path of the ram persistent, default /home/$USER/ramdisk-persistent -g, --gid [group] The gid, it you omit it is the current user -t, --timer [minutes] The timer in minutes, minimum about 10 minutes, Default is 20 minutes, the best -s, --size [megabytes] Ramdisk in size of megabytes, default is 4096 megabytes ``` # IMPORTANT Trash is disabled in GNOME with p3x-ramdisk. It will ask for confirm to delete data. You might have it in the previous save. It is possible to enable trash bin, but for me is not important now, so I disabled, memory is not cheap. # Setup **Use GitHub for info, NPM hides wide strings.** https://github.com/patrikx3/ramdisk ```bash # of course your data will never be deleted, # double persistence (current, previouse, saves every 20 minutes) # load on boot, plus at shutdown and suspend it saves sudo npm install -g p3x-ramdisk --unsafe-perm=true --allow-root # install # if you need less/more memory, add -s 1024 or even more, 10GB is good :) sudo p3x-ramdisk install $USER # Get the output, add to /etc/fstab echo "tmpfs /home/patrikx3/ramdisk tmpfs gid=10000,uid=10000,size=4096M 0 0" | sudo tee -a /etc/fstab sudo mount -a # you should verify the ramdisk is existing now, you might have to reboot # on linux it can show your settings, like below: df -h # if there is an error, you can sudo p3x-ramdisk stop $USER # if all good # STARTUP THE RAMDISK PERSISTENT sudo p3x-ramdisk start $USER # you can work like here (this a symlink, so you can't accidentally delete # so next time boot, it will re-create the symlink ...) # /home/$USER/ramdisk/p3x-persistence # SOME DEBUG p3x-ramdisk watch $USER # to trigger a savs p3x-ramdisk save $USER # you don't need usually to save # the default is 20 minutes # the systemd service saves on suspend and shutdown # to stop the services # removes sync, so the ramdisk files will be unavailable, # only be in /home/username/ramdisk-persistent/current sudo p3x-ramdisk stop $USER # your duplicate copies are ls -all /home/$USER/ramdisk-persistent/current/ ls -all /home/$USER/ramdisk-persistent/previous/ # you are done # the default use case is to speed up working with IntelliJ and my projects to ramdisk # if you just want persistent folder and that's all # there is a special folder, .p3x-ramdisk-link # everything there is linked into /home/$USER # if there is nothing in .p3x-ramdisk-link # no linking is. to test it, you might not need it. ``` ## Linkin' in /home ```bash ### //LINKING:START # LINKING - IS NOT REQUIRED, but is good as a sword :) p3x-ramdisk save $USER sudo p3x-ramdisk stop $USER mkdir -p /home/$USER/ramdisk-persistent/current/.p3x-ramdisk-link cp -avr /home/$USER/.IntelliJIdea2018.3 /home/$USER/ramdisk-persistent/current/.p3x-ramdisk-link # backup mkdir -p /home/$USER/backup mv /home/$USER/.IntelliJIdea2018.3 /home/username/backup/ # need to delete the originals, since they become symlinks rm -rf /home/$USER/.IntelliJIdea2018.3 sudo p3x-ramdisk start $USER ### //LINKING:END ``` # Output ## Install ```text patrikx3@laptop:~/ramdisk/.p3x-ramdik-persistence/content/.p3x-ramdisk-link/Projects/patrikx3/ramdisk$ sudo p3x-ramdisk install patrikx3 -s 6144 2018-05-08 00:30:08: terminal install 2018-05-08 00:30:08: terminal copy 2018-05-08 00:30:08: terminal suspend 2018-05-08 00:30:08: terminal reload services 2018-05-08 00:30:08: terminal install done Settings: { "rampath": "ramdisk", "persistent": "ramdisk-persistent", "uid": "patrikx3", "uidNumber": 10000, "gid": "patrikx3", "timer": 20, "size": "4096", "home": "/home/patrikx3", "script": "/home/patrikx3/.p3x-ramdisk" } Final commands: -------------------------- 1) You only have to do it once, if you haven't done it before echo "tmpfs /home/patrikx3/ramdisk tmpfs gid=10000,uid=10000,size=4096M 0 0" | sudo tee -a /etc/fstab sudo mount -a -------------------------- 2) verify that ramdisk is working, see it here df -h -------------------------- 3) if everything is ok, start the persistent ramdisk sudo p3x-ramdisk start $USER patrikx3@laptop:~/ramdisk/.p3x-ramdik-persistence/content/.p3x-ramdisk-link/Projects/patrikx3/ramdisk$ ``` ## Watching the RAM disk ```bash p3x-ramdisk watch $USER ``` ```text Filesystem Size Used Avail Use% Mounted on tmpfs 4,0G 2,0G 2,1G 50% /home/patrikx3/ramdisk total used free shared buff/cache available Mem: 31G 3,3G 18G 2,0G 9,8G 25G Swap: 8,0G 0B 8,0G Load: 2018-05-27 09:01:49 2018-05-27 09:01:56 0 minutes 7 seconds Save: 2018-05-27 09:20:00 2018-05-27 09:20:16 0 minutes 16 seconds 2018-05-27 09:20:00: timer save, ramdisk to current 2018-05-27 09:20:00: timer save /home/patrikx3/ramdisk/.p3x-ramdik-persistence/content to /home/patrikx3/ramdisk-persistent/current 2018-05-27 09:20:16: timer saved 2018-05-27 09:20:16: timer save done 2018-05-27 09:20:16: timer 0 minutes 16 seconds 5/27/2018, 9:24:45 AM | Persistence 20 minutes | Watch 1 second ``` # LOGS ``` /home/username/ramdisk-persistent/ramdisk-persistent.log ``` ``` /home/username/ramdisk-persistent/update-at-load.log ``` ``` /home/username/ramdisk-persistent/update-at-save.log ``` ## LOG info ```text 2018-05-06 02:57:37: boot loading 2018-05-06 02:57:37: boot load /home/patrikx3/ramdisk-persistent/current to /home/patrikx3/ramdisk/.p3x-ramdik-persistence/content 2018-05-06 02:57:47: boot loaded 2018-05-06 02:57:47: boot link 2018-05-06 02:57:47: boot link /home/patrikx3/ramdisk/.p3x-ramdisk-persistence/content/.IntelliJIdea2018.3 to /home/patrikx3/.IntelliJIdea2018.3 2018-05-06 02:57:47: boot link /home/patrikx3/ramdisk/.p3x-ramdisk-persistence/content/Projects to /home/patrikx3/Projects 2018-05-06 02:57:47: boot link done 2018-05-06 02:57:47: boot 0 minutes 10 seconds 2018-05-06 02:57:47: timer save 2018-05-06 02:57:47: timer save, current to previous 2018-05-06 02:57:47: timer save /home/patrikx3/ramdisk-persistent/current to /home/patrikx3/ramdisk-persistent/previous 2018-05-06 02:57:50: timer saved 2018-05-06 02:57:50: timer save, ramdisk to current 2018-05-06 02:57:50: timer save /home/patrikx3/ramdisk/.p3x-ramdisk-persistence/content to /home/patrikx3/ramdisk-persistent/current 2018-05-06 02:57:53: timer saved 2018-05-06 02:57:53: timer save done 2018-05-06 02:57:53: timer 0 minutes 6 seconds ``` ## LOG Update ```text 2018-05-06 03:31:51 2018-05-06 03:31:57 0 minutes 6 seconds ``` # Thunder ramdisk persistence ```text patrikx3@workstation ~/ramdisk-persistent/current/.p3x-ramdisk-link $ ll total 32 drwxr-xr-x 8 patrikx3 patrikx3 4096 May 7 13:04 ./ drwxr-xr-x 3 patrikx3 patrikx3 4096 May 7 13:02 ../ drwxr-xr-x 4 patrikx3 patrikx3 4096 Apr 25 17:51 .IntelliJIdea2018.3/ patrikx3@workstation ~/ramdisk-persistent/current/.p3x-ramdisk-link $ ``` [//]: #@corifeus-footer --- [**P3X-RAMDISK**](https://pages.corifeus.com/ramdisk) Build v2019.2.1-0 [![Like Corifeus @ Facebook](https://img.shields.io/badge/LIKE-Corifeus-3b5998.svg)](https://www.facebook.com/corifeus.software) [![Donate for Corifeus / P3X](https://img.shields.io/badge/Donate-Corifeus-003087.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QZVM4V6HVZJW6) [![Contact Corifeus / P3X](https://img.shields.io/badge/Contact-P3X-ff9900.svg)](https://www.patrikx3.com/en/front/contact) ## P3X Sponsors [IntelliJ - The most intelligent Java IDE](https://www.jetbrains.com/?from=patrikx3) [![JetBrains](https://cdn.corifeus.com/assets/svg/jetbrains-logo.svg)](https://www.jetbrains.com/?from=patrikx3) [![NoSQLBooster](https://cdn.corifeus.com/assets/png/nosqlbooster-70x70.png)](https://www.nosqlbooster.com/) [The Smartest IDE for MongoDB](https://www.nosqlbooster.com) [//]: #@corifeus-footer:end artifacts/000077500000000000000000000000001516100566200130405ustar00rootroot00000000000000artifacts/readme/000077500000000000000000000000001516100566200142755ustar00rootroot00000000000000artifacts/readme/breaking-change.md000066400000000000000000000051221516100566200176240ustar00rootroot00000000000000[//]: #@corifeus-header # 💾 RAM disk persistent with Systemd timer, service and suspend [//]: #@corifeus-header:end # Breaking change ## v1.1 This is only important if you have an older version (1.0.x-y) and/or you use linked folders (like IntelliJ). It will never change anymore, but sometimes I can delete accidentally my data from the ramdisk, so I refactored the name instead of: ```text /home/user/ramdisk/persistence ``` now it is called ```text /home/user/ramdisk/.p3x-ramdisk-persistence ``` (hidden by default) and if you accidentally deleted, it will be auto-recreate (this is always visible - a symlink) ```text /home/user/ramdisk/p3x-persistence ``` If you are linked to IntelliJ for example, you have to recreate the symlink in your home. For example, migration looks like this: ```bash # exit intellij if you have linked sudo p3x-ramdisk stop rm -rf ~/ramdisk/persistence sudo npm i -g p3x-ramdisk sudo p3x-ramdisk install $USER sudo p3x-ramdisk start # so you are already linked into p3x-ramdisk, here # (if you are not linked, do not delete and # do not execute below, only if the intellij # data is linked and you are sure it is a # symlink ) ll ~/.IntelliJIdea2018.1 ``` Shows: ```text lrwxrwxrwx 1 patrikx3 patrikx3 94 Apr 14 19:34 /home/patrikx3/.IntelliJIdea2018.1 -> /home/patrikx3/ramdisk/.p3x-ramdisk-persistence/content/.p3x-ramdisk-link/.IntelliJIdea2018.1/ ``` **MAKE SURE YOU EXIT FROM INTELLIJ.** If you are sure it is a link, you can recreate like: ```bash rm ~/.IntelliJIdea2018.1 ln -s ~/ramdisk/.p3x-ramdisk-persistence/content/.p3x-ramdisk-link/.IntelliJIdea2018.1/ ~ ``` Now you are safe. [//]: #@corifeus-footer --- [**P3X-RAMDISK**](https://pages.corifeus.com/ramdisk) Build v2019.2.1-0 [![Like Corifeus @ Facebook](https://img.shields.io/badge/LIKE-Corifeus-3b5998.svg)](https://www.facebook.com/corifeus.software) [![Donate for Corifeus / P3X](https://img.shields.io/badge/Donate-Corifeus-003087.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QZVM4V6HVZJW6) [![Contact Corifeus / P3X](https://img.shields.io/badge/Contact-P3X-ff9900.svg)](https://www.patrikx3.com/en/front/contact) ## P3X Sponsors [IntelliJ - The most intelligent Java IDE](https://www.jetbrains.com/?from=patrikx3) [![JetBrains](https://cdn.corifeus.com/assets/svg/jetbrains-logo.svg)](https://www.jetbrains.com/?from=patrikx3) [![NoSQLBooster](https://cdn.corifeus.com/assets/png/nosqlbooster-70x70.png)](https://www.nosqlbooster.com/) [The Smartest IDE for MongoDB](https://www.nosqlbooster.com) [//]: #@corifeus-footer:end bin/000077500000000000000000000000001516100566200116305ustar00rootroot00000000000000bin/p3x-ramdisk.js000077500000000000000000000024461516100566200143410ustar00rootroot00000000000000#!/usr/bin/env node //const os = require('os'); //const process = require('process'); //const cores = os.cpus().length < 4 ? 4 : os.cpus().length; //process.env.UV_THREADPOOL_SIZE = cores; //console.debug(`P3X sets UV_THREADPOOL_SIZE to ${cores} thread pool`) if (!require('fs').existsSync(`${__dirname}/../node_modules`)) { require('child_process').execSync(`cd ${__dirname}/.. && npm install --only=prod`, { stdio: 'inherit' }); } const commander = require('commander'); const utils = require('corifeus-utils'); const pkg = require('../package.json'); const mz = require('mz'); const start = async() => { // command // required // [command] optional // [command ...] variable options commander .version(pkg.version) .usage('[command]') .action((command, options) => { console.error(`unknown command: ${command}`) }) ; require('../src/command/install') require('../src/command/start') require('../src/command/load') require('../src/command/watch') require('../src/command/save') require('../src/command/stop') require('../src/command/link') require('../src/command/status') commander.parse(process.argv); if (!process.argv.slice(2).length) { commander.outputHelp(); } } start();package.json000066400000000000000000000025321516100566200133500ustar00rootroot00000000000000{ "name": "p3x-ramdisk", "version": "2019.2.1-0", "description": "💾 RAM disk persistent with Systemd timer, service and suspend", "main": "Gruntfile.js", "corifeus": { "prefix": "p3x-", "type": "p3x", "publish": true, "code": "Vader", "nodejs": "v11.9.0", "opencollective": false, "reponame": "ramdisk", "build": true }, "bin": { "p3x-ramdisk": "bin/p3x-ramdisk.js" }, "scripts": { "test": "grunt " }, "repository": { "type": "git", "url": "git+https://github.com/patrikx3/ramdisk.git" }, "keywords": [ "linux", "systemd", "ramdisk", "ram", "disk", "suspend", "timer", "service", "unix", "bsd", "osx" ], "author": "Patrik Laszlo ", "license": "MIT", "bugs": { "url": "https://github.com/patrikx3/ramdisk/issues" }, "homepage": "https://pages.corifeus.com/ramdisk", "dependencies": { "clear": "^0.1.0", "commander": "^2.19.0", "corifeus-utils": "^2019.1.29-1", "lodash": "^4.17.11", "userid": "^0.3.1" }, "engines": { "node": ">=10.13.0" }, "devDependencies": { "corifeus-builder": "^2019.1.29-2" } } ramdisk.iml000066400000000000000000000006241516100566200132170ustar00rootroot00000000000000 src/000077500000000000000000000000001516100566200116475ustar00rootroot00000000000000src/command/000077500000000000000000000000001516100566200132655ustar00rootroot00000000000000src/command/install.js000066400000000000000000000022101516100566200152640ustar00rootroot00000000000000const commander = require('commander'); const ramdisk = require('../index'); // install commander .command('install ') .option('-r, --rampath [path]', 'The path of the ram disk, default /home/$USER/ramdisk') .option('-p, --persistent [path]', 'The path of the ram persistent, default /home/$USER/ramdisk-persistent') // .option('-u, --uid ', 'The username, it you omit it is the current user') .option('-g, --gid [group]', 'The gid, it you omit it is the current user') .option('-t, --timer [minutes]', 'The timer in minutes, minimum about 10 minutes, Default is 20 minutes, the best') .option('-s, --size [megabytes]', `Ramdisk in size of megabytes, default is ${ramdisk.defaults.ramdisk.size} megabytes`) // .option('-h, --home [type]', 'Home path, defaults to /home/uid') .description(` Install a p3x-ramdisk `) // .option('-d, --dry', 'Do not actually remove packages, just show what it does') .action(async function (uid, options) { try { await ramdisk.install(uid, options); } catch(e) { console.error(e); process.exit(1); } }) ; src/command/link.js000066400000000000000000000010021516100566200145510ustar00rootroot00000000000000const commander = require('commander'); // install commander .command('link ') .description(` Link from the ramdisk to the home `) // .option('-d, --dry', 'Do not actually remove packages, just show what it does') .action(async function (uid, options) { const link = require('../index').link; try { await link({ uid: uid }); } catch(e) { console.error(e.message); process.exit(1); } }) ; src/command/load.js000066400000000000000000000007631516100566200145500ustar00rootroot00000000000000const commander = require('commander'); // install commander .command('load ') .description(` Load a p3x-ramdisk `) // .option('-d, --dry', 'Do not actually remove packages, just show what it does') .action(async function (uid, options) { const load = require('../index').load; try { await load({ uid: uid }); } catch(e) { console.error(e.message); process.exit(1); } }) ; src/command/save.js000066400000000000000000000007651516100566200145710ustar00rootroot00000000000000const commander = require('commander'); // install commander .command('save ') .description(` Save the p3x-ramdisk `) // .option('-d, --dry', 'Do not actually remove packages, just show what it does') .action(async function (uid, options) { const save = require('../index').save; try { await save({ uid: uid }); } catch(e) { console.error(e.message); process.exit(1); } }) ; src/command/start.js000066400000000000000000000007701516100566200147640ustar00rootroot00000000000000const commander = require('commander'); // install commander .command('start ') .description(` Start a p3x-ramdisk `) // .option('-d, --dry', 'Do not actually remove packages, just show what it does') .action(async function (uid, options) { const start = require('../index').start; try { await start({ uid: uid }); } catch(e) { console.error(e.message); process.exit(1); } }) ; src/command/status.js000066400000000000000000000006261516100566200151520ustar00rootroot00000000000000const commander = require('commander'); // install commander .command('status ') .description(` Status of p3x-ramdisk `) .action(async function (uid, options) { const status = require('../index').status; try { await status({ uid: uid }, options); } catch(e) { console.error(e.message); process.exit(1); } }) ; src/command/stop.js000066400000000000000000000007661516100566200146210ustar00rootroot00000000000000const commander = require('commander'); // install commander .command('stop ') .description(` Stop a p3x-ramdisk `) // .option('-d, --dry', 'Do not actually remove packages, just show what it does') .action(async function (uid, options) { const stop= require('../index').stop; try { await stop({ uid: uid }); } catch(e) { console.error(e.message); process.exit(1); } }) ; src/command/watch.js000066400000000000000000000011101516100566200147220ustar00rootroot00000000000000const commander = require('commander'); // install commander .command('watch ') .description(` Watch the p3x-ramdisk `) .option('-w, --watch [milliseconds]', 'The time for watching, default is 1000 milliseconds') // .option('-d, --dry', 'Do not actually remove packages, just show what it does') .action(async function (uid, options) { const watch = require('../index').watch; try { await watch({ uid: uid }, options); } catch(e) { console.error(e.message); process.exit(1); } }) ; src/index.js000066400000000000000000000166651516100566200133320ustar00rootroot00000000000000const mz = require('mz'); const path = require('path'); const utils = require('corifeus-utils'); const fsx = require('fs-extra'); const _ = require('lodash'); const clear = require('clear'); const ms = require('ms'); const settingsFileFun = (opts) => { const { uid } = opts return `/etc/p3x-ramdisk-${uid}.json`; } const defaults = { ramdisk: { size: 2048, }, timer: { save: 20, } }; const requireRoot = () => { if (process.getuid && process.getuid() === 0) { return true; } throw new Error('you are not root! please sudo!') } const getGeneratedDir = (homedir = process.env.HOME) => { //return path.resolve(`${__dirname}/../generated`); return path.resolve(`${homedir}/.p3x-ramdisk`) } const getSettings = (opts) => { const settings = require(settingsFileFun(opts)); settings.generatedDir = getGeneratedDir(settings.home); settings.program = `${path.resolve(settings.generatedDir )}/p3x-ramdisk.sh`; return settings; } const defaultTerminal= async (opts, command, doesRequireRoot = false) => { if (doesRequireRoot ) { requireRoot(); } const settings = getSettings(opts); let commandExec = `${settings.program} ${command}`; await utils.childProcess.exec(commandExec, true) } const load = async(opts) => { await defaultTerminal(opts, 'load') } const link = async(opts) => { await defaultTerminal(opts, 'link') } const save = async(opts) => { await defaultTerminal(opts, 'save') } const status = async(opts) => { requireRoot(); let commandExec = ` sudo service p3x-ramdisk-${opts.uid} status sudo systemctl status p3x-ramdisk-timer-${opts.uid}.timer `; await utils.childProcess.exec(commandExec, true) } const watch = async(mainOpts, options) => { const settings = getSettings(mainOpts); options.watch = Number(options.watch) || 1000; const watch = ms(options.watch, { long: true }); const timer = ms(settings.timer * 1000 * 60, { long: true }); return new Promise(async () => { const show = async () => { const df = await utils.childProcess.exec(`df -h | grep -e ${settings.home}/${settings.rampath} -e Size`); const free = await utils.childProcess.exec(`free -h`); const loadLogFile = `${settings.home}/${settings.persistent}/update-at-load.log`; let loadLog; if (await mz.fs.exists(loadLogFile)) { loadLog = await mz.fs.readFile(loadLogFile); } else { loadLog = 'Load is not done.' } const saveLogFile = `${settings.home}/${settings.persistent}/update-at-save.log`; let saveLog; if (await mz.fs.exists(saveLogFile)) { saveLog = await mz.fs.readFile(saveLogFile); } else { saveLog = 'Save is not done.' } const logFile = `${settings.home}/${settings.persistent}/ramdisk-persistent.log`; let log; if (await mz.fs.exists(logFile)) { log = await utils.childProcess.exec(`tail -n 5 ${logFile}`); } else { log = 'Log is not done.' } clear() console.log(`${df.stdout.trim()} ${free.stdout} Load: ${loadLog.toString().trim().split('\n').join(' ')} Save: ${saveLog.toString().trim().split('\n').join(' ')} ${log.stdout.trim()} ${new Date().toLocaleString()} | Persistence ${timer} | Watch ${watch}`); }; show(); setInterval(show, options.watch) }) } const start = async(opts) => { await defaultTerminal(opts, 'start', true) } const stop = async(opts) => { await defaultTerminal(opts,'stop', true) } const install = async (uid, options) => { requireRoot(); // .option('-r, --rampath [type]', 'The path of the ram disk') // .option('-p, --persistent [type]', 'The path of the ram persistent') // .option('-u, --uid [type]', 'The username, it you omit it is the current user') // .option('-g, --gid [type]', 'The gid, it you omit it is the current user') // .option('-t, --timer [type]', 'The timer in minutes, minimum about 10 minutes, 20 is the best') // .option('-s, --size [type]', 'Ramdisk in size of MegaBYTEs, default is 8192') // .option('-h, --home [type]', 'Home path, defaults to /home/uid') // uid - current user default // gid - default uid // timer -- 20 min // rampath - default /home/uid/ramdisk // persistent - default /home/uid/ramdisk-persistent // home - default /home/uid/ // sciripts - is given const userid = require('userid'); const homedir = (await utils.childProcess.exec(`sudo -H -u ${uid} -i eval 'echo $HOME'`)).stdout.trim(); options = options || {}; const generateOptions = { rampath: options.rampath || 'ramdisk', persistent : options.persistent || 'ramdisk-persistent', uid : uid, uidNumber: userid.uid(uid), gidNumber: userid.gid(uid), gid : options.gid || uid, timer : options.timer || defaults.timer.save, size : options.size || defaults.ramdisk.size, home : homedir, } const generatedDir = getGeneratedDir(homedir) await fsx.emptyDir(generatedDir); generateOptions.script = generatedDir; const origin = `${__dirname}/../templates`; const files = await mz.fs.readdir(origin); _.templateSettings.interpolate = /{{([\s\S]+?)}}/g; await utils.fs.ensureFile(settingsFileFun(generateOptions), JSON.stringify(generateOptions, null, 4), true ) await files.forEachAsync(async (file) => { const generatedFile = path.basename(file, '.hbs'); const buffer = await mz.fs.readFile(`${origin}/${file}`); const string = buffer.toString(); const generatedString = _.template(string)(generateOptions); let useredFile = generatedFile for(let type of ['.service', '.timer']) { if (useredFile.endsWith(type)) { useredFile = useredFile.substring(0, useredFile.length - type.length) useredFile += '-' + generateOptions.uid + type } } await utils.fs.ensureFile(`${generatedDir}/${useredFile}`, generatedString, true); }) const program = `${path.resolve(generateOptions.script)}/p3x-ramdisk.sh`; let command = `chown -R ${generateOptions.uidNumber}:${generateOptions.gidNumber} ${generatedDir} chmod u+x ${program} ${program} install `; //console.log(command) await utils.childProcess.exec(command, true) console.log(` Settings: ${JSON.stringify(generateOptions, null, 4)} Final commands: -------------------------- 1) You only have to do it once, if you haven't done it before echo "tmpfs ${generateOptions.home}/${generateOptions.rampath} tmpfs gid=${userid.gid(generateOptions.gid)},uid=${userid.uid(generateOptions.uid)},size=${generateOptions.size}M 0 0" | sudo tee -a /etc/fstab sudo mount -a -------------------------- 2) verify that ramdisk is working, see it here df -h -------------------------- 3) if everything is ok, start the persistent ramdisk sudo p3x-ramdisk start `) } module.exports.install = install; module.exports.load = load; module.exports.save = save; module.exports.start = start; module.exports.stop = stop; module.exports.watch = watch; module.exports.link = link; module.exports.status = status; module.exports.requireRoot = requireRoot; module.exports.defaults = defaults;templates/000077500000000000000000000000001516100566200130565ustar00rootroot00000000000000templates/p3x-ramdisk-timer.service.hbs000066400000000000000000000004211516100566200204700ustar00rootroot00000000000000[Unit] Description=P3X ramdisk {{ uid }} persistent timer After=p3x-ramdisk-{{ uid }}.target [Service] Type=oneshot ExecStart={{ script }}/p3x-ramdisk.sh timer save TimeoutStopSec=infinity TimeoutStartSec=infinity TimeoutSec=infinity [Install] WantedBy=multi-user.target templates/p3x-ramdisk-timer.timer.hbs000066400000000000000000000003221516100566200201500ustar00rootroot00000000000000[Unit] Description=P3X ramdisk {{ uid }} persistent timer After=p3x-ramdisk-{{ uid }}.target [Timer] OnCalendar=*:0/{{ timer }} OnBootSec=0min #OnUnitActiveSec={{ timer }}min [Install] WantedBy=timers.target templates/p3x-ramdisk.service.hbs000066400000000000000000000004621516100566200173570ustar00rootroot00000000000000[Unit] Description=P3X ramdisk {{ uid }} persistent [Service] Type=oneshot RemainAfterExit=true ExecStartPre={{ script }}/p3x-ramdisk.sh boot load ExecStop={{ script }}/p3x-ramdisk.sh shutdown save TimeoutStopSec=infinity TimeoutStartSec=infinity TimeoutSec=infinity [Install] WantedBy=multi-user.target templates/p3x-ramdisk.sh000077500000000000000000000207421516100566200155640ustar00rootroot00000000000000#!/usr/bin/env bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" ME="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")" P3X_UID={{ uid }} P3X_UID_NUMBER={{ uidNumber }} P3X_GID={{ gid }} P3X_GID_NUMBER={{ gidNumber }} ROOT={{ home }} PERSISTENCE=$ROOT/{{ persistent }} RAMDISK=$ROOT/{{ rampath }} TYPE=$1 COMMAND=$2 if [ -z "$COMMAND" ]; then COMMAND=$TYPE TYPE=terminal fi TRASH_NAME=.Trash-$P3X_UID_NUMBER PERSISTENCE_LOG=$PERSISTENCE/ramdisk-persistent.log #PERSISTENCE_LOG_LOAD=$PERSISTENCE/ramdisk-persistent-load.log #PERSISTENCE_LOG_SAVE=$PERSISTENCE/ramdisk-persistent-save.log PERSISTENCE_CURRENT=$PERSISTENCE/current PERSISTENCE_PREVIOUS=$PERSISTENCE/previous PERSISTENCE_LOCK=$PERSISTENCE/persistent.lock PERSISTENCE_TRASH=$PERSISTENCE/$TRASH_NAME RAMDISK_TRASH=$RAMDISK/$TRASH_NAME RAMDISK_PERSISTENCE=$RAMDISK/.p3x-ramdisk-persistence RAMDISK_PERSISTENCE_LINKED=$RAMDISK/p3x-persistence RAMDISK_CONTENT=$RAMDISK_PERSISTENCE/content RAMDISK_CONTENT_LINK=$RAMDISK_CONTENT/.p3x-ramdisk-link RAMDISK_LOCK=$RAMDISK_PERSISTENCE/ramdisk.lock SUSPEND_ROOT=/lib/systemd/system-sleep SUSPEND_SCRIPT=$SUSPEND_ROOT/p3x-ramdisk.sh SYSTEMD=/etc/systemd/system function generate_persistence_link() { log "generate_persistance_link remove linked persistence" rm -rf $RAMDISK_PERSISTENCE_LINKED || true ln -s $RAMDISK_CONTENT $RAMDISK_PERSISTENCE_LINKED chown -h $P3X_UID_NUMBER:$P3X_GID_NUMBER $RAMDISK_PERSISTENCE_LINKED } function require_sudo() { if [[ $EUID -ne 0 ]]; then printf "You are not root!\n\n" exit 1 fi } function notify() { if hash notify-send 2>/dev/null; then notify-send P3X-RAMDISK $1 # else # date "$@" fi } function install() { require_sudo mkdir -p $PERSISTENCE_CURRENT mkdir -p $PERSISTENCE_PREVIOUS mkdir -p $PERSISTENCE_TRASH #mkdir -p $RAMDISK_CONTENT mkdir -p $RAMDISK_CONTENT_LINK printf "\n" >> $PERSISTENCE_LOG log "install" log "copy" cp $DIR/p3x-ramdisk-timer-$P3X_UID.service $SYSTEMD cp $DIR/p3x-ramdisk-timer-$P3X_UID.timer $SYSTEMD cp $DIR/p3x-ramdisk-$P3X_UID.service $SYSTEMD log suspend mkdir -p $SUSPEND_ROOT touch $SUSPEND_SCRIPT chmod u+x $SUSPEND_SCRIPT cat < $SUSPEND_SCRIPT #!/usr/bin/env bash ACTION=\$1 TYPE=\$2 LOG_DATA="\`date '+%Y-%m-%d %H:%M:%S'\`: SUSPEND \$TYPE \$ACTION" if [ "\$ACTION" == "pre" ]; then # Do the thing you want before suspend here, e.g.: sudo -u $P3X_UID printf "\n\$LOG_DATA Suspending" >> $PERSISTENCE_LOG $DIR/$ME suspend save elif [ "\$1" == "post" ]; then # Do the thing you want after resume here, e.g.: sudo -u $P3X_UID printf "\n\$LOG_DATA On again" >> $PERSISTENCE_LOG fi chown $P3X_UID_NUMBER:$P3X_GID_NUMBER $PERSISTENCE_LOG EOT log "reload services" systemctl daemon-reload log "install done" touch $PERSISTENCE_LOG # touch $PERSISTENCE_LOG_LOAD # touch $PERSISTENCE_LOG_SAVE fix_permissions } function start() { require_sudo install log "start" systemctl enable p3x-ramdisk-$P3X_UID systemctl enable p3x-ramdisk-timer-$P3X_UID.timer systemctl start p3x-ramdisk-$P3X_UID systemctl start p3x-ramdisk-timer-$P3X_UID.timer } function stop() { require_sudo printf "\n" >> $PERSISTENCE_LOG log "stop" systemctl stop p3x-ramdisk-timer-$P3X_UID.timer systemctl stop p3x-ramdisk-$P3X_UID systemctl disable p3x-ramdisk-$P3X_UID systemctl disable p3x-ramdisk-timer-$P3X_UID.timer if [ -d $SUSPEND_SCRIPT ]; then rm -rf $SUSPEND_SCRIPT fi if [ -f $SYSTEMD/p3x-ramdisk-$P3X_UID.service ]; then rm $SYSTEMD/p3x-ramdisk-$P3X_UID.service fi if [ -f $SYSTEMD/p3x-ramdisk-timer-$P3X_UID.timer ]; then rm $SYSTEMD/p3x-ramdisk-timer-$P3X_UID.timer fi if [ -f $SYSTEMD/p3x-ramdisk-timer-$P3X_UID.service ]; then rm $SYSTEMD/p3x-ramdisk-timer-$P3X_UID.service fi if [ -f $RAMDISK_LOCK ]; then rm $RAMDISK_LOCK fi } function fix_permissions() { chown $P3X_UID_NUMBER:$P3X_GID_NUMBER -R $RAMDISK chown $P3X_UID_NUMBER:$P3X_GID_NUMBER -R $PERSISTENCE # chown $P3X_UID_NUMBER:$P3X_GID_NUMBER $PERSISTENCE_LOG_LOAD # chown $P3X_UID_NUMBER:$P3X_GID_NUMBER $PERSISTENCE_LOG_SAVE } function log() { if [ -z ${2+x} ]; then false; else notify $1 fi LOG_DATA="`date '+%Y-%m-%d %H:%M:%S'`: $TYPE $1" echo $LOG_DATA echo $LOG_DATA >> $PERSISTENCE_LOG } function timer_start() { SECONDS=0 STARTED=`date '+%Y-%m-%d %H:%M:%S'` } function timer_end() { DURATION=$SECONDS PERSISTENCE_UPDATED_AT=$PERSISTENCE/$1 echo $STARTED > $PERSISTENCE_UPDATED_AT echo `date '+%Y-%m-%d %H:%M:%S'` >> $PERSISTENCE_UPDATED_AT DURATION_STRING="$(($DURATION / 60)) minutes $(($DURATION % 60)) seconds" echo $DURATION_STRING >> $PERSISTENCE_UPDATED_AT chown $P3X_UID_NUMBER:$P3X_GID_NUMBER $PERSISTENCE_UPDATED_AT log "$DURATION_STRING" } function load() { timer_start printf "\n" >> $PERSISTENCE_LOG log "loading" if [ -f $PERSISTENCE_LOCK ]; then log "has a lock at $PERSISTENCE_LOCK ! not loading! quitting..." true return fi if [ -f $RAMDISK_LOCK ]; then log "already loaded! quitting, existing ramdisk lock: $RAMDISK_LOCK" true return fi cd $PERSISTENCE_CURRENT #tar xvf $PERSISTENCE_COMPRESSED_CURRENT >$PERSISTENCE_LOG_LOAD log "load $PERSISTENCE_CURRENT to $RAMDISK_CONTENT" mkdir -p $RAMDISK_CONTENT cp -avr . $RAMDISK_CONTENT > /dev/null #$PERSISTENCE_LOG_LOAD #rsync -atvq --delete . $RAMDISK_CONTENT > /dev/null #$PERSISTENCE_LOG_LOAD log "loaded" true if ! [ -d $RAMDISK_TRASH ]; then ln -s $PERSISTENCE_TRASH $RAMDISK fi # truncate $PERSISTENCE_LOG_LOAD # chown $P3X_UID_NUMBER:$P3X_GID_NUMBER $PERSISTENCE_LOG_LOAD fix_permissions generate_persistence_link timer_end "update-at-load.log" echo `date '+%Y-%m-%d %H:%M:%S'` > $RAMDISK_LOCK } function truncate() { tail -n 10240 $1 > $1.1 mv $1.1 $1 } function internal_save() { FROM=$1 TO=$2 log "save $FROM to $TO" cd $FROM rsync --rsync-path="nice -n19 ionice -c3 rsync" -aq --delete . $TO > /dev/null #$PERSISTENCE_LOG_SAVE log "saved" # truncate $PERSISTENCE_LOG_SAVE } function save() { printf "\n" >> $PERSISTENCE_LOG timer_start log "save" if [ -f $RAMDISK_LOCK ]; then if [ -f $PERSISTENCE_LOCK ]; then log "has a lock at $PERSISTENCE_LOCK ! quitting..." true return fi touch $PERSISTENCE_LOCK log "save, current to previous" internal_save $PERSISTENCE_CURRENT $PERSISTENCE_PREVIOUS log "save, ramdisk to current" internal_save $RAMDISK_CONTENT $PERSISTENCE_CURRENT rm $PERSISTENCE_LOCK log "save done" true # cannot use it at save, it will change modification #fix_permissions truncate $PERSISTENCE_LOG timer_end "update-at-save.log" else log "not saving, not loaded" true fi } function link() { log "link" if [ -d "$RAMDISK_CONTENT_LINK" ]; then cd $RAMDISK_CONTENT_LINK shopt -s dotglob for d in */ ; do if [ "$d" = "*/" ]; then continue fi GENERATED_LINK="${ROOT}/${d}" DIR=${d%/*} log "link $RAMDISK_CONTENT_LINK/$DIR to $ROOT/$DIR" # delete actual directory, no slash! otherwise it shows not empty if [ -d "${ROOT}/${DIR}" ]; then unlink "${ROOT}/${DIR}" || true fi ln -s "${RAMDISK_CONTENT_LINK}/${DIR}" $ROOT done fi log "link done" } if [ "$COMMAND" == "load" ] then load exit fi if [ "$COMMAND" == "save" ] then save exit fi if [ "$COMMAND" == "link" ] then link exit fi if [ "$COMMAND" == "start" ] then start exit fi if [ "$COMMAND" == "stop" ] then stop exit fi if [ "$COMMAND" == "install" ] then install exit fi if [ "$COMMAND" == "watch" ] then WATCH1="df -h | grep -e " WATCH2=$RAMDISK WATCH3=" -e Size" watch $WATCH1$WATCH2$WATCH3 exit fi cat <&1 Eg: sudo $ME install sudo $ME start $ME watch $ME save $ME load Unknown type: {$TYPE} command: {$COMMAND} Requires 2 parameters: type: anything (like boot, timer, terminal), default is "terminal" command: install, start, stop, load, save, watch EOT