Ejemplo n.º 1
0
    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}.')
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
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}'.")
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
    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