magellan-gcs-proxy 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +38 -4
- data/lib/magellan/gcs/proxy/cli.rb +19 -16
- data/lib/magellan/gcs/proxy/context.rb +25 -25
- data/lib/magellan/gcs/proxy/gcp.rb +60 -0
- data/lib/magellan/gcs/proxy/log.rb +12 -0
- data/lib/magellan/gcs/proxy/version.rb +1 -1
- data/lib/magellan/gcs/proxy.rb +2 -2
- data/magellan-gcs-proxy.gemspec +1 -0
- metadata +18 -4
- data/lib/magellan/gcs/proxy/file_operation.rb +0 -46
- data/lib/magellan/gcs/proxy/pubsub_operation.rb +0 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e2d9990ba10bfc49119dc24969dac164773e526b
|
4
|
+
data.tar.gz: 135838363859a7755d687ec3f9ec5f6d17639383
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c6176dc804d2ddb6c913973296c6c343e8faaf11ceb9dedc4ce17875b7f0353c1f166cd68602ee2444390b99eb61f3372d3439444fea0cd5decd607577867da
|
7
|
+
data.tar.gz: 51772e727ad2ea9a7c813d4f62efa041a5c770f7f4713b4bd613d81943a4f8dadd7061ac346eaef9a8f1d079fd9e8e351d7e4b6e2ad57e7bf28c3500cb551518
|
data/README.md
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
-
#
|
1
|
+
# magellang-gcs-proxy
|
2
2
|
|
3
|
-
|
3
|
+
magellang-gcs-proxy is a gem for MAGELLAN BLOCKS "Batch type" IoT board.
|
4
4
|
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
6
5
|
|
7
6
|
## Installation
|
8
7
|
|
@@ -22,7 +21,42 @@ Or install it yourself as:
|
|
22
21
|
|
23
22
|
## Usage
|
24
23
|
|
25
|
-
|
24
|
+
```
|
25
|
+
magellan-gcs-proxy COMMAND ARGS...
|
26
|
+
```
|
27
|
+
|
28
|
+
### TODO How it works
|
29
|
+
|
30
|
+
### TODO Expanding variables
|
31
|
+
|
32
|
+
|
33
|
+
## Debugging with gcloud
|
34
|
+
|
35
|
+
### Setup
|
36
|
+
|
37
|
+
```
|
38
|
+
export PROJECT_ID=[Project ID]
|
39
|
+
export TOPIC=projects/$PROJECT_ID/topics/[Topic name]
|
40
|
+
export SUB=projects/$PROJECT_ID/subscriptions/[Subscription name of topic]
|
41
|
+
$ gcloud beta pubsub topics create projects/$PROJECT_ID/topics/$TOPIC
|
42
|
+
$ gcloud beta pubsub topics list
|
43
|
+
$ gcloud beta pubsub subscriptions create $SUB --topic $TOPIC
|
44
|
+
$ gcloud beta pubsub subscriptions list
|
45
|
+
```
|
46
|
+
|
47
|
+
### Publish message
|
48
|
+
|
49
|
+
```
|
50
|
+
$ gcloud beta pubsub topics publish $TOPIC "" --attribute='download_files=["gs://bucket1/path/to/file"]'
|
51
|
+
```
|
52
|
+
|
53
|
+
|
54
|
+
### Run application
|
55
|
+
|
56
|
+
```
|
57
|
+
$ magellan-gcs-proxy COMMAND ARGS...
|
58
|
+
```
|
59
|
+
|
26
60
|
|
27
61
|
## Development
|
28
62
|
|
@@ -1,15 +1,16 @@
|
|
1
1
|
require "magellan/gcs/proxy"
|
2
|
-
require "magellan/gcs/proxy/
|
2
|
+
require "magellan/gcs/proxy/log"
|
3
3
|
|
4
4
|
require 'json'
|
5
5
|
require 'logger'
|
6
6
|
require 'tmpdir'
|
7
|
+
require 'logger_pipe'
|
7
8
|
|
8
9
|
module Magellan
|
9
10
|
module Gcs
|
10
11
|
module Proxy
|
11
12
|
class Cli
|
12
|
-
include
|
13
|
+
include Log
|
13
14
|
|
14
15
|
attr_reader :cmd_template
|
15
16
|
def initialize(*args)
|
@@ -18,11 +19,14 @@ module Magellan
|
|
18
19
|
|
19
20
|
def run
|
20
21
|
logger.info("Start listening")
|
21
|
-
|
22
|
+
GCP.subscription.listen do |msg|
|
22
23
|
begin
|
23
24
|
process(msg)
|
24
25
|
rescue => e
|
25
26
|
logger.error("[#{e.class.name}] #{e.message}")
|
27
|
+
if ENV['VERBOSE'] =~ /true|yes|on|1/i
|
28
|
+
logger.debug("Backtrace\n " << e.backtrace.join("\n "))
|
29
|
+
end
|
26
30
|
end
|
27
31
|
end
|
28
32
|
rescue => e
|
@@ -34,32 +38,31 @@ module Magellan
|
|
34
38
|
logger.info("Processing message: #{msg.inspect}")
|
35
39
|
Dir.mktmpdir 'workspace' do |dir|
|
36
40
|
dfiles = parse(msg.attributes['download_files'])
|
37
|
-
|
41
|
+
logger.info("dfiles: #{dfiles}")
|
38
42
|
|
39
|
-
context = Context.new(dir, dfiles
|
43
|
+
context = Context.new(dir, dfiles)
|
40
44
|
context.setup
|
45
|
+
logger.info("context.setup done.")
|
41
46
|
|
42
47
|
context.download
|
48
|
+
logger.info("context.download done.")
|
49
|
+
logger.info("msg: #{msg}")
|
50
|
+
logger.info("context: #{context}")
|
43
51
|
|
44
52
|
cmd = build_command(msg, context)
|
45
53
|
|
46
|
-
|
47
|
-
|
48
|
-
|
54
|
+
begin
|
55
|
+
LoggerPipe.run(logger, cmd, returns: :none, logging: :both)
|
56
|
+
rescue => e
|
57
|
+
logger.error("Error: #{cmd.inspect}")
|
58
|
+
else
|
49
59
|
context.upload
|
50
|
-
|
51
|
-
sub.acknowledge msg
|
60
|
+
msg.acknowledge!
|
52
61
|
logger.info("Complete processing and acknowledged")
|
53
|
-
else
|
54
|
-
logger.error("Error: #{cmd.inspect}")
|
55
62
|
end
|
56
63
|
end
|
57
64
|
end
|
58
65
|
|
59
|
-
def logger
|
60
|
-
@logger ||= Logger.new($stdout)
|
61
|
-
end
|
62
|
-
|
63
66
|
def parse(str)
|
64
67
|
return nil if str.nil? || str.empty?
|
65
68
|
JSON.parse(str)
|
@@ -1,27 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
1
2
|
require "magellan/gcs/proxy"
|
2
|
-
require "magellan/gcs/proxy/
|
3
|
+
require "magellan/gcs/proxy/log"
|
3
4
|
|
5
|
+
require 'fileutils'
|
4
6
|
require 'uri'
|
5
7
|
|
6
8
|
module Magellan
|
7
9
|
module Gcs
|
8
10
|
module Proxy
|
9
11
|
class Context
|
10
|
-
include
|
11
|
-
|
12
|
-
attr_reader :workspace, :remote_download_files
|
13
|
-
def initialize(workspace, remote_download_files
|
12
|
+
include Log
|
13
|
+
|
14
|
+
attr_reader :workspace, :remote_download_files
|
15
|
+
def initialize(workspace, remote_download_files)
|
14
16
|
@workspace = workspace
|
15
17
|
@remote_download_files = remote_download_files
|
16
|
-
@remote_upload_files = remote_upload_files
|
17
18
|
end
|
18
19
|
|
19
20
|
KEYS = [
|
20
21
|
:workspace,
|
21
22
|
:downloads_dir, :uploads_dir,
|
22
|
-
:download_files,
|
23
|
-
:local_download_files,
|
24
|
-
:remote_download_files,
|
23
|
+
:download_files,
|
24
|
+
:local_download_files,
|
25
|
+
:remote_download_files,
|
25
26
|
].freeze
|
26
27
|
|
27
28
|
def [](key)
|
@@ -52,35 +53,33 @@ module Magellan
|
|
52
53
|
File.join(workspace, 'uploads')
|
53
54
|
end
|
54
55
|
|
55
|
-
def upload_mapping
|
56
|
-
@upload_mapping ||= build_mapping(uploads_dir, remote_upload_files)
|
57
|
-
end
|
58
|
-
|
59
|
-
def local_upload_files
|
60
|
-
@local_upload_files ||= build_local_files_obj(remote_upload_files, upload_mapping)
|
61
|
-
end
|
62
|
-
alias_method :upload_files, :local_upload_files
|
63
|
-
|
64
56
|
def setup
|
65
57
|
setup_dirs
|
66
58
|
end
|
67
59
|
|
68
60
|
def download
|
69
61
|
download_mapping.each do |url, path|
|
70
|
-
|
62
|
+
FileUtils.mkdir_p File.dirname(path)
|
63
|
+
logger.debug("Downloading: #{url} to #{path}")
|
71
64
|
uri = parse_uri(url)
|
72
|
-
|
65
|
+
@last_bucket_name = uri.host
|
66
|
+
bucket = GCP.storage.bucket(@last_bucket_name)
|
73
67
|
file = bucket.file uri.path.sub(/\A\//, '')
|
74
68
|
file.download(path)
|
69
|
+
logger.info("Download OK: #{url} to #{path}")
|
75
70
|
end
|
76
71
|
end
|
77
72
|
|
78
73
|
def upload
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
74
|
+
Dir.chdir(uploads_dir) do
|
75
|
+
Dir.glob('**/*') do |path|
|
76
|
+
next if File.directory?(path)
|
77
|
+
url = "gs://#{@last_bucket_name}/#{path}"
|
78
|
+
logger.info("Uploading: #{path} to #{url}")
|
79
|
+
bucket = GCP.storage.bucket(@last_bucket_name)
|
80
|
+
bucket.create_file path, path
|
81
|
+
logger.info("Upload OK: #{path} to #{url}")
|
82
|
+
end
|
84
83
|
end
|
85
84
|
end
|
86
85
|
|
@@ -97,6 +96,7 @@ module Magellan
|
|
97
96
|
|
98
97
|
def flatten_values(obj)
|
99
98
|
case obj
|
99
|
+
when nil then []
|
100
100
|
when Hash then flatten_values(obj.values)
|
101
101
|
when Array then obj.map{|i| flatten_values(i) }
|
102
102
|
else obj
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'magellan/gcs/proxy'
|
3
|
+
|
4
|
+
require "google/cloud/pubsub"
|
5
|
+
require "google/cloud/storage"
|
6
|
+
require 'net/http'
|
7
|
+
|
8
|
+
module Magellan
|
9
|
+
module Gcs
|
10
|
+
module Proxy
|
11
|
+
module GCP
|
12
|
+
extend Log
|
13
|
+
include Log
|
14
|
+
|
15
|
+
module_function
|
16
|
+
|
17
|
+
def project_id
|
18
|
+
@project_id ||= retrieve_project_id
|
19
|
+
end
|
20
|
+
|
21
|
+
def retrieve_project_id
|
22
|
+
ENV['BLOCKS_BATCH_PROJECT_ID'] || retrieve_metadata('project/project-id')
|
23
|
+
end
|
24
|
+
|
25
|
+
METADATA_HOST = 'metadata.google.internal'.freeze
|
26
|
+
METADATA_PATH_BASE = '/computeMetadata/v1/'.freeze
|
27
|
+
METADATA_HEADER = {"Metadata-Flavor" => "Google"}.freeze
|
28
|
+
|
29
|
+
def retrieve_metadata(key)
|
30
|
+
http = Net::HTTP.new(METADATA_HOST)
|
31
|
+
res = http.get(METADATA_PATH_BASE + key, METADATA_HEADER)
|
32
|
+
case res.code
|
33
|
+
when /\A2\d{2}\z/ then res.body
|
34
|
+
else raise "[#{res.code}] #{res.body}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def storage
|
39
|
+
@storage ||= Google::Cloud::Storage.new(project: project_id)
|
40
|
+
end
|
41
|
+
|
42
|
+
def pubsub
|
43
|
+
@pubsub ||= Google::Cloud::Pubsub.new(project: project_id)
|
44
|
+
end
|
45
|
+
|
46
|
+
def subscription
|
47
|
+
unless @subscription
|
48
|
+
@subscription = pubsub.subscription(ENV['BLOCKS_BATCH_PUBSUB_SUBSCRIPTION'] || 'test-subscription')
|
49
|
+
logger.info("subscription: #{@subscription.inspect}")
|
50
|
+
end
|
51
|
+
@subscription
|
52
|
+
end
|
53
|
+
|
54
|
+
def reset
|
55
|
+
instance_variables.each {|ivar| instance_variable_set(ivar, nil)}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/magellan/gcs/proxy.rb
CHANGED
@@ -2,9 +2,9 @@ require "magellan/gcs/proxy/version"
|
|
2
2
|
require 'magellan/gcs/proxy/cli'
|
3
3
|
require 'magellan/gcs/proxy/context'
|
4
4
|
require 'magellan/gcs/proxy/expand_variable'
|
5
|
-
require 'magellan/gcs/proxy/
|
5
|
+
require 'magellan/gcs/proxy/gcp'
|
6
|
+
require 'magellan/gcs/proxy/log'
|
6
7
|
require 'magellan/gcs/proxy/message_wrapper'
|
7
|
-
require 'magellan/gcs/proxy/pubsub_operation'
|
8
8
|
|
9
9
|
module Magellan
|
10
10
|
module Gcs
|
data/magellan-gcs-proxy.gemspec
CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
|
24
24
|
spec.add_runtime_dependency "google-cloud-pubsub"
|
25
25
|
spec.add_runtime_dependency "google-cloud-storage"
|
26
|
+
spec.add_runtime_dependency "logger_pipe"
|
26
27
|
|
27
28
|
spec.add_development_dependency "bundler", "~> 1.13"
|
28
29
|
spec.add_development_dependency "rake", "~> 10.0"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: magellan-gcs-proxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- akm
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-11-
|
11
|
+
date: 2016-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google-cloud-pubsub
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: logger_pipe
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -104,9 +118,9 @@ files:
|
|
104
118
|
- lib/magellan/gcs/proxy/cli.rb
|
105
119
|
- lib/magellan/gcs/proxy/context.rb
|
106
120
|
- lib/magellan/gcs/proxy/expand_variable.rb
|
107
|
-
- lib/magellan/gcs/proxy/
|
121
|
+
- lib/magellan/gcs/proxy/gcp.rb
|
122
|
+
- lib/magellan/gcs/proxy/log.rb
|
108
123
|
- lib/magellan/gcs/proxy/message_wrapper.rb
|
109
|
-
- lib/magellan/gcs/proxy/pubsub_operation.rb
|
110
124
|
- lib/magellan/gcs/proxy/version.rb
|
111
125
|
- magellan-gcs-proxy.gemspec
|
112
126
|
homepage: https://github.com/groovenauts/magellan-gcs-proxy
|
@@ -1,46 +0,0 @@
|
|
1
|
-
require "magellan/gcs/proxy"
|
2
|
-
|
3
|
-
require 'uri'
|
4
|
-
require "google/cloud/storage"
|
5
|
-
|
6
|
-
module Magellan
|
7
|
-
module Gcs
|
8
|
-
module Proxy
|
9
|
-
module FileOperation
|
10
|
-
def storage
|
11
|
-
@storage ||= Google::Cloud::Storage.new(
|
12
|
-
# default credential を利用するため、プロジェクトの指定はしない
|
13
|
-
# project: ENV['GOOGLE_PROJECT'] || 'dummy-project-id',
|
14
|
-
# keyfile: ENV['GOOGLE_KEY_JSON_FILE'],
|
15
|
-
)
|
16
|
-
end
|
17
|
-
|
18
|
-
def download(base_dir, urls)
|
19
|
-
(urls || []).each do |url|
|
20
|
-
logger.info("Downloading: #{url}")
|
21
|
-
uri = parse_uri(url)
|
22
|
-
bucket = storage.bucket(uri.host)
|
23
|
-
file = bucket.file uri.path.sub(/\A\//, '')
|
24
|
-
file.download File.join(base_dir, uri.path)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def upload(base_dir, urls)
|
29
|
-
(urls || []).each do |url|
|
30
|
-
logger.info("Uploading: #{url}")
|
31
|
-
uri = parse_uri(url)
|
32
|
-
bucket = storage.bucket(uri.host)
|
33
|
-
bucket.create_file File.join(base_dir, uri.path), uri.path.sub(/\A\//, '')
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def parse_uri(str)
|
38
|
-
uri = URI.parse(str)
|
39
|
-
raise "Unsupported scheme #{uri.scheme.inspect} of #{str}" unless uri.scheme == 'gs'
|
40
|
-
uri
|
41
|
-
end
|
42
|
-
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
require "magellan/gcs/proxy"
|
2
|
-
|
3
|
-
require "google/cloud/pubsub"
|
4
|
-
|
5
|
-
module Magellan
|
6
|
-
module Gcs
|
7
|
-
module Proxy
|
8
|
-
module PubsubOperation
|
9
|
-
def pubsub
|
10
|
-
@pubsub ||= Google::Cloud::Pubsub.new(
|
11
|
-
# default credential を利用するため、プロジェクトの指定はしない
|
12
|
-
# project: ENV['GOOGLE_PROJECT'] || 'dummy-project-id',
|
13
|
-
# keyfile: ENV['GOOGLE_KEY_JSON_FILE'],
|
14
|
-
)
|
15
|
-
end
|
16
|
-
|
17
|
-
def topic
|
18
|
-
unless @topic
|
19
|
-
topic_name = ENV['BATCH_TOPIC_NAME'] || 'test-topic'
|
20
|
-
@topic = pubsub.topic(topic_name) || pubsub.create_topic(topic_name)
|
21
|
-
logger.info("topic: #{@topic.inspect}")
|
22
|
-
end
|
23
|
-
@topic
|
24
|
-
end
|
25
|
-
|
26
|
-
def sub
|
27
|
-
unless @sub
|
28
|
-
sub_name = ENV['BATCH_SUBSCRIPTION_NAME'] || 'test-subscription'
|
29
|
-
@sub = topic.subscription(sub_name) || topic.subscribe(sub_name)
|
30
|
-
logger.info("subscription: #{@sub.inspect}")
|
31
|
-
end
|
32
|
-
@sub
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|