pax_global_header00006660000000000000000000000064134077277700014530gustar00rootroot0000000000000052 comment=9d2d7bb76b0d368b0e9e15bd3a32490908704dcb profile-sync-daemon-6.34/000077500000000000000000000000001340772777000153375ustar00rootroot00000000000000profile-sync-daemon-6.34/INSTALL000066400000000000000000000016761340772777000164020ustar00rootroot00000000000000DEPENDENCIES bash >=4.0 coreutils findutils kmod rsync systemd WARNING To avoid data loss, it is HIGHLY recommended that users stop any running versions of this software before install updates. Internal changes are always possible from one release to another. BUILDING Setup the via a make. $ make Running a `make install` as root will distribute the files to the filesystem. # make install Note that it is not required in many case, but on occasion, internals are changed in the psd code which makes users stopping any active psd session BEFORE the make install setup a good idea. Users of Arch/Chakra/Antergos and graysky's PPA (Ubuntu/Debian) do not need to worry about this as the respective package managers will do this for you. The Fedora packages should also have this built it. USE A DISTRO PROVIDED PACKAGE See the project homepage for an updated list of provided packages: https://github.com/graysky2/profile-sync-daemon profile-sync-daemon-6.34/LICENSE000066400000000000000000000000771340772777000163500ustar00rootroot00000000000000All files in this software are licensed under The MIT License. profile-sync-daemon-6.34/MIT000066400000000000000000000020401340772777000157070ustar00rootroot00000000000000Copyright (c) 2013-2019 graysky 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. profile-sync-daemon-6.34/Makefile000066400000000000000000000056351340772777000170100ustar00rootroot00000000000000VERSION = 6.34 PN = profile-sync-daemon PREFIX ?= /usr INITDIR_SYSTEMD = /usr/lib/systemd/user BINDIR = $(PREFIX)/bin SHAREDIR = $(PREFIX)/share/psd MANDIR = $(PREFIX)/share/man/man1 ZSHDIR = $(PREFIX)/share/zsh/site-functions # set to anything except 0 to enable manpage compression COMPRESS_MAN = 1 RM = rm SED = sed INSTALL = install -p INSTALL_PROGRAM = $(INSTALL) -m755 INSTALL_SCRIPT = $(INSTALL) -m755 INSTALL_DATA = $(INSTALL) -m644 INSTALL_DIR = $(INSTALL) -d RSYNC = rsync -a Q = @ common/$(PN): common/$(PN).in $(Q)echo -e '\033[1;32mSetting version\033[0m' $(Q)$(SED) 's/@VERSION@/'$(VERSION)'/' common/$(PN).in > common/$(PN) install-bin: common/$(PN) $(Q)echo -e '\033[1;32mInstalling main script...\033[0m' $(INSTALL_DIR) "$(DESTDIR)$(BINDIR)" $(INSTALL_PROGRAM) common/$(PN) "$(DESTDIR)$(BINDIR)/$(PN)" $(INSTALL_PROGRAM) common/psd-overlay-helper "$(DESTDIR)$(BINDIR)/psd-overlay-helper" ln -s $(PN) "$(DESTDIR)$(BINDIR)/psd" $(INSTALL_DIR) "$(DESTDIR)$(ZSHDIR)" $(INSTALL_DATA) common/zsh-completion "$(DESTDIR)/$(ZSHDIR)/_psd" $(INSTALL_DIR) "$(DESTDIR)$(SHAREDIR)/browsers" $(INSTALL_DATA) common/psd.conf "$(DESTDIR)$(SHAREDIR)/psd.conf" cp common/browsers/* "$(DESTDIR)$(SHAREDIR)/browsers" install-man: $(Q)echo -e '\033[1;32mInstalling manpage...\033[0m' $(INSTALL_DIR) "$(DESTDIR)$(MANDIR)" $(INSTALL_DATA) doc/psd.1 "$(DESTDIR)$(MANDIR)/psd.1" $(INSTALL_DATA) doc/psd-overlay-helper.1 "$(DESTDIR)$(MANDIR)/psd-overlay-helper.1" ifneq ($(COMPRESS_MAN),0) gzip -9 "$(DESTDIR)$(MANDIR)/psd.1" gzip -9 "$(DESTDIR)$(MANDIR)/psd-overlay-helper.1" ln -s psd.1.gz "$(DESTDIR)$(MANDIR)/$(PN).1.gz" else ln -s psd.1 "$(DESTDIR)$(MANDIR)/$(PN).1" endif install-systemd: $(Q)echo -e '\033[1;32mInstalling systemd files...\033[0m' $(INSTALL_DIR) "$(DESTDIR)$(INITDIR_SYSTEMD)" $(INSTALL_DATA) init/psd.service "$(DESTDIR)$(INITDIR_SYSTEMD)/psd.service" $(INSTALL_DATA) init/psd-resync.service "$(DESTDIR)$(INITDIR_SYSTEMD)/psd-resync.service" $(INSTALL_DATA) init/psd-resync.timer "$(DESTDIR)$(INITDIR_SYSTEMD)/psd-resync.timer" install: install-bin install-man install-systemd uninstall-bin: $(RM) "$(DESTDIR)$(BINDIR)/$(PN)" $(RM) "$(DESTDIR)$(BINDIR)/psd" $(RM) "$(DESTDIR)$(ZSHDIR)/_psd" $(RM) "$(DESTDIR)$(BINDIR)/psd-overlay-helper" $(RM) "$(DESTDIR)$(SHAREDIR)/psd.conf" $(RM) -rf "$(DESTDIR)$(SHAREDIR)/browsers" rmdir "$(DESTDIR)$(SHAREDIR)" uninstall-man: $(RM) -f "$(DESTDIR)$(MANDIR)/$(PN).1.gz" $(RM) -f "$(DESTDIR)$(MANDIR)/psd.1.gz" $(RM) -f "$(DESTDIR)$(MANDIR)/$(PN).1" $(RM) -f "$(DESTDIR)$(MANDIR)/psd.1" uninstall-systemd: $(RM) "$(DESTDIR)$(INITDIR_SYSTEMD)/psd.service" $(RM) "$(DESTDIR)$(INITDIR_SYSTEMD)/psd-resync.service" $(RM) "$(DESTDIR)$(INITDIR_SYSTEMD)/psd-resync.timer" uninstall: uninstall-bin uninstall-man uninstall-systemd clean: $(RM) -f common/$(PN) .PHONY: install-bin install-man install-systemd install uninstall-bin uninstall-man uninstall-systemd uninstall clean profile-sync-daemon-6.34/README.md000066400000000000000000000134121340772777000166170ustar00rootroot00000000000000# Profile-sync-daemon Profile-sync-daemon (psd) is a tiny pseudo-daemon designed to manage your browser's profile in tmpfs and to periodically sync it back to your physical disc (HDD/SSD). This is accomplished via a symlinking step and an innovative use of rsync to maintain back-up and synchronization between the two. One of the major design goals of psd is a completely transparent user experience. ## Good Advice Always backup your browser profile(s) before using psd for the first time. ## Users of eCryptFS User of eCryptFS are encouraged not to use psd unless willing to help troubleshoot suspected browser corruption. See [#158](https://github.com/graysky2/profile-sync-daemon/issues/158). ## Supported Browsers * Chromium * Conkeror * Epiphany * Firefox (stable, beta, and aurora) * Firefox-trunk (this is an Ubuntu-only browser: http://www.webupd8.org/2011/05/install-firefox-nightly-from-ubuntu-ppa.html) * Google Chrome (stable, beta, and dev) * Heftig's version of Aurora (this is an Arch Linux-only browser: https://bbs.archlinux.org/viewtopic.php?id=117157) * Icecat (GNU version of Firefox) * Iceweasel (Debian version of Firefox) * Inox (https://bbs.archlinux.org/viewtopic.php?id=198763) * Luakit * Midori * Opera, Opera-Beta, Opera-Developer, and Opera-Legacy * Otter-browser * Palemoon * QupZilla * Qutebrowser * Rekonq * Seamonkey * Surf (http://surf.suckless.org/) * Vivaldi-browser and Vivaldi-browser-snapshot ## Documentation Consult the man page or the wiki page: https://wiki.archlinux.org/index.php/Profile-sync-daemon ## Installation from Source To build from source, see the included INSTALL text document. ## Installation from Distro Packages ### Officially Packaged * ![logo](http://gnulinuxvagos.es/public/style_extra/downloads_traffic_images/os_Antergos.png "antergos logo")Antergos: in the official [repos](http://build.antergos.com/package/profile-sync-daemon). * ![logo](http://freedos-32.sourceforge.net/lean/debian_logo.png "debian logo")Debian jesse+: in the official [repos](https://packages.debian.org/unstable/profile-sync-daemon). * ![logo](https://s19.postimg.org/sjwaizg8j/zebrapig_head.png "exherbo logo")Exherbo: in the official [repos](http://git.exherbo.org/summer/packages/net-www/profile-sync-daemon). * ![logo](http://s9.postimg.org/p5f1tscxn/fedora.jpg "fedora logo")Fedora: in the official [repos](http://koji.fedoraproject.org/koji/packageinfo?packageID=16307). * ![logo](http://www.monitorix.org/imgs/gentoo.png "gentoo logo")Gentoo: in the official [repos](http://packages.gentoo.org/package/www-misc/profile-sync-daemon). * ![logo](http://s23.postimg.org/5pabe2o5z/void_logo_transparent.png "void logo")Void: in the official [repos](https://github.com/xtraeme/xbps-packages/tree/master/srcpkgs/profile-sync-daemon). * ![logo](http://www.monitorix.org/imgs/ubuntu.png "ubuntu logo")Ubuntu 16.10+: in the universe [repo](http://packages.ubuntu.com/yakkety/profile-sync-daemon). ### User Packaged * ![logo](http://www.monitorix.org/imgs/archlinux.png "arch logo")Arch: in the [AUR](https://aur.archlinux.org/packages/profile-sync-daemon). * ![logo](http://s18.postimg.org/w5jvz71mt/chakra.jpg "chakra logo")Chakra: in the [CCR](http://chakraos.org/ccr/packages.php?ID=5008). * ![logo](http://wiki.codeblocks.org/images/8/8b/Slackware-logo_32.png "slack logo")Slackware: on [slackbuilds](http://slackbuilds.org/apps/profile-sync-daemon/). * ![logo](http://www.monitorix.org/imgs/ubuntu.png "ubuntu logo")Ubuntu: in [graysky's PPA](https://github.com/graysky2/profile-sync-daemon#ubuntu-users). ### Debian Users Since June of 2016, Profile-sync-daemon is in the official repos for Users of jesse+! [Reference](https://tracker.debian.org/pkg/profile-sync-daemon). sudo apt-get install profile-sync-daemon ### Fedora Users Since June of 2013, Profile-sync-daemon is in the official repos! [Reference](https://bugzilla.redhat.com/show_bug.cgi?id=968253). sudo yum install profile-sync-daemon ### Ubuntu Users Since June of 2016, Profile-sync-daemon is in the official repos for users of Yakkety+ (16.10+)! [Reference](https://launchpad.net/ubuntu/+source/profile-sync-daemon). Others must be using AT LEAST Ubuntu 15.04 (Vivid) or have systemd as your init system to use these packages! To add the PPA (personal package archive) to your Ubuntu system (packages available for Vivid and newer), and to install psd: sudo add-apt-repository ppa:graysky/utils sudo apt-get update sudo apt-get install profile-sync-daemon ### Other Distros If you are interested in packaging psd for your favorite distro, please contact me. ## NOTE FOR VERSION 6 My desktop distro (Arch) switched to systemd a while ago and other big ones (Fedora, Debian, Ubuntu) have followed suite. With the release of psd version 6.x I will no longer be supporting alternative init systems such as upstart and openrc. It is too complex for me to maintain and test multiple configurations on non-native init systems for me. Also of note for version 6.x is that no longer does psd run in as a system service. It now runs as a user service. This is much more simple and means that: * There is no more need for `/etc/psd.conf` and the USERS array therein. * Different users can have their own config files that THEY own (`~/.psd/psd.conf`). * Encrypted $HOME should be supported under this model (NOT yet implemented). Update instructions from version 5.x: * Stop psd v5.7x and close your browsers. * Build the package linked above and install it. * Run psd to create your `~/.config/psd/psd.conf` and then edit it as you normally would. * Check it in parse mode `psd p` and if happy with the output, run it via systemd usermode: `systemctl --user start psd` (and optionally enable it). Note that if you're using overlayfs mode, your user needs to have sudo right to /usr/bin/psd-overlay-helper or else psd will refuse to run in overlayfs mode. profile-sync-daemon-6.34/common/000077500000000000000000000000001340772777000166275ustar00rootroot00000000000000profile-sync-daemon-6.34/common/browsers/000077500000000000000000000000001340772777000204755ustar00rootroot00000000000000profile-sync-daemon-6.34/common/browsers/chromium000066400000000000000000000000701340772777000222400ustar00rootroot00000000000000DIRArr[0]="$XDG_CONFIG_HOME/$browser" PSNAME="$browser" profile-sync-daemon-6.34/common/browsers/chromium-dev000066400000000000000000000000701340772777000230140ustar00rootroot00000000000000DIRArr[0]="$XDG_CONFIG_HOME/$browser" PSNAME="$browser" profile-sync-daemon-6.34/common/browsers/conkeror.mozdev.org000066400000000000000000000000571340772777000243350ustar00rootroot00000000000000DIRArr[0]="$HOME/.$browser" PSNAME="xulrunner" profile-sync-daemon-6.34/common/browsers/epiphany000066400000000000000000000000701340772777000222320ustar00rootroot00000000000000DIRArr[0]="$XDG_CONFIG_HOME/$browser" PSNAME="$browser" profile-sync-daemon-6.34/common/browsers/falkon000066400000000000000000000001421340772777000216670ustar00rootroot00000000000000[[ -d $XDG_CONFIG_HOME/$browser ]] && DIRArr[0]="$XDG_CONFIG_HOME/$browser" PSNAME="$browser" profile-sync-daemon-6.34/common/browsers/firefox000066400000000000000000000011151340772777000220600ustar00rootroot00000000000000if [[ -d $HOME/.mozilla/firefox ]]; then profileArr=( $(grep '[P,p]'ath= $HOME/.mozilla/firefox/profiles.ini | sed 's/[P,p]ath=//') ) index=0 PSNAME="$browser" for profileItem in ${profileArr[@]}; do if [[ $(echo $profileItem | cut -c1) = "/" ]]; then # path is not relative DIRArr[index]="$profileItem" else # we need to append the default path to give a # fully qualified path DIRArr[index]="$HOME/.mozilla/firefox/$profileItem" fi index=$index+1 done fi check_suffix=1 profile-sync-daemon-6.34/common/browsers/firefox-trunk000066400000000000000000000011371340772777000232250ustar00rootroot00000000000000if [[ -d $HOME/.mozilla/firefox-trunk ]]; then profileArr=( $(grep '[P,p]'ath= $HOME/.mozilla/firefox-trunk/profiles.ini | sed 's/[P,p]ath=//') ) index=0 PSNAME="$browser" for profileItem in ${profileArr[@]}; do if [[ $(echo $profileItem | cut -c1) = "/" ]]; then # path is not relative DIRArr[index]="$profileItem" else # we need to append the default path to give a fully # qualified path DIRArr[index]="$HOME/.mozilla/firefox-trunk/$profileItem" fi index=$index+1 done fi check_suffix=1 profile-sync-daemon-6.34/common/browsers/google-chrome000066400000000000000000000000661340772777000231510ustar00rootroot00000000000000DIRArr[0]="$XDG_CONFIG_HOME/$browser" PSNAME="chrome" profile-sync-daemon-6.34/common/browsers/google-chrome-beta000066400000000000000000000000661340772777000240620ustar00rootroot00000000000000DIRArr[0]="$XDG_CONFIG_HOME/$browser" PSNAME="chrome" profile-sync-daemon-6.34/common/browsers/google-chrome-unstable000066400000000000000000000000661340772777000247640ustar00rootroot00000000000000DIRArr[0]="$XDG_CONFIG_HOME/$browser" PSNAME="chrome" profile-sync-daemon-6.34/common/browsers/heftig-aurora000066400000000000000000000011741340772777000231600ustar00rootroot00000000000000# https://bbs.archlinux.org/viewtopic.php?id=117157 if [[ -d $HOME/.mozilla/aurora ]]; then profileArr=( $(grep '[P,p]'ath= $HOME/.mozilla/aurora/profiles.ini | sed 's/[P,p]ath=//') ) index=0 PSNAME="aurora" for profileItem in ${profileArr[@]}; do if [[ $(echo $profileItem | cut -c1) = "/" ]]; then # path is not relative DIRArr[index]="$profileItem" else # we need to append the default path to give a fully # qualified path DIRArr[index]="$HOME/.mozilla/aurora/$profileItem" fi index=$index+1 done fi check_suffix=1 profile-sync-daemon-6.34/common/browsers/icecat000066400000000000000000000011121340772777000216430ustar00rootroot00000000000000if [[ -d $HOME/.mozilla/icecat ]]; then profileArr=( $(grep '[P,p]'ath= $HOME/.mozilla/icecat/profiles.ini | sed 's/[P,p]ath=//') ) index=0 PSNAME="$browser" for profileItem in ${profileArr[@]}; do if [[ $(echo $profileItem | cut -c1) = "/" ]]; then # path is not relative DIRArr[index]="$profileItem" else # we need to append the default path to give a # fully qualified path DIRArr[index]="$HOME/.mozilla/icecat/$profileItem" fi index=$index+1 done fi check_suffix=1 profile-sync-daemon-6.34/common/browsers/inox000066400000000000000000000000701340772777000213720ustar00rootroot00000000000000DIRArr[0]="$XDG_CONFIG_HOME/$browser" PSNAME="$browser" profile-sync-daemon-6.34/common/browsers/luakit000066400000000000000000000000721340772777000217100ustar00rootroot00000000000000DIRArr[0]="$HOME/.local/share/$browser" PSNAME="$browser" profile-sync-daemon-6.34/common/browsers/midori000066400000000000000000000000701340772777000217000ustar00rootroot00000000000000DIRArr[0]="$XDG_CONFIG_HOME/$browser" PSNAME="$browser" profile-sync-daemon-6.34/common/browsers/opera000066400000000000000000000002301340772777000215210ustar00rootroot00000000000000# version 26 moved the profile dir but keep this for older versions DIRArr[0]="$HOME/.$browser" DIRArr[1]="$XDG_CONFIG_HOME/$browser" PSNAME="$browser" profile-sync-daemon-6.34/common/browsers/opera-beta000066400000000000000000000000701340772777000224340ustar00rootroot00000000000000DIRArr[0]="$XDG_CONFIG_HOME/$browser" PSNAME="$browser" profile-sync-daemon-6.34/common/browsers/opera-developer000066400000000000000000000000701340772777000235060ustar00rootroot00000000000000DIRArr[0]="$XDG_CONFIG_HOME/$browser" PSNAME="$browser" profile-sync-daemon-6.34/common/browsers/opera-legacy000066400000000000000000000000561340772777000227710ustar00rootroot00000000000000DIRArr[0]="$HOME/.$browser" PSNAME="$browser" profile-sync-daemon-6.34/common/browsers/opera-next000066400000000000000000000002301340772777000224750ustar00rootroot00000000000000# version 26 moved the profile dir but keep this for older versions DIRArr[0]="$HOME/.$browser" DIRArr[1]="$XDG_CONFIG_HOME/$browser" PSNAME="$browser" profile-sync-daemon-6.34/common/browsers/otter-browser000066400000000000000000000000651340772777000232370ustar00rootroot00000000000000DIRArr[0]="$XDG_CONFIG_HOME/otter" PSNAME="$browser" profile-sync-daemon-6.34/common/browsers/palemoon000066400000000000000000000012011340772777000222240ustar00rootroot00000000000000if [[ -d $HOME/.moonchild\ productions/pale\ moon ]]; then profileArr=( $(grep '[P,p]'ath= $HOME/.moonchild\ productions/pale\ moon/profiles.ini | sed 's/[P,p]ath=//') ) index=0 PSNAME="$browser" for profileItem in ${profileArr[@]}; do if [[ $(echo $profileItem | cut -c1) = "/" ]]; then # path is not relative DIRArr[index]="$profileItem" else # we need to append the default path to give a # fully qualified path DIRArr[index]="$HOME/.moonchild productions/pale moon/$profileItem" fi index=$index+1 done fi check_suffix=1 profile-sync-daemon-6.34/common/browsers/qupzilla000066400000000000000000000003341340772777000222610ustar00rootroot00000000000000# http://blog.qupzilla.com/2013/03/qupzilla-140-released.html [[ -d $HOME/.$browser ]] && DIRArr[0]="$HOME/.$browser" [[ -d $XDG_CONFIG_HOME/$browser ]] && DIRArr[0]="$XDG_CONFIG_HOME/$browser" PSNAME="$browser" profile-sync-daemon-6.34/common/browsers/qutebrowser000066400000000000000000000000721340772777000230010ustar00rootroot00000000000000DIRArr[0]="$HOME/.local/share/$browser" PSNAME="$browser" profile-sync-daemon-6.34/common/browsers/rekonq000066400000000000000000000003101340772777000217110ustar00rootroot00000000000000[[ -d $HOME/.kde4/share/apps/$browser ]] && DIRArr[0]="$HOME/.kde4/share/apps/$browser" [[ -d $HOME/.kde/share/apps/$browser ]] && DIRArr[0]="$HOME/.kde/share/apps/$browser" PSNAME="$browser" profile-sync-daemon-6.34/common/browsers/seamonkey000066400000000000000000000011231340772777000224100ustar00rootroot00000000000000if [[ -d $HOME/.mozilla/seamonkey ]]; then profileArr=( $(grep '[P,p]'ath= $HOME/.mozilla/seamonkey/profiles.ini | sed 's/[P,p]ath=//') ) index=0 PSNAME="$browser" for profileItem in ${profileArr[@]}; do if [[ $(echo $profileItem | cut -c1) = "/" ]]; then # path is not relative DIRArr[index]="$profileItem" else # we need to append the default path to give a fully # qualified path DIRArr[index]="$HOME/.mozilla/seamonkey/$profileItem" fi index=$index+1 done fi check_suffix=1 profile-sync-daemon-6.34/common/browsers/surf000066400000000000000000000000571340772777000214010ustar00rootroot00000000000000DIRArr[0]="$HOME/.$browser/" PSNAME="$browser" profile-sync-daemon-6.34/common/browsers/vivaldi000066400000000000000000000000741340772777000220570ustar00rootroot00000000000000DIRArr[0]="$XDG_CONFIG_HOME/$browser" PSNAME="$browser"-bin profile-sync-daemon-6.34/common/browsers/vivaldi-snapshot000066400000000000000000000001031340772777000237050ustar00rootroot00000000000000DIRArr[0]="$XDG_CONFIG_HOME/vivaldi-snapshot" PSNAME="vivaldi-bin" profile-sync-daemon-6.34/common/debian/000077500000000000000000000000001340772777000200515ustar00rootroot00000000000000profile-sync-daemon-6.34/common/debian/README000066400000000000000000000000761340772777000207340ustar00rootroot00000000000000These are just scripts that the ubuntu/debian packager needs. profile-sync-daemon-6.34/common/debian/postinst000066400000000000000000000013731340772777000216630ustar00rootroot00000000000000#!/bin/sh set -e if [ -f /etc/psd.conf ]; then mv /etc/psd.conf /etc/psd.conf.old echo 'ATTENTION: MAJOR CHANGES TO PSD WITH VERSION 6.00+' echo '-> 1. A global /etc/psd.conf is no longer used. $HOME/.config/psd/psd.conf will be' echo '-> created when psd is invoked the first time.' echo '-> 2. A system service is no longer used. A user service is provided and can be' echo '-> used like this: systemctl --user start psd.service' echo '-> 3. Users wanting to use overlayfs mode MUST have sudo access with nopasswd to' echo '-> /usr/bin/psd-overlay-helper. See the man page for an example configured with visudo.' fi for i in $(users); do su $i -s /bin/bash -c 'XDG_RUNTIME_DIR=/run/user/$UID systemctl --user daemon-reload' return 0 done profile-sync-daemon-6.34/common/debian/preinst000066400000000000000000000016061340772777000214630ustar00rootroot00000000000000#!/bin/sh set -e case "$1" in install|upgrade) # version 6 is a user daemon so clear out old system level files if [ -f /usr/lib/systemd/system/psd.service ]; then [ "$(systemctl is-enabled psd)" = "enabled" ] && systemctl disable psd.service &>/dev/null [ "$(systemctl is-active psd)" = "active" ] && systemctl stop psd.service &>/dev/null fi for i in $(users); do if [ "$(su $i -s /bin/bash -c 'XDG_RUNTIME_DIR=/run/user/$UID systemctl --user is-active psd')" = "active" ]; then echo "--> Internal changes to psd require it to be stopped before the update." echo "--> Restart it manually: systemctl --user start psd" su $i -s /bin/bash -c 'XDG_RUNTIME_DIR=/run/user/$UID systemctl --user stop psd.service' fi return 0 done ;; abort-upgrade) /bin/true ;; *) echo "preinst called with unknown argument \`$1'" >&2 exit 1 ;; esac exit 0 profile-sync-daemon-6.34/common/debian/prerm000066400000000000000000000022511340772777000211210ustar00rootroot00000000000000#!/bin/sh set -e # summary of how this script can be called: # * `remove' # * `upgrade' # * `failed-upgrade' # * `remove' `in-favour' # * `deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package case "$1" in remove) for i in $(users); do if [ "$(su $i -s /bin/bash -c 'XDG_RUNTIME_DIR=/run/user/$UID systemctl --user is-active psd')" = "active" ]; then echo "--> In order to preserve your profiles, psd service will be stopped now." echo "--> Any running and managed browsers will be exited." su $i -s /bin/bash -c 'XDG_RUNTIME_DIR=/run/user/$UID systemctl --user stop psd.service' su $i -s /bin/bash -c 'XDG_RUNTIME_DIR=/run/user/$UID systemctl --user disable psd.service' fi return 0 done ;; upgrade|failed-upgrade) /bin/true # Do nothing ;; *) echo "prerm called with unknown argument \`$1'" >&2 exit 1 ;; esac exit 0 profile-sync-daemon-6.34/common/profile-sync-daemon.in000066400000000000000000000604351340772777000230420ustar00rootroot00000000000000#!/bin/bash # # Profile-sync-daemon by graysky # Inspired by some code originally written by Colin Verot # # needed for debian 8.x [[ -h /sbin ]] || PATH=$PATH:/sbin BLD="\e[01m" RED="\e[01;31m" GRN="\e[01;32m" BLU="\e[01;34m" NRM="\e[00m" VERS="@VERSION@" user=$(id -un) HOME="$(getent passwd "$user" | cut -d: -f6)" XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" PSDCONFDIR="$XDG_CONFIG_HOME/psd" PSDCONF="$PSDCONFDIR/psd.conf" SHAREDIR="/usr/share/psd" VOLATILE="$XDG_RUNTIME_DIR" PID_FILE="$VOLATILE/psd.pid" if [[ ! -d "$SHAREDIR" ]]; then echo -e " ${RED}ERROR:${NRM}${BLD} Missing ${BLU}$SHAREDIR${NRM}${BLD} - reinstall the package to use profile-sync-daemon.${NRM}" exit 1 fi if [[ ! -d "$SHAREDIR/browsers" ]]; then echo -e " ${RED}ERROR:${NRM}${BLD} Missing ${BLU}$SHAREDIR/browsers${NRM}${BLD} - reinstall the package to use profile-sync-daemon.${NRM}" exit 1 fi if [[ $EUID -eq 0 ]]; then echo -e " ${RED}WARNING:${NRM}${BLD} Do not call ${BLU}$0${NRM}${BLD} as root.${NRM}" exit 1 fi if [[ ! -d "$XDG_RUNTIME_DIR" ]]; then echo -e " ${RED}ERROR:${NRM}${BLD} Cannot find XDG_RUNTIME_DIR which should be set by systemd.${NRM}" exit 1 fi # Setup check for config file if [[ -f "$PSDCONF" ]]; then if [[ ! -f "$PID_FILE" ]]; then # do nothing if psd is currently running, otherwise # make sure only comments and variables/arrays are defined to prevent # problems like issue #166 if egrep -q -v '^$|^#|^[^ ]*=[^;]*' "$PSDCONF"; then # something that isn't a blank line, comment, or variable present # so exit echo -e " ${RED}ERROR:${NRM}${BLD} Syntax error(s) detected in ${BLU}$PSDCONF${NRM}${BLD} - edit and try again.${NRM}" echo -e "${NRM}${BLD}Line number: offending comment${NRM}" egrep -vn '^$|^#|^[^ ]*=[^;]*' "$PSDCONF" exit 1 fi fi . "$PSDCONF" elif [[ -d "$HOME/.psd" ]]; then # first check to see if a legacy ~/.psd is present and then move it to the # new location mkdir -p "$PSDCONFDIR" rsync -ax "$HOME/.psd/" "$PSDCONFDIR/" rm -rf "$HOME/.psd" echo " The use of $HOME/.psd is deprecated. Existing config has been moved to $PSDCONFDIR" # source it again retaining any user options [[ -f "$PSDCONF" ]] && . "$PSDCONF" else mkdir -p "$PSDCONFDIR" if [[ -f "$SHAREDIR/psd.conf" ]]; then cp "$SHAREDIR/psd.conf" "$PSDCONFDIR" echo -e " First time running psd so please edit ${BLU}$PSDCONF${NRM}${BLD} to your liking and run again.${NRM}" exit 0 fi fi # if psd is active, source the snapshot of psd.conf preferentially # version 6.03 renames this file so if older version is running then # rotate the old name to the new one [[ -f "$PSDCONFDIR/.$user@$(hostname).pid.conf" ]] && mv "$PSDCONFDIR/.$user@$(hostname).pid.conf" "$PSDCONFDIR/.psd.conf" if [[ -f "$PID_FILE" ]]; then if [[ -f "$PSDCONFDIR/.psd.conf" ]]; then PSDCONF="$PSDCONFDIR/.psd.conf" unset USE_OVERLAYFS BROWSERS USE_BACKUPS . "$PSDCONF" # defining VOLATILE in the config is deprecated since v6.16 VOLATILE="$XDG_RUNTIME_DIR" fi fi # define default number of crash-recovery snapshots to save if the user did not # and check that it is an integer if user did define it if [[ -z "$BACKUP_LIMIT" ]]; then BACKUP_LIMIT=5 else if [[ "$BACKUP_LIMIT" =~ ^[0-9]+$ ]]; then # correctly setup true else echo -e " ${RED}ERROR:${NRM}${BLD} Bad value for BACKUP_LIMIT detected!${NRM}" exit 1 fi fi # BROWSERS defined as string var so redefine it as an array if [[ -z "$BROWSERS" ]]; then BROWSERS=( $(find "$SHAREDIR/browsers" -type f -printf "%f\n") ) else BROWSERS=( $BROWSERS ) fi # simple function to determine user intent rather than using a null value case "${USE_OVERLAYFS,,}" in y|yes|true|t|on|1|enabled|enable|use) OLFS=1 ;; *) OLFS=0 ;; esac # since the default for this one is a yes, need to force a null value to yes [[ -z "${USE_BACKUPS,,}" ]] && USE_BACKUPS="yes" case "${USE_BACKUPS,,}" in y|yes|true|t|on|1|enabled|enable|use) CRRE=1 ;; *) CRRE=0 ;; esac # determine is we are using overlayfs (v22 and below) or overlay (v23 and above) # since mount should call modprobe on invocation, check to see if either # module is in the tree using modinfo if [[ $OLFS -eq 1 ]]; then # first check to see if either is hardcoded into the kernel # and of course prefer version 23 [[ $(grep -ciE "overlayfs$" /proc/filesystems) -eq 1 ]] && OLFSVER=22 [[ $(grep -ciE "overlay$" /proc/filesystems) -eq 1 ]] && OLFSVER=23 fi if [[ -z $OLFSVER ]]; then # if neither is hardcoded, see if either module is available modinfo overlayfs &>/dev/null [[ $? -eq 0 ]] && OLFSVER=22 modinfo overlay &>/dev/null [[ $? -eq 0 ]] && OLFSVER=23 fi # get distro name # first try os-release if [[ -f /etc/os-release ]]; then . /etc/os-release if [[ -n "$PRETTY_NAME" ]]; then distro="$PRETTY_NAME" elif [[ -n "$NAME" ]]; then distro="$NAME" fi else # if not os-release try issue if [[ -n $(sed 's| \\.*$||' /etc/issue | head -n 1) ]]; then distro="$(sed 's| \\.*$||' /etc/issue | head -n 1)" else # fuck it distro= fi fi header() { [[ -z "$distro" ]] && echo -e "${BLD}Profile-sync-daemon v$VERS${NRM}" || echo -e "${BLD}Profile-sync-daemon v$VERS${NRM}${BLD} on $distro${NRM}" echo } dep_check() { # checks for dependencies and that psd.conf is setup correctly command -v rsync >/dev/null 2>&1 || { echo -e " ${BLD}I require rsync but it's not installed. ${RED}Aborting!${NRM}" >&2; exit 1; } command -v modinfo >/dev/null 2>&1 || { echo -e " ${BLD}I require modinfo but it's not installed. ${RED}Aborting!${NRM}" >&2; exit 1; } command -v awk >/dev/null 2>&1 || { echo -e " ${BLD}I require awk but it's not installed. ${RED}Aborting!${NRM}" >&2; exit 1; } if [[ $OLFS -eq 1 ]]; then [[ $OLFSVER -ge 22 ]] || { echo -e " ${BLD}Your kernel requires either the ${BLU}overlay${NRM}${BLD} or ${BLU}overlayfs${NRM}${BLD} module to use${NRM}" echo -e " ${BLD}to use psd's in overlay mode. Cannot find either in your kernel so compile it in and${NRM}" echo -e " ${BLD}try again or remove the option from ${BLU}$PSDCONF${NRM}${BLD}. ${RED}Aborting!${NRM}" >&2; exit 1;} fi if [[ -f /etc/psd.conf ]]; then echo -e "${BLD} This version of psd does not support /etc/psd.conf since it runs as your user.${NRM}" echo -e "${BLD} Recommend that you remove /etc/psd.conf and run it in systemd's user mode:${NRM}" echo -e "${BLD} systemd --user psd.service${NRM}" exit 1 fi } config_check() { if [[ $OLFS -eq 1 ]]; then # user must have sudo rights to call /usr/bin/mount # and /usr/bin/umount to use overlay mode sudo -kn psd-overlay-helper &>/dev/null [[ $? -ne 0 ]] && FAILCODE=1 if [[ $FAILCODE -ne 0 ]]; then echo -e "${BLD}${RED} ERROR!${NRM}${BLD} To use overlayfs mode, $user needs sudo access to ${BLU}/usr/bin/psd-overlay-helper${NRM}${BLD}${NRM}" echo echo -e " ${BLD}Add the following line to the end of ${BLU}/etc/sudoers${NRM}${BLD} to enable this functionality:${NRM}" echo -e " ${BLD}$user ALL=(ALL) NOPASSWD: /usr/bin/psd-overlay-helper${NRM}" exit 1 fi fi for browser in "${BROWSERS[@]}"; do if [[ ! -f "$SHAREDIR/browsers/$browser" ]]; then # user defined an invalid browser echo -e " ${BLD}${RED}$browser${NRM}${BLD} is not a supported browser. Check config file for typos: ${NRM}${BLU}$PSDCONF${NRM}" exit 1 fi done } ungraceful_state_check() { # if the machine was ungracefully shutdown then the backup will be # on the filesystem and the link to tmpfs will be on the filesystem # but the contents will be empty we need to simply remove the link # and rotate the backup into place local browser for browser in "${BROWSERS[@]}"; do load_env_for "$browser" for item in "${DIRArr[@]}"; do DIR="$item" BACKUP="$item-backup" BACK_OVFS="$item-back-ovfs" # all is well so continue [[ -e "$DIR/.flagged" ]] && continue NOW=$(date +%Y%m%d_%H%M%S) if [[ -h "$DIR" ]]; then # symlinked browser profiles are not supported so bail if one is detected if [[ -d $(readlink "$DIR") ]]; then echo -e " ${RED}Warning!${NRM}" echo -e " ${BLD}${BLU}$DIR${NRM}${BLD} appears to be a symlink but these are not supported.${NRM}" echo -e " ${BLD}Please make the browser profile a live directory and try again. Exiting.${NRM}" exit 1 else echo "Ungraceful state detected for $DIR so fixing" unlink "$DIR" fi fi if [[ -d "$BACKUP" ]]; then if [[ -d "$BACK_OVFS" ]]; then # always snapshot the most recent of these two dirs... # if using overlayfs $BACK_OVFS and $BACKUP should be compared # against each other to see which is newer and then that should # be what psd snapshots since BACKUP (the lowerdir) is readonly # at the time the user started psd could be many resync cycles # in the past BACKUP_TIME=$(stat "$BACKUP" | grep Change | awk '{ print $2,$3 }') BACK_OVFS_TIME=$(stat "$BACK_OVFS" | grep Change | awk '{ print $2,$3 }') [[ $(date -d "$BACK_OVFS_TIME" "+%s") -ge $(date -d "$BACKUP_TIME" "+%s") ]] && TARGETTOKEEP="$BACK_OVFS" || TARGETTOKEEP="$BACKUP" if [[ $CRRE -eq 1 ]]; then opts="-a --reflink=auto" cp $opts "$TARGETTOKEEP" "$BACKUP-crashrecovery-$NOW" fi mv --no-target-directory "$TARGETTOKEEP" "$DIR" rm -rf "$BACKUP" else # we only find the BACKUP and no BACKOVFS then either the initial resync # never occurred before the crash using overlayfs or we aren't using overlayfs # at all which can be treated the same way if [[ $CRRE -eq 1 ]]; then opts="-a --reflink=auto" cp $opts "$BACKUP" "$BACKUP-crashrecovery-$NOW" mv --no-target-directory "$BACKUP" "$DIR" fi fi fi # if overlayfs was active but is no longer, remove $BACK_OVFS [[ $OLFS -eq 1 ]] || rm -rf "$BACK_OVFS" done done } cleanup() { local browser for browser in "${BROWSERS[@]}"; do load_env_for "$browser" for item in "${DIRArr[@]}"; do DIR="$item" CRASHArr=( $(find "${DIR%/*}" -type d -name '*crashrecovery*'|sort -r) ) if [[ ${#CRASHArr[@]} -gt 0 ]]; then echo -e "${BLD}Deleting ${#CRASHArr[@]} crashrecovery dir(s) for profile ${BLU}$DIR${NRM}" for backup in "${CRASHArr[@]}"; do echo -e "${BLD}${RED} $backup${NRM}" rm -rf "$backup" done unset CRASHArr else echo -e "${BLD}Found no crashrecovery dirs for: ${BLU}$DIR${NRM}${BLD}${NRM}" fi echo done done } load_env_for() { browser="$1" homedir=$HOME group=$(id -g "$user") ### Arrays # profileArr is transient used to store profile paths parsed from # firefox and aurora unset profileArr # DIRArr is a full path corrected for both relative and absolute paths # reset global variables and arrays unset DIRArr unset PSNAME . "$SHAREDIR/browsers/$browser" } running_check() { # check for browsers running and refuse to start if so # without this cannot guarantee profile integrity local browser for browser in "${BROWSERS[@]}"; do load_env_for "$browser" [[ -z "$PSNAME" ]] && continue if pgrep -u "$user" "\<$PSNAME\>" &>/dev/null; then echo "Refusing to start; $browser is running by $user!" exit 1 fi done } suffix_needed() { browser=$1 unset check_suffix . "$SHAREDIR/browsers/$browser" [[ -n "$check_suffix" ]] } dup_check() { # only for firefox, icecat, seamonkey, palemoon, and aurora # the LAST directory in the profile MUST be unique # make sure there are no duplicates in ~/.mozilla//profiles.ini local browser for browser in "${BROWSERS[@]}"; do load_env_for "$browser" if suffix_needed "$browser"; then # nothing to check [[ -z "${DIRArr[@]}" ]] && continue # browser is on system so check profiles # # check that the LAST DIRECTORY in the full path is unique unique_count=$(echo "${DIRArr[@]##*/}" | sed 's/ /\n/g' | sort -u | wc -l) # no problems so do nothing [[ ${#DIRArr[@]} -eq $unique_count ]] && continue echo -e " ${RED}Error: ${NRM}${BLD}dup profile for ${GRN}$browser${NRM}${BLD} detected. See psd manpage, correct, and try again.${NRM}" # clip of the 'heftig-' to give correct path [[ "$browser" = "heftig-aurora" ]] && browser="${browser##*-}" profile_ini="$homedir/.mozilla/$browser/profiles.ini" [[ "$browser" = "palemoon" ]] && profile_ini="$homedir/.moonchild productions/pale moon/profiles.ini" echo -e " ${BLD}Must have unique last directories in ${BLU}${profile_ini}${NRM}${BLD} to use psd.${NRM}" exit 1 fi done } kill_browsers() { # check for browsers running and kill them to safely sync/unsync # without this cannot guarantee profile integrity local browser for browser in "${BROWSERS[@]}"; do load_env_for "$browser" local x=1 while [[ $x -le 60 ]]; do [[ -n "$PSNAME" ]] || break pgrep -u "$user" "\<$PSNAME\>" &>/dev/null || break if [[ $x -le 5 ]]; then pkill -SIGTERM -u "$user" "\<$PSNAME\>" else pkill -SIGKILL -u "$user" "\<$PSNAME\>" fi x=$(( x + 1 )) sleep .05 done done } do_sync_for() { browser=$1 load_env_for "$browser" for item in "${DIRArr[@]}"; do DIR="$item" BACKUP="$item-backup" BACK_OVFS="$item-back-ovfs" suffix= if suffix_needed "$browser"; then suffix="-${item##*/}" fi TMP="$VOLATILE/$user-$browser$suffix" UPPER="$VOLATILE/$user-$browser${suffix}-rw" WORK="$VOLATILE/.$user-$browser${suffix}" local REPORT # make tmpfs container if [[ -d "$DIR" ]]; then # retain permissions on sync target PREFIXP=$(stat -c %a "$DIR") [[ -r "$TMP" ]] || install -dm"$PREFIXP" --owner="$user" --group="$group" "$TMP" if [[ $OLFS -eq 1 ]]; then if [[ $OLFSVER -eq 23 ]]; then [[ -r "$UPPER" ]] || install -dm"$PREFIXP" --owner="$user" --group="$group" "$UPPER" [[ -r "$WORK" ]] || install -dm"$PREFIXP" --owner="$user" --group="$group" "$WORK" elif [[ $OLFSVER -eq 22 ]]; then [[ -r "$UPPER" ]] || install -dm"$PREFIXP" --owner="$user" --group="$group" "$UPPER" fi fi # backup target and link to tmpfs container if [[ $(readlink "$DIR") != "$TMP" ]]; then mv --no-target-directory "$DIR" "$BACKUP" # refuse to start browser while initial sync ln -s /dev/null "$DIR" fi # sync the tmpfs targets to the disc if [[ -e "$DIR"/.flagged ]]; then REPORT="resync" if [[ $OLFS -eq 1 ]]; then rsync -aX --delete-after --inplace --no-whole-file --exclude .flagged "$DIR/" "$BACK_OVFS/" else rsync -aX --delete-after --inplace --no-whole-file --exclude .flagged "$DIR/" "$BACKUP/" fi else # initial sync REPORT="sync" if [[ $OLFS -eq 1 ]]; then sudo psd-overlay-helper -v "$OLFSVER" -l "$BACKUP" -u "$UPPER" -w "$WORK" -d "$TMP" mountup if [[ $? -ne 0 ]]; then echo -e "Error in trying to mount $TMP - this should not happen!" exit 1 fi else # keep user from launching browser while rsync is active rsync -aX --inplace --no-whole-file "$BACKUP/" "$TMP" fi # now browser can start [[ $(readlink "$DIR") = "/dev/null" ]] && unlink "$DIR" ln -s "$TMP" "$DIR" chown -h "$user":"$group" "$DIR" touch "$DIR/.flagged" fi echo -e "${BLD}$browser $REPORT successful${NRM}" else if [[ ! -d "$homedir" ]] ; then echo -e "${RED}$DIR does not exist! Is /home unmounted?${NRM}" >&2 exit 1 elif [[ -d "$BACKUP" ]] ; then echo -e "${RED}$DIR does not exist or is a broken symlink! Is $VOLATILE unmounted?${NRM}" >&2 exit 1 fi fi done } do_sync() { touch "$PID_FILE" # make a snapshot of psd.conf and redefine its location to this snapshot # while psd is running to keep any edits made to the "live" psd.conf from # potentially orphaning the snapshot copies thus preserving the data [[ -f "$PSDCONFDIR/.psd.conf" ]] || { echo "# Automatically generated file; DO NOT EDIT!" > "$PSDCONFDIR/.psd.conf" echo "# The purpose is to snapshot the settings used when psd was activated." >> "$PSDCONFDIR/.psd.conf" echo "# Any edits to the live config: $PSDCONFDIR/psd.conf" >> "$PSDCONFDIR/.psd.conf" echo "# will be applied the _next_ time psd is activated." >> "$PSDCONFDIR/.psd.conf" echo "#" >> "$PSDCONFDIR/.psd.conf" echo "USE_OVERLAYFS=\"$USE_OVERLAYFS\"" >> "$PSDCONFDIR/.psd.conf" echo "BROWSERS=\"${BROWSERS[*]}\"" >> "$PSDCONFDIR/.psd.conf" echo "USE_BACKUPS=\"$USE_BACKUPS\"" >> "$PSDCONFDIR/.psd.conf" chmod 400 "$PSDCONFDIR/.psd.conf" } local browser for browser in "${BROWSERS[@]}"; do do_sync_for "$browser" done } enforce() { local browser for browser in "${BROWSERS[@]}"; do CRASHArr=( $(find "${DIR%/*}" -type d -name '*crashrecovery*'|sort -r) ) if [[ ${#CRASHArr[@]} -gt $BACKUP_LIMIT ]]; then for remove in "${CRASHArr[@]:$BACKUP_LIMIT}"; do rm -rf "$remove" done fi unset CRASHArr done } do_unsync() { rm -f "$PID_FILE" "$PSDCONFDIR/.psd.conf" local browser for browser in "${BROWSERS[@]}"; do load_env_for "$browser" for item in "${DIRArr[@]}"; do DIR="$item" BACKUP="$item-backup" BACK_OVFS="$item-back-ovfs" suffix= if suffix_needed "$browser"; then suffix="-${item##*/}" fi TMP="$VOLATILE/$user-$browser$suffix" UPPER="$VOLATILE/$user-$browser${suffix}-rw" WORK="$VOLATILE/.$user-$browser${suffix}" # check if user has browser profile if [[ -h "$DIR" ]]; then unlink "$DIR" # this assumes that the backup is always updated so # be sure to invoke a sync before an unsync # # restore original dirtree [[ -d "$BACKUP" ]] && mv --no-target-directory "$BACKUP" "$DIR" if [[ $OLFS -eq 1 ]] && mountpoint -q "$TMP"; then rsync -aX --delete-after --inplace --no-whole-file --exclude .flagged "$BACK_OVFS/" "$DIR/" sudo psd-overlay-helper -d "$TMP" mountdown && rm -rf "$TMP" "$UPPER" "$WORK" fi [[ -d "$TMP" ]] && rm -rf "$TMP" echo -e "${BLD}$browser unsync successful${NRM}" else if [[ ! -d "$homedir" ]] ; then echo -e "${RED}$DIR does not exist! Is /home unmounted?${NRM}" >&2 exit 1 fi fi done done } parse() { psd_state=$(systemctl --user is-active psd) resync_state=$(systemctl --user is-active psd-resync.timer) [[ "$psd_state" = "active" ]] && psd_color="${GRN}" || psd_color="${RED}" [[ "$resync_state" = "active" ]] && resync_color="${GRN}" || resync_color="${RED}" echo -e " ${BLD}Systemd service is currently ${psd_color}$psd_state${NRM}${BLD}.${NRM}" echo -e " ${BLD}Systemd resync-timer is currently ${resync_color}$resync_state${NRM}${BLD}.${NRM}" [[ $OLFS -eq 1 ]] && echo -e "${BLD} Overlayfs v$OLFSVER is currently ${GRN}active${NRM}${BLD}.${NRM}" || echo -e "${BLD} Overlayfs technology is currently ${RED}inactive${NRM}${BLD}.${NRM}" echo echo -e "${BLD}Psd will manage the following per ${BLU}${PSDCONF}${NRM}${BLD}:${NRM}" echo local browser for browser in "${BROWSERS[@]}"; do load_env_for "$browser" for item in "${DIRArr[@]}"; do DIR="$item" BACKUP="$item-backup" suffix= if suffix_needed "$browser"; then suffix="-${item##*/}" fi UPPER="$VOLATILE/$user-$browser${suffix}-rw" if [[ -d "$DIR" ]]; then CRASHArr=( $(find "${DIR%/*}" -type d -name '*crashrecovery*'|sort -r) ) # get permissions on profile dir and be smart about it since symlinks are all 777 [[ -f $PID_FILE ]] && TRUEP=$(stat -c %a "$BACKUP") || TRUEP=$(stat -c %a "$DIR") # since $XDG_RUNTIME_DIR is 700 by default so pass on by if [[ "$VOLATILE" = "$XDG_RUNTIME_DIR" ]]; then warn= else # using something other than $XDG_RUNTIME_DIR so check for privacy [[ $TRUEP -ne 700 ]] && warn=1 fi # profile dir size psize=$(du -Dh --max-depth=0 "$DIR" 2>/dev/null | awk '{ print $1 }') echo -en " ${BLD}browser/psname:" echo -e "$(tput cr)$(tput cuf 17) $browser/$PSNAME${NRM}" echo -en " ${BLD}owner/group id:" echo -e "$(tput cr)$(tput cuf 17) $user/$group${NRM}" echo -en " ${BLD}sync target:" echo -e "$(tput cr)$(tput cuf 17) ${BLU}$DIR${NRM}" if [[ $warn -eq 1 ]]; then echo -e "$(tput cr)$(tput cuf 17) ${RED} Permissions are $TRUEP on this profile.${NRM}" echo -e "$(tput cr)$(tput cuf 17) ${RED} Recommend a setting of 700 for increased privacy!${NRM}" warn= fi echo -en " ${BLD}tmpfs dir:" echo -e "$(tput cr)$(tput cuf 17) ${GRN}$VOLATILE/$user-$browser$suffix${NRM}" echo -en " ${BLD}profile size:" echo -e "$(tput cr)$(tput cuf 17) $psize${NRM}" if [[ $OLFS -eq 1 ]]; then rwsize=$(du -Dh --max-depth=0 "$UPPER" 2>/dev/null | awk '{ print $1 }') echo -en " ${BLD}overlayfs size:" echo -e "$(tput cr)$(tput cuf 17) $rwsize${NRM}" fi echo -en " ${BLD}recovery dirs:" if [[ "${#CRASHArr[@]}" -eq 0 ]]; then echo -e "$(tput cr)$(tput cuf 17) none${NRM}" else echo -e "$(tput cr)$(tput cuf 17) ${RED}${#CRASHArr[@]}${NRM}${BLD} <- delete with the c option${NRM}" for backup in "${CRASHArr[@]}"; do psize=$(du -Dh --max-depth=0 "$backup" 2>/dev/null | awk '{ print $1 }') echo -en " ${BLD} dir path/size:" echo -e "$(tput cr)$(tput cuf 17) ${BLU}$backup ${NRM}${BLD}($psize)${NRM}" done fi unset CRASHArr echo fi done done } case "$1" in p|P|Parse|parse|Preview|preview|debug) dep_check config_check dup_check ungraceful_state_check header parse ;; c|C|clean|Clean) dep_check config_check dup_check header cleanup ;; sync|resync) if [[ -f $PID_FILE ]]; then do_sync else dep_check config_check dup_check running_check ungraceful_state_check do_sync enforce fi ;; unsync) if [[ -f $PID_FILE ]]; then do_sync kill_browsers do_unsync fi ;; *) header echo -e " ${BLD}$0 ${NRM}${GRN}[option]${NRM}" echo -e " ${BLD} ${NRM}${GRN}preview${NRM}${BLD} Parse config file (${NRM}${BLU}${PSDCONF}${NRM}${BLD}) to see which profiles will be managed.${NRM}" echo -e " ${BLD} ${NRM}${GRN}clean${NRM}${BLD} Clean (delete without prompting) ALL crashrecovery dirs for all profiles.${NRM}" echo echo -e " ${BLD}It is ${RED}HIGHLY DISCOURAGED${NRM}${BLD} to directly call $0 to sync, resync, or to unsync.${NRM}" echo if [[ -f /usr/lib/systemd/user/psd.service ]]; then echo -e " ${BLD}Instead, use systemd to start/stop profile-sync-daemon.${NRM}" echo echo -e " ${BLD}systemctl --user ${NRM}${GRN}[option]${NRM}${BLD} psd${NRM}" echo -e " ${BLD} ${NRM}${GRN}start${NRM}${BLD} Turn on daemon; make symlinks and actively manage targets in tmpfs.${NRM}" echo -e " ${BLD} ${NRM}${GRN}stop${NRM}${BLD} Turn off daemon; remove symlinks and rotate tmpfs data back to disc.${NRM}" echo -e " ${BLD} ${NRM}${GRN}enable${NRM}${BLD} Autostart daemon when system comes up.${NRM}" echo -e " ${BLD} ${NRM}${GRN}disable${NRM}${BLD} Remove daemon from the list of autostart daemons.${NRM}" elif [[ -f /etc/init.d/psd ]]; then echo -e " ${BLD}Instead, use the init system to start/stop profile-sync-daemon.${NRM}" echo echo -e " ${BLD}sudo service psd ${NRM}${GRN}[option]${NRM}${BLD} or /etc/init.d/psd ${NRM}${GRN}[option]${NRM}" echo -e " ${BLD} ${NRM}${GRN}start${NRM}${BLD} Turn on daemon; make symlinks and actively manage targets in tmpfs.${NRM}" echo -e " ${BLD} ${NRM}${GRN}stop${NRM}${BLD} Turn off daemon; remove symlinks and rotate tmpfs data back to disc.${NRM}" fi ;; esac exit 0 # vim:set ts=2 sw=2 et: profile-sync-daemon-6.34/common/psd-overlay-helper000066400000000000000000000015731340772777000223020ustar00rootroot00000000000000#!/bin/bash readonly PATH=/usr/bin:/bin readonly IFS=$' \t\n' while getopts :v:l:u:w:d: OPT; do case $OPT in v|+v) declare -ir OLFSVER=$OPTARG ;; l|+l) readonly BACKUP=$OPTARG ;; u|+u) readonly UPPER=$OPTARG ;; w|+w) readonly WORK=$OPTARG ;; d|+d) readonly TMP=$OPTARG ;; esac done shift $(( OPTIND - 1 )) OPTIND=1 ## TODO - pass error codes back to psd so it can break if the mount command fails case "$1" in mountup) if [[ $OLFSVER -eq 23 ]]; then mount -o nosuid,nodev -t overlay overlaid -olowerdir="$BACKUP",upperdir="$UPPER",workdir="$WORK" "$TMP" elif [[ $OLFSVER -eq 22 ]]; then mount -o nosuid,nodev -t overlayfs overlaid -olowerdir="$BACKUP",upperdir="$UPPER" "$TMP" fi ;; mountdown) umount -l "$TMP" ;; *) echo "Do not call this script directly; psd will do so for you. Thank you, come again." exit 0 ;; esac profile-sync-daemon-6.34/common/psd.conf000066400000000000000000000033771340772777000202760ustar00rootroot00000000000000# # $XDG_HOME_CONFIG/psd/psd.conf # # For documentation, refer to the psd man page or the wiki page # https://wiki.archlinux.org/index.php/Profile-sync-daemon ## NOTE the following: ## To protect data from corruption, in the event that you do make an edit while ## psd is active, any changes made will be applied the next time you start psd. # Uncomment and set to "yes" to use overlayfs instead of a full copy to reduce # the memory costs and to improve sync/unsync operations. Note that your kernel # MUST have this module available in order to use this mode # #USE_OVERLAYFS="no" # List browsers separated by spaces to include in the sync. Useful if you do not # wish to have all possible browser profiles sync'ed which is the default if # this variable is left commented. # # Possible values: # chromium # chromium-dev # conkeror.mozdev.org # epiphany # falkon # firefox # firefox-trunk # google-chrome # google-chrome-beta # google-chrome-unstable # heftig-aurora # icecat # inox # luakit # midori # opera # opera-beta # opera-developer # opera-legacy # otter-browser # qupzilla # qutebrowser # palemoon # rekonq # seamonkey # surf # vivaldi # vivaldi-snapshot # #BROWSERS="" # Uncomment and set to "no" to completely disable the crash recovery feature. # # The default is to create crash recovery backups if the system is ungracefully # powered-down due to a kernel panic, hitting the reset switch, battery going # dead, etc. Some users keep very diligent backups and don't care to have this # feature enabled. #USE_BACKUPS="yes" # Uncomment and set to an integer that is the maximum number of crash recovery # snapshots to keep (the oldest ones are delete first). # # The default is to save the most recent 5 crash recovery snapshots. #BACKUP_LIMIT=5 profile-sync-daemon-6.34/common/zsh-completion000066400000000000000000000004111340772777000215210ustar00rootroot00000000000000#compdef psd profile-sync-daemon _psd() { local -a options options=('p:Preview what psd will do/is doing and printout useful info' 'c:Clean (delete without prompting) ALL crashrecovery dirs for all profiles') _describe 'options' options } _psd profile-sync-daemon-6.34/doc/000077500000000000000000000000001340772777000161045ustar00rootroot00000000000000profile-sync-daemon-6.34/doc/psd-overlay-helper.1000066400000000000000000000020351340772777000217100ustar00rootroot00000000000000.TH psd-overlay-helper 1 "13 June 2016" "" "" .SH NAME \fBpsd-overlay-helper \fP- Script to use overlay file system for profile-sync-daemon. \fB .SH DESCRIPTION Profile-sync-daemon (psd) is a tiny pseudo-daemon designed to manage browser profile/profiles in tmpfs and to periodically sync back to the physical disc (HDD/SSD). This is accomplished by an innovative use of rsync to maintain synchronization between a tmpfs copy and media-bound backup of the browser profile/profiles. Additionally, psd features several crash recovery features. The psd-overlay-helper script is used internally to enable the usage of the overlay file system. It should not be called by the user directly. .SH CONTRIBUTE Users wishing to contribute to this code, should fork and send a pull request. Source is freely available on the project page linked below. .SH ONLINE .IP \(bu 3 Project page: https://github.com/graysky2/profile-sync-daemon .IP \(bu 3 Wiki page: https://wiki.archlinux.org/index.php/Profile-sync-daemon .SH AUTHOR graysky (graysky AT archlinux DOT us) profile-sync-daemon-6.34/doc/psd.1000066400000000000000000000303271340772777000167610ustar00rootroot00000000000000.\" Text automatically generated by txt2man .TH profile-sync-daemon 1 "28 February 2018" "" "" .SH NAME \fBprofile-sync-daemon \fP- Symlinks and syncs browser profiles to RAM (tmpfs) thus reducing HDD/SSD calls and speeding-up browsers. \fB .SH DESCRIPTION Profile-sync-daemon (psd) is a tiny pseudo-daemon designed to manage browser profile/profiles in tmpfs and to periodically sync back to the physical disc (HDD/SSD). This is accomplished by an innovative use of rsync to maintain synchronization between a tmpfs copy and media-bound backup of the browser profile/profiles. Additionally, psd features several crash-recovery features. .PP Design goals of psd: .RS .IP \(bu 3 Completely transparent user experience. .IP \(bu 3 Reduced wear to physical discs (particularly SSDs). .IP \(bu 3 Speed. .RE .PP Since the profile/profiles, browser cache*, etc. are relocated into tmpfs (RAM disk), the corresponding I/O associated with using the browser is also redirected from the physical disc to the RAM, thus reducing wear to the physical disc and improving browser responsiveness. .PP *Note that some browsers such as Chrome/Chromium, Firefox (since v21), Midori, and Rekonq actually keeps their cache directories separately from their browser profile directory. It is not within the scope of profile-sync-daemon to modify this behavior; users wishing to relocate this directory, may refer to the following url for several work-arounds: https://wiki.archlinux.org/index.php/Chromium_Tips_and_Tweaks#Cache_in_tmpfs .SH SETUP $XDG_CONFIG_HOME/psd/psd.conf (referred to hereafter as "the config file") contains all user managed settings. .PP NOTE: edits made to the config file while psd is active will be applied only after the service has been restarted. .RS .IP \(bu 3 Optionally enable the use of overlayfs to improve sync speed and to use a smaller memory footprint. Do this in the USE_OVERLAYFS variable. The user will require no password sudo rights to /usr/bin/psd-overlay-helper to use this option and the kernel must support overlayfs version 22 or higher. See the FAQ below for additional details. .IP \(bu 3 Optionally define which browsers are to be managed in the BROWSERS array. If none are defined, the default is all detected browsers. .IP \(bu 3 Optionally disable the use of crash-recovery snapshots (not recommended). Do this in the USE_BACKUPS variable. .IP \(bu 3 Optionally define the number of crash-recovery snapshots to keep. Do this in the BACKUP_LIMIT variable. .RE .PP NOTE: occasionally, updates/changes are made to the default config file (/usr/share/psd/psd.conf) upstream. The user copy ($XDG_CONFIG_HOME/psd/psd.conf) will need to be diffed against it. .SH RUNNING PSD .SS PREVIEW MODE The preview option can be called to show users exactly what psd will do/is doing based on the entries in the config file. It will also provide useful information such as profile size, paths, and if any recovery snapshots have been created. .PP .nf .fam C $ psd p Profile-sync-daemon on Arch Linux. .nf .fam C Systemd service is currently active. Systemd resync-timer is currently active. Overlayfs v23 is currently active. .fam T .fi .RS Psd will manage the following per /home/facade/.config/psd/.psd.conf settings: .PP .nf .fam C browser/psname: chromium/chromium owner/group id: facade/100 sync target: /home/facade/.config/chromium tmpfs dir: /run/user/1000/facade-chromium profile size: 93M overlayfs size: 39M recovery dirs: 2 <- delete with the c option dir path/size: /home/facade/.config/chromium-backup-crashrecovery-20150117_171359 (92M) dir path/size: /home/facade/.config/chromium-backup-crashrecovery-20150119_112204 (93M) browser/psname: firefox/firefox owner/group id: facade/100 sync target: /home/facade/.mozilla/firefox/f8cv8bfu.default tmpfs dir: /run/user/1000/facade-firefox-f8cv8bfu.default profile size: 145M overlayfs size: 13M recovery dirs: none .fam T .fi .SS CLEAN MODE The clean mode will delete ALL recovery snapshots that have accumulated. Only run it when sure these are no longer needed. .PP .nf .fam C $ psd c Profile-sync-daemon on Arch Linux. Deleting 2 crashrecovery dirs for profile /home/facade/.config/chromium /home/facade/.config/chromium-backup-crashrecovery-20150117_171359 /home/facade/.config/chromium-backup-crashrecovery-20150119_112204 .fam T .fi .SS START AND STOP PSD With the release of the version 6.x series of psd, the only init system that is officially supported is systemd. Psd ships with a systemd user service to start or stop it (psd.service). Additionally, a provided resync-timer will run an hourly resync from tmpfs back to the disk. The resync-timer is started automatically with psd.service so there is no need to start the timer; only start psd.service. .PP .nf .fam C $ systemctl --user [option] psd.service .fam T .fi Available options: start stop enable disable .SH SUPPORTED BROWSERS .IP \(bu 3 Chromium (stable, beta, and dev) .IP \(bu 3 Conkeror .IP \(bu 3 Epiphany .IP \(bu 3 Falkon .IP \(bu 3 Firefox (stable, beta, and aurora) .IP \(bu 3 Firefox-trunk (this is an Ubuntu-only browser: http://www.webupd8.org/2011/05/install-firefox-nightly-from-ubuntu-ppa.html) .IP \(bu 3 Google Chrome (stable, beta, and dev) .IP \(bu 3 Heftig's version of Aurora (Arch Linux: https://bbs.archlinux.org/viewtopic.php?id=117157) .IP \(bu 3 Icecat .IP \(bu 3 Iceweasel .IP \(bu 3 Inox (https://bbs.archlinux.org/viewtopic.php?id=198763) .IP \(bu 3 Luakit .IP \(bu 3 Midori .IP \(bu 3 Opera (legacy, stable, next, and developer) .IP \(bu 3 Otter-browser .IP \(bu 3 Palemoon .IP \(bu 3 QupZilla .IP \(bu 3 Qutebrowser .IP \(bu 3 Rekonq .IP \(bu 3 Seamonkey .IP \(bu 3 Vivaldi .IP \(bu 3 Vivaldi-snapshot .SH NOTE ON SYMLINKED PROFILES Currently, psd does not support symlinked profiles and will refuse to sync if one is detected. For example, your firefox profile is ~/.mozilla/firefox/f8cv8bfu.default but you have moved that directory to /foo/bar/f8cv8bfu.default and replaced it with symlink: .PP .nf .fam C $ ls -l ~/.mozilla/firefox lrwxrwxrwx 1 facade users 26 Oct 1 17:02 f8cv8bfu.default -> /foo/bar/f8cv8bfu.default .fam T .fi Running psd in preview mode will end in an error in forming you of this: .PP .nf .fam C $ psd p Warning! /home/facade/.mozilla/firefox/f8cv8bfu.default appears to be a symlink but these are not supported. Please make the browser profile a live directory and try again. Exiting. .fam T .fi A proper work around for firefox is to simply edit ~/.mozilla/firefox/profiles.ini defining the canonical path there. One also needs to adjust the IsRelative flag like so: .PP .nf .fam C [Profile0] Name=default IsRelative=0 Path=/foo/bar/f8cv8bfu.default .fam T .fi Other solutions may exist for others browser but documenting them all here is out of scope. .SH SUPPORTED DISTROS Since psd is just a bash script with a systemd service, it should run on any flavor of Linux running systemd. Around a dozen distros provide an official package or user-maintained option to install psd. One can also build psd from source. See the official website for available packages and installation instructions. .SH FAQ Q1: What is overlayfs mode? .PP A1: Overlayfs is a simple union file-system mainlined in the Linux kernel version 3.18.0. When used with psd, a reduced memory footprint and faster sync operations can be realized. The magic is in how the overlay mount only writes out data that has changed rather than the entire profile. The same recovery features psd uses in its default mode are also active when running in overlayfs mode. .PP See the example in the PREVIEW MODE section above which shows a system using overlayfs to illustrate the typical memory savings. Note the "overlayfs size" report compared to the total "profile size" report for each profile. Be aware that these numbers will change depending on just how much new data is written to the profile, but in common use cases, the overlayfs size will always be less than the profile size. .PP Q2: How do I enable overlayfs mode? .PP A2: First, be sure psd is not active or else any changes to the config file will be ignored until it is restarted. Overlayfs mode is enabled with the USE_OVERLAYFS= variable which should be set to "yes" in the config file. Psd will automatically detect the overlayfs version available to the kernel if it is configured to use one of them. It is recommended to run psd in preview mode to verify that the system can in fact use overlayfs (note that Debian 8 currently does not support an overlayfs capable kernel version). .PP Since version 6.05 of psd, users wanting to use this mode MUST have sudo rights without password prompt to /usr/bin/psd-overlay-helper or global sudo rights without password prompt. If the user does not have global rights, add the following line to /etc/sudoers after any other lines defining sudo access. It is recommended to use /usr/bin/visudo as root to set this up: .PP .nf .fam C foo ALL=(ALL) NOPASSWD: /usr/bin/psd-overlay-helper .fam T .fi Q3: Why do I have another browser profile directory "foo-back-ovfs" when I enable overlayfs? .PP A3: The way overlayfs works is to mount a read-only base copy (so-called lower dir) of the profile, and manage the new data on top of that. In order to avoid resyncing to the read-only file system, a copy is used instead. So using overlayfs is a trade off: faster initial sync times and less memory usage vs. disk space in the home dir. .PP Q4: I need more memory to accommodate my profile/profiles in /run/user/xxxx. How can I allocate more? .PP A4: The standard way of controlling the size of /run/user is the RuntimeDirectorySize directive in logind.conf (see the man page for logind.conf for more). By default, 10% of physical memory is used but one can increase it safely. Remember that tmpfs only consumes what is actually used; the number specified here is just a maximum allowed. .PP Q5: My system crashed for some reason and psd didn't sync back. What do I do? .PP A5: The "last good" backup of the browser profile/profiles should be happily on the filesystem. Upon restarting psd (on a reboot for example), a check is preformed to see if the symlink to the tmpfs copy of the profile is invalid. If it is invalid, psd will snapshot the "last good" backup before it rotates it back into place. This is more for a sanity check that psd did no harm and that any data loss was a function of something else. .PP Q6: Where can I find this snapshot? .PP A6: It depends on the browser. The snapshot will be located in the same directory as the browser profile and it will contain a date-time-stamp that corresponds to the time at which the recovery took place. For example, a chromium snapshot will be ~/.config/chromium-backup-crashrecovery-20130912_153310 -- of course, the date_time suffix will be different. .PP Q7: How can I restore the snapshot? .PP A7: Follow these steps: .RS .IP 1. 4 Stop psd. .IP 2. 4 Move the "bad" copy of the profile to a backup (don't blindly delete anything). .IP 3. 4 Copy the snapshot directory to the name that browser expects. .PP Example using chromium: .IP 1. 4 systemctl \fB--user\fP stop psd.service .IP 3. 4 mv ~/.config/chromium ~/.config/chromium-bad .IP 2. 4 cp \fB-a\fP ~/.config/chromium-backup-crashrecovery-20130912_153310 ~/.config/chromium .RE .PP At this point, launch chromium which will use the backup snapshot just copied into place. If all is well, it is safe to delete ~/.config/chromium-bad and the snapshot. Remember, to start psd, no browsers must be open (or psd will refuse to start). .PP Q8: Can psd delete the snapshots automatically? .PP A8: Yes, run psd with the "clean" switch to delete snapshots. .SH CONTRIBUTE Users wishing to contribute to this code, should fork and send a pull request. Source is freely available on the project page linked below. .SH BUGS Discover a bug? Please open an issue on the project page linked below. .RS .IP \(bu 3 Several cases of data loss have been reported when using eCryptFS and psd, therefore until this issue is flushed out, users of eCryptFS are encouraged not to use psd unless willing to help troubleshoot suspected browser corruption. See: https://github.com/graysky2/profile-sync-daemon/issues/158 .SH ONLINE .IP \(bu 3 Project page: https://github.com/graysky2/profile-sync-daemon .IP \(bu 3 Wiki page: https://wiki.archlinux.org/index.php/Profile-sync-daemon .SH AUTHOR graysky (graysky AT archlinux DOT us) profile-sync-daemon-6.34/init/000077500000000000000000000000001340772777000163025ustar00rootroot00000000000000profile-sync-daemon-6.34/init/psd-resync.service000066400000000000000000000003051340772777000217510ustar00rootroot00000000000000[Unit] Description=Timed resync After=psd.service Wants=psd-resync.timer PartOf=psd.service [Service] Type=oneshot ExecStart=/usr/bin/profile-sync-daemon resync [Install] WantedBy=default.target profile-sync-daemon-6.34/init/psd-resync.timer000066400000000000000000000001731340772777000214340ustar00rootroot00000000000000[Unit] Description=Timer for profile-sync-daemon - 1Hour PartOf=psd-resync.service psd.service [Timer] OnUnitActiveSec=1h profile-sync-daemon-6.34/init/psd.service000066400000000000000000000006621340772777000204560ustar00rootroot00000000000000[Unit] Description=Profile-sync-daemon Documentation=man:psd(1) man:profile-sync-daemon(1) Documentation=https://wiki.archlinux.org/index.php/Profile-sync-daemon Wants=psd-resync.service RequiresMountsFor=/home/ After=winbindd.service [Service] Type=oneshot RemainAfterExit=yes # just call /bin/true and let psd-resync.service do it ExecStart=/bin/true ExecStop=/usr/bin/profile-sync-daemon unsync [Install] WantedBy=default.target