activestorage-openstack-shamox 0.7.0.pre.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +161 -0
- data/Rakefile +27 -0
- data/lib/active_storage/openstack/railtie.rb +6 -0
- data/lib/active_storage/openstack/version.rb +5 -0
- data/lib/active_storage/service/open_stack_service.rb +146 -0
- data/lib/activestorage-openstack.rb +2 -0
- data/lib/tasks/activestorage/openstack_tasks.rake +4 -0
- metadata +138 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4d91e85cc650d641f99bdec4ec336e024171e41ccde924e1a31a99a121813e18
|
4
|
+
data.tar.gz: c97143273ac456414917b7e7a1a5d3782d479430904ddf27b874e2b475b1d4f5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 872ec15aaa51d44a55ee894bd1f92d0e4d80c74408340a0c700eb68cfebc93ce8c655080c3556341ca41f58fd75d456ddf654919f74fc5fea9da0dd2c3e51460
|
7
|
+
data.tar.gz: 8f5d505ddb16b08166eb2f81c4920b5fb03f3c52222a1814eb630ad514ed86895ed97cccba9a19b15fc997185c1b55f52194ff57fa16d6525a3c23095de6d36e
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2018 chaadow
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
# ActiveStorage::Openstack
|
2
|
+
This rails plugin wraps the OpenStack Swift provider as an Active Storage service.
|
3
|
+
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/activestorage-openstack.svg)](https://badge.fury.io/rb/activestorage-openstack)
|
5
|
+
[![Build Status](https://travis-ci.com/ShamoX/activestorage-openstack.svg?branch=master)](https://travis-ci.com/ShamoX/activestorage-openstack)
|
6
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/567a1c8e09288db91781/maintainability)](https://codeclimate.com/github/ShamoX/activestorage-openstack/maintainability)
|
7
|
+
[![Test Coverage](https://api.codeclimate.com/v1/badges/567a1c8e09288db91781/test_coverage)](https://codeclimate.com/github/ShamoX/activestorage-openstack/test_coverage)
|
8
|
+
|
9
|
+
|
10
|
+
# PLEASE FORGIVE ME
|
11
|
+
Few monthes ago, I tried to contact `chaadow` - which seems to be the new maintainer
|
12
|
+
of this project - and got no answer. Since I needed updates on this gem and no ones
|
13
|
+
seemed to take it back, I decided to create and setup this new version.
|
14
|
+
|
15
|
+
For now I call it `activestorage-openstack-shamox`, just because I can't take over
|
16
|
+
`activestorage-openstack` from rubygem without a consent of its owner.
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
Add this line to your application's Gemfile:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem 'activestorage-openstack-shamox'
|
23
|
+
```
|
24
|
+
|
25
|
+
And then execute:
|
26
|
+
```bash
|
27
|
+
$ bundle
|
28
|
+
```
|
29
|
+
|
30
|
+
Or install it yourself as:
|
31
|
+
```bash
|
32
|
+
$ gem install activestorage-openstack-shamox
|
33
|
+
```
|
34
|
+
|
35
|
+
## Usage
|
36
|
+
in `config/storage.yml`, in your Rails app, create an entry with the following keys:
|
37
|
+
```yaml
|
38
|
+
dev_openstack:
|
39
|
+
service: OpenStack
|
40
|
+
container: <container name> # Container name for your OpenStack provider
|
41
|
+
credentials:
|
42
|
+
openstack_auth_url: <auth url>
|
43
|
+
openstack_username: <username>
|
44
|
+
openstack_api_key: <password>
|
45
|
+
openstack_project_id: <region>
|
46
|
+
openstack_region: <region>
|
47
|
+
openstack_temp_url_key: <temp url key> # Mandatory, instructions below
|
48
|
+
connection_options: # optional
|
49
|
+
chunk_size: 2097152 # 2MBs - 1MB is the default
|
50
|
+
```
|
51
|
+
|
52
|
+
You can create as many entries as you would like for your different environments. For instance: `dev_openstack` for development, `test_openstack` for test environment, and `prod_openstack` for production. This way you can choose the appropriate container for each scenario.
|
53
|
+
|
54
|
+
Then register the provider in your `config/{environment}.rb` (`config/development.rb`/`config/test.rb`/`config/production.rb`)
|
55
|
+
|
56
|
+
For example, for the `dev_openstack` entry above, change the `config` variable in `config/development.rb` like the following:
|
57
|
+
```ruby
|
58
|
+
# Store uploaded files on the local file system (see config/storage.yml for options)
|
59
|
+
config.active_storage.service = :dev_openstack
|
60
|
+
```
|
61
|
+
|
62
|
+
## Migrating from fog-openstack `0.1.x` to `0.2.x`
|
63
|
+
|
64
|
+
1- From your configuration file (`config/storage.yml`) change the `openstack_auth_uri` from :
|
65
|
+
```yaml
|
66
|
+
openstack_auth_url: https://auth.example.com/v2.0/tokens
|
67
|
+
```
|
68
|
+
to :
|
69
|
+
```yaml
|
70
|
+
openstack_auth_url: https://auth.example.com
|
71
|
+
```
|
72
|
+
==> **specifying the version in the `openstack_auth_url` key would break things**
|
73
|
+
|
74
|
+
2- Second, specify the Keystone version (default is `v3.0`, however it is retro-compatible with v2.0 (So for now, adding this key won't affect the normal functioning of this gem, but is highly recommended)
|
75
|
+
- *Additionally v2.0 is deprecated.*
|
76
|
+
```yaml
|
77
|
+
openstack_identity_api_version: v2.0
|
78
|
+
```
|
79
|
+
|
80
|
+
For further informations, please refer to [fog-openstack's README](https://github.com/fog/fog-openstack/)
|
81
|
+
|
82
|
+
## Setting up a container
|
83
|
+
|
84
|
+
From your OpenStack provider website, create or sign in to your account.
|
85
|
+
Then from your dashboard, create a container, and save the configuration generated.
|
86
|
+
|
87
|
+
It is a good practice to create a separate container for each of your environments.
|
88
|
+
Once safely saved, you can add them to your storage configuration in your Rails application.
|
89
|
+
## `temp_url_key` configuration
|
90
|
+
|
91
|
+
the `openstack_temp_url_key` in your configuration is mandatory for generating URLs (expiring ones) as well as for Direct Upload. You can set it up with `Swift` or with the `Fog/OpenStack` gem. More instructions on how to set it up with Swift are found [HERE](https://docs.openstack.org/swift/latest/api/temporary_url_middleware.html#secret-keys).
|
92
|
+
|
93
|
+
To create it and post it you can use `bin/create_and_post_tempurl_key.sh` after having set your environment.
|
94
|
+
To set your environment set :
|
95
|
+
```shell
|
96
|
+
export OS_AUTH_URL "https://auth.cloud.ovh.net"
|
97
|
+
export OS_IDENTITY_API_VERSION "3"
|
98
|
+
|
99
|
+
export OS_PROJECT_ID="your project id"
|
100
|
+
|
101
|
+
# In addition to the owning entity (tenant), openstack stores the entity
|
102
|
+
# performing the action as the **user**.
|
103
|
+
export OS_USERNAME="your username"
|
104
|
+
|
105
|
+
# With Keystone you pass the keystone password.
|
106
|
+
export OS_PASSWORD="your secret passwor"
|
107
|
+
|
108
|
+
# If your configuration has multiple regions, we set that information here.
|
109
|
+
# OS_REGION_NAME is optional and only valid in certain environments.
|
110
|
+
export OS_REGION_NAME="BHS1"
|
111
|
+
```
|
112
|
+
|
113
|
+
To setup travis tests, you need to set `OPENSTACK_TEMP_URL_KEY`.
|
114
|
+
|
115
|
+
## `ActiveStorage::Openstack`'s Content-Type handling
|
116
|
+
|
117
|
+
OpenStack Swift handles the Content-Type of an object differently from other object storage services. You cannot overwrite the Content-Type via a temp URL. This gem will try very hard to set the right Content-Type for an object at object creation (either via server upload or direct upload) but this is wrong in some edge cases (e.g. you use direct upload and the browser provides a wrong mime type).
|
118
|
+
|
119
|
+
For these edge cases `ActiveStorage::Blob::Identifiable` downloads the first 4K of a file, identifies the content type and saves the result in the database. For `ActiveStorage::Openstack` we also need to update the Content-Type of the object. This is done automatically with a little monkey patch.
|
120
|
+
|
121
|
+
## Testing
|
122
|
+
First, run `bundle` to install the gem dependencies (both development and production)
|
123
|
+
```shell
|
124
|
+
$ bundle
|
125
|
+
```
|
126
|
+
Then, from the root of the plugin, copy the following file and fill in the appropriate credentials.
|
127
|
+
**Preferably, set up a container for your testing, separate from production.**
|
128
|
+
```shell
|
129
|
+
$ cp test/configurations.example.yml test/configurations.yml
|
130
|
+
$ source ./bin/openrc.sh
|
131
|
+
```
|
132
|
+
And then run the tests:
|
133
|
+
```shell
|
134
|
+
$ bin/test
|
135
|
+
```
|
136
|
+
|
137
|
+
## Contributions
|
138
|
+
Contributions are welcome. Feel free to open any issues if you encounter any bug, or if you want to suggest a feature by clicking here: https://github.com/ShamoX/activestorage-openstack/issues
|
139
|
+
|
140
|
+
I use the git flow scheme then, when wanting to merge, please target the `develop`
|
141
|
+
branch and not the `master`. I would recommand you to use `git flow` also, and
|
142
|
+
use the following configuration (which is the default):
|
143
|
+
```
|
144
|
+
$ git flow init
|
145
|
+
Which branch should be used for bringing forth production releases?
|
146
|
+
- master
|
147
|
+
Branch name for production releases: [master]
|
148
|
+
Branch name for "next release" development: [develop]
|
149
|
+
|
150
|
+
How to name your supporting branch prefixes?
|
151
|
+
Feature branches? [feature/]
|
152
|
+
Bugfix branches? [bugfix/]
|
153
|
+
Release branches? [release/]
|
154
|
+
Hotfix branches? [hotfix/]
|
155
|
+
Support branches? [support/]
|
156
|
+
Version tag prefix? []
|
157
|
+
Hooks and filters directory? [/home/rlaures/dev/activestorage-openstack/.git/hooks]
|
158
|
+
```
|
159
|
+
|
160
|
+
## License
|
161
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'ActiveStorage::Openstack'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'bundler/gem_tasks'
|
18
|
+
|
19
|
+
require 'rake/testtask'
|
20
|
+
|
21
|
+
Rake::TestTask.new(:test) do |t|
|
22
|
+
t.libs << 'test'
|
23
|
+
t.pattern = 'test/**/*_test.rb'
|
24
|
+
t.verbose = false
|
25
|
+
end
|
26
|
+
|
27
|
+
task default: :test
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'fog/openstack'
|
2
|
+
|
3
|
+
module ActiveStorage
|
4
|
+
class Service::OpenStackService < Service
|
5
|
+
attr_reader :client, :container
|
6
|
+
|
7
|
+
def initialize(container:, credentials:, connection_options: {})
|
8
|
+
settings =
|
9
|
+
if connection_options.present?
|
10
|
+
credentials.reverse_merge(connection_options: connection_options)
|
11
|
+
else
|
12
|
+
credentials
|
13
|
+
end
|
14
|
+
|
15
|
+
@client = Fog::OpenStack::Storage.new(settings)
|
16
|
+
@container = Fog::OpenStack.escape(container)
|
17
|
+
end
|
18
|
+
|
19
|
+
def upload(key, io, checksum: nil, **)
|
20
|
+
instrument :upload, key: key, checksum: checksum do
|
21
|
+
params = {}.merge(etag: convert_base64digest_to_hexdigest(checksum))
|
22
|
+
begin
|
23
|
+
client.put_object(container, key, io, params)
|
24
|
+
rescue Excon::Error::UnprocessableEntity
|
25
|
+
raise ActiveStorage::IntegrityError
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def download(key, &block)
|
31
|
+
if block_given?
|
32
|
+
instrument :streaming_download, key: key do
|
33
|
+
object_for(key, &block).body
|
34
|
+
end
|
35
|
+
else
|
36
|
+
instrument :download, key: key do
|
37
|
+
object_for(key).body
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def download_chunk(key, range)
|
43
|
+
instrument :download_chunk, key: key, range: range do
|
44
|
+
object_for(key).body[range]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def delete(key)
|
49
|
+
instrument :delete, key: key do
|
50
|
+
begin
|
51
|
+
client.delete_object(container, key)
|
52
|
+
rescue Fog::OpenStack::Storage::NotFound
|
53
|
+
false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def delete_prefixed(prefix)
|
59
|
+
instrument :delete, prefix: prefix do
|
60
|
+
directory = client.directories.get(container)
|
61
|
+
filtered_files = client.files(directory: directory, prefix: prefix)
|
62
|
+
filtered_files = filtered_files.map(&:key)
|
63
|
+
|
64
|
+
client.delete_multiple_objects(container, filtered_files)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def exist?(key)
|
69
|
+
instrument :exist, key: key do |payload|
|
70
|
+
begin
|
71
|
+
answer = object_for(key)
|
72
|
+
payload[:exist] = answer
|
73
|
+
rescue Fog::OpenStack::Storage::NotFound
|
74
|
+
payload[:exist] = false
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def url(key, expires_in:, disposition:, filename:, content_type:)
|
80
|
+
instrument :url, key: key do |payload|
|
81
|
+
expire_at = unix_timestamp_expires_at(expires_in)
|
82
|
+
generated_url =
|
83
|
+
client.get_object_https_url(
|
84
|
+
container,
|
85
|
+
key,
|
86
|
+
expire_at,
|
87
|
+
disposition: disposition,
|
88
|
+
filename: filename,
|
89
|
+
content_type: content_type
|
90
|
+
)
|
91
|
+
|
92
|
+
payload[:url] = generated_url
|
93
|
+
generated_url
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:)
|
98
|
+
instrument :url, key: key do |payload|
|
99
|
+
expire_at = unix_timestamp_expires_at(expires_in)
|
100
|
+
|
101
|
+
generated_url =
|
102
|
+
client.create_temp_url(
|
103
|
+
container,
|
104
|
+
key,
|
105
|
+
expire_at,
|
106
|
+
'PUT',
|
107
|
+
port: 443,
|
108
|
+
scheme: "https",
|
109
|
+
content_type: content_type,
|
110
|
+
content_length: content_length,
|
111
|
+
etag: convert_base64digest_to_hexdigest(checksum)
|
112
|
+
)
|
113
|
+
|
114
|
+
payload[:url] = generated_url
|
115
|
+
generated_url
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def headers_for_direct_upload(key, content_type:, content_length:, checksum:)
|
120
|
+
{
|
121
|
+
'Content-Type' => content_type,
|
122
|
+
'Etag' => convert_base64digest_to_hexdigest(checksum),
|
123
|
+
'Content-Length' => content_length,
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
def object_for(key, &block)
|
129
|
+
client.get_object(container, key, &block)
|
130
|
+
end
|
131
|
+
|
132
|
+
# ActiveStorage sends a `Digest::MD5.base64digest` checksum
|
133
|
+
# OpenStack expects a `Digest::MD5.hexdigest` Etag
|
134
|
+
def convert_base64digest_to_hexdigest(base64digest)
|
135
|
+
base64digest.unpack('m0').first.unpack('H*').first if base64digest
|
136
|
+
end
|
137
|
+
|
138
|
+
def unix_timestamp_expires_at(seconds_from_now)
|
139
|
+
Time.current.advance(seconds: seconds_from_now).to_i
|
140
|
+
end
|
141
|
+
|
142
|
+
def format_range(range)
|
143
|
+
" bytes=#{range.begin}-#{range.exclude_end? ? range.end - 1 : range.end}"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
metadata
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: activestorage-openstack-shamox
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.7.0.pre.alpha
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chedli Bourguiba
|
8
|
+
- Roland Laurès
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2019-10-10 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: fog-openstack
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: mime-types
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: sqlite3
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rails
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 5.2.0
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 5.2.0
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: simplecov
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: simplecov-console
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
description: Wraps the OpenStack Swift/Storage service as an Active Storage service
|
99
|
+
email:
|
100
|
+
- bourguiba.chedli@gmail.com
|
101
|
+
- roland@rlaures.pro
|
102
|
+
executables: []
|
103
|
+
extensions: []
|
104
|
+
extra_rdoc_files: []
|
105
|
+
files:
|
106
|
+
- MIT-LICENSE
|
107
|
+
- README.md
|
108
|
+
- Rakefile
|
109
|
+
- lib/active_storage/openstack/railtie.rb
|
110
|
+
- lib/active_storage/openstack/version.rb
|
111
|
+
- lib/active_storage/service/open_stack_service.rb
|
112
|
+
- lib/activestorage-openstack.rb
|
113
|
+
- lib/tasks/activestorage/openstack_tasks.rake
|
114
|
+
homepage: https://github.com/shamox/activestorage-openstack
|
115
|
+
licenses:
|
116
|
+
- MIT
|
117
|
+
metadata: {}
|
118
|
+
post_install_message:
|
119
|
+
rdoc_options: []
|
120
|
+
require_paths:
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: 2.2.2
|
127
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 1.8.11
|
132
|
+
requirements: []
|
133
|
+
rubyforge_project:
|
134
|
+
rubygems_version: 2.7.6.2
|
135
|
+
signing_key:
|
136
|
+
specification_version: 4
|
137
|
+
summary: ActiveStorage wrapper for OpenStack Storage (ShamoX version)
|
138
|
+
test_files: []
|