def __init__(self, config=None, emborg_opts=(), _queue=None): self.settings = dict() self.do_not_expand = () self.emborg_opts = emborg_opts self.version = tuple(int(p) for p in __version__.split('.')) # reset the logfile so anything logged after this is placed in the # logfile for this config get_informer().set_logfile(LoggingCache()) self.config_dir = to_path(CONFIG_DIR) self.read_config(name=config, queue=_queue) self.check() set_shlib_prefs( encoding=self.encoding if self.encoding else DEFAULT_ENCODING) self.hooks = Hooks(self) self.borg_ran = False # set colorscheme if self.colorscheme: colorscheme = self.colorscheme.lower() if colorscheme == 'none': get_informer().colorscheme = None elif colorscheme in ('light', 'dark'): get_informer().colorscheme = colorscheme else: warn(f'unknown colorscheme: {self.colorscheme}.')
def __enter__(self): # change to working directory working_dir = self.value('working_dir') if not working_dir: working_dir = self.resolve(DEFAULT_WORKING_DIR) self.working_dir = to_path(working_dir) mkdir(self.working_dir) narrate('changing to working_dir:', working_dir) self.starting_dir = cd(self.working_dir).starting_dir # resolve src and dest directories src_dir = self.resolve(self.src_dir) self.src_dir = to_path(src_dir) dest_dir = self.resolve(self.dest_dir) self.dest_dir = to_path(dest_dir) # resolve other files and directories config_dir = self.resolve(CONFIG_DIR) self.config_dir = to_path(config_dir, config_dir) logfile = self.resolve(EMBALM_LOG_FILE) self.logfile = to_path(working_dir, logfile) incr_date_file = self.resolve(INCR_DATE_FILE) self.incr_date_file = to_path(working_dir, incr_date_file) full_date_file = self.resolve(FULL_DATE_FILE) self.full_date_file = to_path(working_dir, full_date_file) restore_dir = self.resolve(RESTORE_DIR) self.restore_dir = to_path(working_dir, restore_dir) archive_dir = self.resolve(ARCHIVE_DIR) self.archive_dir = to_path(working_dir, archive_dir) # perform locking if self.requires_exclusivity: # check for existance of lockfile lockfile = self.lockfile = to_path(working_dir, LOCK_FILE) if lockfile.exists(): raise Error(f'currently running (see {lockfile} for details).') # create lockfile now = arrow.now() pid = os.getpid() lockfile.write_text( dedent(f''' started = {now!s} pid = {pid} ''').lstrip()) # open logfile get_informer().set_logfile(self.logfile) return self
def __enter__(self): # resolve src directories self.src_dirs = [self.resolve_path(d) for d in self.src_dirs] if not self.src_dirs: raise Error('no source directories given.') # resolve repository and archive self.repository = self.resolve_path(self.repository) self.archive = self.resolve(self.archive) # resolve other files and directories data_dir = self.resolve_path(DATA_DIR) self.data_dir = data_dir if not data_dir.exists(): # data dir does not exist, create it self.data_dir.mkdir(mode=0o700, parents=True, exist_ok=True) self.logfile = self.resolve_path(LOG_FILE, data_dir) if 'no-log' not in self.options: self.prev_logfile = self.resolve_path(PREV_LOG_FILE, data_dir) rm(self.prev_logfile) if self.logfile.exists(): mv(self.logfile, self.prev_logfile) self.date_file = self.resolve_path(DATE_FILE, data_dir) # perform locking lockfile = self.lockfile = self.resolve_path(LOCK_FILE, data_dir) if self.requires_exclusivity: # check for existence of lockfile if lockfile.exists(): raise Error(f'currently running (see {lockfile} for details).') # create lockfile now = arrow.now() pid = os.getpid() lockfile.write_text( dedent(f''' started = {now!s} pid = {pid} ''').lstrip()) # open logfile if 'no-log' not in self.options: get_informer().set_logfile(self.logfile) return self
def __enter__(self): # resolve src directories self.src_dirs = [to_path(self.resolve(d)) for d in self.src_dirs] # resolve repository and archive self.repository = self.resolve(self.repository) self.archive = self.resolve(self.archive) # resolve other files and directories config_dir = self.resolve(CONFIG_DIR) self.config_dir = to_path(config_dir, config_dir) logfile = self.resolve(LOG_FILE) self.logfile = to_path(config_dir, logfile) if 'no-log' not in self.options: prev_logfile = self.resolve(PREV_LOG_FILE) self.prev_logfile = to_path(config_dir, prev_logfile) rm(self.prev_logfile) if self.logfile.exists(): mv(self.logfile, self.prev_logfile) date_file = self.resolve(DATE_FILE) self.date_file = to_path(config_dir, date_file) # perform locking lockfile = self.lockfile = to_path(config_dir, self.resolve(LOCK_FILE)) if self.requires_exclusivity: # check for existance of lockfile if lockfile.exists(): raise Error(f'currently running (see {lockfile} for details).') # create lockfile now = arrow.now() pid = os.getpid() lockfile.write_text( dedent(f''' started = {now!s} pid = {pid} ''').lstrip()) # open logfile if 'no-log' not in self.options: get_informer().set_logfile(self.logfile) return self
def publish_scp(config, workspace): """ Copy the archive to one or more remote hosts via `scp`. """ hosts = require_one_or_more(config, 'host') remote_dir = config.get('remote_dir', 'backup/sparekeys') remote_dir = remote_dir.format(**PARAMS) run_flags = 'sOEW' if get_informer().quiet else 'soEW' for host in hosts: try: run(['ssh', host, f'mkdir -p {remote_dir}'], run_flags) run(['scp', '-r', workspace, f'{host}:{remote_dir}'], run_flags) except Error as e: e.reraise(codicil=e.cmd) display(f"Archive copied to '{host}'.")
def load_config(): config_dir = to_path(appdirs.user_config_dir(__slug__)) config_path = config_dir / 'config.toml' inform = get_informer() inform.set_logfile(config_dir / 'log') if not config_path.exists(): display(f"'{config_path}' not found, installing defaults.") defaults = to_path(__file__).parent / 'default_config.toml' mkdir(config_dir) cp(defaults, config_path) try: config = toml.load(config_path) except toml.decoder.TomlDecodeError as e: raise ConfigError(str(e), culprit=config_path) # Set default values for options that are accessed in multiple places: config.setdefault('plugins', {}) config['plugins'].setdefault('archive', []) config['plugins'].setdefault('auth', []) config['plugins'].setdefault('publish', []) return config_path, config
def __enter__(self): # resolve src directories self.src_dirs = self.as_paths("src_dirs", resolve=False) # set repository repository = self.value("repository") if ":" not in repository: # is a local repository repository = to_path(repository) if not repository.is_absolute(): raise Error( "local repository must be specified using an absolute path.", culprit=repository, ) self.repository = repository # default archive if not given if "archive" not in self.settings: if "prefix" not in self.settings: self.settings[ "prefix"] = "{host_name}-{user_name}-{config_name}-" self.settings["archive"] = self.prefix + "{{now}}" # resolve other files and directories data_dir = to_path(DATA_DIR) if not data_dir.exists(): # data dir does not exist, create it data_dir.mkdir(mode=0o700, parents=True, exist_ok=True) self.date_file = data_dir / self.resolve(DATE_FILE) self.data_dir = data_dir # perform locking lockfile = self.lockfile = data_dir / self.resolve(LOCK_FILE) if self.requires_exclusivity: # check for existence of lockfile if lockfile.exists(): report = True try: lock_contents = lockfile.read_text() pid = None for l in lock_contents.splitlines(): name, _, value = l.partition("=") if name.strip().lower() == "pid": pid = int(value.strip()) assert pid > 0 os.kill(pid, 0) except ProcessLookupError as e: if e.errno == errno.ESRCH: report = False # process no longer exists except Exception as e: log("garbled lock file:", e) if report: raise Error( f"currently running (see {lockfile} for details).") # create lockfile now = arrow.now() pid = os.getpid() lockfile.write_text( dedent(f""" started = {now!s} pid = {pid} """).lstrip()) # open logfile # do this after checking lock so we do not overwrite logfile # of emborg process that is currently running self.logfile = data_dir / self.resolve(LOG_FILE) if "no-log" not in self.emborg_opts: self.prev_logfile = data_dir / self.resolve(PREV_LOG_FILE) rm(self.prev_logfile) if self.logfile.exists(): mv(self.logfile, self.prev_logfile) get_informer().set_logfile(self.logfile) log("working dir =", self.working_dir) return self