strongspace 0.2.0 → 0.3.5

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.
data/bin/as_installed/ss CHANGED
@@ -16,4 +16,9 @@ if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
16
16
  end
17
17
 
18
18
  gem 'strongspace', version
19
- load 'strongspace'
19
+
20
+ begin
21
+ load Gem.bin_path('strongspace', 'strongspace', version)
22
+ rescue
23
+ load 'strongspace'
24
+ end
@@ -16,5 +16,9 @@ if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
16
16
  end
17
17
 
18
18
  gem 'strongspace', version
19
- load 'strongspace'
20
19
 
20
+ begin
21
+ load Gem.bin_path('strongspace', 'strongspace', version)
22
+ rescue
23
+ load 'strongspace'
24
+ end
@@ -62,8 +62,13 @@ class Strongspace::Client
62
62
  doc = delete("/api/v1/files/#{escape(path[1..-1])}")
63
63
  end
64
64
 
65
+ def size(path)
66
+ doc = JSON.parse get("/api/v1/files/#{escape(path[1..-1])}?op=size")
67
+ end
68
+
65
69
  def spaces
66
70
  doc = JSON.parse get('/api/v1/spaces')
71
+ doc["spaces"]
67
72
  end
68
73
 
69
74
  def delete_space(space_name)
@@ -91,6 +96,10 @@ class Strongspace::Client
91
96
  doc = JSON.parse post("/api/v1/spaces/#{escape(space_name)}/snapshots", :name => snapshot_name)
92
97
  end
93
98
 
99
+ def filesystem
100
+ doc = JSON.parse get("/api/v1/filesystem").to_s
101
+ doc["filesystem"]
102
+ end
94
103
 
95
104
  # Get the list of ssh public keys for the current user.
96
105
  def keys
@@ -19,8 +19,15 @@ module Strongspace
19
19
  run_internal(command, args.dup)
20
20
  rescue InvalidCommand
21
21
  error "Unknown command. Run 'strongspace help' for usage information."
22
+ rescue Strongspace::Exceptions::InvalidCredentials
23
+ if retries < 1
24
+ STDERR.puts "Authentication failure"
25
+ run(command, args, retries+1)
26
+ else
27
+ error "! Authentication failure"
28
+ end
22
29
  rescue RestClient::Unauthorized
23
- if retries < 3
30
+ if retries < 1
24
31
  STDERR.puts "Authentication failure"
25
32
  run(command, args, retries+1)
26
33
  else
@@ -27,9 +27,9 @@ module Strongspace::Command
27
27
 
28
28
  def authorize!
29
29
  @credentials = [args.first, args[1]]
30
- r = Strongspace::Client.auth(@credentials[0], @credentials[1])
30
+ r = Strongspace::Client.auth(@credentials[0], @credentials[1], host)
31
31
  if r
32
- @credentials[0] = "#{@credentials[0]}/token"
32
+ @credentials[0] = r['username']
33
33
  @credentials[1] = r['api_token']
34
34
  write_credentials
35
35
  return true
@@ -58,10 +58,6 @@ module Strongspace::Command
58
58
  @credentials[1]
59
59
  end
60
60
 
61
- def credentials_file
62
- "#{credentials_folder}/credentials"
63
- end
64
-
65
61
  def get_credentials # :nodoc:
66
62
  return if @credentials
67
63
  unless @credentials = read_credentials
@@ -84,6 +80,10 @@ module Strongspace::Command
84
80
  end
85
81
 
86
82
  def ask_for_credentials
83
+ if ENV["STRONGSPACE_DISPLAY"] == "silent"
84
+ return [nil, nil]
85
+ end
86
+
87
87
  puts "Enter your Strongspace credentials."
88
88
 
89
89
  print "Username or Email: "
@@ -92,13 +92,14 @@ module Strongspace::Command
92
92
  print "Password: "
93
93
  password = running_on_windows? ? ask_for_password_on_windows : ask_for_password
94
94
 
95
- ["#{user}/token", Strongspace::Client.auth(user, password, host)['api_token']]
95
+ r = Strongspace::Client.auth(user, password, host)
96
+ [r['username'], r['api_token']]
96
97
  end
97
98
 
98
99
  def valid_saved_credentials?
99
100
  if File.exists?(credentials_file)
100
101
  credentials = read_credentials
101
- r = Strongspace::Client.auth(credentials[0], credentials[1])
102
+ r = Strongspace::Client.auth(credentials[0], credentials[1], host)
102
103
  return !r.blank?
103
104
  end
104
105
  return false
@@ -131,6 +132,13 @@ module Strongspace::Command
131
132
  end
132
133
 
133
134
  def save_credentials
135
+
136
+ if args[0] and args[1]
137
+ @credentials = []
138
+ @credentials[0] = args[0]
139
+ @credentials[1] = args[1]
140
+ end
141
+
134
142
  begin
135
143
  write_credentials
136
144
  command = 'auth:check'
@@ -55,4 +55,26 @@ module Strongspace::Command
55
55
  end
56
56
  end
57
57
 
58
+ class Quota < Base
59
+ def index
60
+
61
+ f = strongspace.filesystem
62
+ display "#{strongspace.username}:"
63
+ display " Quota: #{f["quota_gib"]} GiB"
64
+ display " Used: #{f["used_gib"]} GiB"
65
+ display " Available: #{f["avail_gib"]} GiB"
66
+ end
67
+ end
68
+
69
+ class Size < Base
70
+ def index
71
+ if args.length != 1
72
+ error "please supply a remote path"
73
+ end
74
+
75
+ r = strongspace.size(args[0])
76
+ puts r
77
+ end
78
+ end
79
+
58
80
  end
@@ -30,9 +30,9 @@ module Strongspace::Command
30
30
  end
31
31
 
32
32
 
33
- if !File.exist? "#{credentials_folder}/#{hostname}.rsa"
34
- `/usr/bin/ssh-keygen -f #{credentials_folder}/#{hostname}.rsa -b 2048 -C \" Strongspace App - #{hostname}\" -q -N ""` unless File.exist? "#{credentials_folder}/#{hostname}.rsa"
35
- args[0] = "#{credentials_folder}/#{hostname}.rsa.pub"
33
+ if !File.exist? "#{credentials_folder}/#{computername}.rsa"
34
+ `/usr/bin/ssh-keygen -f \"#{credentials_folder}/#{computername}.rsa\" -b 2048 -C \" Strongspace App - #{computername}\" -q -N ""` unless File.exist? "#{credentials_folder}/#{computername}.rsa"
35
+ args[0] = "#{credentials_folder}/#{computername}.rsa.pub"
36
36
  begin
37
37
  add
38
38
  rescue RestClient::Conflict => e # Swallow errors if the key already exists on Strongspace
@@ -62,7 +62,7 @@ module Strongspace::Command
62
62
  def valid_key_gui?
63
63
  return unless running_on_a_mac? and File.exist? "#{support_directory}/ssh"
64
64
 
65
- ret = `ssh -o PreferredAuthentications=publickey -i "#{support_directory}/ssh/#{hostname}.rsa" #{strongspace.username}@#{strongspace.username}.strongspace.com 2>&1`
65
+ ret = `ssh -o PreferredAuthentications=publickey -i "#{support_directory}/ssh/#{computername}.rsa" #{strongspace.username}@#{strongspace.username}.strongspace.com 2>&1`
66
66
 
67
67
  if ret.include? "Strongspace"
68
68
  display "Valid key installed"
@@ -63,7 +63,7 @@ module Strongspace::Command
63
63
  while (!success and (retries < 5)) do
64
64
  begin
65
65
  create_snapshot
66
- thin_snapshots
66
+ #thin_snapshots
67
67
  rescue SocketError => e
68
68
  sleep(10)
69
69
  retries = retries + 1
@@ -86,17 +86,11 @@ module Strongspace::Command
86
86
 
87
87
  keeplist = []
88
88
 
89
- if snapshots.count < 24
90
- return
91
- end
92
-
93
89
  snapshots.each do |s|
94
-
95
- if Time.parse(s['created_at']) > (Time.now - 3600*24)
90
+ if DateTime.parse(s['created_at']).to_local_time > (Time.now - 3600*24)
96
91
  keeplist << s
97
92
  next
98
93
  end
99
-
100
94
  end
101
95
 
102
96
  (snapshots - keeplist).each do |k|
@@ -141,6 +135,8 @@ module Strongspace::Command
141
135
  <string>#{log_file}</string>
142
136
  <key>EnvironmentVariables</key>
143
137
  <dict>
138
+ <key>STRONGSPACE_DISPLAY</key>
139
+ <string>logging</string>
144
140
  <key>GEM_PATH</key>
145
141
  <string>#{support_directory}/gems</string>
146
142
  <key>GEM_HOME</key>
@@ -187,7 +183,6 @@ module Strongspace::Command
187
183
  CronEdit::Crontab.Remove "strongspace-snapshots-#{space_name}"
188
184
  end
189
185
 
190
- display "Unscheduled snapshotting of #{space_name}"
191
186
  end
192
187
 
193
188
 
@@ -202,3 +197,4 @@ module Strongspace::Command
202
197
 
203
198
  end
204
199
  end
200
+
@@ -38,22 +38,38 @@ module Strongspace
38
38
  end
39
39
 
40
40
  def gui_ssh_key
41
- "#{credentials_folder}/#{hostname}.rsa"
41
+ "#{credentials_folder}/#{computername}.rsa"
42
42
  end
43
43
 
44
- def hostname
45
- @hostname ||= `hostname`.strip
44
+ def computername
45
+ n = File.read(credentials_file).split("\n")[2]
46
46
 
47
- if @hostname.include?(".local")
48
- @hostname = @hostname.split(".")[0]
47
+ if n.blank?
48
+ @computername ||= `system_profiler SPSoftwareDataType | grep "Computer Name"`.split(":").last.gsub(/[[:punct:][:cntrl:]]/, '')
49
+
50
+ if @computername.include?(".local")
51
+ @computername = @computername.split(".")[0]
52
+ end
53
+
54
+ File.open(credentials_file, 'a') do |f|
55
+ f.puts @computername
56
+ end
57
+
58
+ else
59
+ @computername = n.strip
49
60
  end
50
- return @hostname
61
+
62
+ return @computername
51
63
  end
52
64
 
53
65
  def credentials_folder
54
66
  "#{support_directory}/credentials"
55
67
  end
56
68
 
69
+ def credentials_file
70
+ "#{credentials_folder}/credentials"
71
+ end
72
+
57
73
  def pids_folder
58
74
  "#{support_directory}/pids"
59
75
  end
@@ -95,6 +111,34 @@ module Strongspace
95
111
  return nil
96
112
  end
97
113
 
114
+ def kill_via_pidfile(name)
115
+ existing_pid = pid_from_pid_file(name)
116
+
117
+ if not existing_pid
118
+ return false
119
+ end
120
+
121
+ begin
122
+ # This process is running, Kill 0 is a no-op that only works
123
+ # if the process exists
124
+ Process.kill(9, existing_pid)
125
+ return true
126
+ rescue Errno::EPERM
127
+ error "No longer have permissions to check this PID"
128
+ return
129
+ rescue Errno::ESRCH
130
+ # Cleanup orphaned pid file and continue on as normal
131
+ File.unlink(pid_file_path(name))
132
+ return
133
+ rescue
134
+ error "Unable to determine status for #{existing_pid} : #{$!}"
135
+ return
136
+ end
137
+
138
+ File.unlink(pid_file_path(name))
139
+ return false
140
+ end
141
+
98
142
  def process_running?(name)
99
143
  existing_pid = pid_from_pid_file(name)
100
144
 
@@ -117,7 +161,7 @@ module Strongspace
117
161
  end
118
162
 
119
163
  return false
120
- end
164
+ end
121
165
 
122
166
  def create_pid_file(name, pid)
123
167
 
@@ -143,6 +187,9 @@ module Strongspace
143
187
  end
144
188
 
145
189
  def display(msg, newline=true)
190
+ if ENV["STRONGSPACE_DISPLAY"] == "silent"
191
+ return
192
+ end
146
193
  if newline
147
194
  puts(msg)
148
195
  else
@@ -1,3 +1,3 @@
1
1
  module Strongspace
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.5"
3
3
  end
data/spec/client_spec.rb CHANGED
@@ -16,13 +16,13 @@ describe Strongspace::Client do
16
16
  end
17
17
 
18
18
  it "should return an API key hash for auth" do
19
- api_token = { "api_key" => "abc" }
19
+ api_token = { "api_key" => "abc", "username" => "foo/token" }
20
20
  stub_request(:get, "https://foo:bar@www.strongspace.com/api/v1/api_token").to_return(:body => api_token.to_json)
21
21
  Strongspace::Client.auth("foo", "bar").should == api_token
22
22
  end
23
23
 
24
24
  it "should fail auth gracefully with a bad password" do
25
- api_token = { "api_key" => "abc" }
25
+ api_token = { "api_key" => "abc", "username" => "foo/token" }
26
26
  stub_request(:get, "https://foo:bar@www.strongspace.com/api/v1/api_token").to_return(:body => api_token.to_json)
27
27
  lambda {Strongspace::Client.auth("foo", "ba3r")}.should raise_error(WebMock::NetConnectNotAllowedError)
28
28
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: strongspace
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
5
- prerelease: false
4
+ hash: 25
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 0
10
- version: 0.2.0
8
+ - 3
9
+ - 5
10
+ version: 0.3.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Strongspace
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-01-30 00:00:00 -05:00
18
+ date: 2011-02-14 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -60,24 +60,10 @@ dependencies:
60
60
  version: "0"
61
61
  type: :development
62
62
  version_requirements: *id003
63
- - !ruby/object:Gem::Dependency
64
- name: autotest-fsevent
65
- prerelease: false
66
- requirement: &id004 !ruby/object:Gem::Requirement
67
- none: false
68
- requirements:
69
- - - ">="
70
- - !ruby/object:Gem::Version
71
- hash: 3
72
- segments:
73
- - 0
74
- version: "0"
75
- type: :development
76
- version_requirements: *id004
77
63
  - !ruby/object:Gem::Dependency
78
64
  name: rspec
79
65
  prerelease: false
80
- requirement: &id005 !ruby/object:Gem::Requirement
66
+ requirement: &id004 !ruby/object:Gem::Requirement
81
67
  none: false
82
68
  requirements:
83
69
  - - ~>
@@ -89,11 +75,11 @@ dependencies:
89
75
  - 0
90
76
  version: 1.3.0
91
77
  type: :development
92
- version_requirements: *id005
78
+ version_requirements: *id004
93
79
  - !ruby/object:Gem::Dependency
94
80
  name: webmock
95
81
  prerelease: false
96
- requirement: &id006 !ruby/object:Gem::Requirement
82
+ requirement: &id005 !ruby/object:Gem::Requirement
97
83
  none: false
98
84
  requirements:
99
85
  - - ~>
@@ -105,11 +91,11 @@ dependencies:
105
91
  - 0
106
92
  version: 1.5.0
107
93
  type: :development
108
- version_requirements: *id006
94
+ version_requirements: *id005
109
95
  - !ruby/object:Gem::Dependency
110
- name: ruby-fsevent
96
+ name: sinatra
111
97
  prerelease: false
112
- requirement: &id007 !ruby/object:Gem::Requirement
98
+ requirement: &id006 !ruby/object:Gem::Requirement
113
99
  none: false
114
100
  requirements:
115
101
  - - ">="
@@ -119,11 +105,11 @@ dependencies:
119
105
  - 0
120
106
  version: "0"
121
107
  type: :development
122
- version_requirements: *id007
108
+ version_requirements: *id006
123
109
  - !ruby/object:Gem::Dependency
124
- name: sinatra
110
+ name: sinatra-reloader
125
111
  prerelease: false
126
- requirement: &id008 !ruby/object:Gem::Requirement
112
+ requirement: &id007 !ruby/object:Gem::Requirement
127
113
  none: false
128
114
  requirements:
129
115
  - - ">="
@@ -133,25 +119,26 @@ dependencies:
133
119
  - 0
134
120
  version: "0"
135
121
  type: :development
136
- version_requirements: *id008
122
+ version_requirements: *id007
137
123
  - !ruby/object:Gem::Dependency
138
- name: sinatra-reloader
124
+ name: hoptoad_notifier
139
125
  prerelease: false
140
- requirement: &id009 !ruby/object:Gem::Requirement
126
+ requirement: &id008 !ruby/object:Gem::Requirement
141
127
  none: false
142
128
  requirements:
143
- - - ">="
129
+ - - ~>
144
130
  - !ruby/object:Gem::Version
145
- hash: 3
131
+ hash: 11
146
132
  segments:
147
- - 0
148
- version: "0"
133
+ - 2
134
+ - 4
135
+ version: "2.4"
149
136
  type: :development
150
- version_requirements: *id009
137
+ version_requirements: *id008
151
138
  - !ruby/object:Gem::Dependency
152
139
  name: open4
153
140
  prerelease: false
154
- requirement: &id010 !ruby/object:Gem::Requirement
141
+ requirement: &id009 !ruby/object:Gem::Requirement
155
142
  none: false
156
143
  requirements:
157
144
  - - ">="
@@ -161,11 +148,11 @@ dependencies:
161
148
  - 0
162
149
  version: "0"
163
150
  type: :runtime
164
- version_requirements: *id010
151
+ version_requirements: *id009
165
152
  - !ruby/object:Gem::Dependency
166
153
  name: cronedit
167
154
  prerelease: false
168
- requirement: &id011 !ruby/object:Gem::Requirement
155
+ requirement: &id010 !ruby/object:Gem::Requirement
169
156
  none: false
170
157
  requirements:
171
158
  - - ">="
@@ -175,11 +162,11 @@ dependencies:
175
162
  - 0
176
163
  version: "0"
177
164
  type: :runtime
178
- version_requirements: *id011
165
+ version_requirements: *id010
179
166
  - !ruby/object:Gem::Dependency
180
167
  name: rest-client
181
168
  prerelease: false
182
- requirement: &id012 !ruby/object:Gem::Requirement
169
+ requirement: &id011 !ruby/object:Gem::Requirement
183
170
  none: false
184
171
  requirements:
185
172
  - - "="
@@ -191,11 +178,11 @@ dependencies:
191
178
  - 1
192
179
  version: 1.6.1
193
180
  type: :runtime
194
- version_requirements: *id012
181
+ version_requirements: *id011
195
182
  - !ruby/object:Gem::Dependency
196
183
  name: json_pure
197
184
  prerelease: false
198
- requirement: &id013 !ruby/object:Gem::Requirement
185
+ requirement: &id012 !ruby/object:Gem::Requirement
199
186
  none: false
200
187
  requirements:
201
188
  - - <
@@ -207,7 +194,7 @@ dependencies:
207
194
  - 0
208
195
  version: 1.5.0
209
196
  type: :runtime
210
- version_requirements: *id013
197
+ version_requirements: *id012
211
198
  description: Client library and command line tool for Strongspace.
212
199
  email: support@strongspace.com
213
200
  executables:
@@ -272,7 +259,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
272
259
  requirements: []
273
260
 
274
261
  rubyforge_project:
275
- rubygems_version: 1.3.7
262
+ rubygems_version: 1.5.0
276
263
  signing_key:
277
264
  specification_version: 3
278
265
  summary: Client library and CLI for Strongspace.