cloudflock-qt 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 40697a3970659343568a5908dba4f69e9fbd8478
4
+ data.tar.gz: bb34bf94706b9419f410d4fdc27b17b0a39a31f6
5
+ SHA512:
6
+ metadata.gz: a5e82a619a4e95fe5c8b695217ef5a3d3fd7d810839ae39645fbb3e1d616533db494f55d7f88ad6a77b4887797427f2ee0f903db02507e2cffe8fbc620783c46
7
+ data.tar.gz: a647877f2cc388b44d7c32037729479c01a1aa514e467818d173462a9268c2f72fddaa5148de89cc324cc4854e7d1059b8363d7bc5b18c3b1ffccc4839c3d54e
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'cloudflock-qt/app'
4
+
5
+ $0 = 'qtflock'
6
+
7
+ app = Qt::Application.new(ARGV)
8
+ CloudFlockQt::App.new
9
+ app.exec
@@ -0,0 +1,13 @@
1
+ # Required to work around bug in Windows binary gem.
2
+ # Issue: https://github.com/ryanmelt/qtbindings/issues/69
3
+ require 'thread'
4
+ require 'Qt'
5
+ require 'cloudflock/app'
6
+ require 'cloudflock/task/server-profile'
7
+
8
+ # Public: Namespace for any application built around the CloudFlock API with a
9
+ # Qt interface.
10
+ module CloudFlockQt
11
+ # Public: Version number of the current gem.
12
+ VERSION = '0.7.2'
13
+ end
@@ -0,0 +1,214 @@
1
+ require 'cloudflock-qt'
2
+ require 'cloudflock-qt/error'
3
+ require 'cloudflock-qt/results'
4
+
5
+ module CloudFlockQt
6
+ # Public: Class to be used for the main window.
7
+ class App < Qt::MainWindow
8
+ include CloudFlock::App::Common
9
+ include CloudFlock::Remote
10
+ # Public: Width of the main form window in pixels.
11
+ WINDOW_WIDTH = 300
12
+ # Public: Height of the main form window in pixels.
13
+ WINDOW_HEIGHT = 220
14
+ # Public: Title of the main form window.
15
+ WINDOW_TITLE = "QtFlock Profile #{CloudFlockQt::VERSION}"
16
+
17
+ # Public: Height of each row in the form in pixels
18
+ FORM_LINE_HEIGHT = 30
19
+
20
+ # Public: Raised when information provided to log in to a host is
21
+ # incomplete.
22
+ class HostNotConfigured < StandardError; end
23
+
24
+ # Public: Set up application state and create the main application window,
25
+ # populating it with the form to take target host details.
26
+ def initialize
27
+ super
28
+
29
+ init_instance_variables
30
+ init_ui
31
+ end
32
+
33
+ private
34
+
35
+ # Internal: Set the default values for instance variables.
36
+ #
37
+ # Returns nothing.
38
+ def init_instance_variables
39
+ @hostname = ''
40
+ @username = 'root'
41
+ @password = ''
42
+ @root_password = ''
43
+ @port = '22'
44
+ @sudo = false
45
+
46
+ @lines = 0
47
+ end
48
+
49
+ # Internal: Set up the main window and add the form UI for target host
50
+ # definition.
51
+ #
52
+ # Returns nothing.
53
+ def init_ui
54
+ set_window_title WINDOW_TITLE
55
+ resize WINDOW_WIDTH, WINDOW_HEIGHT
56
+
57
+ file = menu_bar.add_menu('&File')
58
+ add_menu_item('E&xit', file, :quit)
59
+
60
+ build_main_form
61
+
62
+ show
63
+ end
64
+
65
+ # Internal: Build the form to collect data on the host to profile.
66
+ #
67
+ # Returns nothing.
68
+ def build_main_form
69
+ add_form_line_text('Hostname: ', :@hostname)
70
+ add_form_line_text('Username: ', :@username)
71
+ add_form_pass_text('Password: ', :@password)
72
+ add_form_pass_text('Root Password: ', :@root_password)
73
+ add_form_line_text('Port: ', :@port)
74
+
75
+ add_form_line_toggle('Use Sudo', :@sudo)
76
+ add_submit_button('Run Profile') { run_profile }
77
+ end
78
+
79
+ # Internal: Add an entry to a menu (e.g. 'File'), and assign an action to
80
+ # it.
81
+ #
82
+ # item_text - String containing the text to be displayed. An '&' character
83
+ # preceding a character will cause that character to be a
84
+ # hotkey for the item.
85
+ # menu - Qt::Menu to contain the new entry.
86
+ # action - Action to be taken upon triggering the menu item.
87
+ #
88
+ # Returns nothing.
89
+ def add_menu_item(item_text, menu, action)
90
+ item = Qt::Action.new item_text, self
91
+ menu.add_action item
92
+ connect(item, SIGNAL(:triggered), Qt::Application.instance, SLOT(action))
93
+ end
94
+
95
+ # Internal: Create a text input field and corrsponding label.
96
+ #
97
+ # item_text - String with which to populate a text label.
98
+ # varname - Symbol containing the name of the instance variable with
99
+ # which to associate the form entry.
100
+ #
101
+ # Returns the Qt::LineEdit object.
102
+ def add_form_line_text(item_text, varname)
103
+ @lines += 1
104
+
105
+ label = Qt::Label.new self
106
+ label.set_text item_text
107
+ label.adjust_size
108
+ label.move(5, FORM_LINE_HEIGHT * @lines)
109
+
110
+ input = Qt::LineEdit.new self
111
+ input.set_geometry 105, FORM_LINE_HEIGHT * @lines - 10, 190, FORM_LINE_HEIGHT
112
+ input.connect(SIGNAL('textChanged(QString)')) do |string|
113
+ instance_variable_set(varname, string)
114
+ end
115
+ input.set_text instance_variable_get(varname)
116
+
117
+ input
118
+ end
119
+
120
+ # Internal: Wrap add_form_line_text, ensuring the the text display mode is
121
+ # appropriate for passwords.
122
+ #
123
+ # item_text - String with which to populate a text label.
124
+ # varname - Symbol containing the name of the instance variable with
125
+ # which to associate the form entry.
126
+ #
127
+ # Returns nothing.
128
+ def add_form_pass_text(item_text, varname)
129
+ add_form_line_text(item_text, varname).echoMode = Qt::LineEdit::Password
130
+ end
131
+
132
+ # Internal: Create a toggle button input field.
133
+ #
134
+ # item_text - String which will be displayed on the toggle button.
135
+ # varname - Symbol containing the name of the instance variable with
136
+ # which to associate the form entry.
137
+ # block - Optional block to attach to clicking the toggle.
138
+ #
139
+ # Returns nothing.
140
+ def add_form_line_toggle(item_text, varname, &block)
141
+ @lines += 1
142
+
143
+ toggle = Qt::PushButton.new item_text, self
144
+ toggle.set_checkable true
145
+ toggle.set_geometry 5, FORM_LINE_HEIGHT * @lines - 5, 80, 30
146
+ if block.nil?
147
+ toggle.connect(SIGNAL(:clicked)) do
148
+ instance_variable_set(varname, toggle.is_checked)
149
+ end
150
+ else
151
+ toggle.connect(SIGNAL(:clicked), &block)
152
+ end
153
+ end
154
+
155
+ # Internal: Create a submit button.
156
+ #
157
+ # item_text - String which will be displayed on the toggle button.
158
+ # varname - Symbol containing the name of the instance variable with
159
+ # which to associate the form entry.
160
+ # block - Optional block to attach to clicking the toggle.
161
+ #
162
+ # Returns nothing.
163
+ def add_submit_button(item_text, &block)
164
+ submit = Qt::PushButton.new item_text, self
165
+ submit.set_geometry 175, FORM_LINE_HEIGHT * @lines - 5, 120, 30
166
+ submit.connect(SIGNAL(:clicked), &block)
167
+ end
168
+
169
+ # Internal: Check that all necessary data is present, alerting the user if
170
+ # not. If everything appears present, attempt to profile the host.
171
+ #
172
+ # Returns nothing.
173
+ def run_profile
174
+ source_host = { hostname: @hostname, username: @username, port: @port,
175
+ password: @password, sudo: @sudo, ssh_key: '' }
176
+ check_source(source_host)
177
+
178
+ source_ssh = SSH.new(source_host)
179
+ profile = CloudFlock::Task::ServerProfile.new(source_ssh)
180
+
181
+ CloudFlockQt::ResultsWindow.new(profile)
182
+ rescue HostNotConfigured => e
183
+ CloudFlockQt::ErrorWindow.new(e.message)
184
+ rescue CloudFlock::Remote::SSH::InvalidHostname
185
+ CloudFlockQt::ErrorWindow.new("Unable to resolve '#{@hostname}'")
186
+ rescue Net::SSH::AuthenticationFailed
187
+ CloudFlockQt::ErrorWindow.new("Unable to log in as '#{@username}'")
188
+ rescue CloudFlock::Remote::SSH::SSHCannotConnect
189
+ CloudFlockQt::ErrorWindow.new("Cannot connect to #{@hostname}:#{@port}")
190
+ end
191
+
192
+ # Internal: Verify that all entries necessary for logging in to a remote
193
+ # host are present.
194
+ #
195
+ # Raises HostNotConfigured if any necessary information is not present.
196
+ #
197
+ # Returns nothing.
198
+ def check_source(host)
199
+ [:hostname, :username, :port].each do |option|
200
+ if host[option].to_s.empty?
201
+ raise(HostNotConfigured, "Missing #{option.to_s.capitalize}")
202
+ end
203
+ end
204
+ host[:sudo] = false if host[:username] == 'root'
205
+
206
+ # If non-root and using su, the root password is needed
207
+ if host[:username] == 'root' || host[:sudo]
208
+ host[:root_password] = host[:password]
209
+ else
210
+ raise HostNotConfigured if host[:root_password].to_s.empty?
211
+ end
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,19 @@
1
+ require 'cloudflock-qt'
2
+
3
+ module CloudFlockQt
4
+ # Public: Class to be used for error notifications.
5
+ class ErrorWindow < Qt::ErrorMessage
6
+ # Public: Width of the results window in pixels.
7
+ WINDOW_WIDTH = 300
8
+ # Public: Height of the results window in pixels.
9
+ WINDOW_HEIGHT = 150
10
+
11
+ # Public: Create and populate the window with results from profiling a
12
+ # remote host.
13
+ def initialize(message)
14
+ super()
15
+
16
+ show_message(message)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,73 @@
1
+ require 'cloudflock-qt'
2
+
3
+ module CloudFlockQt
4
+ # Public: Class to be used for results windows.
5
+ class ResultsWindow < Qt::Widget
6
+ # Public: Width of the results window in pixels.
7
+ WINDOW_WIDTH = 400
8
+ # Public: Height of the results window in pixels.
9
+ WINDOW_HEIGHT = 500
10
+
11
+ # Public: Create and populate the window with results from profiling a
12
+ # remote host.
13
+ def initialize(profile)
14
+ super()
15
+
16
+ init_ui(profile)
17
+ end
18
+
19
+ private
20
+
21
+ # Internal: Create the results window and text field, then populate it with
22
+ # the results of a host profile.
23
+ #
24
+ # profile - CloudFlock::Task::ServerProfile object.
25
+ #
26
+ # Returns nothing.
27
+ def init_ui(profile)
28
+ hostname = profile.select_entries(/System/, /Hostname/).first.to_s
29
+
30
+ set_window_title "Results for #{hostname}"
31
+ resize WINDOW_WIDTH, WINDOW_HEIGHT
32
+
33
+ results = Qt::TextEdit.new self
34
+ results.set_geometry 5, 5, WINDOW_WIDTH - 5, WINDOW_HEIGHT - 5
35
+ results.set_text generate_report(profile)
36
+
37
+ show
38
+ end
39
+
40
+ # Internal: Generate a String representation of the profile run against a
41
+ # remote host.
42
+ #
43
+ # profile - CloudFlock::Task::ServerProfile object.
44
+ #
45
+ # Returns a String.
46
+ def host_info(profile)
47
+ data = profile.map { |section| [section.title, distill_entries(section)] }
48
+ data.map { |section| section.join("\n") }.join("\n\n")
49
+ end
50
+
51
+ # Internal: Filter any empty entries from a section, then map the rest to
52
+ # Strings.
53
+ #
54
+ # section - CloudFlock::Task::ServerProfile::Section
55
+ #
56
+ # Returns an Array containing Strings.
57
+ def distill_entries(section)
58
+ non_empty = section.entries.reject { |entry| entry.values.to_s.empty? }
59
+ non_empty.map { |entry| "#{entry.name}: #{entry.values}" }
60
+ end
61
+
62
+ # Internal: Produce a human-readable report from the results of profiling a
63
+ # target host.
64
+ #
65
+ # profile - CloudFlock::Task::ServerProfile object.
66
+ #
67
+ # Returns a String.
68
+ def generate_report(profile)
69
+ profile_hash = profile.to_hash
70
+ host_info(profile_hash[:info])
71
+ end
72
+ end
73
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cloudflock-qt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.7.2
5
+ platform: ruby
6
+ authors:
7
+ - Chris Wuest
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cloudflock
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.7'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.7.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.7'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.7.2
33
+ - !ruby/object:Gem::Dependency
34
+ name: qtbindings
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '4.8'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '4.8'
47
+ description: Graphical frontend for CloudFlock in Qt
48
+ email: chris@chriswuest.com
49
+ executables:
50
+ - qtflock
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - bin/qtflock
55
+ - lib/cloudflock-qt.rb
56
+ - lib/cloudflock-qt/app.rb
57
+ - lib/cloudflock-qt/error.rb
58
+ - lib/cloudflock-qt/results.rb
59
+ homepage: http://github.com/cwuest/cloudflock-qt
60
+ licenses:
61
+ - Apache 2.0
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 2.2.2
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: Unix migration automation
83
+ test_files: []