homeseed 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
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