forked from wal-e/wal-e
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added a new blobstore based on OpenStack Swift
- Loading branch information
Showing
16 changed files
with
401 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
gevent>=0.13.1 | ||
boto>=2.6.0 | ||
azure==0.7.0 | ||
python-swiftclient | ||
python-keystoneclient |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from wal_e.blobstore.swift.credentials import Credentials | ||
from wal_e.blobstore.swift.utils import ( | ||
uri_put_file, uri_get_file, do_lzop_get, write_and_return_error, SwiftKey | ||
) | ||
|
||
__all__ = [ | ||
"Credentials", | ||
"uri_put_file", | ||
"uri_get_file", | ||
"do_lzop_get", | ||
"write_and_return_error", | ||
"SwiftKey", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import swiftclient | ||
|
||
|
||
def connect(creds): | ||
""" | ||
Construct a connection value from a container | ||
""" | ||
return swiftclient.Connection( | ||
authurl=creds.authurl, | ||
user=creds.user, | ||
key=creds.password, | ||
auth_version="2", | ||
tenant_name=creds.tenant_name, | ||
os_options={"region_name": creds.region}, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
class Credentials(object): | ||
def __init__(self, authurl, user, password, tenant_name, region): | ||
self.authurl = authurl | ||
self.user = user | ||
self.password = password | ||
self.tenant_name = tenant_name | ||
self.region = region |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
import socket | ||
import traceback | ||
from urlparse import urlparse | ||
|
||
import gevent | ||
|
||
from wal_e import log_help | ||
from wal_e.blobstore.swift import calling_format | ||
from wal_e.pipeline import get_download_pipeline | ||
from wal_e.piper import PIPE | ||
from wal_e.retries import retry, retry_with_count | ||
|
||
|
||
logger = log_help.WalELogger(__name__) | ||
|
||
|
||
class SwiftKey(object): | ||
def __init__(self, name, size, last_modified=None): | ||
self.name = name | ||
self.size = size | ||
self.last_modified = last_modified | ||
|
||
|
||
def uri_put_file(creds, uri, fp, content_encoding=None): | ||
assert fp.tell() == 0 | ||
assert uri.startswith('swift://') | ||
|
||
url_tup = urlparse(uri) | ||
|
||
container_name = url_tup.netloc | ||
conn = calling_format.connect(creds) | ||
|
||
data = fp.read() | ||
conn.put_object( | ||
container_name, url_tup.path, data, content_type=content_encoding | ||
) | ||
return SwiftKey(url_tup.path, len(data)) | ||
|
||
|
||
def do_lzop_get(creds, uri, path, decrypt): | ||
""" | ||
Get and decompress a Swift URL | ||
This streams the content directly to lzop; the compressed version | ||
is never stored on disk. | ||
""" | ||
assert uri.endswith('.lzo'), 'Expect an lzop-compressed file' | ||
|
||
def log_wal_fetch_failures_on_error(exc_tup, exc_processor_cxt): | ||
def standard_detail_message(prefix=''): | ||
return (prefix + ' There have been {n} attempts to fetch wal ' | ||
'file {uri} so far.'.format(n=exc_processor_cxt, uri=uri)) | ||
typ, value, tb = exc_tup | ||
del exc_tup | ||
|
||
# Screen for certain kinds of known-errors to retry from | ||
if issubclass(typ, socket.error): | ||
socketmsg = value[1] if isinstance(value, tuple) else value | ||
|
||
logger.info( | ||
msg='Retrying fetch because of a socket error', | ||
detail=standard_detail_message( | ||
"The socket error's message is '{0}'." | ||
.format(socketmsg))) | ||
else: | ||
# For all otherwise untreated exceptions, report them as a | ||
# warning and retry anyway -- all exceptions that can be | ||
# justified should be treated and have error messages | ||
# listed. | ||
logger.warning( | ||
msg='retrying WAL file fetch from unexpected exception', | ||
detail=standard_detail_message( | ||
'The exception type is {etype} and its value is ' | ||
'{evalue} and its traceback is {etraceback}' | ||
.format(etype=typ, evalue=value, | ||
etraceback=''.join(traceback.format_tb(tb))))) | ||
|
||
# Help Python GC by resolving possible cycles | ||
del tb | ||
|
||
@retry(retry_with_count(log_wal_fetch_failures_on_error)) | ||
def download(): | ||
with open(path, 'wb') as decomp_out: | ||
pipeline = get_download_pipeline(PIPE, decomp_out, decrypt) | ||
|
||
conn = calling_format.connect(creds) | ||
|
||
g = gevent.spawn(write_and_return_error, uri, conn, pipeline.stdin) | ||
|
||
# Raise any exceptions from write_and_return_error | ||
exc = g.get() | ||
if exc is not None: | ||
raise exc | ||
|
||
pipeline.finish() | ||
|
||
logger.info( | ||
msg='completed download and decompression', | ||
detail='Downloaded and decompressed "{uri}" to "{path}"' | ||
.format(uri=uri, path=path)) | ||
return True | ||
|
||
return download() | ||
|
||
|
||
def uri_get_file(creds, uri, conn=None): | ||
assert uri.startswith('swift://') | ||
url_tup = urlparse(uri) | ||
container_name = url_tup.netloc | ||
object_name = url_tup.path | ||
|
||
if conn is None: | ||
conn = calling_format.connect(creds) | ||
_, content = conn.get_object(container_name, object_name) | ||
return content | ||
|
||
|
||
def write_and_return_error(uri, conn, stream): | ||
try: | ||
stream.write(uri_get_file(None, uri, conn)) | ||
stream.flush() | ||
except Exception, e: | ||
return e | ||
finally: | ||
stream.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
from wal_e.blobstore.swift import calling_format | ||
from wal_e.operator.backup import Backup | ||
from wal_e.worker.swift import swift_worker | ||
|
||
|
||
class SwiftBackup(Backup): | ||
""" | ||
Aerforms OpenStack Swift uploads of PostgreSQL WAL files and clusters | ||
""" | ||
|
||
def __init__(self, layout, creds, gpg_key_id): | ||
super(SwiftBackup, self).__init__(layout, creds, gpg_key_id) | ||
self.cinfo = calling_format | ||
self.worker = swift_worker |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import json | ||
|
||
from wal_e.blobstore import swift | ||
from wal_e.storage.base import BackupInfo | ||
|
||
|
||
class SwiftBackupInfo(BackupInfo): | ||
def load_detail(self, conn): | ||
if self._details_loaded: | ||
return | ||
|
||
uri = "{scheme}://{bucket}/{path}".format( | ||
scheme=self.layout.scheme, | ||
bucket=self.layout.store_name(), | ||
path=self.layout.basebackup_sentinel(self)) | ||
|
||
data = json.loads(swift.uri_get_file(None, uri, conn=conn)) | ||
for k, v in data.items(): | ||
setattr(self, k, v) | ||
|
||
self._details_loaded = True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
from wal_e.worker.swift.swift_deleter import Deleter | ||
from wal_e.worker.swift.swift_worker import ( | ||
TarPartitionLister, BackupFetcher, BackupList, DeleteFromContext | ||
) | ||
|
||
__all__ = [ | ||
"Deleter", | ||
"TarPartitionLister", | ||
"BackupFetcher", | ||
"BackupList", | ||
"DeleteFromContext", | ||
] |
Oops, something went wrong.