homeseed 0.0.9 → 0.0.10

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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- Y2JiOWJlZmM3YTgzZWI4MDg5Y2VlYjVjNWFkMTBmZTNiYjRhMGY5MA==
4
+ NGY0MDNlYmJkMzEzNTQxZWRmMWRkODlhZjAxNDgzYjJiOTIwMzA1NQ==
5
5
  data.tar.gz: !binary |-
6
- MjY1ZTJlNTAyM2I1MWI0NDE3NWMwNDRlYzkxMmNhYzk2YTNkM2JlZA==
6
+ MDQxZjQ1MDViYTEzNzc4NTJlYzgyYmQ3NzVhZDliN2FjYTJhMDQwMQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NDA1ZWVmMDdiMDFhY2JiMWZlNWJlMGNmZGE1NWFkNDM0YWI2ZmM2OWFkNWNm
10
- YmEyZjAyZGYzYThkMDQ5MjUwMTJmMGU5ZmQ0NTdiMDdiZDQ0MGE1YWY2Njhk
11
- NzFiOGYyYzVlZmVjZDQ4NjAyOWRlYmNmNWRlODVjZGEzNmRmMTI=
9
+ NmIwODQwMDg5ZDMyZDhhZmIxNGRlMTFkNTdmNTc3YTkwZjA3NzY2ZThkZDEy
10
+ YTJkZDllMTY5YzgwMDc5MmZkZWM0OWY4M2NlZGZlY2I0Njg0MTUzZjMwZDVj
11
+ MTM2MDk1NDNmYWU4ZDhlMjlmNzRlMjQxNzlmYTdjMGQyYWEwNTk=
12
12
  data.tar.gz: !binary |-
13
- YjM5ZTliMTllYzY2Mzk0NDU0ZDQwYzI3OGY1ZWQ0ODRmMzdiMjNhN2E0Y2Y1
14
- ZmRhNTlmMWU1NmJkMjIwYjM0ZTk3Y2I3OTVmMDQ4ZDhmNDc4NzhhOWU4Njlm
15
- NjU2NWEyNDlkZGViZTViYThhNDJiM2VkYTFhYWZmYmM4ZTkzNGM=
13
+ Y2M3OWRiMGZjNmQ0YzRlM2Q4NTlkNzM3MDQ5YTY5MDdiNDAyZDhmZDQyNTI5
14
+ OTE1MTg5NGE1NTFjNWY1MWIxMzRiM2FlMmUyMGY2NGYxZmM1YWFkN2Q0MGU0
15
+ ODdkNTQ2OTJjYTVjOGM5MGVmNTlhYzJlODVlZGYwMDUwMjkzMDE=
data/bin/homeseed CHANGED
@@ -5,21 +5,23 @@ require 'thor'
5
5
 
6
6
  module Homeseed
7
7
  class HomeseedCliApp < Thor
8
- desc 'exec [-e <command> or -f <files>] [-u <user>]',
8
+ desc 'exec [-e <command> or -f <files>] [-u <user>] [-p <has_password>]',
9
9
  'executes bash login session(s) on remote servers to run inline bash commands or bash commands from yml file'
10
10
  method_option :servers, required: true, aliases: '-s', desc: 'ssh hostname(s); csv if multiple'
11
11
  method_option :command, aliases: '-e', desc: 'bash command to exec'
12
12
  method_option :files, aliases: '-f', desc: 'yml bash command file(s) to exec'
13
13
  method_option :user, aliases: '-u', desc: 'ssh username', default: ENV['USER']
14
+ method_option :has_password, aliases: '-p', type: :boolean, default: false, desc: 'connection uses password; no ssh keys'
14
15
  def exec
15
16
  connection = Homeseed::Connection.new options
16
17
  connection.ssh_exec
17
18
  end
18
19
 
19
- desc 'plant [-u <user>]',
20
+ desc 'plant [-u <user>] [-p <has_password>]',
20
21
  'installs homeshick and then dot profile based on localhost $HOME/.homeseed.yml'
21
- method_option :servers, required: true, aliases: '-s', desc: 'ssh hostname(s); csv if multiple'
22
+ method_option :servers, required: true, aliases: '-s', desc: 'ssh hostname(s) or localhost; csv if multiple'
22
23
  method_option :user, aliases: '-u', desc: 'ssh username', default: ENV['USER']
24
+ method_option :has_password, aliases: '-p', type: :boolean, default: false, desc: 'connection uses password; no ssh keys'
23
25
  def plant
24
26
  config_files = %w(homeshick-prep.yml homeshick-install.yml homeshick-source.yml)
25
27
  files = config_files.map { |file| File.expand_path("../../config/#{file}", __FILE__) }
@@ -28,10 +30,11 @@ module Homeseed
28
30
  connection.ssh_exec
29
31
  end
30
32
 
31
- desc 'update [-u <user>]',
33
+ desc 'update [-u <user>] [-p <has_password>]',
32
34
  'updates dot profile based on localhost $HOME/.homeup.yml'
33
35
  method_option :servers, required: true, aliases: '-s', desc: 'ssh hostname(s); csv if multiple'
34
36
  method_option :user, aliases: '-u', desc: 'ssh username', default: ENV['USER']
37
+ method_option :has_password, aliases: '-p', type: :boolean, default: false, desc: 'connection uses password; no ssh keys'
35
38
  def update
36
39
  config_files = %w(homeshick-source.yml)
37
40
  files = config_files.map { |file| File.expand_path("../../config/#{file}", __FILE__) }
@@ -40,12 +43,13 @@ module Homeseed
40
43
  connection.ssh_exec
41
44
  end
42
45
 
43
- desc 'upload [-f <upload_files>] [-p <remote_path>] [-u <user>]',
46
+ desc 'upload [-f <upload_files>] [-r <remote_path>] [-u <user>] [-p <has_password>]',
44
47
  'scp uploads file(s) to remote servers'
45
48
  method_option :servers, required: true, aliases: '-s', desc: 'ssh hostname(s); csv if multiple'
46
49
  method_option :upload_files, aliases: '-f', desc: 'file(s) to upload to server(s)'
47
- method_option :remote_path, aliases: '-p', desc: 'path to upload to server(s)'
50
+ method_option :remote_path, aliases: '-r', desc: 'path to upload to server(s)'
48
51
  method_option :user, aliases: '-u', desc: 'ssh username', default: ENV['USER']
52
+ method_option :has_password, aliases: '-p', type: :boolean, default: false, desc: 'connection uses password; no ssh keys'
49
53
  def upload
50
54
  connection = Homeseed::Connection.new options
51
55
  connection.scp_upload
data/homeseed.gemspec CHANGED
@@ -23,4 +23,5 @@ Gem::Specification.new do |spec|
23
23
  spec.add_dependency 'net-ssh', '~> 2.6'
24
24
  spec.add_dependency 'net-scp', '~> 1.1'
25
25
  spec.add_dependency 'thor', '~> 0.19'
26
+ spec.add_dependency 'highline', '~> 1.6'
26
27
  end
@@ -0,0 +1,117 @@
1
+ module Homeseed
2
+ class Connection
3
+ include Logging
4
+
5
+ def initialize(params={})
6
+ raise 'servers and/or user not specified' unless params[:servers] and params[:user]
7
+ @servers = params[:servers].split(',')
8
+ @user = params[:user]
9
+
10
+ if params[:has_password]
11
+ cli = HighLine.new
12
+ @password = cli.ask("Enter password: ") { |q| q.echo = false }
13
+ else
14
+ @password = params[:password] || ''
15
+ end
16
+
17
+ if params[:logger]
18
+ @logger = params[:logger]
19
+ else
20
+ logger.level = params[:logger_level] || Logger::INFO
21
+ end
22
+
23
+ if params[:command]
24
+ @flat_commands = params[:command]
25
+ elsif params[:files]
26
+ @files = params[:files].split(',')
27
+ @flat_commands = ''
28
+ @files.each do |file|
29
+ yml_commands = YAML.load_file(file)
30
+ commands = []
31
+ self.process_hash(commands, '', yml_commands)
32
+ @flat_commands += commands.join('; ') + ';'
33
+ end
34
+ elsif params[:upload_files]
35
+ @remote_path = params[:remote_path] || '/tmp/'
36
+ @upload_files = params[:upload_files].split(',')
37
+ else
38
+ raise 'ERROR command, files or upload_files not specified'
39
+ end
40
+ end
41
+
42
+ def process_hash(commands, current_key, obj)
43
+ if obj.is_a?(Hash)
44
+ obj.each do |new_key, value|
45
+ combined_key = [current_key, new_key].delete_if { |k| k == '' }.join(" ")
46
+ process_hash(commands, combined_key, value)
47
+ end
48
+ else obj.is_a?(Array)
49
+ obj.each do |value|
50
+ combined_key = [current_key, value].delete_if { |k| k == '' }.join(" ")
51
+ commands << combined_key
52
+ end
53
+ end
54
+ end
55
+
56
+ def ssh_exec
57
+ Hash[@servers.map do |server|
58
+ logger.info "ssh #{@user}@#{server} exec: #{@flat_commands}"
59
+
60
+ exit_status = nil
61
+ exit_signal = nil
62
+
63
+ Net::SSH.start(server, @user, password: @password) do |ssh|
64
+ ssh.open_channel do |channel|
65
+ channel.exec("bash -l") do |ch,success|
66
+ ch.send_data "#{@flat_commands}\n"
67
+ ch.on_data do |c,data|
68
+ data_lines = data.split(/[\r,\n]/)
69
+ data_lines.each do |data_line|
70
+ logger.info data_line unless data_line == ''
71
+ end
72
+ end
73
+
74
+ ch.on_extended_data do |c,type,data|
75
+ data_lines = data.split(/[\r,\n]/)
76
+ data_lines.each do |data_line|
77
+ unless data_line == ''
78
+ if data_line.match(/error|failed/i)
79
+ logger.error data_line
80
+ else
81
+ logger.info data_line
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ ch.on_request("exit-status") do |c,data|
88
+ exit_status = data.read_long
89
+ end
90
+
91
+ ch.on_request("exit-signal") do |c,data|
92
+ exit_signal = data.read_long
93
+ end
94
+
95
+ ch.send_data "exit\n"
96
+ end
97
+ end
98
+ end
99
+ [server, { exit_status: exit_status, exit_signal: exit_signal }]
100
+ end]
101
+ end
102
+
103
+ def scp_upload
104
+ @servers.each do |server|
105
+ @upload_files.each do |upload_file|
106
+ logger.info "starting scp #{upload_file} #{@user}@#{server}:#{@remote_path}"
107
+ begin
108
+ Net::SCP.start(server, @user) { |scp| scp.upload!(upload_file, @remote_path) }
109
+ logger.info "finished scp #{upload_file} #{@user}@#{server}:#{@remote_path}"
110
+ rescue => err
111
+ logger.error "scp FAILED #{err}"
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -1,3 +1,3 @@
1
1
  module Homeseed
2
- VERSION = "0.0.9"
2
+ VERSION = "0.0.10"
3
3
  end
data/lib/homeseed.rb CHANGED
@@ -1,111 +1,8 @@
1
- require "homeseed/version"
2
1
  require 'logger'
3
2
  require 'net/ssh'
4
3
  require 'net/scp'
5
4
  require 'yaml'
5
+ require 'highline/import'
6
6
  require_relative './logging'
7
7
 
8
- module Homeseed
9
- class Connection
10
- include Logging
11
-
12
- def initialize(params={})
13
- raise 'servers and/or user not specified' unless params[:servers] and params[:user]
14
- @servers = params[:servers].split(',')
15
- @user = params[:user]
16
- @password = params[:password] || ''
17
-
18
- if params[:logger]
19
- @logger = params[:logger]
20
- else
21
- logger.level = params[:logger_level] || Logger::INFO
22
- end
23
-
24
- if params[:command]
25
- @flat_commands = params[:command]
26
- elsif params[:files]
27
- @files = params[:files].split(',')
28
- @flat_commands = ''
29
- @files.each do |file|
30
- yml_commands = YAML.load_file(file)
31
- commands = []
32
- self.process_hash(commands, '', yml_commands)
33
- @flat_commands += commands.join('; ') + ';'
34
- end
35
- elsif params[:upload_files]
36
- @remote_path = params[:remote_path] || '/tmp/'
37
- @upload_files = params[:upload_files].split(',')
38
- else
39
- raise 'ERROR command, files or upload_files not specified'
40
- end
41
- end
42
-
43
- def process_hash(commands, current_key, obj)
44
- if obj.is_a?(Hash)
45
- obj.each do |new_key, value|
46
- combined_key = [current_key, new_key].delete_if { |k| k == '' }.join(" ")
47
- process_hash(commands, combined_key, value)
48
- end
49
- else obj.is_a?(Array)
50
- obj.each do |value|
51
- combined_key = [current_key, value].delete_if { |k| k == '' }.join(" ")
52
- commands << combined_key
53
- end
54
- end
55
- end
56
-
57
- def ssh_exec
58
- Hash[@servers.map do |server|
59
- logger.info "ssh #{@user}@#{server} exec: #{@flat_commands}"
60
-
61
- exit_status = 0
62
- Net::SSH.start(server, @user, password: @password) do |ssh|
63
- ssh.open_channel do |channel|
64
- channel.exec("bash -l") do |ch,success|
65
- ch.send_data "#{@flat_commands}\n"
66
- ch.on_data do |c,data|
67
- data_lines = data.split(/[\r,\n]/)
68
- data_lines.each do |data_line|
69
- logger.info data_line unless data_line == ''
70
- end
71
- end
72
-
73
- ch.on_extended_data do |c,type,data|
74
- data_lines = data.split(/[\r,\n]/)
75
- data_lines.each do |data_line|
76
- unless data_line == ''
77
- if data_line.match(/error|failed/i)
78
- logger.error data_line
79
- else
80
- logger.info data_line
81
- end
82
- end
83
- end
84
- end
85
-
86
- ch.on_request("exit-status") do |c,data|
87
- exit_status = data.read_long
88
- end
89
- ch.send_data "exit\n"
90
- end
91
- end
92
- end
93
- [server, { exit_status: exit_status }]
94
- end]
95
- end
96
-
97
- def scp_upload
98
- @servers.each do |server|
99
- @upload_files.each do |upload_file|
100
- logger.info "starting scp #{upload_file} #{@user}@#{server}:#{@remote_path}"
101
- begin
102
- Net::SCP.start(server, @user) { |scp| scp.upload!(upload_file, @remote_path) }
103
- logger.info "finished scp #{upload_file} #{@user}@#{server}:#{@remote_path}"
104
- rescue => err
105
- logger.error "scp FAILED #{err}"
106
- end
107
- end
108
- end
109
- end
110
- end
111
- end
8
+ Dir["./lib/homeseed/*.rb"].sort.each { |f| require f }
data/lib/logging.rb CHANGED
@@ -3,18 +3,24 @@ module Logging
3
3
  @logger ||= Logging.logger_for(self.class.name)
4
4
  end
5
5
 
6
- # Use a hash class-ivar to cache a unique Logger per class:
7
- @loggers = {}
6
+ @@global_level = Logger::INFO
7
+ @@loggers = {}
8
8
 
9
9
  class << self
10
10
  def logger_for(classname)
11
- @loggers[classname] ||= configure_logger_for(classname)
11
+ @@loggers[classname] ||= configure_logger_for(classname)
12
12
  end
13
13
 
14
14
  def configure_logger_for(classname)
15
15
  logger = Logger.new(STDOUT)
16
+ logger.level = @@global_level
16
17
  logger.progname = classname
17
18
  logger
18
19
  end
20
+
21
+ def global_level=(level)
22
+ @@global_level = level
23
+ @@loggers.each { |classname,logger| logger.level = level }
24
+ end
19
25
  end
20
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: homeseed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - rbuchss
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-17 00:00:00.000000000 Z
11
+ date: 2014-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ~>
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0.19'
83
+ - !ruby/object:Gem::Dependency
84
+ name: highline
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '1.6'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '1.6'
83
97
  description: Flattens then SSH execs commands on remote server
84
98
  email:
85
99
  - rbuchss@gmail.com
@@ -100,6 +114,7 @@ files:
100
114
  - config/rbuchss-setup-linux.yml
101
115
  - homeseed.gemspec
102
116
  - lib/homeseed.rb
117
+ - lib/homeseed/connection.rb
103
118
  - lib/homeseed/version.rb
104
119
  - lib/logging.rb
105
120
  homepage: http://github.com/rbuchss/homeseed