homeseed 0.0.13 → 0.0.14

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
- YTkzMmRlMmM3NjA0ODczNDhmMTA1NDk4ZTk0NmUwZjI4NTJjMThkNg==
4
+ ZTJiMDg0ZDU5ZTkzM2IwN2EyNTI3ODI0ZTFkNThhMzMwNGNhYjgxMg==
5
5
  data.tar.gz: !binary |-
6
- M2JiMzk4NDk0MWI4MGIzMWQ0NDgxZmVlZGU3Y2NmYTI0ZmEwYTQ0Zg==
6
+ ODYxNWY2MDFhZDhiMTQ4MzVhYTA4ZGFjZDM2MTQ0NTMxNmY0MWQ3NA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MDNmOTJhMjgyODRlZDUwZTg4N2FlNzI4ZTQ3MWU3MjNkY2FhOThkZGIyNjI3
10
- M2VmNzE2ODA4MTY4MWMxNDkyZTJlNjhiNmYwYTM4ZTllODk5NWEzYTNiNDQy
11
- ZWRlZTA1YmM5NjA0YTEzZjQwOGYwYmEwNWY1NzZiMjZiYzEwMjY=
9
+ Y2M0NTYxMjU2MjZhMDVmODAyODMyMzM0N2ZiNGVmYzAyMzA4M2NhNDZjMzNh
10
+ ZGM4MWU3NzQxYzBiYmJmNzM3YzczNjEwM2E3OGVmNmUxNWQwN2NhZWQ4Zjdl
11
+ MjcyNmM0MjgwZTU1ZDNlZjQyNmMwN2E2OTIwMjBkOGUwOTY4Yzg=
12
12
  data.tar.gz: !binary |-
13
- ODBkYzExMzZjZDM0ZTgyN2NmODg1MzI4ZWNkYWFiMzNhZTIwZmQ3N2NjM2U4
14
- Y2ExYmY3MmQ1ZTE4NWU1YzNiN2JjMTg3MjA2ZTZkYmVhOGY1MzAwYjQ4NDQ5
15
- MDcwN2QzNWQwMjk4MWQ1YThlNjYzMjcwZjEzZjcxNmM2ODNiNDg=
13
+ MzBjZjQxZTQ4YTA1YjdiODgwYTNiZjBkMzhmY2FiZjFkMTQ5Njg4NmU3ZDlj
14
+ MWJlMGExMjI0NmI0ZTIyNWJmOWUwZTVjOGQxY2NjOTIzYWM1Y2U1ZGMzZWYw
15
+ YzQzNThlMTg5MjkxYTNlYmI2NWZjYWUwMTg5Y2RmNjNiOGU5MmQ=
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Homeseed
2
2
 
3
- CLI for config/dot-profile deployments
4
- also is a bash login session command flattener for remote ssh exec
3
+ CLI for managing system configs and dot-profiles
4
+ can be used for initializations, deployments and updates on remotes or localhost
5
5
 
6
6
  ## Installation
7
7
 
@@ -21,17 +21,26 @@ Or install it yourself as:
21
21
 
22
22
  homeseed commands
23
23
  ```
24
- homeseed help
24
+ $ homeseed
25
25
  Commands:
26
- homeseed exec [-e <command> or -f <files>] [-u <user>] -s, --servers=SERVERS # executes bash login session(s) on remote servers to run inline bash commands or bash commands from yml file
27
- homeseed help [COMMAND] # Describe available commands or one specific command
28
- homeseed plant [-u <user>] -s, --servers=SERVERS # installs homeshick and then dot profile based on localhost $HOME/.homeseed.yml
29
- homeseed update [-u <user>] -s, --servers=SERVERS # updates dot profile based on localhost $HOME/.homeup.yml
26
+ homeseed exec [-e <command> or -f <files>] [-u <user>] [-p <has_password>] -s, --servers=SERVERS # executes bash login session(s) on remote servers to run inline bash commands or bash ...
27
+ homeseed help [COMMAND] # Describe available commands or one specific command
28
+ homeseed plant [-u <user>] [-p <has_password>] [-c <clean>] [--url <url>] -s, --servers=SERVERS # installs homeshick and then dot profile based on localhost $HOME/.homeseed.yml or url...
29
+ homeseed update [-u <user>] [-p <has_password>] [--url <url>] -s, --servers=SERVERS # updates dot profile based on localhost $HOME/.homeup.yml or url with yml commands
30
+ homeseed upload [-f <upload_files>] [-r <remote_path>] [-u <user>] [-p <has_password>] -s, --servers=SERVERS # scp uploads file(s) to remote servers
30
31
  ```
31
32
 
32
- to install dot profile on csv server list run; uses $HOME/.homeseed.yml
33
+ to distribute and install your dot profile(s) on multiple of servers run
33
34
  ```
34
- homeseed plant -s blackberry,blueberry,raspberry
35
+ $ homeseed plant -s blackberry,blueberry,raspberry
36
+ ```
37
+ this uses localhost's $HOME/.homeseed.yml by default; a url can given instead
38
+ ```
39
+ $ homeseed plant -s pom --url 'i_am_a_homeseed.yml_file'
40
+ ```
41
+ localhost can be specified as the target for system initialization
42
+ ```
43
+ $ homeseed exec -s localhost --url 'setup_bluez_mupen_and_such.yml'
35
44
  ```
36
45
 
37
46
  ex $HOME/.homeseed.yml
@@ -45,9 +54,13 @@ homeshick:
45
54
  - vim-4-eva --force
46
55
  ```
47
56
 
48
- to update run; uses $HOME/.homeup.yml
57
+ to update run; uses $HOME/.homeup.yml (same url based overrides apply here as well)
58
+ ```
59
+ $ homeseed update -s soho
60
+ ```
61
+ localhost can be specified here as well
49
62
  ```
50
- homeseed update -s soho
63
+ $ homeseed update -s localhost
51
64
  ```
52
65
 
53
66
  ex $HOME/.homeup.yml
@@ -14,45 +14,42 @@ module Homeseed
14
14
  method_option :has_password, aliases: '-p', type: :boolean, default: false, desc: 'connection uses password; no ssh keys'
15
15
  def exec
16
16
  connection = Homeseed::Connection.new options
17
- connection.ssh_exec
17
+ connection.exec
18
18
  end
19
19
 
20
- desc 'plant [-u <user>] [-p <has_password>]',
21
- 'installs homeshick and then dot profile based on localhost $HOME/.homeseed.yml'
22
- method_option :servers, required: true, aliases: '-s', desc: 'ssh hostname(s) or localhost; csv if multiple'
20
+ desc 'upload [-f <upload_files>] [-r <remote_path>] [-u <user>] [-p <has_password>]',
21
+ 'scp uploads file(s) to remote servers'
22
+ method_option :servers, required: true, aliases: '-s', desc: 'ssh hostname(s); csv if multiple'
23
+ method_option :upload_files, aliases: '-f', desc: 'file(s) to upload to server(s)'
24
+ method_option :remote_path, aliases: '-r', desc: 'path to upload to server(s)'
23
25
  method_option :user, aliases: '-u', desc: 'ssh username', default: ENV['USER']
24
26
  method_option :has_password, aliases: '-p', type: :boolean, default: false, desc: 'connection uses password; no ssh keys'
25
- def plant
26
- config_files = %w(homeshick-prep.yml homeshick-install.yml homeshick-source.yml)
27
- files = config_files.map { |file| File.expand_path("../../config/#{file}", __FILE__) }
28
- files << File.expand_path('.homeseed.yml', ENV['HOME'])
29
- connection = Homeseed::Connection.new options.merge(files: files.join(','))
30
- connection.ssh_exec
27
+ def upload
28
+ connection = Homeseed::Connection.new options
29
+ connection.scp_upload
31
30
  end
32
31
 
33
- desc 'update [-u <user>] [-p <has_password>]',
34
- 'updates dot profile based on localhost $HOME/.homeup.yml'
35
- method_option :servers, required: true, aliases: '-s', desc: 'ssh hostname(s); csv if multiple'
32
+ desc 'plant [-u <user>] [-p <has_password>] [-c <clean>] [--url <url>]',
33
+ 'installs homeshick and then dot profile based on localhost $HOME/.homeseed.yml or url with yml commands'
34
+ method_option :servers, required: true, aliases: '-s', desc: 'ssh hostname(s) or localhost; csv if multiple'
36
35
  method_option :user, aliases: '-u', desc: 'ssh username', default: ENV['USER']
37
36
  method_option :has_password, aliases: '-p', type: :boolean, default: false, desc: 'connection uses password; no ssh keys'
38
- def update
39
- config_files = %w(homeshick-source.yml)
40
- files = config_files.map { |file| File.expand_path("../../config/#{file}", __FILE__) }
41
- files << File.expand_path('.homeup.yml', ENV['HOME'])
42
- connection = Homeseed::Connection.new options.merge(files: files.join(','))
43
- connection.ssh_exec
37
+ method_option :clean, type: :boolean, default: true, desc: 'clean install toogle'
38
+ method_option :url, desc: "url to use vs file default: #{ENV['HOME']}/.homeseed.yml"
39
+ def plant
40
+ homeshick = Homeseed::Homeshick.new options
41
+ homeshick.install options
44
42
  end
45
43
 
46
- desc 'upload [-f <upload_files>] [-r <remote_path>] [-u <user>] [-p <has_password>]',
47
- 'scp uploads file(s) to remote servers'
44
+ desc 'update [-u <user>] [-p <has_password>] [--url <url>]',
45
+ 'updates dot profile based on localhost $HOME/.homeup.yml or url with yml commands'
48
46
  method_option :servers, required: true, aliases: '-s', desc: 'ssh hostname(s); csv if multiple'
49
- method_option :upload_files, aliases: '-f', desc: 'file(s) to upload to server(s)'
50
- method_option :remote_path, aliases: '-r', desc: 'path to upload to server(s)'
51
47
  method_option :user, aliases: '-u', desc: 'ssh username', default: ENV['USER']
52
48
  method_option :has_password, aliases: '-p', type: :boolean, default: false, desc: 'connection uses password; no ssh keys'
53
- def upload
54
- connection = Homeseed::Connection.new options
55
- connection.scp_upload
49
+ method_option :url, desc: "url to use vs file default: #{ENV['HOME']}/.homeup.yml"
50
+ def update
51
+ homeshick = Homeseed::Homeshick.new options
52
+ homeshick.update options
56
53
  end
57
54
  end
58
55
  HomeseedCliApp.start
@@ -24,4 +24,5 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency 'net-scp', '~> 1.1'
25
25
  spec.add_dependency 'thor', '~> 0.19'
26
26
  spec.add_dependency 'highline', '~> 1.6'
27
+ spec.add_dependency 'httparty', '~> 0.11'
27
28
  end
@@ -4,6 +4,8 @@ require 'net/ssh'
4
4
  require 'net/scp'
5
5
  require 'yaml'
6
6
  require 'highline/import'
7
- require_relative './logging'
8
-
9
- require_relative './homeseed/connection'
7
+ require 'httparty'
8
+ require 'logging'
9
+ require 'homeseed/connection'
10
+ require 'homeseed/homeshick'
11
+ require 'homeseed/errors'
@@ -1,11 +1,14 @@
1
1
  module Homeseed
2
2
  class Connection
3
3
  include Logging
4
+ attr_reader :servers, :user, :has_password
4
5
 
5
6
  def initialize(params={})
6
- raise 'servers and/or user not specified' unless params[:servers] and params[:user]
7
+ raise ConnectionError, 'servers and/or user not specified' unless params[:servers] and params[:user]
7
8
  @servers = params[:servers].split(',')
8
9
  @user = params[:user]
10
+ @commands = []
11
+ @logger = params[:logger] || logger
9
12
 
10
13
  if params[:has_password]
11
14
  cli = HighLine.new
@@ -14,31 +17,54 @@ module Homeseed
14
17
  @password = params[:password] || ''
15
18
  end
16
19
 
17
- if params[:logger]
18
- @logger = params[:logger]
19
- else
20
- logger.level = params[:logger_level] || Logger::INFO
21
- end
20
+ push_commands(params)
21
+ end
22
22
 
23
+ def push_commands(params={})
23
24
  if params[:command]
24
- @flat_commands = params[:command]
25
+ @commands.push(*params[:command])
25
26
  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
27
+ push_bash_files(params[:files])
28
+ elsif params[:file]
29
+ push_bash_file(params[:file])
30
+ elsif params[:url]
31
+ push_url_commands(params[:url])
34
32
  elsif params[:upload_files]
35
33
  @remote_path = params[:remote_path] || '/tmp/'
36
34
  @upload_files = params[:upload_files].split(',')
37
- else
38
- raise 'ERROR command, files or upload_files not specified'
39
35
  end
40
36
  end
41
37
 
38
+ def config_file_path(file)
39
+ File.expand_path("../../../config/#{file}", __FILE__)
40
+ end
41
+
42
+ def push_bash_files(files)
43
+ @files = files
44
+ @files.each do |file|
45
+ push_bash_file(file)
46
+ end
47
+ end
48
+
49
+ def push_bash_file(file)
50
+ @file = file
51
+ yml_commands = YAML.load_file(file)
52
+ push_yml_commands(yml_commands)
53
+ end
54
+
55
+ def push_url_commands(url)
56
+ response = HTTParty.get(url)
57
+ raise HTTPartyError unless response.code == 200
58
+ yml_commands = YAML.load(response.body)
59
+ push_yml_commands(yml_commands)
60
+ end
61
+
62
+ def push_yml_commands(yml_commands)
63
+ commands = []
64
+ self.process_hash(commands, '', yml_commands)
65
+ @commands.push(*commands)
66
+ end
67
+
42
68
  def process_hash(commands, current_key, obj)
43
69
  if obj.is_a?(Hash)
44
70
  obj.each do |new_key, value|
@@ -53,9 +79,29 @@ module Homeseed
53
79
  end
54
80
  end
55
81
 
82
+ def exec(params={})
83
+ if @servers.include?('localhost')
84
+ local_exec
85
+ else
86
+ ssh_exec
87
+ end
88
+ end
89
+
90
+ def local_exec
91
+ commands = @commands.join('; ') + ';'
92
+ @logger.info "localhost exec: #{commands}"
93
+
94
+ IO.popen("#{commands}") do |chunks|
95
+ chunks.each do |line|
96
+ log_exec(line)
97
+ end
98
+ end
99
+ end
100
+
56
101
  def ssh_exec
57
102
  Hash[@servers.map do |server|
58
- logger.info "ssh #{@user}@#{server} exec: #{@flat_commands}"
103
+ commands = @commands.join('; ') + ';'
104
+ @logger.info "ssh #{@user}@#{server} exec: #{commands}"
59
105
 
60
106
  exit_status = nil
61
107
  exit_signal = nil
@@ -63,25 +109,14 @@ module Homeseed
63
109
  Net::SSH.start(server, @user, password: @password) do |ssh|
64
110
  ssh.open_channel do |channel|
65
111
  channel.exec("bash -l") do |ch,success|
66
- ch.send_data "#{@flat_commands}\n"
112
+ ch.send_data "#{commands}\n"
113
+
67
114
  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
115
+ log_exec(data)
72
116
  end
73
117
 
74
118
  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
119
+ log_exec(data)
85
120
  end
86
121
 
87
122
  ch.on_request("exit-status") do |c,data|
@@ -100,15 +135,29 @@ module Homeseed
100
135
  end]
101
136
  end
102
137
 
138
+ def log_exec(data)
139
+ data_lines = data.split(/[\r,\n]/)
140
+ data_lines.each do |data_line|
141
+ unless data_line == ''
142
+ if data_line.match(/error|failed|fatal/i)
143
+ @logger.error data_line
144
+ else
145
+ @logger.info data_line
146
+ end
147
+ end
148
+ end
149
+ end
150
+
103
151
  def scp_upload
152
+ raise ConnectionError, 'cannot scp to localhost' if @servers.include?('localhost')
104
153
  @servers.each do |server|
105
154
  @upload_files.each do |upload_file|
106
- logger.info "starting scp #{upload_file} #{@user}@#{server}:#{@remote_path}"
155
+ @logger.info "starting scp #{upload_file} #{@user}@#{server}:#{@remote_path}"
107
156
  begin
108
157
  Net::SCP.start(server, @user) { |scp| scp.upload!(upload_file, @remote_path) }
109
- logger.info "finished scp #{upload_file} #{@user}@#{server}:#{@remote_path}"
158
+ @logger.info "finished scp #{upload_file} #{@user}@#{server}:#{@remote_path}"
110
159
  rescue => err
111
- logger.error "scp FAILED #{err}"
160
+ @logger.error "scp FAILED #{err}"
112
161
  end
113
162
  end
114
163
  end
@@ -0,0 +1,4 @@
1
+ module Homeseed
2
+ class ConnectionError < StandardError; end
3
+ class HTTPartyError < StandardError; end
4
+ end
@@ -0,0 +1,43 @@
1
+ module Homeseed
2
+ class Homeshick < Connection
3
+ include Logging
4
+
5
+ def install(params={})
6
+ @config_files = Array[config_file_path('homeshick-install.yml')]
7
+ @config_files.push(config_file_path('homeshick-source.yml'))
8
+ @config_files.unshift(config_file_path('homeshick-prep.yml')) if params[:clean]
9
+ push_commands(files: @config_files)
10
+ if params[:url]
11
+ exec(params.merge(user_config: :url))
12
+ else
13
+ exec(params.merge(user_config: :local, file: '.homeseed.yml'))
14
+ end
15
+ end
16
+
17
+ def update(params={})
18
+ @config_files = Array[config_file_path('homeshick-source.yml')]
19
+ push_commands(files: @config_files)
20
+ fetch_user_config(params)
21
+ if params[:url]
22
+ exec(params.merge(user_config: :url))
23
+ else
24
+ exec(params.merge(user_config: :local, file: '.homeup.yml'))
25
+ end
26
+ end
27
+
28
+ def fetch_user_config(params={})
29
+ case params[:user_config]
30
+ when :url
31
+ push_commands(url: params[:url])
32
+ when :local
33
+ file = File.expand_path(params[:file], ENV['HOME'])
34
+ push_commands(file: file)
35
+ end
36
+ end
37
+
38
+ def exec(params={})
39
+ fetch_user_config(params)
40
+ super
41
+ end
42
+ end
43
+ end
@@ -1,3 +1,3 @@
1
1
  module Homeseed
2
- VERSION = "0.0.13"
2
+ VERSION = "0.0.14"
3
3
  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.13
4
+ version: 0.0.14
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-28 00:00:00.000000000 Z
11
+ date: 2014-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ~>
95
95
  - !ruby/object:Gem::Version
96
96
  version: '1.6'
97
+ - !ruby/object:Gem::Dependency
98
+ name: httparty
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '0.11'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '0.11'
97
111
  description: Flattens then SSH execs commands on remote server
98
112
  email:
99
113
  - rbuchss@gmail.com
@@ -115,6 +129,8 @@ files:
115
129
  - homeseed.gemspec
116
130
  - lib/homeseed.rb
117
131
  - lib/homeseed/connection.rb
132
+ - lib/homeseed/errors.rb
133
+ - lib/homeseed/homeshick.rb
118
134
  - lib/homeseed/version.rb
119
135
  - lib/logging.rb
120
136
  homepage: http://github.com/rbuchss/homeseed