sacback 0.0.3
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 +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +106 -0
- data/Rakefile +2 -0
- data/bin/sacback +5 -0
- data/lib/sacback.rb +6 -0
- data/lib/sacback/cli.rb +189 -0
- data/lib/sacback/sacloud_request.rb +53 -0
- data/lib/sacback/version.rb +3 -0
- data/sacback.gemspec +27 -0
- metadata +126 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 83bc1c9dd28613bc0b8d1cea52f5b184dcb3f973
|
4
|
+
data.tar.gz: 46b2464c5306818f8b6652c2e4bd7ac3ea31196c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a4b0938d093e2eef1fa4d06d8e771285d5f59c4919f7ee94cd0bda09bcc786fa8e8e73ff32b506a0c9f59b1fffcaad74556808bc8fe7484d64180912b62efb42
|
7
|
+
data.tar.gz: c109d33c5978ec2398b36604cf5f4eac339ffd2934aeeb13375872856bbadd0d4b1a219cb1552d3c3df4dc503430c90f95e58a485d84e47bac2ba202407d5c1d
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Eiichi Shimotori
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
# Sacback
|
2
|
+
|
3
|
+
Sacbackはさくらのクラウドのディスクをローカルホストにバックアップするツールです。 (Sakura Cloud Backup tool)
|
4
|
+
|
5
|
+
以下の一連の処理を一気に実行します。また、それぞれの処理を個別に実行することもできます。
|
6
|
+
|
7
|
+
1. さくらのクラウド上でディスクのアーカイブを作成
|
8
|
+
1. アーカイブをローカルホストにダウンロード
|
9
|
+
1. さくらのクラウド上のアーカイブを削除
|
10
|
+
1. ローカルのアーカイブファイルを圧縮
|
11
|
+
|
12
|
+
|
13
|
+
## セットアップ
|
14
|
+
|
15
|
+
まだgem化していないため、プロジェクトをクローンしてください。
|
16
|
+
|
17
|
+
```
|
18
|
+
$ git clone https://github.com/shimotori/sacback.git
|
19
|
+
$ cd sacback
|
20
|
+
$ bundle install
|
21
|
+
```
|
22
|
+
|
23
|
+
さくらのクラウドの認証情報とゾーン名を以下の環境変数にセットします。
|
24
|
+
|
25
|
+
* SACLOUD_TOKEN: アクセス・トークン
|
26
|
+
|
27
|
+
* SACLOUD_SECRET: アクセス・トークン・シークレット
|
28
|
+
|
29
|
+
* SACLOUD_ZONE: ゾーン名(石狩第1: is1a, 石狩第2: is1b)
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
## 使い方
|
34
|
+
|
35
|
+
```
|
36
|
+
$ bundle exec bin/sacback
|
37
|
+
Commands:
|
38
|
+
sacback a DISK_NAME [LOCAL_DIR_PATH] # Run all through with the disk (def...
|
39
|
+
sacback c DISK_NAME # Create an archive from the disk
|
40
|
+
sacback g ARCHIVE_ID [LOCAL_DIR_PATH] # Get the archive (default path: /tmp)
|
41
|
+
sacback help [COMMAND] # Describe available commands or one...
|
42
|
+
sacback r ARCHIVE_ID # Remove the archive
|
43
|
+
sacback z LOCAL_DIR [FILE_NAME] # Compress the local file (default f...
|
44
|
+
|
45
|
+
Options:
|
46
|
+
-s, [--silent], [--no-silent] # Not write log messages
|
47
|
+
[--curl], [--no-curl] # Use curl command for downloading
|
48
|
+
[--ftpblocksize=N] # Block size on FTP transfer (KB) (not used on curl mode)
|
49
|
+
# Default: 512
|
50
|
+
```
|
51
|
+
|
52
|
+
まだgem化していないため、直接 `sacback` コマンドを使うことはできません。
|
53
|
+
|
54
|
+
実行する時にはプロジェクトディレクトリーに移動して、`bundle exec bin/sacback` で実行してください。
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
#### コマンド
|
59
|
+
|
60
|
+
* a: すべての処理を一気に実行します。(以降のc, g, r, z)
|
61
|
+
|
62
|
+
例: `bundle exec bin/sacback a disk1 /backup`
|
63
|
+
|
64
|
+
* c: さくらのクラウド上でディスクからアーカイブを作成します。
|
65
|
+
|
66
|
+
アーカイブ名:{ディスク名}-YYMMDD-HHMM
|
67
|
+
|
68
|
+
* g: アーカイブをローカルホストにダウンロードします。
|
69
|
+
|
70
|
+
デフォルトファイル名:archive.img
|
71
|
+
|
72
|
+
* r: さくらのクラウド上でアーカイブを削除します。
|
73
|
+
|
74
|
+
* z: ローカルホストのファイルを圧縮します。(gzip)
|
75
|
+
|
76
|
+
圧縮ファイル名:{アーカイブ名}.gz
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
#### オプション
|
81
|
+
|
82
|
+
-s, --silent: ログメッセージを表示しません。cronなどで実行する場合はこのオプションを指定してください。
|
83
|
+
|
84
|
+
--curl: アーカイブのダウンロードをcurlで行います。デフォルトでは [DoubleBagFTPS](https://github.com/bnix/double-bag-ftps) を使用しますが非常に遅いため、curlが使える環境ではこのオプションの使用をお勧めします。
|
85
|
+
|
86
|
+
--ftpblocksize=N: アーカイブダウンロード時のブロックサイズを指定します(KB単位)。curlモードの場合は影響しません。
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
#### 注意事項
|
91
|
+
|
92
|
+
a, cコマンドのパラメーターで指定する「ディスク名」は部分一致となります。複数のディスク名が該当した場合は最初のものが使用されるため、ユニークに決まる名称を指定した方が良いでしょう。
|
93
|
+
|
94
|
+
アーカイブのダウンロード時に、さくらのクラウドのコンソール上では、ステータスが「アップロード」と表示されます。今のところ原因がわかりませんが、動作上は問題ありません。
|
95
|
+
|
96
|
+
さくらのクラウド側でたまに `HttpServiceUnavailableException` が発生することがあります。aコマンドで実行していた場合は、失敗した処理から個別に実行して継続することができます。
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
## Contributing
|
101
|
+
|
102
|
+
1. Fork it ( https://github.com/shimotori/sacback/fork )
|
103
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
104
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
105
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
106
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/sacback
ADDED
data/lib/sacback.rb
ADDED
data/lib/sacback/cli.rb
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
require 'date'
|
5
|
+
require 'zlib'
|
6
|
+
require 'double_bag_ftps'
|
7
|
+
require 'saklient/cloud/api'
|
8
|
+
require 'sacback'
|
9
|
+
require 'sacback/sacloud_request'
|
10
|
+
|
11
|
+
|
12
|
+
module Sacback
|
13
|
+
class CLI < Thor
|
14
|
+
|
15
|
+
ARCHIVE_IMAGE_NAME = 'archive.img'
|
16
|
+
DEFAULT_LOCAL_DIR_PATH = '/tmp'
|
17
|
+
FTP_PORT = 21
|
18
|
+
SACLOUD_API_VERSION = '1.1'
|
19
|
+
|
20
|
+
class_option :silent, type: :boolean, default: false, desc: 'Not write log messages', aliases: '-s'
|
21
|
+
class_option :curl, type: :boolean, default: false, desc: 'Use curl command for downloading'
|
22
|
+
class_option :ftpblocksize, type: :numeric, default: 512, desc: 'Block size on FTP transfer (KB) (not used on curl mode)'
|
23
|
+
|
24
|
+
|
25
|
+
desc "a DISK_NAME [LOCAL_DIR_PATH]", "Run all through with the disk (default path: #{DEFAULT_LOCAL_DIR_PATH})"
|
26
|
+
def a(disk_name, local_dir_path = DEFAULT_LOCAL_DIR_PATH)
|
27
|
+
log "a: Run all through: disk=#{disk_name}, local dir=#{local_dir_path}"
|
28
|
+
log
|
29
|
+
archive = invoke :c, [disk_name]
|
30
|
+
# log "archive: #{archive.id} #{archive.name}"
|
31
|
+
invoke :g, [archive.id, local_dir_path]
|
32
|
+
invoke :r, [archive.id]
|
33
|
+
compressed_file_name = archive.name + '.gz'
|
34
|
+
invoke :z, [local_dir_path, ARCHIVE_IMAGE_NAME, compressed_file_name]
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
desc "c DISK_NAME", "Create an archive from the disk"
|
39
|
+
def c(disk_name)
|
40
|
+
log "c: Create an archive: disk=#{disk_name}"
|
41
|
+
@api = authorize
|
42
|
+
disk = get_disk disk_name
|
43
|
+
# say "disk: #{disk.id}"
|
44
|
+
archive = create_archive disk
|
45
|
+
log "The archive was created: id=#{archive.id}, name=#{archive.name}"
|
46
|
+
log
|
47
|
+
archive
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
desc "g ARCHIVE_ID [LOCAL_DIR_PATH]", "Get the archive (default path: #{DEFAULT_LOCAL_DIR_PATH})"
|
52
|
+
def g(archive_id, local_dir_path = DEFAULT_LOCAL_DIR_PATH)
|
53
|
+
log "g: Get the archive: archive id=#{archive_id}, local dir=#{local_dir_path}"
|
54
|
+
@api = authorize
|
55
|
+
archive = @api.archive.get_by_id archive_id
|
56
|
+
log "archive: #{archive.id} #{archive.name}"
|
57
|
+
|
58
|
+
archive.open_ftp
|
59
|
+
log 'ftp opened'
|
60
|
+
begin
|
61
|
+
ftp_info = archive.ftp_info
|
62
|
+
# log "ftp: #{ftp_info.user},#{ftp_info.password},#{ftp_info.host_name}"
|
63
|
+
|
64
|
+
local_file = File.join local_dir_path, ARCHIVE_IMAGE_NAME
|
65
|
+
if options[:curl]
|
66
|
+
download_with_curl ftp_info, local_file
|
67
|
+
else
|
68
|
+
download_with_doublebugftps ftp_info, local_file
|
69
|
+
end
|
70
|
+
|
71
|
+
ensure
|
72
|
+
archive.close_ftp
|
73
|
+
log 'ftp closed'
|
74
|
+
end
|
75
|
+
log
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
desc "r ARCHIVE_ID", "Remove the archive"
|
80
|
+
def r(archive_id)
|
81
|
+
log "r: Remove the archive: archive id=#{archive_id}"
|
82
|
+
request = create_rest_api_request
|
83
|
+
result = request.send :delete, "/archive/#{archive_id}"
|
84
|
+
if result['Success'] && result['is_ok']
|
85
|
+
log "The archive #{archive_id} was removed."
|
86
|
+
else
|
87
|
+
abort "Error: removing the archive #{archive_id} failed"
|
88
|
+
end
|
89
|
+
log
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
desc "z LOCAL_DIR FILE_NAME COMPRESSED_NAME", "Compress the local file (default file name: #{ARCHIVE_IMAGE_NAME})"
|
94
|
+
def z(dir, name_orig, name_new)
|
95
|
+
log "z: Compress the local file: local dir=#{dir}, target file=#{name_orig}, compressed file=#{name_new}"
|
96
|
+
path_orig = File.join dir, name_orig
|
97
|
+
path_new = File.join dir, name_new
|
98
|
+
log "Start compressing #{path_orig} to #{path_new}"
|
99
|
+
# Zlib::GzipWriter.open(path_new, Zlib::BEST_COMPRESSION) do |gz|
|
100
|
+
# gz.mtime = File.mtime(path_orig)
|
101
|
+
# gz.orig_name = name_orig
|
102
|
+
# File.open(path_orig, 'rb') do |fp|
|
103
|
+
# while chunk = fp.read(1024 * 1024) do
|
104
|
+
# gz.puts chunk
|
105
|
+
# end
|
106
|
+
# end
|
107
|
+
# end
|
108
|
+
command = "(gzip -c #{path_orig} > #{path_new}) && rm #{path_orig}"
|
109
|
+
`#{command}`
|
110
|
+
log "Compression succeeded: #{path_new}"
|
111
|
+
log
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
def log(text = '')
|
120
|
+
say text unless options[:silent]
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
def authorize
|
125
|
+
Saklient::Cloud::API::authorize ENV['SACLOUD_TOKEN'], ENV['SACLOUD_SECRET'], ENV['SACLOUD_ZONE']
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
# Get the disk data whose name includes the specific name
|
130
|
+
def get_disk(name)
|
131
|
+
disks = @api.disk.with_name_like(name).limit(1).find()
|
132
|
+
abort "Error: disk is not found: #{name}" if disks.count == 0
|
133
|
+
|
134
|
+
disks[0]
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
def create_archive(disk)
|
139
|
+
datetime = DateTime.now.strftime "%Y%m%d-%H%M"
|
140
|
+
archive_name = "#{disk.name}-#{datetime}"
|
141
|
+
log "Creating a new archive: #{archive_name}"
|
142
|
+
|
143
|
+
archive = @api.archive.create
|
144
|
+
archive.name = archive_name
|
145
|
+
archive.source = disk
|
146
|
+
archive.save
|
147
|
+
result = archive.sleep_while_copying
|
148
|
+
abort "Creating the archive failed: #{archive_name}" unless result
|
149
|
+
|
150
|
+
log "Creating the archive succeeded: #{archive_name}"
|
151
|
+
archive
|
152
|
+
end
|
153
|
+
|
154
|
+
|
155
|
+
def create_rest_api_request
|
156
|
+
Sacback::SacloudRequest.new(ENV['SACLOUD_TOKEN'], ENV['SACLOUD_SECRET'], ENV['SACLOUD_ZONE'], SACLOUD_API_VERSION)
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
def download_with_doublebugftps(ftp_info, local_file)
|
161
|
+
BasicSocket.do_not_reverse_lookup = true
|
162
|
+
ftps = DoubleBagFTPS.new
|
163
|
+
ftps.ftps_mode = DoubleBagFTPS::EXPLICIT
|
164
|
+
ftps.passive = true
|
165
|
+
# ftps.debug_mode = true
|
166
|
+
block_size = options[:ftpblocksize] * 1024
|
167
|
+
ftps.connect ftp_info.host_name, FTP_PORT
|
168
|
+
begin
|
169
|
+
ftps.login ftp_info.user, ftp_info.password
|
170
|
+
log "Start downloading (DoubleBagFTPS): remote file=#{ARCHIVE_IMAGE_NAME}, local file=#{local_file}, block size=#{block_size} bytes"
|
171
|
+
ftps.getbinaryfile ARCHIVE_IMAGE_NAME, local_file, block_size
|
172
|
+
log "Finished downloading: #{local_file}"
|
173
|
+
ensure
|
174
|
+
ftps.close unless ftps.closed?
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
def download_with_curl(ftp_info, local_file)
|
180
|
+
url = "ftp://#{ftp_info.host_name}/#{ARCHIVE_IMAGE_NAME}"
|
181
|
+
auth = "-u #{ftp_info.user}:#{ftp_info.password}"
|
182
|
+
silent = options[:silent] ? '-s -S' : '' # Show errors only
|
183
|
+
log "Start downloading (curl): remote file=#{ARCHIVE_IMAGE_NAME}, local file=#{local_file}"
|
184
|
+
command = "curl --ftp-ssl --ftp-pasv #{silent} #{auth} -o #{local_file} #{url}"
|
185
|
+
`#{command}`
|
186
|
+
log "Finished downloading: #{local_file}"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'net/https'
|
4
|
+
require 'uri'
|
5
|
+
|
6
|
+
|
7
|
+
module Sacback
|
8
|
+
class SacloudRequest
|
9
|
+
|
10
|
+
def initialize(token, secret, zone, api_version = '1.1')
|
11
|
+
@token = token
|
12
|
+
@secret = secret
|
13
|
+
@base_url = "https://secure.sakura.ad.jp/cloud/zone/#{zone}/api/cloud/#{api_version}"
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
# Send a request
|
18
|
+
def send(method, path, params = {})
|
19
|
+
uri = URI.parse(@base_url + path)
|
20
|
+
|
21
|
+
# HTTPS setting
|
22
|
+
https = Net::HTTP.new(uri.host, uri.port)
|
23
|
+
https.use_ssl = true
|
24
|
+
https.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
25
|
+
|
26
|
+
# Set the request class
|
27
|
+
request_class = case method
|
28
|
+
when :get then Net::HTTP::Get
|
29
|
+
when :post then Net::HTTP::Post
|
30
|
+
when :delete then Net::HTTP::Delete
|
31
|
+
when :put then Net::HTTP::Put
|
32
|
+
else
|
33
|
+
raise ArgumentError, 'invalid method'
|
34
|
+
end
|
35
|
+
|
36
|
+
# Basic Auth setting
|
37
|
+
request = request_class.new(uri.path)
|
38
|
+
request.basic_auth @token, @secret
|
39
|
+
|
40
|
+
# Parameter setting
|
41
|
+
request.body = JSON.generate(params) if (method == :post) || (method == :put)
|
42
|
+
|
43
|
+
# Send the request
|
44
|
+
response = https.start do |x|
|
45
|
+
x.request request
|
46
|
+
end
|
47
|
+
|
48
|
+
# Return the body as JSON
|
49
|
+
JSON.parse response.body
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
data/sacback.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sacback/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "sacback"
|
8
|
+
spec.version = Sacback::VERSION
|
9
|
+
spec.authors = ["Eiichi Shimotori"]
|
10
|
+
spec.email = ["eiichi.shimotori@gmail.com"]
|
11
|
+
spec.summary = %q{Sakura Cloud disk backup tool}
|
12
|
+
spec.description = %q{Command line tool to backup a disk on Sakura Cloud}
|
13
|
+
spec.homepage = "https://github.com/shimotori/sacback"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
|
24
|
+
spec.add_dependency "thor"
|
25
|
+
spec.add_dependency "saklient"
|
26
|
+
spec.add_dependency "double-bag-ftps"
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sacback
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eiichi Shimotori
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: thor
|
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'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: saklient
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: double-bag-ftps
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Command line tool to backup a disk on Sakura Cloud
|
84
|
+
email:
|
85
|
+
- eiichi.shimotori@gmail.com
|
86
|
+
executables:
|
87
|
+
- sacback
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- ".gitignore"
|
92
|
+
- Gemfile
|
93
|
+
- LICENSE.txt
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- bin/sacback
|
97
|
+
- lib/sacback.rb
|
98
|
+
- lib/sacback/cli.rb
|
99
|
+
- lib/sacback/sacloud_request.rb
|
100
|
+
- lib/sacback/version.rb
|
101
|
+
- sacback.gemspec
|
102
|
+
homepage: https://github.com/shimotori/sacback
|
103
|
+
licenses:
|
104
|
+
- MIT
|
105
|
+
metadata: {}
|
106
|
+
post_install_message:
|
107
|
+
rdoc_options: []
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
requirements: []
|
121
|
+
rubyforge_project:
|
122
|
+
rubygems_version: 2.2.2
|
123
|
+
signing_key:
|
124
|
+
specification_version: 4
|
125
|
+
summary: Sakura Cloud disk backup tool
|
126
|
+
test_files: []
|