Skip to content

Commit

Permalink
- Use XDG env vars to override location of config and data dirs
Browse files Browse the repository at this point in the history
- With composite configs, change exception handling to allow remaining
  configs to run after an error from an earlier config
  • Loading branch information
Ken Kundert authored and Ken Kundert committed Aug 28, 2024
1 parent d48516b commit d060647
Show file tree
Hide file tree
Showing 11 changed files with 72 additions and 23 deletions.
11 changes: 6 additions & 5 deletions doc/configuring.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ Configuring
===========

Typically the settings files go in the default location for configuration files
on your system. On Linux systems, that location is ~/.config/emborg. Other
systems use more awkward locations, so while *Emborg* creates initial versions
in the default location, you are free to move them to ~/.config/emborg if you
prefer. *Emborg* always checks for the files in ~/.config/emborg if it exists
before looking in the default location for your system.
on your system. On Linux systems, that location is `~/.config/emborg`. Other
systems use more awkward locations, so *Emborg* allows you to specify the
configuration directory using the `XDG_CONFIG_HOME` environment variable. If
`XDG_CONFIG_HOME` is set to `/home/$HOME/.config`, then the *Emborg*
configuration directory will be `/home/$HOME/.config/emborg`, as on Linux
systems.

You need a shared settings file and then one file for each backup configuration
you need. Except for :ref:`configurations` and :ref:`default_configuration` any
Expand Down
2 changes: 1 addition & 1 deletion doc/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ And this one sends an email:
0 * * * * emborg --mute due --days 1 --mail me@mydomain.com
Alternately, you can use :ref:`emborg-overdue <client_overdue>`.
Alternately, you can use :ref:`emborg-overdue <emborg_overdue>`.


.. _snapshot example:
Expand Down
25 changes: 22 additions & 3 deletions doc/monitoring.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@ Monitoring
==========


Log Files
---------

When there are problems, the log file can help you understand what is going
wrong. *Emborg* writes a log file to the *Emborg* data directory. On Linux
systems that would be `~/.local/share/emborg`. Other systems use more awkward
locations, so *Emborg* allows you to specify the data directory using the
`XDG_DATA_HOME` environment variable. If `XDG_DATA_HOME` is set to
`/home/$HOME/.local/share`, then the *Emborg* log files will be written to
`/home/$HOME/.local/share/emborg`, as on Linux systems.

Besides visiting the *Emborg* data directory and viewing the log file directly,
you can use the :ref:`log command <log>` to view the log file.

*Emborg* overwrites its log file every time it runs. You can use :ref:`ntlog
<ntlog accessory>` to gather log files as they are created into a composite log
file.


Due and Info
------------

Expand All @@ -28,8 +47,9 @@ Checking for Overdue Backups from the Server

*Emborg* contains an additional executable, *emborg-overdue*, that can be run on
the destination server to determine whether the backups have been performed
recently. It reads its own settings file in ~/.config/emborg/overdue.conf that
is also a Python file and may contain the following settings:
recently. It reads its own settings file in `overdue.conf`, contained in the
:ref:`Emborg configuration directory <configuring_emborg>`, that is also
a Python file and may contain the following settings:

.. code-block:: text
Expand Down Expand Up @@ -192,7 +212,6 @@ Alternately you can run *emborg-overdue* from cron.daily (described in the
:ref:`root example <root example>`).



.. _client_overdue:

Checking for Overdue Backups from the Client
Expand Down
18 changes: 17 additions & 1 deletion doc/releases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,26 @@ Latest development release
| Version: 1.40
| Released: 2024-08-05
- Allow location of config and data directory to be overridden with
`XDG_CONFIG_HOME` and `XDG_DATA_HOME` environment variables. This replaces an
earlier behavior that simply treated `~/.config/` as the configuration
directory if it exists. No provision was made previously to support an
alternative data directory.

.. note::

If your configuration files are in `~/.config/emborg` and you are not on
a Linux system you will now have to set `XDG_CONFIG_HOME` to
`$HOME/.config`.

- When *Emborg* encounters an error when operating on a composite configuration
it will terminate the problematic configuration and move to the next.
Previously it would exit without attempting the remaining configs.


1.40 (2024-08-05)
-----------------
- Enhance :ref:`emborg-overdue <emborg-overdue>` command.
- Enhance :ref:`emborg-overdue <emborg_overdue>` command.
- Fix bug in :ref:`restore <restore>` when there are multiple roots.


Expand Down
7 changes: 6 additions & 1 deletion emborg/emborg.py
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,12 @@ def run_user_commands(self, setting):
except Error as e:
if is_str(cmd):
cmd = cmd.split()
e.reraise(culprit=(setting, i, cmd[0]))
if 'before' in setting:
e.reraise(culprit=(setting, i, cmd[0]))
elif 'after' in setting:
e.report(culprit=(setting, i, cmd[0]))
else:
raise NotImplementedError

# the following two statements are only useful from run_before_borg
self.settings[setting] = [] # erase the setting so it is not run again
Expand Down
2 changes: 1 addition & 1 deletion emborg/help.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def help():
Better yet is to simply not store the passphrase. This can be
arranged if you are using Avendesora
(https://github.com/KenKundert/avendesora), which is a flexible
(https://avendesora.readthedocs.io/en/stable), which is a flexible
password management system. The interface to Avendesora is already
built in to Emborg, but its use is optional (it need not be
installed).
Expand Down
2 changes: 1 addition & 1 deletion emborg/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def main():
except Error as e:
exit_status = 2
settings.fail(e, cmd=' '.join(sys.argv))
e.terminate()
e.report()

if exit_status and exit_status > worst_exit_status:
worst_exit_status = exit_status
Expand Down
8 changes: 5 additions & 3 deletions emborg/overdue.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@
-M, --message <msg> Status message template for each repository
--version Show software version
The program requires a configuration file: ~/.config/emborg/overdue.conf. The
contents are described here:
https://emborg.readthedocs.io/en/stable/utilities.html#overdue
The program requires a configuration file, overdue.conf, which should be placed
in the Emborg configuration directory, typically ~/.config/emborg. The contents
are described here:
https://emborg.readthedocs.io/en/stable/monitoring.html#overdue
The message given by --message may contain the following keys in braces:
host: replaced by the host field from the config file, a string.
Expand Down
13 changes: 8 additions & 5 deletions emborg/preferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
# along with this program. If not, see http://www.gnu.org/licenses.

# Imports {{{1
from .shlib import to_path
from appdirs import user_config_dir, user_data_dir
from inform import dedent
import os

# Preferences {{{1
# Constants {{{2
Expand All @@ -32,12 +32,15 @@
# always preferred by users, whereas the directory used by Linux
# (~/.config/emborg) seems to have universal appeal. So, use the Linux path if
# it exists and backstop with the system preferred location.
config_dir = to_path("~/.config/emborg")
if config_dir.exists():
CONFIG_DIR = str(config_dir)

if 'XDG_CONFIG_HOME' in os.environ:
CONFIG_DIR = os.sep.join([os.environ['XDG_CONFIG_HOME'], PROGRAM_NAME])
else:
CONFIG_DIR = user_config_dir(PROGRAM_NAME)
DATA_DIR = user_data_dir(PROGRAM_NAME)
if 'XDG_DATA_HOME' in os.environ:
DATA_DIR = os.sep.join([os.environ['XDG_DATA_HOME'], PROGRAM_NAME])
else:
DATA_DIR = user_data_dir(PROGRAM_NAME)

SETTINGS_FILE = "settings"
OVERDUE_FILE = "overdue.conf"
Expand Down
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ name = "emborg"
version = "1.40"
description = "Borg front end."
readme = "README.rst"
keywords = ["emborg", "borg", "borgmatic", "backups"]
keywords = ["emborg", "borg", "borgbackup", "borgmatic", "vorta", "backups"]
authors = [
{name = "Ken Kundert"},
{email = "emborg@nurdletech.com"}
]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Environment :: Console",
"Intended Audience :: End Users/Desktop",
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Natural Language :: English",
"Operating System :: POSIX :: Linux",
Expand Down
2 changes: 2 additions & 0 deletions tests/test_emborg.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ def initialize(dependency_options):
ln("~/.local/bin", ".local/bin")
ln("~/.local/lib", ".local/lib")
ln("configs", "configs.symlink")
os.environ["XDG_CONFIG_HOME"] = str(f"{cwd()}/.config")
os.environ["XDG_DATA_HOME"] = str(f"{cwd()}/.local/share")
os.environ["HOME"] = str(cwd())
return dependency_options

Expand Down

0 comments on commit d060647

Please sign in to comment.