lsst-git-lfs-s3 0.2.6 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f6ba3c617f42a8dc43d5f39c4f2baa77acd8a084
4
- data.tar.gz: c35b0e7293b2c9a343fa52c3cad6bebfbe48a94a
3
+ metadata.gz: 68caf4d6acf139d3cc4f120bc7715b7fc129a444
4
+ data.tar.gz: 78d03cd5f3d5428049b1f9f6918e78109bd97208
5
5
  SHA512:
6
- metadata.gz: 84c16ef08fd5020073398b9c4ab50270f2154880d318dd8cbefdbc90030e3c90dde046d40089012041b8813398f51b255b0711ba93378bd66cf2867271972ddd
7
- data.tar.gz: 6456b0f1741b306b5b6894159ce82da2cf5527114a966e8912fd7f6d8e4b459bdc6e410b9e5a71ba19a5f3c275c6f7665490cc86d20d11639021d62f2d274265
6
+ metadata.gz: 1d1d01d2052bda7b8a93b82f0f9c62e387225f3c46dbfb0eef75d6b581814af58c805364c67c7a1a74cbf91b476cca929a860c4b442214a614183b9793b8e4a6
7
+ data.tar.gz: ce0faca488560ff2f38fdaa6589c56d6c8c33d578af4d3be7a1f8a15c474523118392161ec2582b61ff81f32889845edeb9f61e34a1aa0ea96aafb7d82e506f7
data/README.md CHANGED
@@ -29,6 +29,9 @@ All configuration is done via environment variables. All of these configuration
29
29
  * `AWS_SECRET_ACCESS_KEY` - your AWS secret key.
30
30
  * `S3_BUCKET` - the bucket you wish to use for LFS storage. While not required, I recommend using a dedicated bucket for this.
31
31
  * `LFS_SERVER_URL` - the URL where this server can be reached; needed to fetch download URLs.
32
+ * `LFS_PUBLIC_SERVER` - (Optional) Support anonymous users for safe operations such as git-clone and git-pull.
33
+ * `LFS_CEPH_S3` - (Optional) support [Ceph S3](http://ceph.com/) (Hammer version, through radosgw).
34
+ * `LFS_CEPH_ENDPOINT` - (Optional) the Ceph S3 endpoint URL. Required when using `LFS_CEPH_S3`.
32
35
 
33
36
  You can (and should) also set authentication information. When you push for the first time from git, you will be prompted to enter a username and password when authentication is enabled. You can configure these with environment variables as well.
34
37
 
@@ -65,6 +68,7 @@ If you are new to Git LFS, make sure you read the [Getting Started](https://git-
65
68
  ``` git
66
69
  [lfs]
67
70
  url = "http://yourserver.com"
71
+ batch = false
68
72
  ```
69
73
 
70
74
  Once that is done, you can tell Git LFS to track files with `git lfs track "*.psd"`, for example.
@@ -83,6 +87,19 @@ However, because this is a Sinatra application, it can also be mounted within ot
83
87
  mount GitLfsS3::Application => '/lfs'
84
88
  ```
85
89
 
90
+
91
+
92
+ Allow anonymous clones and pulls of the git-lfs git repository.
93
+
94
+ ## Ceph S3 Server
95
+
96
+ Through the `LFS_CEPH_S3` and `LFS_CEPH_ENDPOINT` environment variables use a Ceph S3 storage service (Hammer version, through radosgw) instead of AWS S3.
97
+
98
+ ## More Complex Server Example
99
+
100
+ * https://github.com/lsst-sqre/git-lfs-s3-server
101
+
86
102
  ## TODO
87
103
 
88
- * Cloudfront support
104
+ * Cloudfront support.
105
+ * Batch API support.
data/git-lfs-s3.gemspec CHANGED
@@ -8,9 +8,9 @@ Gem::Specification.new do |gem|
8
8
  gem.version = GitLfsS3::VERSION
9
9
  gem.authors = ["Ryan LeFevre", "J. Matt Peterson"]
10
10
  gem.email = ["meltingice8917@gmail.com", "jmatt@lsst.org"]
11
- gem.description = %q{LSST's Git LFS server that uses S3 for the storage backend.}
12
- gem.summary = %q{LSST's Git LFS server that uses S3 for the storage backend by providing presigned S3 URLs.}
13
- gem.homepage = "https://github.com/lsst-sqre/git-lfs-s3"
11
+ gem.description = %q{A Git LFS server that uses S3 for the storage backend.}
12
+ gem.summary = %q{A Git LFS server that uses S3 for the storage backend by providing presigned S3 URLs.}
13
+ gem.homepage = "https://github.com/meltingice/git-lfs-s3"
14
14
  gem.license = 'MIT'
15
15
 
16
16
  gem.files = `git ls-files`.split($/)
@@ -1,3 +1,5 @@
1
+ require 'date'
2
+
1
3
  module GitLfsS3
2
4
  class Application < Sinatra::Application
3
5
  include AwsHelpers
@@ -47,6 +49,145 @@ module GitLfsS3
47
49
  "Git LFS S3 is online."
48
50
  end
49
51
 
52
+ def valid_object?(object)
53
+ begin
54
+ valid = object[:size] >= 0
55
+ rescue
56
+ valid = false
57
+ end
58
+ begin
59
+ if valid
60
+ oid = object[:oid].hex
61
+ valid = oid.size == 32 && object[:oid].size == 64
62
+ end
63
+ rescue
64
+ valid = false
65
+ end
66
+ valid
67
+ end
68
+
69
+ def object_download(authenticated, object, object_json)
70
+ oid = object_json[:oid]
71
+ size = object_json[:size]
72
+ {
73
+ 'oid' => oid,
74
+ 'size' => size,
75
+ 'authenticated' => authenticated,
76
+ 'actions' => {
77
+ 'download' => {
78
+ 'href' => object.presigned_url(:get, :expires_in => 86400)
79
+ }
80
+ },
81
+ 'expires_at' => DateTime.now.next_day.to_time.utc.iso8601
82
+ }
83
+ end
84
+
85
+ def object_upload(authenticated, object, object_json)
86
+ # Format a single upload object.
87
+ oid = object_json[:oid]
88
+ size = object_json[:size]
89
+ {
90
+ 'oid' => oid,
91
+ 'size' => size,
92
+ 'authenticated' => authenticated,
93
+ 'actions' => {
94
+ 'upload' => {
95
+ 'href' => object.presigned_url(:put, acl: 'public-read', :expires_in => 86400)
96
+ }
97
+ },
98
+ 'expires_at' => DateTime.now.next_day.to_time.utc.iso8601
99
+ }
100
+ end
101
+
102
+ def object_error(error, message, object, object_json)
103
+ {
104
+ 'oid' => object_json[:oid],
105
+ 'size' => object_json[:size],
106
+ 'error' => {
107
+ 'code' => error,
108
+ 'message' => message
109
+ }
110
+ }
111
+ end
112
+
113
+ def download(authenticated, params)
114
+ objects = Array.new
115
+ params[:objects].each do |object_json|
116
+ object_json = indifferent_params object_json
117
+ object = object_data object_json[:oid]
118
+ if valid_object? object_json
119
+ if object.exists?
120
+ objects.push object_download(authenticated, object, object_json)
121
+ else
122
+ objects.push object_error(404, 'Object does not exist', object, object_json)
123
+ end
124
+ else
125
+ objects.push object_error(422, 'Validation error', object, object_json)
126
+ end
127
+ end
128
+ objects
129
+ end
130
+
131
+ def upload(authenticated, params)
132
+ objects = Array.new
133
+ params[:objects].each do |object_json|
134
+ object_json = indifferent_params object_json
135
+ object = object_data object_json[:oid]
136
+ if valid_object? object_json
137
+ if object.exists?
138
+ objects.push object_download(authenticated, object, object_json)
139
+ else
140
+ objects.push object_upload(authenticated, object, object_json)
141
+ end
142
+ else
143
+ objects.push object_error(422, 'Validation error', object, object_json)
144
+ end
145
+ end
146
+ objects
147
+ end
148
+
149
+ def lfs_resp(objects)
150
+ status 200
151
+ resp = {
152
+ 'transfer' => 'basic',
153
+ 'objects' => objects
154
+ }
155
+ logger.debug resp
156
+ body MultiJson.dump(resp)
157
+ end
158
+
159
+ def error_resp(status_code, message)
160
+ status status_code
161
+ resp = {
162
+ 'message' => message,
163
+ 'request_id' => SecureRandom::uuid
164
+ }
165
+ logger.debug resp
166
+ body MultiJson.dump(resp)
167
+ end
168
+
169
+ post '/objects/batch', provides: 'application/vnd.git-lfs+json' do
170
+ # Git LFS Batch API
171
+ authenticated = authorized?
172
+ params = indifferent_params(JSON.parse(request.body.read))
173
+
174
+ if params[:operation] == 'download'
175
+ objects = download(authenticated, params)
176
+ elsif params[:operation] == 'upload'
177
+ if authenticated
178
+ objects = upload(authenticated, params)
179
+ else
180
+ objects = nil
181
+ end
182
+ end
183
+
184
+ if objects
185
+ lfs_resp(objects)
186
+ else
187
+ error_resp(401, 'Credentials needed')
188
+ end
189
+ end
190
+
50
191
  get "/objects/:oid", provides: 'application/vnd.git-lfs+json' do
51
192
  object = object_data(params[:oid])
52
193
 
@@ -94,6 +235,16 @@ module GitLfsS3
94
235
  body MultiJson.dump(service.response)
95
236
  end
96
237
 
238
+ post "/objects/batch", provides: 'application/vnd.git-lfs+json' do
239
+ logger.debug headers.inspect
240
+ service = UploadBatchService.service_for(request.body)
241
+ logger.debug service.response
242
+
243
+ status service.status
244
+ body MultiJson.dump(service.response)
245
+ end
246
+
247
+
97
248
  post '/verify', provides: 'application/vnd.git-lfs+json' do
98
249
  data = MultiJson.load(request.body.tap { |b| b.rewind }.read)
99
250
  object = object_data(data['oid'])
@@ -9,7 +9,7 @@ module GitLfsS3
9
9
  {
10
10
  '_links' => {
11
11
  'download' => {
12
- 'href' => object.presigned_url(:get)
12
+ 'href' => object.presigned_url(:get, :expires_in => 86400)
13
13
  }
14
14
  }
15
15
  }
@@ -32,9 +32,9 @@ module GitLfsS3
32
32
  GitLfsS3::CephPresignerService::signed_url(object)
33
33
  else
34
34
  if GitLfsS3::Application.settings.public_server
35
- object.presigned_url(:put, acl: 'public-read')
35
+ object.presigned_url(:put, acl: 'public-read', :expires_in => 86400)
36
36
  else
37
- object.presigned_url(:put)
37
+ object.presigned_url(:put, :expires_in => 86400)
38
38
  end
39
39
  end
40
40
  end
@@ -1,3 +1,3 @@
1
1
  module GitLfsS3
2
- VERSION = '0.2.6'
2
+ VERSION = '0.3.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lsst-git-lfs-s3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan LeFevre
@@ -9,65 +9,65 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-11-04 00:00:00.000000000 Z
12
+ date: 2017-02-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aws-sdk
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ~>
18
+ - - "~>"
19
19
  - !ruby/object:Gem::Version
20
20
  version: '2'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - ~>
25
+ - - "~>"
26
26
  - !ruby/object:Gem::Version
27
27
  version: '2'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: sinatra
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - ~>
32
+ - - "~>"
33
33
  - !ruby/object:Gem::Version
34
34
  version: '1'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - ~>
39
+ - - "~>"
40
40
  - !ruby/object:Gem::Version
41
41
  version: '1'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: multi_json
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - ~>
46
+ - - "~>"
47
47
  - !ruby/object:Gem::Version
48
48
  version: '1'
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - ~>
53
+ - - "~>"
54
54
  - !ruby/object:Gem::Version
55
55
  version: '1'
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: rake
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - ~>
60
+ - - "~>"
61
61
  - !ruby/object:Gem::Version
62
62
  version: '10'
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - ~>
67
+ - - "~>"
68
68
  - !ruby/object:Gem::Version
69
69
  version: '10'
70
- description: LSST's Git LFS server that uses S3 for the storage backend.
70
+ description: A Git LFS server that uses S3 for the storage backend.
71
71
  email:
72
72
  - meltingice8917@gmail.com
73
73
  - jmatt@lsst.org
@@ -76,7 +76,7 @@ executables:
76
76
  extensions: []
77
77
  extra_rdoc_files: []
78
78
  files:
79
- - .gitignore
79
+ - ".gitignore"
80
80
  - Gemfile
81
81
  - README.md
82
82
  - Rakefile
@@ -91,7 +91,7 @@ files:
91
91
  - lib/git-lfs-s3/services/upload/object_exists.rb
92
92
  - lib/git-lfs-s3/services/upload/upload_required.rb
93
93
  - lib/git-lfs-s3/version.rb
94
- homepage: https://github.com/lsst-sqre/git-lfs-s3
94
+ homepage: https://github.com/meltingice/git-lfs-s3
95
95
  licenses:
96
96
  - MIT
97
97
  metadata: {}
@@ -101,19 +101,19 @@ require_paths:
101
101
  - lib
102
102
  required_ruby_version: !ruby/object:Gem::Requirement
103
103
  requirements:
104
- - - '>='
104
+ - - ">="
105
105
  - !ruby/object:Gem::Version
106
106
  version: '0'
107
107
  required_rubygems_version: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - '>='
109
+ - - ">="
110
110
  - !ruby/object:Gem::Version
111
111
  version: '0'
112
112
  requirements: []
113
113
  rubyforge_project:
114
- rubygems_version: 2.0.14
114
+ rubygems_version: 2.6.10
115
115
  signing_key:
116
116
  specification_version: 4
117
- summary: LSST's Git LFS server that uses S3 for the storage backend by providing presigned
117
+ summary: A Git LFS server that uses S3 for the storage backend by providing presigned
118
118
  S3 URLs.
119
119
  test_files: []