-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DB Backups to Openstack Swift #371
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
ecf715f
DB Backups to Openstack Swift
jerryk55 efe38c5
Rubocop Complaints
jerryk55 1e91321
Travis Failure Fix
jerryk55 57a2d95
Review Comments
jerryk55 5c3ebdc
Fix Travis Failure
jerryk55 f3a3f05
Swift DB Backup Support with MiqObjectStorage Methodology
jerryk55 aa8f839
Remove ref to $fog_log
jerryk55 49ccf0f
Review Comments
jerryk55 11cb304
Initial Set of MiqSwiftStorage Tests and Stub #download_single.
jerryk55 c8730ec
Lots of spacing and comment changes brought up in review.
jerryk55 2e8c9e8
Remove #uri_to_local_path and add initial tests for MiqSwiftStorage
jerryk55 47dd52c
Make #auth_url a private Method separate from #swift.
jerryk55 518f48f
Add tests to make sure Query String is empty in auth_url
jerryk55 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
159 changes: 159 additions & 0 deletions
159
lib/gems/pending/util/object_storage/miq_swift_storage.rb
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,159 @@ | ||
require 'util/miq_object_storage' | ||
|
||
class MiqSwiftStorage < MiqObjectStorage | ||
attr_reader :container_name | ||
|
||
def self.uri_scheme | ||
"swift".freeze | ||
end | ||
|
||
def self.new_with_opts(opts) | ||
new(opts.slice(:uri, :username, :password)) | ||
end | ||
|
||
def initialize(settings) | ||
super(settings) | ||
@bucket_name = URI(@settings[:uri]).host | ||
|
||
raise "username and password are required values!" if @settings[:username].nil? || @settings[:password].nil? | ||
_scheme, _userinfo, @host, @port, _registry, @mount_path, _opaque, query, _fragment = URI.split(URI.encode(@settings[:uri])) | ||
query_params(query) if query | ||
@swift = nil | ||
@username = @settings[:username] | ||
@password = @settings[:password] | ||
@container_name = @mount_path[0] == File::Separator ? @mount_path[1..-1] : @mount_path | ||
end | ||
|
||
def uri_to_object_path(remote_file) | ||
# Strip off the leading "swift://" and the container name from the URI" | ||
# Also remove the leading delimiter. | ||
object_file_with_bucket = URI.split(URI.encode(remote_file))[5] | ||
object_file_with_bucket.split(File::Separator)[2..-1].join(File::Separator) | ||
end | ||
|
||
def upload_single(dest_uri) | ||
# | ||
# Get the remote path, and parse out the bucket name. | ||
# | ||
object_file = uri_to_object_path(dest_uri) | ||
# | ||
# write dump file to swift | ||
# | ||
logger.debug("Writing [#{source_input}] to => Bucket [#{container_name}] using object file name [#{object_file}]") | ||
begin | ||
swift_file = container.files.new(:key => object_file) | ||
params = { | ||
:expects => [201, 202], | ||
:headers => {}, | ||
:request_block => -> { read_single_chunk }, | ||
:idempotent => false, | ||
:method => "PUT", | ||
:path => "#{Fog::OpenStack.escape(swift_file.directory.key)}/#{Fog::OpenStack.escape(swift_file.key)}" | ||
} | ||
# | ||
# Because of how `Fog::OpenStack` (and probably `Fog::Core`) is designed, | ||
# it has hidden the functionality to provide a block for streaming uploads | ||
# that is available out of the box with Excon. | ||
# | ||
# we use .send here because #request is private | ||
# we can't use #put_object (public) directly because it doesn't allow a 202 response code, | ||
# which is what swift responds with when we pass it the :request_block | ||
# (This allows us to stream the response in chunks) | ||
# | ||
swift_file.service.send(:request, params) | ||
jerryk55 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
clear_split_vars | ||
rescue Excon::Errors::Unauthorized => err | ||
msg = "Access to Swift container #{@container_name} failed due to a bad username or password. #{err}" | ||
logger.error(msg) | ||
raise err, msg, err.backtrace | ||
rescue => err | ||
msg = "Error uploading #{source_input} to Swift container #{@container_name}. #{err}" | ||
carbonin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
logger.error(msg) | ||
raise err, msg, err.backtrace | ||
end | ||
end | ||
|
||
def mkdir(_dir) | ||
container | ||
end | ||
|
||
# | ||
# Some calls to Fog::Storage::OpenStack::Directories#get will | ||
# return 'nil', and not return an error. This would cause errors down the | ||
# line in '#upload' or '#download'. | ||
# | ||
# Instead of investigating further, we created a new method that is in charge of | ||
# OpenStack container creation, '#create_container', and that is called from '#container' | ||
# if 'nil' is returned from 'swift.directories.get(container_name)', or in the rescue case | ||
# for 'NotFound' to cover that scenario as well | ||
# | ||
|
||
def container(create_if_missing = true) | ||
@container ||= begin | ||
container = swift.directories.get(container_name) | ||
logger.debug("Swift container [#{container}] found") if container | ||
raise Fog::Storage::OpenStack::NotFound unless container | ||
jerryk55 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
container | ||
rescue Fog::Storage::OpenStack::NotFound | ||
if create_if_missing | ||
logger.debug("Swift container #{container_name} does not exist. Creating.") | ||
create_container | ||
else | ||
msg = "Swift container #{container_name} does not exist. #{err}" | ||
logger.error(msg) | ||
raise err, msg, err.backtrace | ||
end | ||
rescue => err | ||
msg = "Error getting Swift container #{container_name}. #{err}" | ||
logger.error(msg) | ||
raise err, msg, err.backtrace | ||
end | ||
end | ||
|
||
private | ||
|
||
def auth_url | ||
URI::Generic.build( | ||
:scheme => @security_protocol == 'non-ssl' ? "http" : "https", | ||
:host => @host, | ||
:port => @port.to_i, | ||
:path => "/#{@api_version}#{@api_version == "v3" ? "/auth" : ".0"}/tokens" | ||
).to_s | ||
end | ||
|
||
def swift | ||
return @swift if @swift | ||
require 'fog/openstack' | ||
|
||
connection_params = { | ||
:openstack_auth_url => auth_url, | ||
:openstack_username => @username, | ||
:openstack_api_key => @password, | ||
:openstack_project_domain_id => @domain_id, | ||
:openstack_user_domain_id => @domain_id, | ||
:openstack_region => @region, | ||
:connection_options => { :debug_request => true } | ||
} | ||
|
||
@swift = Fog::Storage::OpenStack.new(connection_params) | ||
end | ||
|
||
def create_container | ||
container = swift.directories.create(:key => container_name) | ||
logger.debug("Swift container [#{container_name}] created") | ||
container | ||
rescue => err | ||
msg = "Error creating Swift container #{container_name}. #{err}" | ||
logger.error(msg) | ||
raise err, msg, err.backtrace | ||
end | ||
|
||
def download_single(_source, _destination) | ||
raise NotImplementedError, "MiqSwiftStorage.download_single Not Yet Implemented" | ||
end | ||
|
||
def query_params(query_string) | ||
parts = URI.decode_www_form(query_string).to_h | ||
@region, @api_version, @domain_id, @security_protocol = parts.values_at("region", "api_version", "domain_id", "security_protocol") | ||
end | ||
end |
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 |
---|---|---|
|
@@ -27,7 +27,9 @@ Gem::Specification.new do |s| | |
s.add_runtime_dependency "aws-sdk", "~> 2.9.7" | ||
s.add_runtime_dependency "binary_struct", "~> 2.1" | ||
s.add_runtime_dependency "bundler", ">= 1.8.4" # rails-assets requires bundler >= 1.8.4, see: https://rails-assets.org/ | ||
s.add_runtime_dependency "fog-openstack", "~> 0.1.22" | ||
s.add_runtime_dependency "linux_admin", "~> 1.0" | ||
s.add_runtime_dependency "mime-types", "~> 3.0" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ugh.... another gem that uses There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For those completely confused with the above, see: ManageIQ/manageiq#14525 |
||
s.add_runtime_dependency "minitar", "~> 0.6" | ||
s.add_runtime_dependency "more_core_extensions", "~> 3.4" | ||
s.add_runtime_dependency "net-scp", "~> 1.2.1" | ||
|
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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reference, this comes from
net/protocol
, and it is the same chunk size that is used byNet::FTP
when uploading. Figured it was a reasonable value to pick out of a hat and use here.