diff options
56 files changed, 750 insertions, 486 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..26a7c92 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.pc/ diff --git a/Changes.txt b/Changes.txt index a2f9148..f2ed854 100644 --- a/Changes.txt +++ b/Changes.txt @@ -1,3 +1,17 @@ +2019-03-31, S3QL 3.1 + + * Added a new `--fs-name` option to `mount.s3ql` allowing users + to specify a name for the fuse mount (This name is visible + in the first column of the system `mount` command output). + + * Added support for "Onezone-IA" to the S3 backend. + + * The `s3ql_oauth_client` command is working again now (it was + broken due to changes in Google's OAuth2 workflow). + + * Fixed refresh of Google Storage authentication tokens (expired + tokens were resulting in crashes). + 2019-02-09, S3QL 3.0 * Added a new `--systemd` option to simplify running mount.s3ql @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: s3ql -Version: 3.0 +Version: 3.1 Summary: a full-featured file system for online data storage Home-page: https://bitbucket.org/nikratio/s3ql/ Author: Nikolaus Rath diff --git a/contrib/benchmark.py b/contrib/benchmark.py index 2af39a9..3391a68 100755 --- a/contrib/benchmark.py +++ b/contrib/benchmark.py @@ -12,7 +12,7 @@ This work can be distributed under the terms of the GNU GPLv3. ''' import argparse -import atexit +import contextlib import os import shutil import subprocess @@ -34,7 +34,6 @@ from s3ql.logging import logging, setup_logging, QuietError from s3ql.common import get_backend from s3ql.backends.common import DanglingStorageURLError from s3ql.backends.comprenc import ComprencBackend -from s3ql.backends.local import Backend from s3ql import BUFSIZE from s3ql.parse_args import ArgumentParser @@ -50,6 +49,7 @@ def parse_args(args): 'compression speed and determine limiting factor.') parser.add_quiet() + parser.add_log() parser.add_debug() parser.add_backend_options() parser.add_version() @@ -63,6 +63,58 @@ def parse_args(args): return parser.parse_args(args) +def test_write_speed(size, blocksize, cachedir, rnd_fh): + + with contextlib.ExitStack() as mgr: + mnt_dir = tempfile.mkdtemp(prefix='s3ql-mnt') + mgr.callback(shutil.rmtree, mnt_dir) + + backend_dir = tempfile.mkdtemp(prefix='s3ql-benchmark-') + mgr.callback(shutil.rmtree, backend_dir) + + subprocess.check_call([exec_prefix + 'mkfs.s3ql', '--plain', 'local://%s' % backend_dir, + '--quiet', '--cachedir', cachedir]) + subprocess.check_call([exec_prefix + 'mount.s3ql', '--threads', '1', '--quiet', + '--cachesize', '%d' % (2 * size / 1024), '--log', + '%s/mount.log' % backend_dir, '--cachedir', cachedir, + 'local://%s' % backend_dir, mnt_dir]) + try: + write_time = 0 + while write_time < 3: + log.debug('Write took %.3g seconds, retrying', write_time) + size *= 2 + with open('%s/bigfile' % mnt_dir, 'wb', 0) as dst: + rnd_fh.seek(0) + write_time = time.time() + copied = 0 + while copied < size: + buf = rnd_fh.read(blocksize) + if not buf: + rnd_fh.seek(0) + continue + dst.write(buf) + copied += len(buf) + write_time = time.time() - write_time + os.unlink('%s/bigfile' % mnt_dir) + finally: + subprocess.check_call([exec_prefix + 'umount.s3ql', mnt_dir]) + + return copied / write_time + + +class MockBackend: + def open_write(key, metadata=None, is_compressed=False): + return MockFH() + + +class MockFH: + def write(self, buf): + pass + + def close(self): + pass + + def main(args=None): if args is None: args = sys.argv[1:] @@ -81,43 +133,10 @@ def main(args=None): copied += len(buf) log.info('Measuring throughput to cache...') - backend_dir = tempfile.mkdtemp(prefix='s3ql-benchmark-') - mnt_dir = tempfile.mkdtemp(prefix='s3ql-mnt') - atexit.register(shutil.rmtree, backend_dir) - atexit.register(shutil.rmtree, mnt_dir) - block_sizes = [ 2**b for b in range(12, 18) ] for blocksize in block_sizes: - write_time = 0 size = 50 * 1024 * 1024 - while write_time < 3: - log.debug('Write took %.3g seconds, retrying', write_time) - subprocess.check_call([exec_prefix + 'mkfs.s3ql', '--plain', 'local://%s' % backend_dir, - '--quiet', '--force', '--cachedir', options.cachedir]) - subprocess.check_call([exec_prefix + 'mount.s3ql', '--threads', '1', '--quiet', - '--cachesize', '%d' % (2 * size / 1024), '--log', - '%s/mount.log' % backend_dir, '--cachedir', options.cachedir, - 'local://%s' % backend_dir, mnt_dir]) - try: - size *= 2 - with open('%s/bigfile' % mnt_dir, 'wb', 0) as dst: - rnd_fh.seek(0) - write_time = time.time() - copied = 0 - while copied < size: - buf = rnd_fh.read(blocksize) - if not buf: - rnd_fh.seek(0) - continue - dst.write(buf) - copied += len(buf) - - write_time = time.time() - write_time - os.unlink('%s/bigfile' % mnt_dir) - finally: - subprocess.check_call([exec_prefix + 'umount.s3ql', mnt_dir]) - - fuse_speed = copied / write_time + fuse_speed = test_write_speed(size, blocksize, options.cachedir, rnd_fh) log.info('Cache throughput with %3d KiB blocks: %d KiB/sec', blocksize / 1024, fuse_speed / 1024) @@ -159,7 +178,7 @@ def main(args=None): out_speed = dict() for alg in ALGS: log.info('compressing with %s-6...', alg) - backend = ComprencBackend(b'pass', (alg, 6),Backend(argparse.Namespace(storage_url='local://' + backend_dir))) + backend = ComprencBackend(b'pass', (alg, 6), MockBackend()) def do_write(dst): #pylint: disable=E0102 src.seek(0) stamp = time.time() @@ -188,7 +207,7 @@ def main(args=None): threads.add(options.threads) print('%-26s' % 'Threads:', - ('%12d' * len(threads)) % tuple(sorted(threads))) + ('%16d' * len(threads)) % tuple(sorted(threads))) for alg in ALGS: speeds = [] @@ -209,9 +228,9 @@ def main(args=None): speeds.append(speed / 1024) print('%-26s' % ('Max FS throughput (%s):' % alg), - ('%7d KiB/s' * len(threads)) % tuple(speeds)) + ('%10d KiB/s' * len(threads)) % tuple(speeds)) print('%-26s' % '..limited by:', - ('%12s' * len(threads)) % tuple(limits)) + ('%16s' * len(threads)) % tuple(limits)) print('') print('All numbers assume that the test file is representative and that', diff --git a/contrib/clone_fs.py b/contrib/clone_fs.py index 389630c..6b78d55 100755 --- a/contrib/clone_fs.py +++ b/contrib/clone_fs.py @@ -39,6 +39,7 @@ def parse_args(args): description='Clone an S3QL file system.') parser.add_quiet() + parser.add_log() parser.add_debug() parser.add_backend_options() parser.add_version() diff --git a/contrib/expire_backups.1 b/contrib/expire_backups.1 index 940edb2..2903214 100644 --- a/contrib/expire_backups.1 +++ b/contrib/expire_backups.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "EXPIRE_BACKUPS" "1" "Feb 09, 2019" "3.0" "S3QL" +.TH "EXPIRE_BACKUPS" "1" "Mar 31, 2019" "3.1" "S3QL" .SH NAME expire_backups \- Intelligently expire old backups . @@ -130,6 +130,14 @@ The \fBexpire_backups\fP command accepts the following options: .B \-\-quiet be really quiet .TP +.BI \-\-log \ <target> +Destination for log messages. Specify \fBnone\fP for +standard output or \fBsyslog\fP for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\fBNone\fP +.TP .BI \-\-debug\-modules \ <modules> Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages diff --git a/contrib/expire_backups.py b/contrib/expire_backups.py index 3f7c159..aebab85 100755 --- a/contrib/expire_backups.py +++ b/contrib/expire_backups.py @@ -51,6 +51,7 @@ def parse_args(args): ''')) parser.add_quiet() + parser.add_log() parser.add_debug() parser.add_version() diff --git a/contrib/pcp.1 b/contrib/pcp.1 index 3018d30..c420988 100644 --- a/contrib/pcp.1 +++ b/contrib/pcp.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "PCP" "1" "Feb 09, 2019" "3.0" "S3QL" +.TH "PCP" "1" "Mar 31, 2019" "3.1" "S3QL" .SH NAME pcp \- Recursive, parallel copy of directory trees . @@ -58,6 +58,14 @@ The \fBpcp\fP command accepts the following options: .INDENT 3.5 .INDENT 0.0 .TP +.BI \-\-log \ <target> +Destination for log messages. Specify \fBnone\fP for +standard output or \fBsyslog\fP for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\fBNone\fP +.TP .B \-\-quiet be really quiet .TP diff --git a/contrib/pcp.py b/contrib/pcp.py index f18699a..c192add 100755 --- a/contrib/pcp.py +++ b/contrib/pcp.py @@ -33,6 +33,7 @@ def parse_args(args): description='Recursively copy source(s) to destination using multiple ' 'parallel rsync processes.') + parser.add_log() parser.add_quiet() parser.add_debug() parser.add_version() diff --git a/contrib/remove_objects.py b/contrib/remove_objects.py index 3e53def..1d96a2f 100755 --- a/contrib/remove_objects.py +++ b/contrib/remove_objects.py @@ -32,6 +32,7 @@ def parse_args(args): parser.add_storage_url() parser.add_quiet() + parser.add_log() parser.add_debug() parser.add_backend_options() parser.add_version() diff --git a/contrib/scramble_db.py b/contrib/scramble_db.py index 11ba09d..70fcf4c 100755 --- a/contrib/scramble_db.py +++ b/contrib/scramble_db.py @@ -44,6 +44,7 @@ def parse_args(args): "This is intended to preserve privacy when a metadata copy " "needs to be provided to the developers for debugging.") + parser.add_log() parser.add_debug() parser.add_quiet() parser.add_version() diff --git a/debian/changelog b/debian/changelog index 1dde460..c2947e0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +s3ql (3.1+dfsg-1) unstable; urgency=medium + + * New upstream release. + + -- Nikolaus Rath <Nikolaus@rath.org> Sat, 06 Apr 2019 16:28:05 +0100 + s3ql (3.0+dfsg-1) unstable; urgency=medium * New upstream release. diff --git a/debian/patches/auto-gitignore b/debian/patches/auto-gitignore new file mode 100644 index 0000000..a7a4674 --- /dev/null +++ b/debian/patches/auto-gitignore @@ -0,0 +1,15 @@ +Subject: Update .gitignore from Debian packaging branch + +The Debian packaging git branch contains these updates to the upstream +.gitignore file(s). This patch is autogenerated, to provide these +updates to users of the official Debian archive view of the package. + +[dgit (3.11~deb9u1) update-gitignore] +--- +diff --git a/.gitignore b/.gitignore +new file mode 100644 +index 0000000..26a7c92 +--- /dev/null ++++ b/.gitignore +@@ -0,0 +1 @@ ++/.pc/ diff --git a/debian/patches/series b/debian/patches/series index 05b8717..f349004 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,3 +1,4 @@ proc_mount.diff clock-granularity.diff show_pdflatex_output.diff +auto-gitignore diff --git a/debian/patches/show_pdflatex_output.diff b/debian/patches/show_pdflatex_output.diff index 9e49722..b8269f3 100644 --- a/debian/patches/show_pdflatex_output.diff +++ b/debian/patches/show_pdflatex_output.diff @@ -12,10 +12,10 @@ Upstream is not interested in this patch. 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py -index 4f28bd3..7d2dc48 100755 +index 02964e1..ee7a257 100755 --- a/setup.py +++ b/setup.py -@@ -98,9 +98,8 @@ class build_docs(setuptools.Command): +@@ -99,9 +99,8 @@ class build_docs(setuptools.Command): print('Running pdflatex...') for _ in range(3): diff --git a/doc/latex/manual.aux b/doc/latex/manual.aux index 2ee1ba1..50e86ad 100644 --- a/doc/latex/manual.aux +++ b/doc/latex/manual.aux @@ -65,24 +65,25 @@ \newlabel{backends:cmdoption-s3-backend-arg-tcp-timeout}{{3.2}{8}{Amazon S3}{section*.7}{}} \newlabel{backends:cmdoption-s3-backend-arg-sse}{{3.2}{8}{Amazon S3}{section*.8}{}} \newlabel{backends:cmdoption-s3-backend-arg-ia}{{3.2}{8}{Amazon S3}{section*.9}{}} -\newlabel{backends:cmdoption-s3-backend-arg-rrs}{{3.2}{8}{Amazon S3}{section*.10}{}} +\newlabel{backends:cmdoption-s3-backend-arg-oia}{{3.2}{8}{Amazon S3}{section*.10}{}} +\newlabel{backends:cmdoption-s3-backend-arg-rrs}{{3.2}{8}{Amazon S3}{section*.11}{}} \@writefile{toc}{\contentsline {section}{\numberline {3.3}OpenStack/Swift}{9}{section.3.3}} \newlabel{backends:openstack-swift}{{3.3}{9}{OpenStack/Swift}{section.3.3}{}} \newlabel{backends:openstack-backend}{{3.3}{9}{OpenStack/Swift}{section.3.3}{}} -\newlabel{backends:cmdoption-swift-backend-arg-no-ssl}{{3.3}{9}{OpenStack/Swift}{section*.11}{}} -\newlabel{backends:cmdoption-swift-backend-arg-ssl-ca-path}{{3.3}{9}{OpenStack/Swift}{section*.12}{}} -\newlabel{backends:cmdoption-swift-backend-arg-tcp-timeout}{{3.3}{9}{OpenStack/Swift}{section*.13}{}} -\newlabel{backends:cmdoption-swift-backend-arg-disable-expect100}{{3.3}{9}{OpenStack/Swift}{section*.14}{}} -\newlabel{backends:cmdoption-swift-backend-arg-no-feature-detection}{{3.3}{9}{OpenStack/Swift}{section*.15}{}} +\newlabel{backends:cmdoption-swift-backend-arg-no-ssl}{{3.3}{9}{OpenStack/Swift}{section*.12}{}} +\newlabel{backends:cmdoption-swift-backend-arg-ssl-ca-path}{{3.3}{9}{OpenStack/Swift}{section*.13}{}} +\newlabel{backends:cmdoption-swift-backend-arg-tcp-timeout}{{3.3}{9}{OpenStack/Swift}{section*.14}{}} +\newlabel{backends:cmdoption-swift-backend-arg-disable-expect100}{{3.3}{9}{OpenStack/Swift}{section*.15}{}} +\newlabel{backends:cmdoption-swift-backend-arg-no-feature-detection}{{3.3}{9}{OpenStack/Swift}{section*.16}{}} \@writefile{toc}{\contentsline {section}{\numberline {3.4}Rackspace CloudFiles}{10}{section.3.4}} \newlabel{backends:rackspace-cloudfiles}{{3.4}{10}{Rackspace CloudFiles}{section.3.4}{}} \@writefile{toc}{\contentsline {section}{\numberline {3.5}S3 compatible}{10}{section.3.5}} \newlabel{backends:s3-compatible}{{3.5}{10}{S3 compatible}{section.3.5}{}} -\newlabel{backends:cmdoption-s3c-backend-arg-no-ssl}{{3.5}{10}{S3 compatible}{section*.16}{}} -\newlabel{backends:cmdoption-s3c-backend-arg-ssl-ca-path}{{3.5}{10}{S3 compatible}{section*.17}{}} -\newlabel{backends:cmdoption-s3c-backend-arg-tcp-timeout}{{3.5}{10}{S3 compatible}{section*.18}{}} -\newlabel{backends:cmdoption-s3c-backend-arg-disable-expect100}{{3.5}{10}{S3 compatible}{section*.19}{}} -\newlabel{backends:cmdoption-s3c-backend-arg-dumb-copy}{{3.5}{10}{S3 compatible}{section*.20}{}} +\newlabel{backends:cmdoption-s3c-backend-arg-no-ssl}{{3.5}{10}{S3 compatible}{section*.17}{}} +\newlabel{backends:cmdoption-s3c-backend-arg-ssl-ca-path}{{3.5}{10}{S3 compatible}{section*.18}{}} +\newlabel{backends:cmdoption-s3c-backend-arg-tcp-timeout}{{3.5}{10}{S3 compatible}{section*.19}{}} +\newlabel{backends:cmdoption-s3c-backend-arg-disable-expect100}{{3.5}{10}{S3 compatible}{section*.20}{}} +\newlabel{backends:cmdoption-s3c-backend-arg-dumb-copy}{{3.5}{10}{S3 compatible}{section*.21}{}} \@writefile{toc}{\contentsline {section}{\numberline {3.6}Local}{11}{section.3.6}} \newlabel{backends:local}{{3.6}{11}{Local}{section.3.6}{}} \@writefile{toc}{\contentsline {chapter}{\numberline {4}Important Rules to Avoid Losing Data}{13}{chapter.4}} @@ -275,8 +276,8 @@ \newlabel{man/adm::doc}{{16.2}{52}{The \sphinxstyleliteralstrong {\sphinxupquote {s3qladm}} command}{section.16.2}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.2.1}Synopsis}{52}{subsection.16.2.1}} \newlabel{man/adm:synopsis}{{16.2.1}{52}{Synopsis}{subsection.16.2.1}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.2.2}Description}{52}{subsection.16.2.2}} -\newlabel{man/adm:description}{{16.2.2}{52}{Description}{subsection.16.2.2}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.2.2}Description}{53}{subsection.16.2.2}} +\newlabel{man/adm:description}{{16.2.2}{53}{Description}{subsection.16.2.2}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.2.3}Options}{53}{subsection.16.2.3}} \newlabel{man/adm:options}{{16.2.3}{53}{Options}{subsection.16.2.3}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.2.4}Actions}{53}{subsection.16.2.4}} @@ -303,8 +304,8 @@ \newlabel{man/stat::doc}{{16.4}{56}{The \sphinxstyleliteralstrong {\sphinxupquote {s3qlstat}} command}{section.16.4}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.4.1}Synopsis}{56}{subsection.16.4.1}} \newlabel{man/stat:synopsis}{{16.4.1}{56}{Synopsis}{subsection.16.4.1}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.4.2}Description}{56}{subsection.16.4.2}} -\newlabel{man/stat:description}{{16.4.2}{56}{Description}{subsection.16.4.2}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.4.2}Description}{57}{subsection.16.4.2}} +\newlabel{man/stat:description}{{16.4.2}{57}{Description}{subsection.16.4.2}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.4.3}Options}{57}{subsection.16.4.3}} \newlabel{man/stat:options}{{16.4.3}{57}{Options}{subsection.16.4.3}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.4.4}Exit Codes}{57}{subsection.16.4.4}} @@ -316,27 +317,27 @@ \newlabel{man/ctrl::doc}{{16.5}{57}{The \sphinxstyleliteralstrong {\sphinxupquote {s3qlctrl}} command}{section.16.5}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.5.1}Synopsis}{57}{subsection.16.5.1}} \newlabel{man/ctrl:synopsis}{{16.5.1}{57}{Synopsis}{subsection.16.5.1}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.5.2}Description}{57}{subsection.16.5.2}} -\newlabel{man/ctrl:description}{{16.5.2}{57}{Description}{subsection.16.5.2}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.5.2}Description}{58}{subsection.16.5.2}} +\newlabel{man/ctrl:description}{{16.5.2}{58}{Description}{subsection.16.5.2}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.5.3}Options}{58}{subsection.16.5.3}} \newlabel{man/ctrl:options}{{16.5.3}{58}{Options}{subsection.16.5.3}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.5.4}Exit Codes}{58}{subsection.16.5.4}} \newlabel{man/ctrl:exit-codes}{{16.5.4}{58}{Exit Codes}{subsection.16.5.4}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.5.5}See Also}{58}{subsection.16.5.5}} -\newlabel{man/ctrl:see-also}{{16.5.5}{58}{See Also}{subsection.16.5.5}{}} -\@writefile{toc}{\contentsline {section}{\numberline {16.6}The \sphinxstyleliteralstrong {\sphinxupquote {s3qlcp}} command}{58}{section.16.6}} -\newlabel{man/cp:the-command-command}{{16.6}{58}{The \sphinxstyleliteralstrong {\sphinxupquote {s3qlcp}} command}{section.16.6}{}} -\newlabel{man/cp::doc}{{16.6}{58}{The \sphinxstyleliteralstrong {\sphinxupquote {s3qlcp}} command}{section.16.6}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.6.1}Synopsis}{58}{subsection.16.6.1}} -\newlabel{man/cp:synopsis}{{16.6.1}{58}{Synopsis}{subsection.16.6.1}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.5.5}See Also}{59}{subsection.16.5.5}} +\newlabel{man/ctrl:see-also}{{16.5.5}{59}{See Also}{subsection.16.5.5}{}} +\@writefile{toc}{\contentsline {section}{\numberline {16.6}The \sphinxstyleliteralstrong {\sphinxupquote {s3qlcp}} command}{59}{section.16.6}} +\newlabel{man/cp:the-command-command}{{16.6}{59}{The \sphinxstyleliteralstrong {\sphinxupquote {s3qlcp}} command}{section.16.6}{}} +\newlabel{man/cp::doc}{{16.6}{59}{The \sphinxstyleliteralstrong {\sphinxupquote {s3qlcp}} command}{section.16.6}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.6.1}Synopsis}{59}{subsection.16.6.1}} +\newlabel{man/cp:synopsis}{{16.6.1}{59}{Synopsis}{subsection.16.6.1}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.6.2}Description}{59}{subsection.16.6.2}} \newlabel{man/cp:description}{{16.6.2}{59}{Description}{subsection.16.6.2}{}} -\@writefile{toc}{\contentsline {subsubsection}{Snapshotting vs Hardlinking}{59}{subsubsection*.21}} -\newlabel{man/cp:snapshotting-vs-hardlinking}{{16.6.2}{59}{Snapshotting vs Hardlinking}{subsubsection*.21}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.6.3}Options}{59}{subsection.16.6.3}} -\newlabel{man/cp:options}{{16.6.3}{59}{Options}{subsection.16.6.3}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.6.4}Exit Codes}{59}{subsection.16.6.4}} -\newlabel{man/cp:exit-codes}{{16.6.4}{59}{Exit Codes}{subsection.16.6.4}{}} +\@writefile{toc}{\contentsline {subsubsection}{Snapshotting vs Hardlinking}{59}{subsubsection*.22}} +\newlabel{man/cp:snapshotting-vs-hardlinking}{{16.6.2}{59}{Snapshotting vs Hardlinking}{subsubsection*.22}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.6.3}Options}{60}{subsection.16.6.3}} +\newlabel{man/cp:options}{{16.6.3}{60}{Options}{subsection.16.6.3}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.6.4}Exit Codes}{60}{subsection.16.6.4}} +\newlabel{man/cp:exit-codes}{{16.6.4}{60}{Exit Codes}{subsection.16.6.4}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.6.5}See Also}{60}{subsection.16.6.5}} \newlabel{man/cp:see-also}{{16.6.5}{60}{See Also}{subsection.16.6.5}{}} \@writefile{toc}{\contentsline {section}{\numberline {16.7}The \sphinxstyleliteralstrong {\sphinxupquote {s3qlrm}} command}{60}{section.16.7}} @@ -346,10 +347,10 @@ \newlabel{man/rm:synopsis}{{16.7.1}{60}{Synopsis}{subsection.16.7.1}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.7.2}Description}{60}{subsection.16.7.2}} \newlabel{man/rm:description}{{16.7.2}{60}{Description}{subsection.16.7.2}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.7.3}Options}{60}{subsection.16.7.3}} -\newlabel{man/rm:options}{{16.7.3}{60}{Options}{subsection.16.7.3}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.7.4}Exit Codes}{60}{subsection.16.7.4}} -\newlabel{man/rm:exit-codes}{{16.7.4}{60}{Exit Codes}{subsection.16.7.4}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.7.3}Options}{61}{subsection.16.7.3}} +\newlabel{man/rm:options}{{16.7.3}{61}{Options}{subsection.16.7.3}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.7.4}Exit Codes}{61}{subsection.16.7.4}} +\newlabel{man/rm:exit-codes}{{16.7.4}{61}{Exit Codes}{subsection.16.7.4}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.7.5}See Also}{61}{subsection.16.7.5}} \newlabel{man/rm:see-also}{{16.7.5}{61}{See Also}{subsection.16.7.5}{}} \@writefile{toc}{\contentsline {section}{\numberline {16.8}The \sphinxstyleliteralstrong {\sphinxupquote {s3qllock}} command}{61}{section.16.8}} @@ -359,114 +360,114 @@ \newlabel{man/lock:synopsis}{{16.8.1}{61}{Synopsis}{subsection.16.8.1}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.8.2}Description}{61}{subsection.16.8.2}} \newlabel{man/lock:description}{{16.8.2}{61}{Description}{subsection.16.8.2}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.8.3}Rationale}{61}{subsection.16.8.3}} -\newlabel{man/lock:rationale}{{16.8.3}{61}{Rationale}{subsection.16.8.3}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.8.4}Options}{61}{subsection.16.8.4}} -\newlabel{man/lock:options}{{16.8.4}{61}{Options}{subsection.16.8.4}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.8.3}Rationale}{62}{subsection.16.8.3}} +\newlabel{man/lock:rationale}{{16.8.3}{62}{Rationale}{subsection.16.8.3}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.8.4}Options}{62}{subsection.16.8.4}} +\newlabel{man/lock:options}{{16.8.4}{62}{Options}{subsection.16.8.4}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.8.5}Exit Codes}{62}{subsection.16.8.5}} \newlabel{man/lock:exit-codes}{{16.8.5}{62}{Exit Codes}{subsection.16.8.5}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.8.6}See Also}{62}{subsection.16.8.6}} \newlabel{man/lock:see-also}{{16.8.6}{62}{See Also}{subsection.16.8.6}{}} -\@writefile{toc}{\contentsline {section}{\numberline {16.9}The \sphinxstyleliteralstrong {\sphinxupquote {umount.s3ql}} command}{62}{section.16.9}} -\newlabel{man/umount:the-command-command}{{16.9}{62}{The \sphinxstyleliteralstrong {\sphinxupquote {umount.s3ql}} command}{section.16.9}{}} -\newlabel{man/umount::doc}{{16.9}{62}{The \sphinxstyleliteralstrong {\sphinxupquote {umount.s3ql}} command}{section.16.9}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.9.1}Synopsis}{62}{subsection.16.9.1}} -\newlabel{man/umount:synopsis}{{16.9.1}{62}{Synopsis}{subsection.16.9.1}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.9.2}Description}{62}{subsection.16.9.2}} -\newlabel{man/umount:description}{{16.9.2}{62}{Description}{subsection.16.9.2}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.9.3}Options}{62}{subsection.16.9.3}} -\newlabel{man/umount:options}{{16.9.3}{62}{Options}{subsection.16.9.3}{}} +\@writefile{toc}{\contentsline {section}{\numberline {16.9}The \sphinxstyleliteralstrong {\sphinxupquote {umount.s3ql}} command}{63}{section.16.9}} +\newlabel{man/umount:the-command-command}{{16.9}{63}{The \sphinxstyleliteralstrong {\sphinxupquote {umount.s3ql}} command}{section.16.9}{}} +\newlabel{man/umount::doc}{{16.9}{63}{The \sphinxstyleliteralstrong {\sphinxupquote {umount.s3ql}} command}{section.16.9}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.9.1}Synopsis}{63}{subsection.16.9.1}} +\newlabel{man/umount:synopsis}{{16.9.1}{63}{Synopsis}{subsection.16.9.1}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.9.2}Description}{63}{subsection.16.9.2}} +\newlabel{man/umount:description}{{16.9.2}{63}{Description}{subsection.16.9.2}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.9.3}Options}{63}{subsection.16.9.3}} +\newlabel{man/umount:options}{{16.9.3}{63}{Options}{subsection.16.9.3}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.9.4}Exit Codes}{63}{subsection.16.9.4}} \newlabel{man/umount:exit-codes}{{16.9.4}{63}{Exit Codes}{subsection.16.9.4}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.9.5}See Also}{63}{subsection.16.9.5}} -\newlabel{man/umount:see-also}{{16.9.5}{63}{See Also}{subsection.16.9.5}{}} -\@writefile{toc}{\contentsline {section}{\numberline {16.10}The \sphinxstyleliteralstrong {\sphinxupquote {fsck.s3ql}} command}{63}{section.16.10}} -\newlabel{man/fsck:the-command-command}{{16.10}{63}{The \sphinxstyleliteralstrong {\sphinxupquote {fsck.s3ql}} command}{section.16.10}{}} -\newlabel{man/fsck::doc}{{16.10}{63}{The \sphinxstyleliteralstrong {\sphinxupquote {fsck.s3ql}} command}{section.16.10}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.10.1}Synopsis}{63}{subsection.16.10.1}} -\newlabel{man/fsck:synopsis}{{16.10.1}{63}{Synopsis}{subsection.16.10.1}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.10.2}Description}{63}{subsection.16.10.2}} -\newlabel{man/fsck:description}{{16.10.2}{63}{Description}{subsection.16.10.2}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.10.3}Options}{63}{subsection.16.10.3}} -\newlabel{man/fsck:options}{{16.10.3}{63}{Options}{subsection.16.10.3}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.10.4}Exit Codes}{64}{subsection.16.10.4}} -\newlabel{man/fsck:exit-codes}{{16.10.4}{64}{Exit Codes}{subsection.16.10.4}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.9.5}See Also}{64}{subsection.16.9.5}} +\newlabel{man/umount:see-also}{{16.9.5}{64}{See Also}{subsection.16.9.5}{}} +\@writefile{toc}{\contentsline {section}{\numberline {16.10}The \sphinxstyleliteralstrong {\sphinxupquote {fsck.s3ql}} command}{64}{section.16.10}} +\newlabel{man/fsck:the-command-command}{{16.10}{64}{The \sphinxstyleliteralstrong {\sphinxupquote {fsck.s3ql}} command}{section.16.10}{}} +\newlabel{man/fsck::doc}{{16.10}{64}{The \sphinxstyleliteralstrong {\sphinxupquote {fsck.s3ql}} command}{section.16.10}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.10.1}Synopsis}{64}{subsection.16.10.1}} +\newlabel{man/fsck:synopsis}{{16.10.1}{64}{Synopsis}{subsection.16.10.1}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.10.2}Description}{64}{subsection.16.10.2}} +\newlabel{man/fsck:description}{{16.10.2}{64}{Description}{subsection.16.10.2}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.10.3}Options}{64}{subsection.16.10.3}} +\newlabel{man/fsck:options}{{16.10.3}{64}{Options}{subsection.16.10.3}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.10.4}Exit Codes}{65}{subsection.16.10.4}} +\newlabel{man/fsck:exit-codes}{{16.10.4}{65}{Exit Codes}{subsection.16.10.4}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.10.5}See Also}{65}{subsection.16.10.5}} \newlabel{man/fsck:see-also}{{16.10.5}{65}{See Also}{subsection.16.10.5}{}} -\@writefile{toc}{\contentsline {section}{\numberline {16.11}The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{65}{section.16.11}} -\newlabel{man/oauth_client:the-command-command}{{16.11}{65}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{section.16.11}{}} -\newlabel{man/oauth_client:oauth-client}{{16.11}{65}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{section.16.11}{}} -\newlabel{man/oauth_client::doc}{{16.11}{65}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{section.16.11}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.11.1}Synopsis}{65}{subsection.16.11.1}} -\newlabel{man/oauth_client:synopsis}{{16.11.1}{65}{Synopsis}{subsection.16.11.1}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.11.2}Description}{65}{subsection.16.11.2}} -\newlabel{man/oauth_client:description}{{16.11.2}{65}{Description}{subsection.16.11.2}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.11.3}Options}{65}{subsection.16.11.3}} -\newlabel{man/oauth_client:options}{{16.11.3}{65}{Options}{subsection.16.11.3}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.11.4}Exit Codes}{65}{subsection.16.11.4}} -\newlabel{man/oauth_client:exit-codes}{{16.11.4}{65}{Exit Codes}{subsection.16.11.4}{}} +\@writefile{toc}{\contentsline {section}{\numberline {16.11}The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{66}{section.16.11}} +\newlabel{man/oauth_client:the-command-command}{{16.11}{66}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{section.16.11}{}} +\newlabel{man/oauth_client:oauth-client}{{16.11}{66}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{section.16.11}{}} +\newlabel{man/oauth_client::doc}{{16.11}{66}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{section.16.11}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.11.1}Synopsis}{66}{subsection.16.11.1}} +\newlabel{man/oauth_client:synopsis}{{16.11.1}{66}{Synopsis}{subsection.16.11.1}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.11.2}Description}{66}{subsection.16.11.2}} +\newlabel{man/oauth_client:description}{{16.11.2}{66}{Description}{subsection.16.11.2}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.11.3}Options}{66}{subsection.16.11.3}} +\newlabel{man/oauth_client:options}{{16.11.3}{66}{Options}{subsection.16.11.3}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.11.4}Exit Codes}{66}{subsection.16.11.4}} +\newlabel{man/oauth_client:exit-codes}{{16.11.4}{66}{Exit Codes}{subsection.16.11.4}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.11.5}See Also}{66}{subsection.16.11.5}} \newlabel{man/oauth_client:see-also}{{16.11.5}{66}{See Also}{subsection.16.11.5}{}} -\@writefile{toc}{\contentsline {section}{\numberline {16.12}The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_verify}} command}{66}{section.16.12}} -\newlabel{man/verify:the-command-command}{{16.12}{66}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_verify}} command}{section.16.12}{}} -\newlabel{man/verify::doc}{{16.12}{66}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_verify}} command}{section.16.12}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.12.1}Synopsis}{66}{subsection.16.12.1}} -\newlabel{man/verify:synopsis}{{16.12.1}{66}{Synopsis}{subsection.16.12.1}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.12.2}Description}{66}{subsection.16.12.2}} -\newlabel{man/verify:description}{{16.12.2}{66}{Description}{subsection.16.12.2}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.12.3}Options}{66}{subsection.16.12.3}} -\newlabel{man/verify:options}{{16.12.3}{66}{Options}{subsection.16.12.3}{}} +\@writefile{toc}{\contentsline {section}{\numberline {16.12}The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_verify}} command}{67}{section.16.12}} +\newlabel{man/verify:the-command-command}{{16.12}{67}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_verify}} command}{section.16.12}{}} +\newlabel{man/verify::doc}{{16.12}{67}{The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_verify}} command}{section.16.12}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.12.1}Synopsis}{67}{subsection.16.12.1}} +\newlabel{man/verify:synopsis}{{16.12.1}{67}{Synopsis}{subsection.16.12.1}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.12.2}Description}{67}{subsection.16.12.2}} +\newlabel{man/verify:description}{{16.12.2}{67}{Description}{subsection.16.12.2}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.12.3}Options}{67}{subsection.16.12.3}} +\newlabel{man/verify:options}{{16.12.3}{67}{Options}{subsection.16.12.3}{}} \@writefile{toc}{\contentsline {subsection}{\numberline {16.12.4}Exit Codes}{67}{subsection.16.12.4}} \newlabel{man/verify:exit-codes}{{16.12.4}{67}{Exit Codes}{subsection.16.12.4}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.12.5}See Also}{67}{subsection.16.12.5}} -\newlabel{man/verify:see-also}{{16.12.5}{67}{See Also}{subsection.16.12.5}{}} -\@writefile{toc}{\contentsline {section}{\numberline {16.13}The \sphinxstyleliteralstrong {\sphinxupquote {pcp}} command}{67}{section.16.13}} -\newlabel{man/pcp:the-command-command}{{16.13}{67}{The \sphinxstyleliteralstrong {\sphinxupquote {pcp}} command}{section.16.13}{}} -\newlabel{man/pcp::doc}{{16.13}{67}{The \sphinxstyleliteralstrong {\sphinxupquote {pcp}} command}{section.16.13}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.1}Synopsis}{67}{subsection.16.13.1}} -\newlabel{man/pcp:synopsis}{{16.13.1}{67}{Synopsis}{subsection.16.13.1}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.2}Description}{67}{subsection.16.13.2}} -\newlabel{man/pcp:description}{{16.13.2}{67}{Description}{subsection.16.13.2}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.3}Options}{68}{subsection.16.13.3}} -\newlabel{man/pcp:options}{{16.13.3}{68}{Options}{subsection.16.13.3}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.4}Exit Codes}{68}{subsection.16.13.4}} -\newlabel{man/pcp:exit-codes}{{16.13.4}{68}{Exit Codes}{subsection.16.13.4}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.5}See Also}{68}{subsection.16.13.5}} -\newlabel{man/pcp:see-also}{{16.13.5}{68}{See Also}{subsection.16.13.5}{}} -\@writefile{toc}{\contentsline {section}{\numberline {16.14}The \sphinxstyleliteralstrong {\sphinxupquote {expire\_backups}} command}{68}{section.16.14}} -\newlabel{man/expire_backups:the-command-command}{{16.14}{68}{The \sphinxstyleliteralstrong {\sphinxupquote {expire\_backups}} command}{section.16.14}{}} -\newlabel{man/expire_backups::doc}{{16.14}{68}{The \sphinxstyleliteralstrong {\sphinxupquote {expire\_backups}} command}{section.16.14}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.1}Synopsis}{68}{subsection.16.14.1}} -\newlabel{man/expire_backups:synopsis}{{16.14.1}{68}{Synopsis}{subsection.16.14.1}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.2}Description}{68}{subsection.16.14.2}} -\newlabel{man/expire_backups:description}{{16.14.2}{68}{Description}{subsection.16.14.2}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.3}Options}{69}{subsection.16.14.3}} -\newlabel{man/expire_backups:options}{{16.14.3}{69}{Options}{subsection.16.14.3}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.4}Exit Codes}{70}{subsection.16.14.4}} -\newlabel{man/expire_backups:exit-codes}{{16.14.4}{70}{Exit Codes}{subsection.16.14.4}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.5}See Also}{70}{subsection.16.14.5}} -\newlabel{man/expire_backups:see-also}{{16.14.5}{70}{See Also}{subsection.16.14.5}{}} -\@writefile{toc}{\contentsline {chapter}{\numberline {17}Further Resources / Getting Help}{71}{chapter.17}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.12.5}See Also}{68}{subsection.16.12.5}} +\newlabel{man/verify:see-also}{{16.12.5}{68}{See Also}{subsection.16.12.5}{}} +\@writefile{toc}{\contentsline {section}{\numberline {16.13}The \sphinxstyleliteralstrong {\sphinxupquote {pcp}} command}{68}{section.16.13}} +\newlabel{man/pcp:the-command-command}{{16.13}{68}{The \sphinxstyleliteralstrong {\sphinxupquote {pcp}} command}{section.16.13}{}} +\newlabel{man/pcp::doc}{{16.13}{68}{The \sphinxstyleliteralstrong {\sphinxupquote {pcp}} command}{section.16.13}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.1}Synopsis}{68}{subsection.16.13.1}} +\newlabel{man/pcp:synopsis}{{16.13.1}{68}{Synopsis}{subsection.16.13.1}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.2}Description}{68}{subsection.16.13.2}} +\newlabel{man/pcp:description}{{16.13.2}{68}{Description}{subsection.16.13.2}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.3}Options}{69}{subsection.16.13.3}} +\newlabel{man/pcp:options}{{16.13.3}{69}{Options}{subsection.16.13.3}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.4}Exit Codes}{69}{subsection.16.13.4}} +\newlabel{man/pcp:exit-codes}{{16.13.4}{69}{Exit Codes}{subsection.16.13.4}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.13.5}See Also}{69}{subsection.16.13.5}} +\newlabel{man/pcp:see-also}{{16.13.5}{69}{See Also}{subsection.16.13.5}{}} +\@writefile{toc}{\contentsline {section}{\numberline {16.14}The \sphinxstyleliteralstrong {\sphinxupquote {expire\_backups}} command}{69}{section.16.14}} +\newlabel{man/expire_backups:the-command-command}{{16.14}{69}{The \sphinxstyleliteralstrong {\sphinxupquote {expire\_backups}} command}{section.16.14}{}} +\newlabel{man/expire_backups::doc}{{16.14}{69}{The \sphinxstyleliteralstrong {\sphinxupquote {expire\_backups}} command}{section.16.14}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.1}Synopsis}{69}{subsection.16.14.1}} +\newlabel{man/expire_backups:synopsis}{{16.14.1}{69}{Synopsis}{subsection.16.14.1}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.2}Description}{69}{subsection.16.14.2}} +\newlabel{man/expire_backups:description}{{16.14.2}{69}{Description}{subsection.16.14.2}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.3}Options}{70}{subsection.16.14.3}} +\newlabel{man/expire_backups:options}{{16.14.3}{70}{Options}{subsection.16.14.3}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.4}Exit Codes}{71}{subsection.16.14.4}} +\newlabel{man/expire_backups:exit-codes}{{16.14.4}{71}{Exit Codes}{subsection.16.14.4}{}} +\@writefile{toc}{\contentsline {subsection}{\numberline {16.14.5}See Also}{71}{subsection.16.14.5}} +\newlabel{man/expire_backups:see-also}{{16.14.5}{71}{See Also}{subsection.16.14.5}{}} +\@writefile{toc}{\contentsline {chapter}{\numberline {17}Further Resources / Getting Help}{73}{chapter.17}} \@writefile{lof}{\addvspace {10\p@ }} \@writefile{lot}{\addvspace {10\p@ }} -\newlabel{resources:further-resources-getting-help}{{17}{71}{Further Resources / Getting Help}{chapter.17}{}} -\newlabel{resources:resources}{{17}{71}{Further Resources / Getting Help}{chapter.17}{}} -\newlabel{resources::doc}{{17}{71}{Further Resources / Getting Help}{chapter.17}{}} -\@writefile{toc}{\contentsline {chapter}{\numberline {18}Implementation Details}{73}{chapter.18}} +\newlabel{resources:further-resources-getting-help}{{17}{73}{Further Resources / Getting Help}{chapter.17}{}} +\newlabel{resources:resources}{{17}{73}{Further Resources / Getting Help}{chapter.17}{}} +\newlabel{resources::doc}{{17}{73}{Further Resources / Getting Help}{chapter.17}{}} +\@writefile{toc}{\contentsline {chapter}{\numberline {18}Implementation Details}{75}{chapter.18}} \@writefile{lof}{\addvspace {10\p@ }} \@writefile{lot}{\addvspace {10\p@ }} -\newlabel{impl_details:implementation-details}{{18}{73}{Implementation Details}{chapter.18}{}} -\newlabel{impl_details:impl-details}{{18}{73}{Implementation Details}{chapter.18}{}} -\newlabel{impl_details::doc}{{18}{73}{Implementation Details}{chapter.18}{}} -\@writefile{toc}{\contentsline {section}{\numberline {18.1}Metadata Storage}{73}{section.18.1}} -\newlabel{impl_details:metadata-storage}{{18.1}{73}{Metadata Storage}{section.18.1}{}} -\@writefile{toc}{\contentsline {section}{\numberline {18.2}Data Storage}{73}{section.18.2}} -\newlabel{impl_details:data-storage}{{18.2}{73}{Data Storage}{section.18.2}{}} -\@writefile{toc}{\contentsline {section}{\numberline {18.3}Data De-Duplication}{74}{section.18.3}} -\newlabel{impl_details:data-de-duplication}{{18.3}{74}{Data De-Duplication}{section.18.3}{}} -\@writefile{toc}{\contentsline {section}{\numberline {18.4}Caching}{74}{section.18.4}} -\newlabel{impl_details:caching}{{18.4}{74}{Caching}{section.18.4}{}} -\@writefile{toc}{\contentsline {section}{\numberline {18.5}Eventual Consistency Handling}{74}{section.18.5}} -\newlabel{impl_details:eventual-consistency-handling}{{18.5}{74}{Eventual Consistency Handling}{section.18.5}{}} -\@writefile{toc}{\contentsline {section}{\numberline {18.6}Encryption}{74}{section.18.6}} -\newlabel{impl_details:encryption}{{18.6}{74}{Encryption}{section.18.6}{}} +\newlabel{impl_details:implementation-details}{{18}{75}{Implementation Details}{chapter.18}{}} +\newlabel{impl_details:impl-details}{{18}{75}{Implementation Details}{chapter.18}{}} +\newlabel{impl_details::doc}{{18}{75}{Implementation Details}{chapter.18}{}} +\@writefile{toc}{\contentsline {section}{\numberline {18.1}Metadata Storage}{75}{section.18.1}} +\newlabel{impl_details:metadata-storage}{{18.1}{75}{Metadata Storage}{section.18.1}{}} +\@writefile{toc}{\contentsline {section}{\numberline {18.2}Data Storage}{75}{section.18.2}} +\newlabel{impl_details:data-storage}{{18.2}{75}{Data Storage}{section.18.2}{}} +\@writefile{toc}{\contentsline {section}{\numberline {18.3}Data De-Duplication}{76}{section.18.3}} +\newlabel{impl_details:data-de-duplication}{{18.3}{76}{Data De-Duplication}{section.18.3}{}} +\@writefile{toc}{\contentsline {section}{\numberline {18.4}Caching}{76}{section.18.4}} +\newlabel{impl_details:caching}{{18.4}{76}{Caching}{section.18.4}{}} +\@writefile{toc}{\contentsline {section}{\numberline {18.5}Eventual Consistency Handling}{76}{section.18.5}} +\newlabel{impl_details:eventual-consistency-handling}{{18.5}{76}{Eventual Consistency Handling}{section.18.5}{}} +\@writefile{toc}{\contentsline {section}{\numberline {18.6}Encryption}{76}{section.18.6}} +\newlabel{impl_details:encryption}{{18.6}{76}{Encryption}{section.18.6}{}} diff --git a/doc/latex/manual.idx b/doc/latex/manual.idx index eacdd97..6ae3180 100644 --- a/doc/latex/manual.idx +++ b/doc/latex/manual.idx @@ -12,6 +12,8 @@ \indexentry{sse!s3\_backend command line option|hyperpage}{8} \indexentry{s3\_backend command line option!ia|hyperpage}{8} \indexentry{ia!s3\_backend command line option|hyperpage}{8} +\indexentry{s3\_backend command line option!oia|hyperpage}{8} +\indexentry{oia!s3\_backend command line option|hyperpage}{8} \indexentry{s3\_backend command line option!rrs|hyperpage}{8} \indexentry{rrs!s3\_backend command line option|hyperpage}{8} \indexentry{swift\_backend command line option!no-ssl|hyperpage}{9} diff --git a/doc/latex/manual.tex b/doc/latex/manual.tex index 2bb572f..6ec86e8 100644 --- a/doc/latex/manual.tex +++ b/doc/latex/manual.tex @@ -52,8 +52,8 @@ \title{S3QL Documentation} -\date{Feb 09, 2019} -\release{3.0} +\date{Mar 31, 2019} +\release{3.1} \author{Nikolaus Rath} \newcommand{\sphinxlogo}{\vbox{}} \renewcommand{\releasename}{Release} @@ -228,7 +228,7 @@ version between 1.0 (inclusive) and 2.0 (exclusive) version between 3.4 (inclusive) and 4.0 (exclusive) \item {} -\sphinxhref{http://pytest.org/}{pytest}, version 2.7 or newer (optional, to run unit tests) +\sphinxhref{http://pytest.org/}{pytest}, version 3.7 or newer (optional, to run unit tests) \item {} \sphinxhref{https://github.com/systemd/python-systemd}{systemd} (optional, @@ -244,6 +244,10 @@ required for OAuth2 authentication with Google Storage) \sphinxhref{https://pypi.python.org/project/google-auth/}{google-auth} (optional, required for ADC authentication with Google Storage) +\item {} +\sphinxhref{https://pypi.python.org/project/google-auth-oauthlib/}{google-auth-oauthlib} +(optional, required for browser-based authentication with Google Storage) + \end{itemize} To check if a specific module \sphinxcode{\sphinxupquote{\textless{}module\textgreater{}}} is installed, execute @@ -315,7 +319,7 @@ tested with \begin{sphinxVerbatim}[commandchars=\\\{\}] \PYG{l}{python3 setup.py build\PYGZus{}cython} \PYG{l}{python3 setup.py build\PYGZus{}ext \PYGZhy{}\PYGZhy{}inplace} -\PYG{l}{python3 \PYGZhy{}m pytest tests/} +\PYG{l}{python3 \PYGZhy{}m pytest test} \end{sphinxVerbatim} Note that when building from the Mercurial or Git repository, building @@ -554,7 +558,17 @@ side encryption are probably rather small, and this option does \begin{fulllineitems} \phantomsection\label{\detokenize{backends:cmdoption-s3-backend-arg-ia}}\pysigline{\sphinxbfcode{\sphinxupquote{ia}}\sphinxcode{\sphinxupquote{}}} -Use infrequent access storage class for new objects. +Use STANDARD\_IA (infrequent access) storage class for new objects. +See {\color{red}\bfseries{}{}`AWS S3 Storage classes\textless{}https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html\textgreater{}{}`\_} + +\end{fulllineitems} + +\index{s3\_backend command line option!oia}\index{oia!s3\_backend command line option} + +\begin{fulllineitems} +\phantomsection\label{\detokenize{backends:cmdoption-s3-backend-arg-oia}}\pysigline{\sphinxbfcode{\sphinxupquote{oia}}\sphinxcode{\sphinxupquote{}}} +Use ONEZONE\_IA (infrequent access) storage class for new objects. +See {\color{red}\bfseries{}{}`AWS S3 Storage classes\textless{}https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html\textgreater{}{}`\_} \end{fulllineitems} @@ -1116,6 +1130,13 @@ This command accepts the following options: \item [-{-}cachedir \textless{}path\textgreater{}] Store cached data in this directory (default: \sphinxcode{\sphinxupquote{\textasciitilde{}/.s3ql)}} +\item [-{-}log \textless{}target\textgreater{}] +Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for +standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\sphinxcode{\sphinxupquote{None}} \item [-{-}debug-modules \textless{}modules\textgreater{}] Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages @@ -1382,6 +1403,10 @@ Like \sphinxcode{\sphinxupquote{-{-}allow-other}}, but restrict access to the mounting user and the root user. \item [-{-}fg] Do not daemonize, stay in foreground +\item [-{-}fs-name FS\_NAME] +Mount name passed to fuse, the name will be shown in +the first column of the system mount command output. +If not specified your storage url is used. \item [-{-}systemd] Run as systemd unit. Consider specifying \textendash{}log none as well to make use of journald. @@ -1816,6 +1841,13 @@ system. The \sphinxstyleliteralstrong{\sphinxupquote{umount.s3ql}} command accepts the following options: \begin{quote} \begin{optionlist}{3cm} +\item [-{-}log \textless{}target\textgreater{}] +Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for +standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\sphinxcode{\sphinxupquote{None}} \item [-{-}debug-modules \textless{}modules\textgreater{}] Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages @@ -1965,6 +1997,13 @@ The \sphinxstyleliteralstrong{\sphinxupquote{s3ql\_verify}} command has the foll This command accepts the following options: \begin{quote} \begin{optionlist}{3cm} +\item [-{-}log \textless{}target\textgreater{}] +Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for +standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\sphinxcode{\sphinxupquote{None}} \item [-{-}debug-modules \textless{}modules\textgreater{}] Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages @@ -2796,6 +2835,13 @@ The \sphinxstyleliteralstrong{\sphinxupquote{mkfs.s3ql}} command accepts the fol \item [-{-}cachedir \textless{}path\textgreater{}] Store cached data in this directory (default: \sphinxcode{\sphinxupquote{\textasciitilde{}/.s3ql)}} +\item [-{-}log \textless{}target\textgreater{}] +Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for +standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\sphinxcode{\sphinxupquote{None}} \item [-{-}debug-modules \textless{}modules\textgreater{}] Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages @@ -2955,7 +3001,7 @@ Changes the encryption passphrase of the file system. \item[{upgrade}] \leavevmode Upgrade the file system to the newest revision. -\item[{delete}] \leavevmode +\item[{clear}] \leavevmode Delete the file system with all the stored data. \item[{download-metadata}] \leavevmode @@ -3103,6 +3149,10 @@ Like \sphinxcode{\sphinxupquote{-{-}allow-other}}, but restrict access to the mounting user and the root user. \item [-{-}fg] Do not daemonize, stay in foreground +\item [-{-}fs-name FS\_NAME] +Mount name passed to fuse, the name will be shown in +the first column of the system mount command output. +If not specified your storage url is used. \item [-{-}systemd] Run as systemd unit. Consider specifying \textendash{}log none as well to make use of journald. @@ -3240,6 +3290,13 @@ and (if the file system was mounted with \sphinxcode{\sphinxupquote{-{-}allow-ot The \sphinxstyleliteralstrong{\sphinxupquote{s3qlstat}} command accepts the following options: \begin{quote} \begin{optionlist}{3cm} +\item [-{-}log \textless{}target\textgreater{}] +Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for +standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\sphinxcode{\sphinxupquote{None}} \item [-{-}debug-modules \textless{}modules\textgreater{}] Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages @@ -3357,6 +3414,13 @@ The \sphinxstyleliteralstrong{\sphinxupquote{s3qlctrl}} command also accepts the what specific action is being invoked: \begin{quote} \begin{optionlist}{3cm} +\item [-{-}log \textless{}target\textgreater{}] +Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for +standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\sphinxcode{\sphinxupquote{None}} \item [-{-}debug-modules \textless{}modules\textgreater{}] Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages @@ -3483,6 +3547,13 @@ any backup program. The \sphinxstyleliteralstrong{\sphinxupquote{s3qlcp}} command accepts the following options: \begin{quote} \begin{optionlist}{3cm} +\item [-{-}log \textless{}target\textgreater{}] +Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for +standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\sphinxcode{\sphinxupquote{None}} \item [-{-}debug-modules \textless{}modules\textgreater{}] Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages @@ -3558,6 +3629,13 @@ and (if the file system was mounted with \sphinxcode{\sphinxupquote{-{-}allow-ot The \sphinxstyleliteralstrong{\sphinxupquote{s3qlrm}} command accepts the following options: \begin{quote} \begin{optionlist}{3cm} +\item [-{-}log \textless{}target\textgreater{}] +Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for +standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\sphinxcode{\sphinxupquote{None}} \item [-{-}debug-modules \textless{}modules\textgreater{}] Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages @@ -3663,6 +3741,13 @@ changed after they have been made immutable. The \sphinxstyleliteralstrong{\sphinxupquote{s3qllock}} command accepts the following options: \begin{quote} \begin{optionlist}{3cm} +\item [-{-}log \textless{}target\textgreater{}] +Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for +standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\sphinxcode{\sphinxupquote{None}} \item [-{-}debug-modules \textless{}modules\textgreater{}] Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages @@ -3738,6 +3823,13 @@ terminate before shutting down the system. The \sphinxstyleliteralstrong{\sphinxupquote{umount.s3ql}} command accepts the following options. \begin{quote} \begin{optionlist}{3cm} +\item [-{-}log \textless{}target\textgreater{}] +Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for +standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\sphinxcode{\sphinxupquote{None}} \item [-{-}debug-modules \textless{}modules\textgreater{}] Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages @@ -3973,6 +4065,13 @@ backend. The \sphinxstyleliteralstrong{\sphinxupquote{s3ql\_oauth\_client}} command accepts the following options: \begin{quote} \begin{optionlist}{3cm} +\item [-{-}log \textless{}target\textgreater{}] +Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for +standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\sphinxcode{\sphinxupquote{None}} \item [-{-}debug-modules \textless{}modules\textgreater{}] Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages @@ -4044,6 +4143,13 @@ the available backends. The \sphinxstyleliteralstrong{\sphinxupquote{s3ql\_verify}} command accepts the following options. \begin{quote} \begin{optionlist}{3cm} +\item [-{-}log \textless{}target\textgreater{}] +Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for +standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\sphinxcode{\sphinxupquote{None}} \item [-{-}debug-modules \textless{}modules\textgreater{}] Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages @@ -4182,6 +4288,13 @@ using \sphinxstyleliteralstrong{\sphinxupquote{pcp}} is more likely to \sphinxst The \sphinxstyleliteralstrong{\sphinxupquote{pcp}} command accepts the following options: \begin{quote} \begin{optionlist}{3cm} +\item [-{-}log \textless{}target\textgreater{}] +Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for +standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\sphinxcode{\sphinxupquote{None}} \item [-{-}quiet] be really quiet \item [-{-}debug-modules \textless{}modules\textgreater{}] @@ -4324,6 +4437,13 @@ The \sphinxstyleliteralstrong{\sphinxupquote{expire\_backups}} command accepts t \begin{optionlist}{3cm} \item [-{-}quiet] be really quiet +\item [-{-}log \textless{}target\textgreater{}] +Destination for log messages. Specify \sphinxcode{\sphinxupquote{none}} for +standard output or \sphinxcode{\sphinxupquote{syslog}} for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\sphinxcode{\sphinxupquote{None}} \item [-{-}debug-modules \textless{}modules\textgreater{}] Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages diff --git a/doc/latex/manual.toc b/doc/latex/manual.toc index 6b4b40c..2ab1b8b 100644 --- a/doc/latex/manual.toc +++ b/doc/latex/manual.toc @@ -84,7 +84,7 @@ \contentsline {subsection}{\numberline {16.1.5}See Also}{52}{subsection.16.1.5} \contentsline {section}{\numberline {16.2}The \sphinxstyleliteralstrong {\sphinxupquote {s3qladm}} command}{52}{section.16.2} \contentsline {subsection}{\numberline {16.2.1}Synopsis}{52}{subsection.16.2.1} -\contentsline {subsection}{\numberline {16.2.2}Description}{52}{subsection.16.2.2} +\contentsline {subsection}{\numberline {16.2.2}Description}{53}{subsection.16.2.2} \contentsline {subsection}{\numberline {16.2.3}Options}{53}{subsection.16.2.3} \contentsline {subsection}{\numberline {16.2.4}Actions}{53}{subsection.16.2.4} \contentsline {subsection}{\numberline {16.2.5}Exit Codes}{53}{subsection.16.2.5} @@ -97,77 +97,77 @@ \contentsline {subsection}{\numberline {16.3.5}See Also}{56}{subsection.16.3.5} \contentsline {section}{\numberline {16.4}The \sphinxstyleliteralstrong {\sphinxupquote {s3qlstat}} command}{56}{section.16.4} \contentsline {subsection}{\numberline {16.4.1}Synopsis}{56}{subsection.16.4.1} -\contentsline {subsection}{\numberline {16.4.2}Description}{56}{subsection.16.4.2} +\contentsline {subsection}{\numberline {16.4.2}Description}{57}{subsection.16.4.2} \contentsline {subsection}{\numberline {16.4.3}Options}{57}{subsection.16.4.3} \contentsline {subsection}{\numberline {16.4.4}Exit Codes}{57}{subsection.16.4.4} \contentsline {subsection}{\numberline {16.4.5}See Also}{57}{subsection.16.4.5} \contentsline {section}{\numberline {16.5}The \sphinxstyleliteralstrong {\sphinxupquote {s3qlctrl}} command}{57}{section.16.5} \contentsline {subsection}{\numberline {16.5.1}Synopsis}{57}{subsection.16.5.1} -\contentsline {subsection}{\numberline {16.5.2}Description}{57}{subsection.16.5.2} +\contentsline {subsection}{\numberline {16.5.2}Description}{58}{subsection.16.5.2} \contentsline {subsection}{\numberline {16.5.3}Options}{58}{subsection.16.5.3} \contentsline {subsection}{\numberline {16.5.4}Exit Codes}{58}{subsection.16.5.4} -\contentsline {subsection}{\numberline {16.5.5}See Also}{58}{subsection.16.5.5} -\contentsline {section}{\numberline {16.6}The \sphinxstyleliteralstrong {\sphinxupquote {s3qlcp}} command}{58}{section.16.6} -\contentsline {subsection}{\numberline {16.6.1}Synopsis}{58}{subsection.16.6.1} +\contentsline {subsection}{\numberline {16.5.5}See Also}{59}{subsection.16.5.5} +\contentsline {section}{\numberline {16.6}The \sphinxstyleliteralstrong {\sphinxupquote {s3qlcp}} command}{59}{section.16.6} +\contentsline {subsection}{\numberline {16.6.1}Synopsis}{59}{subsection.16.6.1} \contentsline {subsection}{\numberline {16.6.2}Description}{59}{subsection.16.6.2} -\contentsline {subsubsection}{Snapshotting vs Hardlinking}{59}{subsubsection*.21} -\contentsline {subsection}{\numberline {16.6.3}Options}{59}{subsection.16.6.3} -\contentsline {subsection}{\numberline {16.6.4}Exit Codes}{59}{subsection.16.6.4} +\contentsline {subsubsection}{Snapshotting vs Hardlinking}{59}{subsubsection*.22} +\contentsline {subsection}{\numberline {16.6.3}Options}{60}{subsection.16.6.3} +\contentsline {subsection}{\numberline {16.6.4}Exit Codes}{60}{subsection.16.6.4} \contentsline {subsection}{\numberline {16.6.5}See Also}{60}{subsection.16.6.5} \contentsline {section}{\numberline {16.7}The \sphinxstyleliteralstrong {\sphinxupquote {s3qlrm}} command}{60}{section.16.7} \contentsline {subsection}{\numberline {16.7.1}Synopsis}{60}{subsection.16.7.1} \contentsline {subsection}{\numberline {16.7.2}Description}{60}{subsection.16.7.2} -\contentsline {subsection}{\numberline {16.7.3}Options}{60}{subsection.16.7.3} -\contentsline {subsection}{\numberline {16.7.4}Exit Codes}{60}{subsection.16.7.4} +\contentsline {subsection}{\numberline {16.7.3}Options}{61}{subsection.16.7.3} +\contentsline {subsection}{\numberline {16.7.4}Exit Codes}{61}{subsection.16.7.4} \contentsline {subsection}{\numberline {16.7.5}See Also}{61}{subsection.16.7.5} \contentsline {section}{\numberline {16.8}The \sphinxstyleliteralstrong {\sphinxupquote {s3qllock}} command}{61}{section.16.8} \contentsline {subsection}{\numberline {16.8.1}Synopsis}{61}{subsection.16.8.1} \contentsline {subsection}{\numberline {16.8.2}Description}{61}{subsection.16.8.2} -\contentsline {subsection}{\numberline {16.8.3}Rationale}{61}{subsection.16.8.3} -\contentsline {subsection}{\numberline {16.8.4}Options}{61}{subsection.16.8.4} +\contentsline {subsection}{\numberline {16.8.3}Rationale}{62}{subsection.16.8.3} +\contentsline {subsection}{\numberline {16.8.4}Options}{62}{subsection.16.8.4} \contentsline {subsection}{\numberline {16.8.5}Exit Codes}{62}{subsection.16.8.5} \contentsline {subsection}{\numberline {16.8.6}See Also}{62}{subsection.16.8.6} -\contentsline {section}{\numberline {16.9}The \sphinxstyleliteralstrong {\sphinxupquote {umount.s3ql}} command}{62}{section.16.9} -\contentsline {subsection}{\numberline {16.9.1}Synopsis}{62}{subsection.16.9.1} -\contentsline {subsection}{\numberline {16.9.2}Description}{62}{subsection.16.9.2} -\contentsline {subsection}{\numberline {16.9.3}Options}{62}{subsection.16.9.3} +\contentsline {section}{\numberline {16.9}The \sphinxstyleliteralstrong {\sphinxupquote {umount.s3ql}} command}{63}{section.16.9} +\contentsline {subsection}{\numberline {16.9.1}Synopsis}{63}{subsection.16.9.1} +\contentsline {subsection}{\numberline {16.9.2}Description}{63}{subsection.16.9.2} +\contentsline {subsection}{\numberline {16.9.3}Options}{63}{subsection.16.9.3} \contentsline {subsection}{\numberline {16.9.4}Exit Codes}{63}{subsection.16.9.4} -\contentsline {subsection}{\numberline {16.9.5}See Also}{63}{subsection.16.9.5} -\contentsline {section}{\numberline {16.10}The \sphinxstyleliteralstrong {\sphinxupquote {fsck.s3ql}} command}{63}{section.16.10} -\contentsline {subsection}{\numberline {16.10.1}Synopsis}{63}{subsection.16.10.1} -\contentsline {subsection}{\numberline {16.10.2}Description}{63}{subsection.16.10.2} -\contentsline {subsection}{\numberline {16.10.3}Options}{63}{subsection.16.10.3} -\contentsline {subsection}{\numberline {16.10.4}Exit Codes}{64}{subsection.16.10.4} +\contentsline {subsection}{\numberline {16.9.5}See Also}{64}{subsection.16.9.5} +\contentsline {section}{\numberline {16.10}The \sphinxstyleliteralstrong {\sphinxupquote {fsck.s3ql}} command}{64}{section.16.10} +\contentsline {subsection}{\numberline {16.10.1}Synopsis}{64}{subsection.16.10.1} +\contentsline {subsection}{\numberline {16.10.2}Description}{64}{subsection.16.10.2} +\contentsline {subsection}{\numberline {16.10.3}Options}{64}{subsection.16.10.3} +\contentsline {subsection}{\numberline {16.10.4}Exit Codes}{65}{subsection.16.10.4} \contentsline {subsection}{\numberline {16.10.5}See Also}{65}{subsection.16.10.5} -\contentsline {section}{\numberline {16.11}The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{65}{section.16.11} -\contentsline {subsection}{\numberline {16.11.1}Synopsis}{65}{subsection.16.11.1} -\contentsline {subsection}{\numberline {16.11.2}Description}{65}{subsection.16.11.2} -\contentsline {subsection}{\numberline {16.11.3}Options}{65}{subsection.16.11.3} -\contentsline {subsection}{\numberline {16.11.4}Exit Codes}{65}{subsection.16.11.4} +\contentsline {section}{\numberline {16.11}The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_oauth\_client}} command}{66}{section.16.11} +\contentsline {subsection}{\numberline {16.11.1}Synopsis}{66}{subsection.16.11.1} +\contentsline {subsection}{\numberline {16.11.2}Description}{66}{subsection.16.11.2} +\contentsline {subsection}{\numberline {16.11.3}Options}{66}{subsection.16.11.3} +\contentsline {subsection}{\numberline {16.11.4}Exit Codes}{66}{subsection.16.11.4} \contentsline {subsection}{\numberline {16.11.5}See Also}{66}{subsection.16.11.5} -\contentsline {section}{\numberline {16.12}The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_verify}} command}{66}{section.16.12} -\contentsline {subsection}{\numberline {16.12.1}Synopsis}{66}{subsection.16.12.1} -\contentsline {subsection}{\numberline {16.12.2}Description}{66}{subsection.16.12.2} -\contentsline {subsection}{\numberline {16.12.3}Options}{66}{subsection.16.12.3} +\contentsline {section}{\numberline {16.12}The \sphinxstyleliteralstrong {\sphinxupquote {s3ql\_verify}} command}{67}{section.16.12} +\contentsline {subsection}{\numberline {16.12.1}Synopsis}{67}{subsection.16.12.1} +\contentsline {subsection}{\numberline {16.12.2}Description}{67}{subsection.16.12.2} +\contentsline {subsection}{\numberline {16.12.3}Options}{67}{subsection.16.12.3} \contentsline {subsection}{\numberline {16.12.4}Exit Codes}{67}{subsection.16.12.4} -\contentsline {subsection}{\numberline {16.12.5}See Also}{67}{subsection.16.12.5} -\contentsline {section}{\numberline {16.13}The \sphinxstyleliteralstrong {\sphinxupquote {pcp}} command}{67}{section.16.13} -\contentsline {subsection}{\numberline {16.13.1}Synopsis}{67}{subsection.16.13.1} -\contentsline {subsection}{\numberline {16.13.2}Description}{67}{subsection.16.13.2} -\contentsline {subsection}{\numberline {16.13.3}Options}{68}{subsection.16.13.3} -\contentsline {subsection}{\numberline {16.13.4}Exit Codes}{68}{subsection.16.13.4} -\contentsline {subsection}{\numberline {16.13.5}See Also}{68}{subsection.16.13.5} -\contentsline {section}{\numberline {16.14}The \sphinxstyleliteralstrong {\sphinxupquote {expire\_backups}} command}{68}{section.16.14} -\contentsline {subsection}{\numberline {16.14.1}Synopsis}{68}{subsection.16.14.1} -\contentsline {subsection}{\numberline {16.14.2}Description}{68}{subsection.16.14.2} -\contentsline {subsection}{\numberline {16.14.3}Options}{69}{subsection.16.14.3} -\contentsline {subsection}{\numberline {16.14.4}Exit Codes}{70}{subsection.16.14.4} -\contentsline {subsection}{\numberline {16.14.5}See Also}{70}{subsection.16.14.5} -\contentsline {chapter}{\numberline {17}Further Resources / Getting Help}{71}{chapter.17} -\contentsline {chapter}{\numberline {18}Implementation Details}{73}{chapter.18} -\contentsline {section}{\numberline {18.1}Metadata Storage}{73}{section.18.1} -\contentsline {section}{\numberline {18.2}Data Storage}{73}{section.18.2} -\contentsline {section}{\numberline {18.3}Data De-Duplication}{74}{section.18.3} -\contentsline {section}{\numberline {18.4}Caching}{74}{section.18.4} -\contentsline {section}{\numberline {18.5}Eventual Consistency Handling}{74}{section.18.5} -\contentsline {section}{\numberline {18.6}Encryption}{74}{section.18.6} +\contentsline {subsection}{\numberline {16.12.5}See Also}{68}{subsection.16.12.5} +\contentsline {section}{\numberline {16.13}The \sphinxstyleliteralstrong {\sphinxupquote {pcp}} command}{68}{section.16.13} +\contentsline {subsection}{\numberline {16.13.1}Synopsis}{68}{subsection.16.13.1} +\contentsline {subsection}{\numberline {16.13.2}Description}{68}{subsection.16.13.2} +\contentsline {subsection}{\numberline {16.13.3}Options}{69}{subsection.16.13.3} +\contentsline {subsection}{\numberline {16.13.4}Exit Codes}{69}{subsection.16.13.4} +\contentsline {subsection}{\numberline {16.13.5}See Also}{69}{subsection.16.13.5} +\contentsline {section}{\numberline {16.14}The \sphinxstyleliteralstrong {\sphinxupquote {expire\_backups}} command}{69}{section.16.14} +\contentsline {subsection}{\numberline {16.14.1}Synopsis}{69}{subsection.16.14.1} +\contentsline {subsection}{\numberline {16.14.2}Description}{69}{subsection.16.14.2} +\contentsline {subsection}{\numberline {16.14.3}Options}{70}{subsection.16.14.3} +\contentsline {subsection}{\numberline {16.14.4}Exit Codes}{71}{subsection.16.14.4} +\contentsline {subsection}{\numberline {16.14.5}See Also}{71}{subsection.16.14.5} +\contentsline {chapter}{\numberline {17}Further Resources / Getting Help}{73}{chapter.17} +\contentsline {chapter}{\numberline {18}Implementation Details}{75}{chapter.18} +\contentsline {section}{\numberline {18.1}Metadata Storage}{75}{section.18.1} +\contentsline {section}{\numberline {18.2}Data Storage}{75}{section.18.2} +\contentsline {section}{\numberline {18.3}Data De-Duplication}{76}{section.18.3} +\contentsline {section}{\numberline {18.4}Caching}{76}{section.18.4} +\contentsline {section}{\numberline {18.5}Eventual Consistency Handling}{76}{section.18.5} +\contentsline {section}{\numberline {18.6}Encryption}{76}{section.18.6} diff --git a/doc/latex/sphinxhighlight.sty b/doc/latex/sphinxhighlight.sty index 09da86a..2adf06d 100644 --- a/doc/latex/sphinxhighlight.sty +++ b/doc/latex/sphinxhighlight.sty @@ -13,73 +13,73 @@ \PYG@it{\PYG@bf{\PYG@ff{#1}}}}}}} \def\PYG#1#2{\PYG@reset\PYG@toks#1+\relax+\PYG@do{#2}} -\expandafter\def\csname PYG@tok@ss\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.67,0.40,0.00}{##1}}} -\expandafter\def\csname PYG@tok@ne\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}} -\expandafter\def\csname PYG@tok@bp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} -\expandafter\def\csname PYG@tok@c1\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}} -\expandafter\def\csname PYG@tok@nv\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.60,0.40,0.20}{##1}}} -\expandafter\def\csname PYG@tok@cpf\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}} +\expandafter\def\csname PYG@tok@cs\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.80,0.00,0.00}{##1}}} +\expandafter\def\csname PYG@tok@c\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}} +\expandafter\def\csname PYG@tok@nl\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.60,0.47,0.00}{##1}}} \expandafter\def\csname PYG@tok@il\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.87}{##1}}} +\expandafter\def\csname PYG@tok@ow\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} \expandafter\def\csname PYG@tok@gs\endcsname{\let\PYG@bf=\textbf} -\expandafter\def\csname PYG@tok@err\endcsname{\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.67,0.67}{\strut ##1}}} -\expandafter\def\csname PYG@tok@gp\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}} -\expandafter\def\csname PYG@tok@mh\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.33,0.53}{##1}}} -\expandafter\def\csname PYG@tok@ni\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.53,0.00,0.00}{##1}}} -\expandafter\def\csname PYG@tok@gd\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}} -\expandafter\def\csname PYG@tok@s1\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} +\expandafter\def\csname PYG@tok@sx\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.87,0.13,0.00}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} +\expandafter\def\csname PYG@tok@sh\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} +\expandafter\def\csname PYG@tok@gi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}} \expandafter\def\csname PYG@tok@no\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.20,0.40}{##1}}} -\expandafter\def\csname PYG@tok@mo\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.27,0.00,0.93}{##1}}} -\expandafter\def\csname PYG@tok@se\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} \expandafter\def\csname PYG@tok@ch\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}} +\expandafter\def\csname PYG@tok@o\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.20,0.20,0.20}{##1}}} +\expandafter\def\csname PYG@tok@ne\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}} +\expandafter\def\csname PYG@tok@s\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} \expandafter\def\csname PYG@tok@vc\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.20,0.40,0.60}{##1}}} +\expandafter\def\csname PYG@tok@vm\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.60,0.40,0.20}{##1}}} +\expandafter\def\csname PYG@tok@mb\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.40,0.00,0.93}{##1}}} +\expandafter\def\csname PYG@tok@ss\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.67,0.40,0.00}{##1}}} +\expandafter\def\csname PYG@tok@m\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.40,0.00,0.93}{##1}}} +\expandafter\def\csname PYG@tok@k\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}} +\expandafter\def\csname PYG@tok@kd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}} +\expandafter\def\csname PYG@tok@kc\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}} +\expandafter\def\csname PYG@tok@s1\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} \expandafter\def\csname PYG@tok@na\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.80}{##1}}} -\expandafter\def\csname PYG@tok@sd\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.87,0.27,0.13}{##1}}} -\expandafter\def\csname PYG@tok@nt\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.47,0.00}{##1}}} -\expandafter\def\csname PYG@tok@ge\endcsname{\let\PYG@it=\textit} -\expandafter\def\csname PYG@tok@cp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.33,0.47,0.60}{##1}}} -\expandafter\def\csname PYG@tok@cs\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.80,0.00,0.00}{##1}}} -\expandafter\def\csname PYG@tok@fm\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.40,0.73}{##1}}} -\expandafter\def\csname PYG@tok@s\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} -\expandafter\def\csname PYG@tok@o\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.20,0.20,0.20}{##1}}} -\expandafter\def\csname PYG@tok@gu\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}} -\expandafter\def\csname PYG@tok@cm\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}} -\expandafter\def\csname PYG@tok@sa\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} +\expandafter\def\csname PYG@tok@ni\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.53,0.00,0.00}{##1}}} +\expandafter\def\csname PYG@tok@err\endcsname{\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.67,0.67}{\strut ##1}}} +\expandafter\def\csname PYG@tok@nv\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.60,0.40,0.20}{##1}}} +\expandafter\def\csname PYG@tok@mo\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.27,0.00,0.93}{##1}}} \expandafter\def\csname PYG@tok@sr\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,1.00}{\strut ##1}}} -\expandafter\def\csname PYG@tok@w\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}} -\expandafter\def\csname PYG@tok@gr\endcsname{\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}} -\expandafter\def\csname PYG@tok@s2\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} -\expandafter\def\csname PYG@tok@dl\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} -\expandafter\def\csname PYG@tok@kn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}} \expandafter\def\csname PYG@tok@gt\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.27,0.87}{##1}}} -\expandafter\def\csname PYG@tok@mf\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.40,0.00,0.93}{##1}}} -\expandafter\def\csname PYG@tok@vm\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.60,0.40,0.20}{##1}}} -\expandafter\def\csname PYG@tok@kd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}} +\expandafter\def\csname PYG@tok@sa\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} +\expandafter\def\csname PYG@tok@kn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}} \expandafter\def\csname PYG@tok@nc\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.73,0.00,0.40}{##1}}} -\expandafter\def\csname PYG@tok@m\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.40,0.00,0.93}{##1}}} -\expandafter\def\csname PYG@tok@nn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}} -\expandafter\def\csname PYG@tok@sx\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.87,0.13,0.00}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} -\expandafter\def\csname PYG@tok@ow\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.00}{##1}}} -\expandafter\def\csname PYG@tok@si\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{0.93,0.93,0.93}{\strut ##1}}} \expandafter\def\csname PYG@tok@nb\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} -\expandafter\def\csname PYG@tok@kc\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}} -\expandafter\def\csname PYG@tok@kp\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.20,0.53}{##1}}} -\expandafter\def\csname PYG@tok@k\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}} -\expandafter\def\csname PYG@tok@kt\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.20,0.20,0.60}{##1}}} -\expandafter\def\csname PYG@tok@nd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.33,0.33,0.33}{##1}}} +\expandafter\def\csname PYG@tok@kr\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}} +\expandafter\def\csname PYG@tok@nn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}} +\expandafter\def\csname PYG@tok@w\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}} +\expandafter\def\csname PYG@tok@gd\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}} \expandafter\def\csname PYG@tok@gh\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}} -\expandafter\def\csname PYG@tok@nf\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.40,0.73}{##1}}} \expandafter\def\csname PYG@tok@vi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.20,0.20,0.73}{##1}}} -\expandafter\def\csname PYG@tok@gi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}} -\expandafter\def\csname PYG@tok@vg\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.87,0.47,0.00}{##1}}} +\expandafter\def\csname PYG@tok@nt\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.47,0.00}{##1}}} +\expandafter\def\csname PYG@tok@cm\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}} +\expandafter\def\csname PYG@tok@mh\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.33,0.53}{##1}}} +\expandafter\def\csname PYG@tok@gr\endcsname{\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}} +\expandafter\def\csname PYG@tok@mf\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.40,0.00,0.93}{##1}}} \expandafter\def\csname PYG@tok@mi\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.87}{##1}}} -\expandafter\def\csname PYG@tok@nl\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.60,0.47,0.00}{##1}}} +\expandafter\def\csname PYG@tok@vg\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.87,0.47,0.00}{##1}}} +\expandafter\def\csname PYG@tok@nd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.33,0.33,0.33}{##1}}} \expandafter\def\csname PYG@tok@sc\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.27,0.87}{##1}}} -\expandafter\def\csname PYG@tok@sb\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} -\expandafter\def\csname PYG@tok@mb\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.40,0.00,0.93}{##1}}} -\expandafter\def\csname PYG@tok@sh\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} -\expandafter\def\csname PYG@tok@c\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}} +\expandafter\def\csname PYG@tok@ge\endcsname{\let\PYG@it=\textit} \expandafter\def\csname PYG@tok@go\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}} -\expandafter\def\csname PYG@tok@kr\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.53,0.00}{##1}}} +\expandafter\def\csname PYG@tok@nf\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.40,0.73}{##1}}} +\expandafter\def\csname PYG@tok@gp\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}} +\expandafter\def\csname PYG@tok@fm\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.40,0.73}{##1}}} +\expandafter\def\csname PYG@tok@s2\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} +\expandafter\def\csname PYG@tok@cp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.33,0.47,0.60}{##1}}} +\expandafter\def\csname PYG@tok@kt\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.20,0.20,0.60}{##1}}} +\expandafter\def\csname PYG@tok@cpf\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}} +\expandafter\def\csname PYG@tok@si\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{0.93,0.93,0.93}{\strut ##1}}} +\expandafter\def\csname PYG@tok@gu\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}} +\expandafter\def\csname PYG@tok@sd\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.87,0.27,0.13}{##1}}} +\expandafter\def\csname PYG@tok@bp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} +\expandafter\def\csname PYG@tok@sb\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} +\expandafter\def\csname PYG@tok@dl\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} +\expandafter\def\csname PYG@tok@kp\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.20,0.53}{##1}}} +\expandafter\def\csname PYG@tok@c1\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}} +\expandafter\def\csname PYG@tok@se\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} \def\PYGZbs{\char`\\} \def\PYGZus{\char`\_} diff --git a/doc/man/fsck.s3ql.1 b/doc/man/fsck.s3ql.1 index 233f61c..2376072 100644 --- a/doc/man/fsck.s3ql.1 +++ b/doc/man/fsck.s3ql.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "FSCK.S3QL" "1" "Feb 09, 2019" "3.0" "S3QL" +.TH "FSCK.S3QL" "1" "Mar 31, 2019" "3.1" "S3QL" .SH NAME fsck.s3ql \- Check an S3QL file system for errors . diff --git a/doc/man/mkfs.s3ql.1 b/doc/man/mkfs.s3ql.1 index 8744b16..4550fda 100644 --- a/doc/man/mkfs.s3ql.1 +++ b/doc/man/mkfs.s3ql.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "MKFS.S3QL" "1" "Feb 09, 2019" "3.0" "S3QL" +.TH "MKFS.S3QL" "1" "Mar 31, 2019" "3.1" "S3QL" .SH NAME mkfs.s3ql \- Create an S3QL file system . @@ -67,6 +67,14 @@ The \fBmkfs.s3ql\fP command accepts the following options. Store cached data in this directory (default: \fB~/.s3ql)\fP .TP +.BI \-\-log \ <target> +Destination for log messages. Specify \fBnone\fP for +standard output or \fBsyslog\fP for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\fBNone\fP +.TP .BI \-\-debug\-modules \ <modules> Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages diff --git a/doc/man/mount.s3ql.1 b/doc/man/mount.s3ql.1 index 57d69c1..5cb528a 100644 --- a/doc/man/mount.s3ql.1 +++ b/doc/man/mount.s3ql.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "MOUNT.S3QL" "1" "Feb 09, 2019" "3.0" "S3QL" +.TH "MOUNT.S3QL" "1" "Mar 31, 2019" "3.1" "S3QL" .SH NAME mount.s3ql \- Mount an S3QL file system . @@ -125,6 +125,11 @@ mounting user and the root user. .B \-\-fg Do not daemonize, stay in foreground .TP +.BI \-\-fs\-name \ FS_NAME +Mount name passed to fuse, the name will be shown in +the first column of the system mount command output. +If not specified your storage url is used. +.TP .B \-\-systemd Run as systemd unit. Consider specifying \-\-log none as well to make use of journald. diff --git a/doc/man/s3ql_oauth_client.1 b/doc/man/s3ql_oauth_client.1 index 970e8f1..87a3a9d 100644 --- a/doc/man/s3ql_oauth_client.1 +++ b/doc/man/s3ql_oauth_client.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "S3QL_OAUTH_CLIENT" "1" "Feb 09, 2019" "3.0" "S3QL" +.TH "S3QL_OAUTH_CLIENT" "1" "Mar 31, 2019" "3.1" "S3QL" .SH NAME s3ql_oauth_client \- Obtain Google Storage OAuth2 tokens . @@ -64,6 +64,14 @@ The \fBs3ql_oauth_client\fP command accepts the following options: .INDENT 3.5 .INDENT 0.0 .TP +.BI \-\-log \ <target> +Destination for log messages. Specify \fBnone\fP for +standard output or \fBsyslog\fP for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\fBNone\fP +.TP .BI \-\-debug\-modules \ <modules> Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages diff --git a/doc/man/s3ql_verify.1 b/doc/man/s3ql_verify.1 index 3b4f762..19e1060 100644 --- a/doc/man/s3ql_verify.1 +++ b/doc/man/s3ql_verify.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "S3QL_VERIFY" "1" "Feb 09, 2019" "3.0" "S3QL" +.TH "S3QL_VERIFY" "1" "Mar 31, 2019" "3.1" "S3QL" .SH NAME s3ql_verify \- Verify data in an S3QL file system . @@ -62,6 +62,14 @@ The \fBs3ql_verify\fP command accepts the following options. .INDENT 3.5 .INDENT 0.0 .TP +.BI \-\-log \ <target> +Destination for log messages. Specify \fBnone\fP for +standard output or \fBsyslog\fP for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\fBNone\fP +.TP .BI \-\-debug\-modules \ <modules> Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages diff --git a/doc/man/s3qladm.1 b/doc/man/s3qladm.1 index 5e57c66..6f7ed40 100644 --- a/doc/man/s3qladm.1 +++ b/doc/man/s3qladm.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "S3QLADM" "1" "Feb 09, 2019" "3.0" "S3QL" +.TH "S3QLADM" "1" "Mar 31, 2019" "3.1" "S3QL" .SH NAME s3qladm \- Manage S3QL file systems . @@ -116,7 +116,7 @@ Changes the encryption passphrase of the file system. .B upgrade Upgrade the file system to the newest revision. .TP -.B delete +.B clear Delete the file system with all the stored data. .TP .B download\-metadata diff --git a/doc/man/s3qlcp.1 b/doc/man/s3qlcp.1 index 4767c14..c32804a 100644 --- a/doc/man/s3qlcp.1 +++ b/doc/man/s3qlcp.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "S3QLCP" "1" "Feb 09, 2019" "3.0" "S3QL" +.TH "S3QLCP" "1" "Mar 31, 2019" "3.1" "S3QL" .SH NAME s3qlcp \- Copy-on-write replication on S3QL file systems . @@ -108,6 +108,14 @@ The \fBs3qlcp\fP command accepts the following options: .INDENT 3.5 .INDENT 0.0 .TP +.BI \-\-log \ <target> +Destination for log messages. Specify \fBnone\fP for +standard output or \fBsyslog\fP for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\fBNone\fP +.TP .BI \-\-debug\-modules \ <modules> Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages diff --git a/doc/man/s3qlctrl.1 b/doc/man/s3qlctrl.1 index 315b498..6ab455e 100644 --- a/doc/man/s3qlctrl.1 +++ b/doc/man/s3qlctrl.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "S3QLCTRL" "1" "Feb 09, 2019" "3.0" "S3QL" +.TH "S3QLCTRL" "1" "Mar 31, 2019" "3.1" "S3QL" .SH NAME s3qlctrl \- Control a mounted S3QL file system . @@ -116,6 +116,14 @@ what specific action is being invoked: .INDENT 3.5 .INDENT 0.0 .TP +.BI \-\-log \ <target> +Destination for log messages. Specify \fBnone\fP for +standard output or \fBsyslog\fP for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\fBNone\fP +.TP .BI \-\-debug\-modules \ <modules> Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages diff --git a/doc/man/s3qllock.1 b/doc/man/s3qllock.1 index 258449f..f306844 100644 --- a/doc/man/s3qllock.1 +++ b/doc/man/s3qllock.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "S3QLLOCK" "1" "Feb 09, 2019" "3.0" "S3QL" +.TH "S3QLLOCK" "1" "Mar 31, 2019" "3.1" "S3QL" .SH NAME s3qllock \- Make trees on an S3QL file system immutable . @@ -94,6 +94,14 @@ The \fBs3qllock\fP command accepts the following options: .INDENT 3.5 .INDENT 0.0 .TP +.BI \-\-log \ <target> +Destination for log messages. Specify \fBnone\fP for +standard output or \fBsyslog\fP for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\fBNone\fP +.TP .BI \-\-debug\-modules \ <modules> Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages diff --git a/doc/man/s3qlrm.1 b/doc/man/s3qlrm.1 index 6425676..1e31469 100644 --- a/doc/man/s3qlrm.1 +++ b/doc/man/s3qlrm.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "S3QLRM" "1" "Feb 09, 2019" "3.0" "S3QL" +.TH "S3QLRM" "1" "Mar 31, 2019" "3.1" "S3QL" .SH NAME s3qlrm \- Fast tree removal on S3QL file systems . @@ -66,6 +66,14 @@ The \fBs3qlrm\fP command accepts the following options: .INDENT 3.5 .INDENT 0.0 .TP +.BI \-\-log \ <target> +Destination for log messages. Specify \fBnone\fP for +standard output or \fBsyslog\fP for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\fBNone\fP +.TP .BI \-\-debug\-modules \ <modules> Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages diff --git a/doc/man/s3qlstat.1 b/doc/man/s3qlstat.1 index 94d8368..a2a9080 100644 --- a/doc/man/s3qlstat.1 +++ b/doc/man/s3qlstat.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "S3QLSTAT" "1" "Feb 09, 2019" "3.0" "S3QL" +.TH "S3QLSTAT" "1" "Mar 31, 2019" "3.1" "S3QL" .SH NAME s3qlstat \- Gather S3QL file system statistics . @@ -60,6 +60,14 @@ The \fBs3qlstat\fP command accepts the following options: .INDENT 3.5 .INDENT 0.0 .TP +.BI \-\-log \ <target> +Destination for log messages. Specify \fBnone\fP for +standard output or \fBsyslog\fP for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\fBNone\fP +.TP .BI \-\-debug\-modules \ <modules> Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages diff --git a/doc/man/umount.s3ql.1 b/doc/man/umount.s3ql.1 index d0708c8..81daa09 100644 --- a/doc/man/umount.s3ql.1 +++ b/doc/man/umount.s3ql.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "UMOUNT.S3QL" "1" "Feb 09, 2019" "3.0" "S3QL" +.TH "UMOUNT.S3QL" "1" "Mar 31, 2019" "3.1" "S3QL" .SH NAME umount.s3ql \- Unmount an S3QL file system . @@ -66,6 +66,14 @@ The \fBumount.s3ql\fP command accepts the following options. .INDENT 3.5 .INDENT 0.0 .TP +.BI \-\-log \ <target> +Destination for log messages. Specify \fBnone\fP for +standard output or \fBsyslog\fP for the system logging +daemon. Anything else will be interpreted as a file +name. Log files will be rotated when they reach 1 MiB, +and at most 5 old log files will be kept. Default: +\fBNone\fP +.TP .BI \-\-debug\-modules \ <modules> Activate debugging output from specified modules (use commas to separate multiple modules). Debug messages diff --git a/doc/manual.pdf b/doc/manual.pdf Binary files differindex 9751a83..c17cb48 100644 --- a/doc/manual.pdf +++ b/doc/manual.pdf diff --git a/rst/backends.rst b/rst/backends.rst index 29b243f..46fd1a7 100644 --- a/rst/backends.rst +++ b/rst/backends.rst @@ -153,7 +153,13 @@ The Amazon S3 backend accepts the following backend options: .. option:: ia - Use infrequent access storage class for new objects. + Use STANDARD_IA (infrequent access) storage class for new objects. + See `AWS S3 Storage classes<https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html>`_ + +.. option:: oia + + Use ONEZONE_IA (infrequent access) storage class for new objects. + See `AWS S3 Storage classes<https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html>`_ .. option:: rrs diff --git a/rst/installation.rst b/rst/installation.rst index b212440..4c0edbf 100644 --- a/rst/installation.rst +++ b/rst/installation.rst @@ -43,7 +43,7 @@ that is not the case. version between 1.0 (inclusive) and 2.0 (exclusive) * `dugong <https://pypi.org/project/dugong/>`_, any version between 3.4 (inclusive) and 4.0 (exclusive) - * `pytest <http://pytest.org/>`_, version 2.7 or newer (optional, to run unit tests) + * `pytest <http://pytest.org/>`_, version 3.7 or newer (optional, to run unit tests) * `systemd <https://github.com/systemd/python-systemd>`_ (optional, for enabling systemd support). Do *not* install the module from PyPi, this is from a third-party developer and incompatible with @@ -52,6 +52,8 @@ that is not the case. required for OAuth2 authentication with Google Storage) * `google-auth <https://pypi.python.org/project/google-auth/>`_ (optional, required for ADC authentication with Google Storage) + * `google-auth-oauthlib <https://pypi.python.org/project/google-auth-oauthlib/>`_ + (optional, required for browser-based authentication with Google Storage) To check if a specific module :var:`<module>` is installed, execute :samp:`python3 -c 'import {<module>}; @@ -102,7 +104,7 @@ tested with :: python3 setup.py build_cython python3 setup.py build_ext --inplace - python3 -m pytest tests/ + python3 -m pytest test Note that when building from the Mercurial or Git repository, building and testing is done with several additional checks. This may cause diff --git a/rst/man/adm.rst b/rst/man/adm.rst index 4c3af3a..086299f 100644 --- a/rst/man/adm.rst +++ b/rst/man/adm.rst @@ -46,7 +46,7 @@ passphrase upgrade Upgrade the file system to the newest revision. -delete +clear Delete the file system with all the stored data. download-metadata @@ -1,6 +1,9 @@ [easy_install] allow_hosts = None +[aliases] +test = pytest + [egg_info] tag_build = tag_date = 0 @@ -20,6 +20,7 @@ except ImportError: raise SystemExit('Setuptools package not found. Please install from ' 'https://pypi.python.org/pypi/setuptools') from setuptools import Extension +from setuptools.command.test import test as TestCommand from distutils.version import LooseVersion import os @@ -104,6 +105,16 @@ class build_docs(setuptools.Command): os.path.join(dest_dir, 'manual.pdf')) +class pytest(TestCommand): + + def run_tests(self): + # import here, cause outside the eggs aren't loaded + import pytest + + errno = pytest.main(['tests']) + sys.exit(errno) + + def main(): with open(os.path.join(basedir, 'README.rst'), 'r') as fh: @@ -133,7 +144,9 @@ def main(): 'requests', 'defusedxml', 'dugong >= 3.4, < 4.0', - 'llfuse >= 1.0, < 2.0' ] + 'llfuse >= 1.0, < 2.0', + 'google-auth', + 'google-auth-oauthlib'] setuptools.setup( name='s3ql', @@ -182,9 +195,11 @@ def main(): ] }, install_requires=required_pkgs, + tests_require=['pytest >= 3.7'], cmdclass={'upload_docs': upload_docs, 'build_cython': build_cython, - 'build_sphinx': build_docs }, + 'build_sphinx': build_docs, + 'pytest': pytest }, command_options={ 'sdist': { 'formats': ('setup.py', 'bztar') } }, ) diff --git a/src/s3ql.egg-info/PKG-INFO b/src/s3ql.egg-info/PKG-INFO index 05cde60..fd4c4fd 100644 --- a/src/s3ql.egg-info/PKG-INFO +++ b/src/s3ql.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: s3ql -Version: 3.0 +Version: 3.1 Summary: a full-featured file system for online data storage Home-page: https://bitbucket.org/nikratio/s3ql/ Author: Nikolaus Rath diff --git a/src/s3ql.egg-info/requires.txt b/src/s3ql.egg-info/requires.txt index 0337445..a4f4c64 100644 --- a/src/s3ql.egg-info/requires.txt +++ b/src/s3ql.egg-info/requires.txt @@ -4,3 +4,5 @@ requests defusedxml dugong<4.0,>=3.4 llfuse<2.0,>=1.0 +google-auth +google-auth-oauthlib diff --git a/src/s3ql/__init__.py b/src/s3ql/__init__.py index 369a814..01c230c 100644 --- a/src/s3ql/__init__.py +++ b/src/s3ql/__init__.py @@ -38,7 +38,7 @@ assert logging.LOG_ONCE # prevent warnings about unused module from llfuse import ROOT_INODE -VERSION = '3.0' +VERSION = '3.1' RELEASE = '%s' % VERSION # TODO: On next revision bump, remove upgrade code from backend/comprenc.py and diff --git a/src/s3ql/backends/gs.py b/src/s3ql/backends/gs.py index 2bb43cc..508e81e 100644 --- a/src/s3ql/backends/gs.py +++ b/src/s3ql/backends/gs.py @@ -20,7 +20,6 @@ from dugong import (HTTPConnection, is_temp_network_error, BodyFollowing, CaseIn from base64 import b64encode, b64decode from itertools import count from ast import literal_eval -from argparse import Namespace import hashlib import urllib.parse @@ -88,65 +87,10 @@ class RequestError(Exception): self.code, self.reason) -class GAuthHTTPRequestor: - '''Carries out HTTP requests for google.auth - - Implements https://google-auth.readthedocs.io/en/latest/reference/google.auth.transport.html#google.auth.transport.Request +class AccessTokenExpired(Exception): + ''' + Raised if the access token has expired. ''' - - def __init__(self, ssl_context: ssl.SSLContext): - self.ssl_context = ssl_context - self.proxy = get_proxy(ssl=False) - self.ssl_proxy = get_proxy(ssl=True) - self.conn_pool = dict() # type: Dict[Tuple[str,int], HTTPConnection] - - def __call__(self, url: str, method: str = 'GET', body=None, - headers=None, timeout=None): - - # https://github.com/googleapis/google-auth-library-python/issues/318 - if not isinstance(body, bytes): - body = str(body).encode('ascii') - - if timeout is not None: - raise ValueError('*timeout* argument is not supported') - - hit = re.match(r'^(https?)://([^:/]+)(?::(\d+))?(.*)$', url) - if not hit: - raise ValueError('Unsupported URL: ' + url) - - if hit.group(1) == 'https': - ssl_context = self.ssl_context - proxy = self.ssl_proxy - else: - ssl_context = None - proxy = self.proxy - hostname = hit.group(2) - if hit.group(3): - port = int(hit.group(3)) - elif ssl_context: - port = 443 - else: - port = 80 - - path = hit.group(4) - - try: - conn = self.conn_pool[(hostname, port)] - except KeyError: - conn = HTTPConnection(hostname, port, proxy=proxy, - ssl_context=ssl_context) - self.conn_pool[(hostname, port)] = conn - - try: - conn.send_request(method, path, headers=headers, body=body) - resp = conn.read_response() - except (dugong.ConnectionClosed, dugong.InvalidResponse, dugong.UnsupportedResponse, - dugong.ConnectionTimedOut, dugong.HostnameNotResolvable, - dugong.DNSUnavailable, ssl.SSLError) as exc: - raise g_auth.exceptions.TransportError(exc) - - return Namespace(status=resp.status, headers=resp.headers, - data=conn.readall()) class Backend(AbstractBackend, metaclass=ABCDocstMeta): @@ -176,7 +120,13 @@ class Backend(AbstractBackend, metaclass=ABCDocstMeta): if g_auth is None: raise QuietError('ADC authentification requires the google.auth module') elif self.adc is None: - requestor = GAuthHTTPRequestor(self.ssl_context) + import google.auth.transport.urllib3 + import urllib3 + + # Deliberately ignore proxy and SSL context when attemping + # to connect to Compute Engine Metadata server. + requestor = google.auth.transport.urllib3.Request( + urllib3.PoolManager()) try: credentials, _ = g_auth.default( request=requestor, @@ -258,10 +208,17 @@ class Backend(AbstractBackend, metaclass=ABCDocstMeta): 500 <= exc.code <= 599 or exc.code == 408): return True + elif isinstance(exc, AccessTokenExpired): + del self.access_token[self.refresh_token] + return True + # Not clear at all what is happening here, but in doubt we retry elif isinstance(exc, ServerResponseError): return True + if g_auth and isinstance(exc, g_auth.exceptions.TransportError): + return True + return False def _assert_empty_response(self, resp): @@ -469,10 +426,8 @@ class Backend(AbstractBackend, metaclass=ABCDocstMeta): except ConnectionClosed: # No server response available pass else: - if resp.status >= 400: # Got error response - return resp - log.warning('Server broke connection during upload, but signaled ' - '%d %s', resp.status, resp.reason) + log.warning('Server broke connection during upload, signaled ' + '%d %s', resp.status, resp.reason) # Re-raise first ConnectionClosed exception raise @@ -482,6 +437,10 @@ class Backend(AbstractBackend, metaclass=ABCDocstMeta): resp = self.conn.read_response() if resp.status != 200: exc = self._parse_error_response(resp) + # If we're really unlucky, then the token has expired while we + # were uploading data. + if exc.message == 'Invalid Credentials': + raise AccessTokenExpired() raise _map_request_error(exc, key) or exc self._parse_json_response(resp) @@ -672,6 +631,7 @@ class Backend(AbstractBackend, metaclass=ABCDocstMeta): return resp elif resp.status != 401: raise self._parse_error_response(resp) + self.conn.discard() # If we reach this point, then the access token must have # expired, so we try to get a new one. We use a lock to prevent @@ -736,9 +696,9 @@ def _map_request_error(exc: RequestError, key: str): if exc.code == 404 and key: return NoSuchObject(key) elif exc.message == 'Forbidden': - return AuthorizationError() - elif exc.message == 'Login Required': - return AuthenticationError() + return AuthorizationError(exc.message) + elif exc.message in ('Login Required', 'Invalid Credentials'): + return AuthenticationError(exc.message) return None diff --git a/src/s3ql/backends/s3.py b/src/s3ql/backends/s3.py index fcb014a..501fc93 100644 --- a/src/s3ql/backends/s3.py +++ b/src/s3ql/backends/s3.py @@ -36,7 +36,7 @@ class Backend(s3c.Backend): may or may not be available and can be queried for with instance methods. """ - known_options = ((s3c.Backend.known_options | { 'sse', 'rrs', 'ia' }) + known_options = ((s3c.Backend.known_options | {'sse', 'rrs', 'ia', 'oia'}) - {'dumb-copy', 'disable-expect100'}) def __init__(self, options): @@ -91,7 +91,9 @@ class Backend(s3c.Backend): headers['x-amz-server-side-encryption'] = 'AES256' if 'ia' in self.options: - sc = 'STANDARD_IA' + sc = 'STANDARD_IA' + elif 'oia' in self.options: + sc = 'ONEZONE_IA' elif 'rrs' in self.options: sc = 'REDUCED_REDUNDANCY' else: diff --git a/src/s3ql/block_cache.py b/src/s3ql/block_cache.py index 8f12ef6..8652d42 100644 --- a/src/s3ql/block_cache.py +++ b/src/s3ql/block_cache.py @@ -149,7 +149,7 @@ class CacheEntry(object): :pos: current position in file """ - __slots__ = [ 'dirty', 'inode', 'blockno', 'last_access', + __slots__ = [ 'dirty', 'inode', 'blockno', 'last_write', 'size', 'pos', 'fh', 'removed' ] def __init__(self, inode, blockno, filename, mode='w+b'): @@ -161,7 +161,7 @@ class CacheEntry(object): self.dirty = False self.inode = inode self.blockno = blockno - self.last_access = 0 + self.last_write = 0 self.pos = self.fh.tell() self.size = os.fstat(self.fh.fileno()).st_size @@ -195,6 +195,7 @@ class CacheEntry(object): self.fh.write(buf) self.pos += len(buf) self.size = max(self.pos, self.size) + self.last_write = time.time() def close(self): self.fh.close() @@ -785,7 +786,6 @@ class BlockCache(object): self._lock_entry(inode, blockno, release_global=True) try: el = self._get_entry(inode, blockno) - el.last_access = time.time() oldsize = el.size try: yield el diff --git a/src/s3ql/cp.py b/src/s3ql/cp.py index a6e31a4..1eea53a 100644 --- a/src/s3ql/cp.py +++ b/src/s3ql/cp.py @@ -32,6 +32,7 @@ def parse_args(args): additional storage space. ''')) + parser.add_log() parser.add_debug() parser.add_quiet() parser.add_version() diff --git a/src/s3ql/ctrl.py b/src/s3ql/ctrl.py index 35bd530..9433ccf 100644 --- a/src/s3ql/ctrl.py +++ b/src/s3ql/ctrl.py @@ -31,6 +31,7 @@ def parse_args(args): type=(lambda x: x.rstrip('/')), help='Mountpoint of the file system') + parser.add_log() parser.add_debug() parser.add_quiet() parser.add_version() diff --git a/src/s3ql/lock.py b/src/s3ql/lock.py index 645e321..f829c28 100644 --- a/src/s3ql/lock.py +++ b/src/s3ql/lock.py @@ -26,6 +26,7 @@ def parse_args(args): deleted with s3qlrm. ''')) + parser.add_log() parser.add_debug() parser.add_quiet() parser.add_version() diff --git a/src/s3ql/mkfs.py b/src/s3ql/mkfs.py index cf03c6c..b271fd4 100644 --- a/src/s3ql/mkfs.py +++ b/src/s3ql/mkfs.py @@ -31,6 +31,7 @@ def parse_args(args): description="Initializes an S3QL file system") parser.add_cachedir() + parser.add_log() parser.add_debug() parser.add_quiet() parser.add_backend_options() diff --git a/src/s3ql/mount.py b/src/s3ql/mount.py index 0237b4c..b769339 100644 --- a/src/s3ql/mount.py +++ b/src/s3ql/mount.py @@ -431,7 +431,11 @@ def mark_metadata_dirty(backend, cachepath, param): def get_fuse_opts(options): '''Return fuse options for given command line options''' - fuse_opts = [ "nonempty", 'fsname=%s' % options.storage_url, + fsname=options.fs_name + if not fsname: + fsname = options.storage_url + + fuse_opts = [ "nonempty", 'fsname=%s' % fsname, 'subtype=s3ql', 'big_writes', 'max_write=131072', 'no_remote_lock' ] @@ -529,6 +533,10 @@ def parse_args(args): 'user and the root user.') parser.add_argument("--fg", action="store_true", default=False, help="Do not daemonize, stay in foreground") + parser.add_argument("--fs-name", default=None, + help="Mount name passed to fuse, the name will be shown in the first " + "column of the system mount command output. If not specified your " + "storage url is used.") parser.add_argument("--systemd", action="store_true", default=False, help="Run as systemd unit. Consider specifying --log none as well " "to make use of journald.") @@ -731,7 +739,7 @@ class CommitThread(Thread): # ... number=500)/500 * 1e3 # 1.456586996000624 for el in list(self.block_cache.cache.values()): - if self.stop_event.is_set() or stamp - el.last_access < 10: + if self.stop_event.is_set() or stamp - el.last_write < 10: break if el.dirty and el not in self.block_cache.in_transit: self.block_cache.upload_if_dirty(el) diff --git a/src/s3ql/oauth_client.py b/src/s3ql/oauth_client.py index 854eb25..cdac8dd 100644 --- a/src/s3ql/oauth_client.py +++ b/src/s3ql/oauth_client.py @@ -9,10 +9,10 @@ This work can be distributed under the terms of the GNU GPLv3. from .logging import logging, setup_logging, QuietError from .parse_args import ArgumentParser from .common import OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET +from google_auth_oauthlib.flow import InstalledAppFlow import sys import textwrap import requests -import time log = logging.getLogger(__name__) @@ -25,6 +25,7 @@ def parse_args(args): Obtain OAuth2 refresh token for Google Storage ''')) + parser.add_log() parser.add_debug() parser.add_quiet() parser.add_version() @@ -64,40 +65,20 @@ def main(args=None): options = parse_args(args) setup_logging(options) - cli = requests.Session() - # We need full control in order to be able to update metadata # cf. https://stackoverflow.com/questions/24718787 - r = cli.post('https://accounts.google.com/o/oauth2/device/code', - data={ 'client_id': OAUTH_CLIENT_ID, - 'scope': 'https://www.googleapis.com/auth/devstorage.full_control' }, - verify=True, allow_redirects=False, timeout=20) - req_json = _parse_response(r) - - print(textwrap.fill('Please open %s in your browser and enter the following ' - 'user code: %s' % (req_json['verification_url'], - req_json['user_code']))) - - while True: - log.debug('polling..') - time.sleep(req_json['interval']) - - r = cli.post('https://accounts.google.com/o/oauth2/token', - data={ 'client_id': OAUTH_CLIENT_ID, - 'client_secret': OAUTH_CLIENT_SECRET, - 'code': req_json['device_code'], - 'grant_type': 'http://oauth.net/grant_type/device/1.0' }, - verify=True, allow_redirects=False, timeout=20) - resp_json = _parse_response(r) - r.close() - - if 'error' in resp_json: - if resp_json['error'] == 'authorization_pending': - continue - else: - raise QuietError('Authentication failed: ' + resp_json['error']) - else: - break - - print('Success. Your refresh token is:\n', - resp_json['refresh_token']) + flow = InstalledAppFlow.from_client_config( + client_config={ + "installed": { + "client_id": OAUTH_CLIENT_ID, + "client_secret": OAUTH_CLIENT_SECRET, + "redirect_uris": ["http://localhost", "urn:ietf:wg:oauth:2.0:oob"], + "auth_uri": "https://accounts.google.com/o/oauth2/auth", + "token_uri": "https://accounts.google.com/o/oauth2/token" + } + }, + scopes=['https://www.googleapis.com/auth/devstorage.full_control']) + + credentials = flow.run_local_server(open_browser=True) + + print('Success. Your refresh token is:\n', credentials.refresh_token) diff --git a/src/s3ql/remove.py b/src/s3ql/remove.py index b0f1395..5a23576 100644 --- a/src/s3ql/remove.py +++ b/src/s3ql/remove.py @@ -25,6 +25,7 @@ def parse_args(args): including immutable entries. ''')) + parser.add_log() parser.add_debug() parser.add_quiet() parser.add_version() diff --git a/src/s3ql/statfs.py b/src/s3ql/statfs.py index 57c3408..d1f4248 100644 --- a/src/s3ql/statfs.py +++ b/src/s3ql/statfs.py @@ -21,6 +21,7 @@ def parse_args(args): parser = ArgumentParser( description="Print file system statistics.") + parser.add_log() parser.add_debug() parser.add_quiet() parser.add_version() diff --git a/src/s3ql/umount.py b/src/s3ql/umount.py index 1513116..8a0ad1c 100644 --- a/src/s3ql/umount.py +++ b/src/s3ql/umount.py @@ -32,6 +32,7 @@ def parse_args(args): Unmounts an S3QL file system. The command returns only after all data has been uploaded to the backend.''')) + parser.add_log() parser.add_debug() parser.add_quiet() parser.add_version() diff --git a/src/s3ql/verify.py b/src/s3ql/verify.py index b09470c..3ae62a0 100644 --- a/src/s3ql/verify.py +++ b/src/s3ql/verify.py @@ -48,6 +48,7 @@ def parse_args(args): every object. It therefore takes a lot longer. ''')) + parser.add_log() parser.add_debug() parser.add_quiet() parser.add_version() diff --git a/tests/.pytest_cache/v/cache/lastfailed b/tests/.pytest_cache/v/cache/lastfailed index 61889b5..a2c00e2 100644 --- a/tests/.pytest_cache/v/cache/lastfailed +++ b/tests/.pytest_cache/v/cache/lastfailed @@ -1,48 +1,25 @@ { "t1_backends.py::test_clear[remote-gs/aes]": true, - "t1_backends.py::test_complex_meta[remote-gs/raw]": true, "t1_backends.py::test_complex_meta[remote-swiftks/raw]": true, - "t1_backends.py::test_copy[remote-gs/raw]": true, "t1_backends.py::test_copy[remote-swiftks/raw]": true, - "t1_backends.py::test_copy_newmeta[remote-gs/raw]": true, "t1_backends.py::test_copy_newmeta[remote-swiftks/raw]": true, - "t1_backends.py::test_copy_special[remote-gs/raw]": true, "t1_backends.py::test_copy_special[remote-swiftks/raw]": true, - "t1_backends.py::test_delete[remote-gs/aes]": true, "t1_backends.py::test_delete[remote-swiftks/aes]": true, - "t1_backends.py::test_delete_multi[remote-gs/aes]": true, "t1_backends.py::test_delete_multi[remote-swiftks/aes]": true, - "t1_backends.py::test_list[remote-gs/aes]": true, "t1_backends.py::test_list[remote-swiftks/aes]": true, - "t1_backends.py::test_multi_packet[remote-gs/aes+zlib]": true, - "t1_backends.py::test_multi_packet[remote-gs/aes]": true, - "t1_backends.py::test_multi_packet[remote-gs/plain]": true, - "t1_backends.py::test_multi_packet[remote-gs/raw]": true, - "t1_backends.py::test_multi_packet[remote-gs/zlib]": true, "t1_backends.py::test_multi_packet[remote-swiftks/aes+zlib]": true, "t1_backends.py::test_multi_packet[remote-swiftks/aes]": true, "t1_backends.py::test_multi_packet[remote-swiftks/plain]": true, "t1_backends.py::test_multi_packet[remote-swiftks/raw]": true, "t1_backends.py::test_multi_packet[remote-swiftks/zlib]": true, "t1_backends.py::test_read_write[mock-gs/aes]": true, - "t1_backends.py::test_read_write[remote-gs/aes+zlib]": true, - "t1_backends.py::test_read_write[remote-gs/aes]": true, - "t1_backends.py::test_read_write[remote-gs/bzip2]": true, - "t1_backends.py::test_read_write[remote-gs/lzma]": true, - "t1_backends.py::test_read_write[remote-gs/plain]": true, - "t1_backends.py::test_read_write[remote-gs/raw]": true, - "t1_backends.py::test_read_write[remote-gs/zlib]": true, "t1_backends.py::test_read_write[remote-swiftks/aes+zlib]": true, "t1_backends.py::test_read_write[remote-swiftks/bzip2]": true, "t1_backends.py::test_read_write[remote-swiftks/lzma]": true, "t1_backends.py::test_read_write[remote-swiftks/plain]": true, "t1_backends.py::test_read_write[remote-swiftks/raw]": true, "t1_backends.py::test_read_write[remote-swiftks/zlib]": true, - "t1_backends.py::test_readslowly[remote-gs/raw]": true, - "t1_backends.py::test_rename[remote-gs/raw]": true, "t1_backends.py::test_rename[remote-swiftks/raw]": true, - "t1_backends.py::test_rename_newmeta[remote-gs/raw]": true, "t1_backends.py::test_rename_newmeta[remote-swiftks/raw]": true, - "t1_backends.py::test_update_meta[remote-gs/raw]": true, "t1_backends.py::test_update_meta[remote-swiftks/raw]": true }
\ No newline at end of file diff --git a/tests/.pytest_cache/v/cache/nodeids b/tests/.pytest_cache/v/cache/nodeids index 1961ce6..6771a25 100644 --- a/tests/.pytest_cache/v/cache/nodeids +++ b/tests/.pytest_cache/v/cache/nodeids @@ -1,42 +1,49 @@ [ "t1_backends.py::test_read_write[local/aes]", "t1_backends.py::test_read_write[remote-s3/aes]", + "t1_backends.py::test_read_write[remote-gs/aes]", "t1_backends.py::test_read_write[mock-s3c/aes]", "t1_backends.py::test_read_write[mock-swift/aes0]", "t1_backends.py::test_read_write[mock-swift/aes1]", "t1_backends.py::test_read_write[mock-swift/aes2]", "t1_backends.py::test_read_write[local/aes+zlib]", "t1_backends.py::test_read_write[remote-s3/aes+zlib]", + "t1_backends.py::test_read_write[remote-gs/aes+zlib]", "t1_backends.py::test_read_write[mock-s3c/aes+zlib]", "t1_backends.py::test_read_write[mock-swift/aes+zlib0]", "t1_backends.py::test_read_write[mock-swift/aes+zlib1]", "t1_backends.py::test_read_write[mock-swift/aes+zlib2]", "t1_backends.py::test_read_write[local/plain]", "t1_backends.py::test_read_write[remote-s3/plain]", + "t1_backends.py::test_read_write[remote-gs/plain]", "t1_backends.py::test_read_write[mock-s3c/plain]", "t1_backends.py::test_read_write[mock-swift/plain0]", "t1_backends.py::test_read_write[mock-swift/plain1]", "t1_backends.py::test_read_write[mock-swift/plain2]", "t1_backends.py::test_read_write[local/zlib]", "t1_backends.py::test_read_write[remote-s3/zlib]", + "t1_backends.py::test_read_write[remote-gs/zlib]", "t1_backends.py::test_read_write[mock-s3c/zlib]", "t1_backends.py::test_read_write[mock-swift/zlib0]", "t1_backends.py::test_read_write[mock-swift/zlib1]", "t1_backends.py::test_read_write[mock-swift/zlib2]", "t1_backends.py::test_read_write[local/bzip2]", "t1_backends.py::test_read_write[remote-s3/bzip2]", + "t1_backends.py::test_read_write[remote-gs/bzip2]", "t1_backends.py::test_read_write[mock-s3c/bzip2]", "t1_backends.py::test_read_write[mock-swift/bzip20]", "t1_backends.py::test_read_write[mock-swift/bzip21]", "t1_backends.py::test_read_write[mock-swift/bzip22]", "t1_backends.py::test_read_write[local/lzma]", "t1_backends.py::test_read_write[remote-s3/lzma]", + "t1_backends.py::test_read_write[remote-gs/lzma]", "t1_backends.py::test_read_write[mock-s3c/lzma]", "t1_backends.py::test_read_write[mock-swift/lzma0]", "t1_backends.py::test_read_write[mock-swift/lzma1]", "t1_backends.py::test_read_write[mock-swift/lzma2]", "t1_backends.py::test_read_write[local/raw]", "t1_backends.py::test_read_write[remote-s3/raw]", + "t1_backends.py::test_read_write[remote-gs/raw]", "t1_backends.py::test_read_write[mock-s3c/raw]", "t1_backends.py::test_read_write[mock-swift/raw0]", "t1_backends.py::test_read_write[mock-swift/raw1]", @@ -46,6 +53,7 @@ "t1_backends.py::test_issue114[mock-swift/raw2]", "t1_backends.py::test_complex_meta[local/raw]", "t1_backends.py::test_complex_meta[remote-s3/raw]", + "t1_backends.py::test_complex_meta[remote-gs/raw]", "t1_backends.py::test_complex_meta[mock-s3c/raw]", "t1_backends.py::test_complex_meta[mock-swift/raw0]", "t1_backends.py::test_complex_meta[mock-swift/raw1]", @@ -55,11 +63,13 @@ "t1_backends.py::test_complex_meta[local/zlib]", "t1_backends.py::test_list[local/aes]", "t1_backends.py::test_list[remote-s3/aes]", + "t1_backends.py::test_list[remote-gs/aes]", "t1_backends.py::test_list[mock-s3c/aes]", "t1_backends.py::test_list[mock-swift/aes0]", "t1_backends.py::test_list[mock-swift/aes1]", "t1_backends.py::test_list[mock-swift/aes2]", "t1_backends.py::test_readslowly[local/raw]", + "t1_backends.py::test_readslowly[remote-gs/raw]", "t1_backends.py::test_readslowly[mock-s3c/raw]", "t1_backends.py::test_readslowly[mock-swift/raw0]", "t1_backends.py::test_readslowly[mock-swift/raw1]", @@ -70,18 +80,21 @@ "t1_backends.py::test_readslowly[local/aes+zlib]", "t1_backends.py::test_delete[local/aes]", "t1_backends.py::test_delete[remote-s3/aes]", + "t1_backends.py::test_delete[remote-gs/aes]", "t1_backends.py::test_delete[mock-s3c/aes]", "t1_backends.py::test_delete[mock-swift/aes0]", "t1_backends.py::test_delete[mock-swift/aes1]", "t1_backends.py::test_delete[mock-swift/aes2]", "t1_backends.py::test_delete_multi[local/aes]", "t1_backends.py::test_delete_multi[remote-s3/aes]", + "t1_backends.py::test_delete_multi[remote-gs/aes]", "t1_backends.py::test_delete_multi[mock-s3c/aes]", "t1_backends.py::test_delete_multi[mock-swift/aes0]", "t1_backends.py::test_delete_multi[mock-swift/aes1]", "t1_backends.py::test_delete_multi[mock-swift/aes2]", "t1_backends.py::test_copy[local/raw]", "t1_backends.py::test_copy[remote-s3/raw]", + "t1_backends.py::test_copy[remote-gs/raw]", "t1_backends.py::test_copy[mock-s3c/raw]", "t1_backends.py::test_copy[mock-swift/raw0]", "t1_backends.py::test_copy[mock-swift/raw1]", @@ -91,12 +104,14 @@ "t1_backends.py::test_copy[local/zlib]", "t1_backends.py::test_copy_special[local/raw]", "t1_backends.py::test_copy_special[remote-s3/raw]", + "t1_backends.py::test_copy_special[remote-gs/raw]", "t1_backends.py::test_copy_special[mock-s3c/raw]", "t1_backends.py::test_copy_special[mock-swift/raw0]", "t1_backends.py::test_copy_special[mock-swift/raw1]", "t1_backends.py::test_copy_special[mock-swift/raw2]", "t1_backends.py::test_copy_newmeta[local/raw]", "t1_backends.py::test_copy_newmeta[remote-s3/raw]", + "t1_backends.py::test_copy_newmeta[remote-gs/raw]", "t1_backends.py::test_copy_newmeta[mock-s3c/raw]", "t1_backends.py::test_copy_newmeta[mock-swift/raw0]", "t1_backends.py::test_copy_newmeta[mock-swift/raw1]", @@ -105,6 +120,7 @@ "t1_backends.py::test_copy_newmeta[local/zlib]", "t1_backends.py::test_rename[local/raw]", "t1_backends.py::test_rename[remote-s3/raw]", + "t1_backends.py::test_rename[remote-gs/raw]", "t1_backends.py::test_rename[mock-s3c/raw]", "t1_backends.py::test_rename[mock-swift/raw0]", "t1_backends.py::test_rename[mock-swift/raw1]", @@ -113,6 +129,7 @@ "t1_backends.py::test_rename[local/zlib]", "t1_backends.py::test_rename_newmeta[local/raw]", "t1_backends.py::test_rename_newmeta[remote-s3/raw]", + "t1_backends.py::test_rename_newmeta[remote-gs/raw]", "t1_backends.py::test_rename_newmeta[mock-s3c/raw]", "t1_backends.py::test_rename_newmeta[mock-swift/raw0]", "t1_backends.py::test_rename_newmeta[mock-swift/raw1]", @@ -121,6 +138,7 @@ "t1_backends.py::test_rename_newmeta[local/zlib]", "t1_backends.py::test_update_meta[local/raw]", "t1_backends.py::test_update_meta[remote-s3/raw]", + "t1_backends.py::test_update_meta[remote-gs/raw]", "t1_backends.py::test_update_meta[mock-s3c/raw]", "t1_backends.py::test_update_meta[mock-swift/raw0]", "t1_backends.py::test_update_meta[mock-swift/raw1]", @@ -142,30 +160,35 @@ "t1_backends.py::test_extra_data[local/lzma]", "t1_backends.py::test_multi_packet[local/raw]", "t1_backends.py::test_multi_packet[remote-s3/raw]", + "t1_backends.py::test_multi_packet[remote-gs/raw]", "t1_backends.py::test_multi_packet[mock-s3c/raw]", "t1_backends.py::test_multi_packet[mock-swift/raw0]", "t1_backends.py::test_multi_packet[mock-swift/raw1]", "t1_backends.py::test_multi_packet[mock-swift/raw2]", "t1_backends.py::test_multi_packet[local/plain]", "t1_backends.py::test_multi_packet[remote-s3/plain]", + "t1_backends.py::test_multi_packet[remote-gs/plain]", "t1_backends.py::test_multi_packet[mock-s3c/plain]", "t1_backends.py::test_multi_packet[mock-swift/plain0]", "t1_backends.py::test_multi_packet[mock-swift/plain1]", "t1_backends.py::test_multi_packet[mock-swift/plain2]", "t1_backends.py::test_multi_packet[local/aes]", "t1_backends.py::test_multi_packet[remote-s3/aes]", + "t1_backends.py::test_multi_packet[remote-gs/aes]", "t1_backends.py::test_multi_packet[mock-s3c/aes]", "t1_backends.py::test_multi_packet[mock-swift/aes0]", "t1_backends.py::test_multi_packet[mock-swift/aes1]", "t1_backends.py::test_multi_packet[mock-swift/aes2]", "t1_backends.py::test_multi_packet[local/aes+zlib]", "t1_backends.py::test_multi_packet[remote-s3/aes+zlib]", + "t1_backends.py::test_multi_packet[remote-gs/aes+zlib]", "t1_backends.py::test_multi_packet[mock-s3c/aes+zlib]", "t1_backends.py::test_multi_packet[mock-swift/aes+zlib0]", "t1_backends.py::test_multi_packet[mock-swift/aes+zlib1]", "t1_backends.py::test_multi_packet[mock-swift/aes+zlib2]", "t1_backends.py::test_multi_packet[local/zlib]", "t1_backends.py::test_multi_packet[remote-s3/zlib]", + "t1_backends.py::test_multi_packet[remote-gs/zlib]", "t1_backends.py::test_multi_packet[mock-s3c/zlib]", "t1_backends.py::test_multi_packet[mock-swift/zlib0]", "t1_backends.py::test_multi_packet[mock-swift/zlib1]", @@ -320,51 +343,51 @@ "t4_authinfo.py::test_invalid_backend_option", "t4_authinfo.py::test_option_precedence", "t4_authinfo.py::test_passphrase", - "t4_fuse.py::TestFuse::()::test", - "t5_cache.py::TestPerstCache::()::test", - "t5_cache.py::TestPerstCache::()::test_cache_upload", - "t5_cache.py::TestPerstCache::()::test_cache_flush[True]", - "t5_cache.py::TestPerstCache::()::test_cache_flush[False]", - "t5_cache.py::TestPerstCache::()::test_cache_flush_unclean", - "t5_cp.py::TestCp::()::test", - "t5_ctrl.py::TestCtrl::()::test", - "t5_failsafe.py::TestFailsafe::()::test", - "t5_failsafe.py::TestNewerMetadata::()::test", - "t5_fsck.py::TestFsck::()::test", - "t5_full.py::TestFullgs::()::test", - "t5_full.py::TestFullswiftks::()::test", - "t5_full.py::TestFulls3c::()::test", - "t5_full.py::TestFullrackspace::()::test", - "t5_full.py::TestFulls3::()::test", - "t5_full.py::TestFullswift::()::test", - "t5_full.py::TestFull::()::test", - "t5_lock_rm.py::TestLockRemove::()::test", - "t6_upgrade.py::Tests3cUpgrade::()::test[True]", - "t6_upgrade.py::Tests3cUpgrade::()::test[False]", - "t6_upgrade.py::TestPlainswiftksUpgrade::()::test[True]", - "t6_upgrade.py::TestPlainswiftksUpgrade::()::test[False]", - "t6_upgrade.py::TestswiftUpgrade::()::test[True]", - "t6_upgrade.py::TestswiftUpgrade::()::test[False]", - "t6_upgrade.py::Tests3Upgrade::()::test[True]", - "t6_upgrade.py::Tests3Upgrade::()::test[False]", - "t6_upgrade.py::TestPlainswiftUpgrade::()::test[True]", - "t6_upgrade.py::TestPlainswiftUpgrade::()::test[False]", - "t6_upgrade.py::TestPlainrackspaceUpgrade::()::test[True]", - "t6_upgrade.py::TestPlainrackspaceUpgrade::()::test[False]", - "t6_upgrade.py::TestrackspaceUpgrade::()::test[True]", - "t6_upgrade.py::TestrackspaceUpgrade::()::test[False]", - "t6_upgrade.py::TestgsUpgrade::()::test[True]", - "t6_upgrade.py::TestgsUpgrade::()::test[False]", - "t6_upgrade.py::TestPlaingsUpgrade::()::test[True]", - "t6_upgrade.py::TestPlaingsUpgrade::()::test[False]", - "t6_upgrade.py::TestPlains3Upgrade::()::test[True]", - "t6_upgrade.py::TestPlains3Upgrade::()::test[False]", - "t6_upgrade.py::TestPlains3cUpgrade::()::test[True]", - "t6_upgrade.py::TestPlains3cUpgrade::()::test[False]", - "t6_upgrade.py::TestswiftksUpgrade::()::test[True]", - "t6_upgrade.py::TestswiftksUpgrade::()::test[False]", - "t6_upgrade.py::TestUpgrade::()::test[True]", - "t6_upgrade.py::TestUpgrade::()::test[False]", - "t6_upgrade.py::TestPlainUpgrade::()::test[True]", - "t6_upgrade.py::TestPlainUpgrade::()::test[False]" + "t4_fuse.py::TestFuse::test", + "t5_cache.py::TestPerstCache::test", + "t5_cache.py::TestPerstCache::test_cache_upload", + "t5_cache.py::TestPerstCache::test_cache_flush[True]", + "t5_cache.py::TestPerstCache::test_cache_flush[False]", + "t5_cache.py::TestPerstCache::test_cache_flush_unclean", + "t5_cp.py::TestCp::test", + "t5_ctrl.py::TestCtrl::test", + "t5_failsafe.py::TestFailsafe::test", + "t5_failsafe.py::TestNewerMetadata::test", + "t5_fsck.py::TestFsck::test", + "t5_full.py::TestFullgs::test", + "t5_full.py::TestFullrackspace::test", + "t5_full.py::TestFullswiftks::test", + "t5_full.py::TestFulls3::test", + "t5_full.py::TestFullswift::test", + "t5_full.py::TestFulls3c::test", + "t5_full.py::TestFull::test", + "t5_lock_rm.py::TestLockRemove::test", + "t6_upgrade.py::TestswiftUpgrade::test[True]", + "t6_upgrade.py::TestswiftUpgrade::test[False]", + "t6_upgrade.py::TestgsUpgrade::test[True]", + "t6_upgrade.py::TestgsUpgrade::test[False]", + "t6_upgrade.py::TestPlaingsUpgrade::test[True]", + "t6_upgrade.py::TestPlaingsUpgrade::test[False]", + "t6_upgrade.py::Tests3Upgrade::test[True]", + "t6_upgrade.py::Tests3Upgrade::test[False]", + "t6_upgrade.py::TestrackspaceUpgrade::test[True]", + "t6_upgrade.py::TestrackspaceUpgrade::test[False]", + "t6_upgrade.py::TestPlainswiftksUpgrade::test[True]", + "t6_upgrade.py::TestPlainswiftksUpgrade::test[False]", + "t6_upgrade.py::TestPlains3cUpgrade::test[True]", + "t6_upgrade.py::TestPlains3cUpgrade::test[False]", + "t6_upgrade.py::TestPlainswiftUpgrade::test[True]", + "t6_upgrade.py::TestPlainswiftUpgrade::test[False]", + "t6_upgrade.py::TestswiftksUpgrade::test[True]", + "t6_upgrade.py::TestswiftksUpgrade::test[False]", + "t6_upgrade.py::TestPlains3Upgrade::test[True]", + "t6_upgrade.py::TestPlains3Upgrade::test[False]", + "t6_upgrade.py::TestPlainrackspaceUpgrade::test[True]", + "t6_upgrade.py::TestPlainrackspaceUpgrade::test[False]", + "t6_upgrade.py::Tests3cUpgrade::test[True]", + "t6_upgrade.py::Tests3cUpgrade::test[False]", + "t6_upgrade.py::TestUpgrade::test[True]", + "t6_upgrade.py::TestUpgrade::test[False]", + "t6_upgrade.py::TestPlainUpgrade::test[True]", + "t6_upgrade.py::TestPlainUpgrade::test[False]" ]
\ No newline at end of file |