niso 2.0.3

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 44a5eba8f95a0e95645da843a3f3f17c342bdc42
4
+ data.tar.gz: aa7b1186b90247e42dfc3af1086b8b554333fc6d
5
+ SHA512:
6
+ metadata.gz: f3190d8deba79bb938f78fca3580a840a04906b83420819b023b75b90654487619b6cecc7e7b7ebbe9fd6eb4319297a80d19c72cd685e526248bd882f4bdccf5
7
+ data.tar.gz: 36244fbc3c8b5be59fd58afd3f4d82272b6a2584494f14e2101f85ef770b17180a1a842d5343ffb3f2d1cf491ac3572f72d6bdc80417dd0520ecdc378394b14b
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ sandbox
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.4.0
data/CHANGELOG.md ADDED
@@ -0,0 +1,21 @@
1
+ ## 2.0, release 2017-03-28
2
+ * updated to explicitly use digital ocean for `niso setup` and `niso teardown`
3
+ * added `droplet_kit`
4
+ * removed `digital_ocean`
5
+
6
+ ## 1.5, release 2013-09-27
7
+ * `niso deploy [linode|digital_ocean] [name]` will deploy to the instance with additional attributes.
8
+
9
+ ## 1.4, release 2013-09-27
10
+ * `niso teardown` no longer requires instance names as an argument, it lets you choose from a list instead.
11
+
12
+ ## Past Releases
13
+ * v1.3: SSH config support. Thanks to @toooooooby
14
+ * v1.2: Evaluate everything as ERB templates by default. Added "files" folder.
15
+ * v1.1: "set -e" by default. apt-get everywhere in place of aptitude. Linode DNS support for DigitalOcean instances.
16
+ * v1.0: System functions are refactored into niso.mute() and niso.install().
17
+ * v0.9: Support for [DigitalOcean](https://www.digitalocean.com) setup / teardown.
18
+ * v0.8: Added `--sudo` option to `niso deploy`.
19
+ * v0.7: Added `erase_remote_folder` and `cache_remote_recipes` preferences for customized behavior.
20
+ * v0.6: System function niso::silencer() added for succinct log messages.
21
+ * v0.5: Role-based configuration supported. Reworked directory structure. **Incompatible with previous versions**.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,89 @@
1
+ # nîso ᓃᓱ
2
+
3
+ niso is the number 2 (two) in Cree
4
+
5
+ ## Quickstart
6
+
7
+ Install:
8
+
9
+ $ [sudo] gem install niso
10
+
11
+ Go into your project directory (if it's a Rails project, `config` would be a good place to start with), then:
12
+
13
+ $ niso create
14
+
15
+ It generates a `niso` folder along with subdirectories and templates. Inside `niso`, there are `niso.yml` and `install.sh`. Those two are the most important files that you mainly work on.
16
+
17
+ Go into the `niso` directory, then run `niso deploy`:
18
+
19
+ $ cd niso
20
+ $ niso deploy example.com
21
+
22
+ ## Commands
23
+
24
+ $ niso # Show command help
25
+ $ niso compile # Compile niso project
26
+ $ niso create # Create a new niso project
27
+ $ niso deploy [user@host:port] [role] [--sudo] # Deploy niso project
28
+
29
+ $ niso setup # Setup a new digital ocean droplet
30
+ $ niso teardown # Teardown an existing digital ocean droplet
31
+
32
+ ## Directory structure
33
+
34
+ Here's the directory structure that `niso create` automatically generates:
35
+
36
+ niso/
37
+ install.sh # main script
38
+ niso.yml # add custom attributes and remote recipes here
39
+
40
+ recipes/ # put commonly used scripts here, referred from install.sh
41
+ niso.sh
42
+ roles/ # when role is specified, scripts here will be concatenated
43
+ db.sh # to install.sh in the compile phase
44
+ web.sh
45
+ files/ # put any files to be transferred
46
+ compiled/ # everything under this folder will be transferred to the
47
+ # remote server (do not edit directly)
48
+
49
+ ## Dynamic values?
50
+
51
+ There are two ways to pass dynamic values to the script - ruby and bash.
52
+
53
+ Make sure `eval_erb: true` is set in `niso.yml`. In the compile phase, attributes defined in `niso.yml` are accessible from any files in the form of `<%= @attributes.ruby_version %>`.
54
+
55
+ ## Role-based configuration
56
+
57
+ You probably have different configurations between **web servers** and **database servers**.
58
+
59
+ No problem - how niso handles role-based configuration is refreshingly simple.
60
+
61
+ Shell scripts under the `roles` directory, such as `web.sh` or `db.sh`, are automatically recognized as a role. The role script will be appended to `install.sh` at deploy, so you should put common configurations in `install.sh` and role specific procedures in the role script.
62
+
63
+ For instance, when you set up a new web server, deploy with a role name:
64
+
65
+ niso deploy example.com web
66
+
67
+ It is equivalent to running `install.sh`, followed by `web.sh`.
68
+
69
+ ### Requirements
70
+
71
+ For `niso deploy`
72
+
73
+ $ [sudo] gem install droplet_kit
74
+ $ [sudo] gem install highline
75
+
76
+ ### DigitalOcean
77
+ You can setup a new VM, or teardown an existing VM interactively. Use `niso setup` and `niso teardown` for that.
78
+
79
+ [DigitalOcean](https://www.digitalocean.com) only.
80
+
81
+ v2.0 of the DigitalOcean API is supported &mdash; get your [access token](https://cloud.digitalocean.com/api_access).
82
+
83
+ ### What's new:
84
+
85
+ Please see the [CHANGELOG](https://github.com/dakotalightning/niso/blob/master/CHANGELOG.md).
86
+
87
+ ## Credits
88
+
89
+ - This project is a hard fork of the proejct [niso](https://github.com/kenn/niso) by [kenn](https://github.com/kenn).
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ t.test_files = FileList['test/test*.rb']
7
+ t.verbose = true
8
+ end
9
+ task :default => :test
data/bin/niso ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Abort beautifully with ctrl+c.
4
+ Signal.trap(:INT) { abort "\nAborting." }
5
+
6
+ # Load the main lib and invoke CLI.
7
+ require 'niso'
8
+ Niso::Cli.start
data/lib/niso/cli.rb ADDED
@@ -0,0 +1,164 @@
1
+ require 'open3'
2
+ require 'ostruct'
3
+ require 'net/ssh'
4
+
5
+ module Niso
6
+ class Cli < Thor
7
+ include Thor::Actions
8
+
9
+ desc 'create', 'Create niso project'
10
+ def create(project = 'niso')
11
+ do_create(project)
12
+ end
13
+
14
+ desc 'deploy [user@host:port] [role] [--sudo] or deploy droplet [name] [role] [--sudo]', 'Deploy niso project'
15
+ method_options :sudo => false
16
+ def deploy(first, *args)
17
+ do_deploy(first, *args)
18
+ end
19
+
20
+ desc 'compile', 'Compile niso project'
21
+ def compile(role = nil)
22
+ do_compile(role)
23
+ end
24
+
25
+ desc 'setup', 'Setup a new VM'
26
+ def setup(provider = "droplet_kit")
27
+ Niso::Cloud.new(self, provider).setup
28
+ end
29
+
30
+ desc 'teardown', 'Teardown an existing VM'
31
+ def teardown(provider = "droplet_kit")
32
+ Niso::Cloud.new(self, provider).teardown
33
+ end
34
+
35
+ desc 'version', 'Show version'
36
+ def version
37
+ puts Gem.loaded_specs['niso'].version.to_s
38
+ end
39
+
40
+ no_tasks do
41
+ include Niso::Utility
42
+
43
+ def self.source_root
44
+ File.expand_path('../../',__FILE__)
45
+ end
46
+
47
+ def do_create(project)
48
+ copy_file 'templates/create/.gitignore', "#{project}/.gitignore"
49
+ copy_file 'templates/create/niso.yml', "#{project}/niso.yml"
50
+ copy_file 'templates/create/install.sh', "#{project}/install.sh"
51
+ copy_file 'templates/create/recipes/niso.sh', "#{project}/recipes/niso.sh"
52
+ copy_file 'templates/create/roles/db.sh', "#{project}/roles/db.sh"
53
+ copy_file 'templates/create/roles/web.sh', "#{project}/roles/web.sh"
54
+ copy_file 'templates/create/files/.gitkeep', "#{project}/files/.gitkeep"
55
+ end
56
+
57
+ def do_deploy(first, *args)
58
+ if ['droplet'].include?(first)
59
+ @instance_attributes = YAML.load(File.read("#{first}/instances/#{args[0]}.yml"))
60
+ target = @instance_attributes[:fqdn]
61
+ role = args[1]
62
+ else
63
+ target = first
64
+ role = args[0]
65
+ end
66
+
67
+ sudo = 'sudo ' if options.sudo?
68
+ user, host, port = parse_target(target)
69
+ endpoint = "#{user}@#{host}"
70
+
71
+ # compile attributes and recipes
72
+ do_compile(role)
73
+
74
+ # The host key might change when we instantiate a new VM, so
75
+ # we remove (-R) the old host key from known_hosts.
76
+ `ssh-keygen -R #{host} 2> /dev/null`
77
+
78
+ remote_commands = <<-EOS
79
+ rm -rf ~/niso &&
80
+ mkdir ~/niso &&
81
+ cd ~/niso &&
82
+ tar xz &&
83
+ #{sudo}bash install.sh
84
+ EOS
85
+
86
+ remote_commands.strip! << ' && rm -rf ~/niso' if @config['preferences'] and @config['preferences']['erase_remote_folder']
87
+
88
+ local_commands = <<-EOS
89
+ cd compiled
90
+ tar cz . | ssh -o 'StrictHostKeyChecking no' #{endpoint} -p #{port} '#{remote_commands}'
91
+ EOS
92
+
93
+ Open3.popen3(local_commands) do |stdin, stdout, stderr|
94
+ stdin.close
95
+ t = Thread.new do
96
+ while (line = stderr.gets)
97
+ print line.color(:red)
98
+ end
99
+ end
100
+ while (line = stdout.gets)
101
+ print line.color(:green)
102
+ end
103
+ t.join
104
+ end
105
+ end
106
+
107
+ def do_compile(role)
108
+ # Check if you're in the niso directory
109
+ abort_with 'You must be in the niso folder' unless File.exists?('niso.yml')
110
+ # Check if role exists
111
+ abort_with "#{role} doesn't exist!" if role and !File.exists?("roles/#{role}.sh")
112
+
113
+ # Load niso.yml
114
+ @config = YAML.load(File.read('niso.yml'))
115
+
116
+ # Merge instance attributes
117
+ @config['attributes'] ||= {}
118
+ @config['attributes'].update(Hash[@instance_attributes.map{|k,v| [k.to_s, v] }]) if @instance_attributes
119
+
120
+ # Break down attributes into individual files
121
+ (@config['attributes'] || {}).each {|key, value| create_file "compiled/attributes/#{key}", value }
122
+
123
+ # Retrieve remote recipes via HTTP
124
+ cache_remote_recipes = @config['preferences'] && @config['preferences']['cache_remote_recipes']
125
+ (@config['recipes'] || []).each do |key, value|
126
+ next if cache_remote_recipes and File.exists?("compiled/recipes/#{key}.sh")
127
+ get value, "compiled/recipes/#{key}.sh"
128
+ end
129
+
130
+ copy_or_template = (@config['preferences'] && @config['preferences']['eval_erb']) ? :template : :copy_file
131
+ copy_local_files(@config, copy_or_template)
132
+
133
+ # Build install.sh
134
+ if role
135
+ if copy_or_template == :template
136
+ template File.expand_path('install.sh'), 'compiled/_install.sh'
137
+ create_file 'compiled/install.sh', File.binread('compiled/_install.sh') << "\n" << File.binread("compiled/roles/#{role}.sh")
138
+ else
139
+ create_file 'compiled/install.sh', File.binread('install.sh') << "\n" << File.binread("roles/#{role}.sh")
140
+ end
141
+ else
142
+ send copy_or_template, File.expand_path('install.sh'), 'compiled/install.sh'
143
+ end
144
+ end
145
+
146
+ def parse_target(target)
147
+ target.match(/(.*@)?(.*?)(:.*)?$/)
148
+ # Load ssh config if it exists
149
+ config = Net::SSH::Config.for($2)
150
+ [ ($1 && $1.delete('@') || config[:user] || 'root'),
151
+ config[:host_name] || $2,
152
+ ($3 && $3.delete(':') || config[:port] && config[:port].to_s || '22') ]
153
+ end
154
+
155
+ def copy_local_files(config, copy_or_template)
156
+ @attributes = OpenStruct.new(config['attributes'])
157
+ files = Dir['{recipes,roles,files}/**/*'].select { |file| File.file?(file) }
158
+ files.each { |file| send copy_or_template, File.expand_path(file), File.expand_path("compiled/#{file}") }
159
+
160
+ (config['files'] || []).each {|file| send copy_or_template, File.expand_path(file), "compiled/files/#{File.basename(file)}" }
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,103 @@
1
+ Niso::Dependency.load('highline')
2
+
3
+ module Niso
4
+ class Cloud
5
+ class Base
6
+ include Niso::Utility
7
+
8
+ def initialize(cli, provider)
9
+ @provider = provider
10
+ @cli = cli
11
+ @ui = HighLine.new
12
+ end
13
+
14
+ def setup
15
+ unless File.exist? provider_config_path
16
+ @cli.empty_directory "#{@provider}/instances"
17
+ @cli.template "templates/setup/#{@provider}.yml", provider_config_path
18
+ exit_with "Now go ahead and edit #{@provider}.yml, then run this command again!"
19
+ end
20
+
21
+ # get the config { provider }.yml
22
+ assign_config
23
+
24
+ if @config['name'] == 'example-droplet-01'
25
+ abort_with "You must have your own settings in #{@provider}.yml"
26
+ end
27
+
28
+ if @config['access_token'] == 'your_api_key'
29
+ abort_with "You must add a valid access_token in #{@provider}.yml"
30
+ end
31
+
32
+ # Ask environment and hostname
33
+ @env = ask_menu("environment?", @config['environments'])
34
+
35
+ @name = "#{@config['name']}-#{@env}"
36
+ abort_with "#{@name} already exists!" if instance_config_path.exist?
37
+
38
+ # get the client @client
39
+ setup_client
40
+
41
+ @attributes = {}
42
+ do_setup
43
+
44
+ # Save instance info
45
+ @cli.create_file instance_config_path, YAML.dump(@instance)
46
+ end
47
+
48
+ def teardown
49
+ names = Dir.glob("#{@provider}/instances/*.yml").map{|i| i.split('/').last.sub('.yml','') }
50
+ abort_with "No match found with #{@provider}/instances/*.yml" if names.empty?
51
+
52
+ @name = ask_menu("which instance?: ", names)
53
+
54
+ assign_config
55
+
56
+ @instance = YAML.load(instance_config_path.read)
57
+
58
+ # Are you sure?
59
+ moveon = ask("Are you sure about deleting #{@instance[:name]} permanently? (y/n) ", String) {|q| q.in = ['y','n']}
60
+ exit unless moveon == 'y'
61
+
62
+ # Run Linode / DigitalOcean specific tasks
63
+ setup_client
64
+ do_teardown
65
+
66
+ # Remove the instance config file
67
+ @cli.remove_file instance_config_path
68
+
69
+ say 'Done.'
70
+ end
71
+
72
+ def assign_config
73
+ @config = YAML.load(provider_config_path.read)
74
+ end
75
+
76
+ def provider_config_path
77
+ Pathname.new "#{@provider}/#{@provider}.yml"
78
+ end
79
+
80
+ def instance_config_path
81
+ Pathname.new "#{@provider}/instances/#{@name}.yml"
82
+ end
83
+
84
+ def ask(question, answer_type, &details)
85
+ @ui.ask(@ui.color(question, :green, :bold), answer_type, &details)
86
+ end
87
+
88
+ def ask_menu(question, choices)
89
+ answer = @ui.choose do |menu|
90
+ menu.prompt = "#{@ui.color(question, :green, :bold)} "
91
+ choices.each { |n| menu.choice(n) }
92
+ end
93
+ say("=> #{answer}")
94
+ answer
95
+ end
96
+
97
+ def proceed?
98
+ moveon = ask("Are you ready to go ahead and create #{@name}? (y/n) ", String) {|q| q.in = ['y','n']}
99
+ exit unless moveon == 'y'
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,92 @@
1
+ Niso::Dependency.load('droplet_kit')
2
+
3
+ module Niso
4
+ class Cloud
5
+ class DropletKit < Base
6
+ def do_setup
7
+
8
+ if @config["size"]
9
+ # Choose size
10
+ @attributes[:size] = @config["size"]
11
+ say "using config size"
12
+ else
13
+ choose(:size, @client.sizes.all())
14
+ end
15
+
16
+ if @config["region"]
17
+ # Choose region
18
+ @attributes[:region] = @config["region"]
19
+ say "using config region"
20
+ else
21
+ choose(:region, @client.regions.all())
22
+ end
23
+
24
+ # Choose an image
25
+ if @config['images_filter']
26
+ result = @client.images.all(type: @config['images_filter'])
27
+ result = result.select{|i| i.distribution.match Regexp.new(@config['images_filter'], Regexp::IGNORECASE) }
28
+ end
29
+ choose(:image, result)
30
+
31
+ # Go ahead?
32
+ moveon = ask("Are you ready to go ahead and create #{@attributes}? (y/n) ", ['y','n'])
33
+ exit unless moveon == 'y'
34
+
35
+ ssh_keys = @client.ssh_keys.all.collect { |key| key.fingerprint }
36
+
37
+ # Create
38
+ say "creating a new droplet..."
39
+ droplet = ::DropletKit::Droplet.new(name: @config["name"], region: @attributes[:region_slug], image: @attributes[:image_slug], size: @attributes[:size_slug], ssh_keys: ssh_keys)
40
+ result = @client.droplets.create(droplet)
41
+
42
+ @droplet_id = result.id
43
+ say "Created a new droplet (id: #{@droplet_id}). Booting..."
44
+
45
+ # Boot - we need this before getting public IP
46
+ while @client.droplets.find(id: @droplet_id).status.downcase != 'active'
47
+ sleep 3
48
+ end
49
+
50
+ @networks = @client.droplets.find(id: @droplet_id).networks
51
+ say "Done. networks = #{@networks.ip_address}"
52
+
53
+ @instance = {
54
+ :droplet_id => @droplet_id,
55
+ :env => @env,
56
+ :host => @host,
57
+ :name => @name,
58
+ :networks => @networks,
59
+ :size_slug => @attributes[:size_slug],
60
+ :region_slug => @attributes[:region_slug],
61
+ :image_slug => @attributes[:image_slug],
62
+ }
63
+ end
64
+
65
+ def choose(key, result)
66
+ abort "no #{key} found!" if result.first.nil?
67
+ # result.each{|i| say "#{i.slug}" }
68
+ choices = result.map(&:slug).compact
69
+ @attributes[:"#{key}_slug"] = ask_menu("which #{key}?: ", choices)
70
+ end
71
+
72
+ def do_teardown
73
+ say 'deleting droplet...'
74
+ @client.droplets.delete(id: @instance[:droplet_id])
75
+ end
76
+
77
+ # Set the client for DropletKit
78
+ #
79
+ # DropletKit::DropletResource
80
+ def setup_client
81
+ begin
82
+ @client = ::DropletKit::Client.new(access_token: @config['access_token'])
83
+ info = @client.account.info()
84
+ moveon = ask(" ... continue with #{info.email} account? (y/n) ", String) {|q| q.in = ['y','n']}
85
+ exit unless moveon == 'y'
86
+ rescue ::DropletKit::Error => e
87
+ abort_with e.message
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
data/lib/niso/cloud.rb ADDED
@@ -0,0 +1,22 @@
1
+ module Niso
2
+ class Cloud
3
+ include Niso::Utility
4
+
5
+ def initialize(cli, provider)
6
+ @subject = case provider
7
+ when 'droplet_kit'
8
+ Niso::Cloud::DropletKit.new(cli, provider)
9
+ else
10
+ abort_with "Provider #{provider} is not valid!"
11
+ end
12
+ end
13
+
14
+ def method_missing(sym, *args, &block)
15
+ @subject.send sym, *args, &block
16
+ end
17
+
18
+ def respond_to?(method)
19
+ @subject.respond_to?(sym) || super
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,38 @@
1
+ module Niso
2
+ class Dependency
3
+ def self.all
4
+ {
5
+ 'highline' => { :require => 'highline', :version => '>= 1.7.8'},
6
+ 'droplet_kit' => { :require => 'droplet_kit', :version => '>= 2.1.0' },
7
+ }
8
+ end
9
+
10
+ def self.load(name)
11
+ begin
12
+ gem(name, all[name][:version])
13
+ require(all[name][:require])
14
+ rescue LoadError
15
+ if $!.to_s =~ /Gemfile/
16
+ Logger.error <<-EOS
17
+ Dependency missing: #{name}
18
+ Add this line to your application's Gemfile.
19
+
20
+ gem '#{name}', '#{all[name][:version]}'
21
+
22
+ Please try again after running "bundle install".
23
+ EOS
24
+ else
25
+ Logger.error <<-EOS
26
+ Dependency missing: #{name}
27
+ To install the gem, issue the following command:
28
+
29
+ gem install #{name} -v '#{all[name][:version]}'
30
+
31
+ Please try again after installing the missing dependency.
32
+ EOS
33
+ end
34
+ abort
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,17 @@
1
+ module Niso
2
+ module Logger
3
+ class << self
4
+ def info(text)
5
+ puts text.bright
6
+ end
7
+
8
+ def success(text)
9
+ puts text.color(:green).bright
10
+ end
11
+
12
+ def error(text)
13
+ puts text.color(:red).bright
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Niso
2
+ module Utility
3
+ def abort_with(text)
4
+ Logger.error text
5
+ abort
6
+ end
7
+
8
+ def exit_with(text)
9
+ Logger.success text
10
+ exit
11
+ end
12
+
13
+ def say(text)
14
+ Logger.info text
15
+ end
16
+ end
17
+ end
data/lib/niso.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'thor'
2
+ require 'rainbow'
3
+ require 'yaml'
4
+
5
+ # Starting 2.0.0, Rainbow no longer patches string with the color method by default.
6
+ require 'rainbow/version'
7
+ require 'rainbow/ext/string' unless Rainbow::VERSION < '2.0.0'
8
+
9
+ module Niso
10
+ autoload :Cli, 'niso/cli'
11
+ autoload :Cloud, 'niso/cloud'
12
+ autoload :Dependency, 'niso/dependency'
13
+ autoload :Logger, 'niso/logger'
14
+ autoload :Utility, 'niso/utility'
15
+
16
+ class Cloud
17
+ autoload :Base, 'niso/cloud/base'
18
+ autoload :DropletKit, 'niso/cloud/droplet_kit'
19
+ end
20
+ end
@@ -0,0 +1 @@
1
+ /compiled
File without changes
@@ -0,0 +1,50 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # Load base utility functions like niso.mute() and niso.install()
5
+ source recipes/.sh
6
+
7
+ # This line is necessary for automated provisioning for Debian/Ubuntu.
8
+ # Remove if you're not on Debian/Ubuntu.
9
+ export DEBIAN_FRONTEND=noninteractive
10
+
11
+ # Add Dotdeb repository. Recommended if you're using Debian. See http://www.dotdeb.org/about/
12
+ # source recipes/dotdeb.sh
13
+ # source recipes/backports.sh
14
+
15
+ # Update apt catalog and upgrade installed packages
16
+ niso.mute "apt-get update"
17
+ niso.mute "apt-get -y upgrade"
18
+
19
+ # Install packages
20
+ apt-get -y install git-core ntp curl
21
+
22
+ # Install sysstat, then configure if this is a new install.
23
+ if niso.install "sysstat"; then
24
+ sed -i 's/ENABLED="false"/ENABLED="true"/' /etc/default/sysstat
25
+ /etc/init.d/sysstat restart
26
+ fi
27
+
28
+ # Set RAILS_ENV
29
+ environment=<%= @attributes.environment %>
30
+
31
+ if ! grep -Fq "RAILS_ENV" ~/.bash_profile; then
32
+ echo 'Setting up RAILS_ENV...'
33
+ echo "export RAILS_ENV=$environment" >> ~/.bash_profile
34
+ source ~/.bash_profile
35
+ fi
36
+
37
+ # Install Ruby using RVM
38
+ source recipes/rvm.sh
39
+ ruby_version=<%= @attributes.ruby_version %>
40
+
41
+ if [[ "$(which ruby)" != /usr/local/rvm/rubies/ruby-$ruby_version* ]]; then
42
+ echo "Installing ruby-$ruby_version"
43
+ # Install dependencies using RVM autolibs - see https://blog.engineyard.com/2013/rvm-ruby-2-0
44
+ rvm install --autolibs=3 $ruby_version
45
+ rvm $ruby_version --default
46
+ echo 'gem: --no-ri --no-rdoc' > ~/.gemrc
47
+
48
+ # Install Bundler
49
+ gem install bundler
50
+ fi
@@ -0,0 +1,30 @@
1
+ ---
2
+ # Dynamic variables here will be compiled to individual files in compiled/attributes.
3
+ attributes:
4
+ environment: production
5
+ ruby_version: 2.0.0
6
+
7
+ # Remote recipes here will be downloaded to compiled/recipes.
8
+ recipes:
9
+ rvm: https://raw.githubusercontent.com/kenn/niso-recipes/master/ruby/rvm.sh
10
+ # dotdeb: https://raw.githubusercontent.com/kenn/niso-recipes/master/debian/dotdeb-wheezy.sh
11
+ # backports: https://raw.githubusercontent.com/kenn/niso-recipes/master/debian/backports-wheezy.sh
12
+ # mongodb-10gen: https://raw.githubusercontent.com/kenn/niso-recipes/master/debian/mongodb-10gen.sh
13
+
14
+ # Files specified here will be copied to compiled/files.
15
+ # files:
16
+ # - ~/.ssh/id_rsa.pub
17
+
18
+ # Fine tune how Niso should work.
19
+ preferences:
20
+ # Erase the generated folder on the server after deploy.
21
+ # Turn on when you are done with testing and ready for production use.
22
+ erase_remote_folder: true
23
+
24
+ # Skip retrieving remote recipes when local copies already exist. This setting helps
25
+ # iterative deploy testing considerably faster, when you have a lot of remote recipes.
26
+ cache_remote_recipes: false
27
+
28
+ # Evaluate files as ERB templates. When enabled, you can pass dynamic values in the form
29
+ # of <%= @attributes.environment %> in recipes, roles, files and install.sh.
30
+ eval_erb: true
@@ -0,0 +1,47 @@
1
+ # This file is used to define functions under the niso.* namespace.
2
+
3
+ # Set $niso_pkg to "apt-get" or "yum", or abort.
4
+ #
5
+ if which apt-get >/dev/null 2>&1; then
6
+ export niso_pkg=apt-get
7
+ elif which yum >/dev/null 2>&1; then
8
+ export niso_pkg=yum
9
+ fi
10
+
11
+ if [ "$niso_pkg" = '' ]; then
12
+ echo 'niso only supports apt-get or yum!' >&2
13
+ exit 1
14
+ fi
15
+
16
+ # Mute STDOUT and STDERR
17
+ #
18
+ function niso.mute() {
19
+ echo "Running \"$@\""
20
+ `$@ >/dev/null 2>&1`
21
+ return $?
22
+ }
23
+
24
+ # Installer
25
+ #
26
+ function niso.installed() {
27
+ if [ "$niso_pkg" = 'apt-get' ]; then
28
+ dpkg -s $@ >/dev/null 2>&1
29
+ elif [ "$niso_pkg" = 'yum' ]; then
30
+ rpm -qa | grep $@ >/dev/null
31
+ fi
32
+ return $?
33
+ }
34
+
35
+ # When there's "set -e" in install.sh, niso.install should be used with if statement,
36
+ # otherwise the script may exit unexpectedly when the package is already installed.
37
+ #
38
+ function niso.install() {
39
+ if niso.installed "$@"; then
40
+ echo "$@ already installed"
41
+ return 1
42
+ else
43
+ echo "No packages found matching $@. Installing..."
44
+ niso.mute "$niso_pkg -y install $@"
45
+ return 0
46
+ fi
47
+ }
@@ -0,0 +1,5 @@
1
+ # Install Database Server
2
+
3
+ # source recipes/mongodb-10gen.sh # MongoDB
4
+ # apt-get -q -y install mysql-server-5.5 # MySQL 5.5 - You may need to enable Dotdeb in install.sh first
5
+ # apt-get -y install redis-server # Redis - You may need to enable Dotdeb in install.sh first
@@ -0,0 +1,4 @@
1
+ # Install Web server
2
+
3
+ apt-get -y install nginx # Nginx
4
+ # apt-get -y install apache2 # Apache
@@ -0,0 +1,15 @@
1
+ ---
2
+ access_token: your_api_key
3
+
4
+ name: example-droplet-01
5
+ # region: sf01
6
+ # image: ubuntu-14-04-x64
7
+ # size: 512mb
8
+
9
+ # filter out large lists by keyword
10
+ images_filter: ubuntu
11
+
12
+ # add / remove environments
13
+ environments:
14
+ - production
15
+ - staging
data/niso.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'niso'
5
+ spec.version = '2.0.3'
6
+ spec.authors = ['Dakota Lightning']
7
+ spec.email = ['im@koda.io']
8
+ spec.homepage = 'http://github.com/dakotalightning/niso'
9
+ spec.summary = %q{Server provisioning utility}
10
+ spec.description = %q{Server provisioning utility}
11
+ spec.license = 'MIT'
12
+
13
+ spec.files = `git ls-files`.split($/)
14
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.require_paths = ['lib']
17
+
18
+ spec.add_runtime_dependency 'thor'
19
+ spec.add_runtime_dependency 'rainbow'
20
+ spec.add_runtime_dependency 'net-ssh'
21
+ spec.add_development_dependency 'rake'
22
+ spec.add_development_dependency 'minitest'
23
+ end
File without changes
File without changes
data/test/test_cli.rb ADDED
@@ -0,0 +1,52 @@
1
+ require 'niso'
2
+ require 'minitest/autorun'
3
+
4
+ class TestCli < Minitest::Test
5
+ def setup
6
+ @cli = Niso::Cli.new
7
+ end
8
+
9
+ def test_parse_target
10
+ assert_equal ['user', 'example.com', '2222'], @cli.parse_target('user@example.com:2222')
11
+ assert_equal ['root', 'example.com', '2222'], @cli.parse_target('example.com:2222')
12
+ assert_equal ['user', 'example.com', '22'], @cli.parse_target('user@example.com')
13
+ assert_equal ['root', 'example.com', '22'], @cli.parse_target('example.com')
14
+ assert_equal ['root', '192.168.0.1', '22'], @cli.parse_target('192.168.0.1')
15
+ end
16
+
17
+ def test_parse_target_with_ssh_config
18
+ ssh_config = lambda do |host|
19
+ if host == 'example.com'
20
+ { :host_name => "buzz.example.com", :user => "foobar", :port => 2222 }
21
+ else
22
+ {}
23
+ end
24
+ end
25
+
26
+ Net::SSH::Config.stub(:for, ssh_config) do
27
+ assert_equal ['foobar', 'buzz.example.com', '2222'], @cli.parse_target('example.com')
28
+ assert_equal ['foobar', 'buzz.example.com', '8080'], @cli.parse_target('example.com:8080')
29
+ assert_equal ['piyo', 'buzz.example.com', '2222'], @cli.parse_target('piyo@example.com')
30
+ assert_equal ['piyo', 'buzz.example.com', '8080'], @cli.parse_target('piyo@example.com:8080')
31
+ assert_equal ['root', '192.168.0.1', '22'], @cli.parse_target('192.168.0.1')
32
+ end
33
+ end
34
+
35
+ def test_create
36
+ @cli.create 'sandbox'
37
+ assert File.exist?('sandbox/niso.yml')
38
+ FileUtils.rm_rf 'sandbox'
39
+ end
40
+
41
+ def test_copy_local_files
42
+ pwd = Dir.pwd
43
+ Dir.chdir('test/niso_test_dir')
44
+
45
+ @cli.copy_local_files({}, :copy_file)
46
+ assert File.exists?('compiled/files/nginx/nginx.conf')
47
+ assert File.exists?('compiled/recipes/nginx.sh')
48
+ FileUtils.rm_rf 'compiled'
49
+
50
+ Dir.chdir(pwd)
51
+ end
52
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: niso
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Dakota Lightning
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-03-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rainbow
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: net-ssh
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Server provisioning utility
84
+ email:
85
+ - im@koda.io
86
+ executables:
87
+ - niso
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".travis.yml"
93
+ - CHANGELOG.md
94
+ - Gemfile
95
+ - README.md
96
+ - Rakefile
97
+ - bin/niso
98
+ - lib/niso.rb
99
+ - lib/niso/cli.rb
100
+ - lib/niso/cloud.rb
101
+ - lib/niso/cloud/base.rb
102
+ - lib/niso/cloud/droplet_kit.rb
103
+ - lib/niso/dependency.rb
104
+ - lib/niso/logger.rb
105
+ - lib/niso/utility.rb
106
+ - lib/templates/create/.gitignore
107
+ - lib/templates/create/files/.gitkeep
108
+ - lib/templates/create/install.sh
109
+ - lib/templates/create/niso.yml
110
+ - lib/templates/create/recipes/niso.sh
111
+ - lib/templates/create/roles/db.sh
112
+ - lib/templates/create/roles/web.sh
113
+ - lib/templates/setup/droplet_kit.yml
114
+ - niso.gemspec
115
+ - test/niso_test_dir/files/nginx/nginx.conf
116
+ - test/niso_test_dir/recipes/nginx.sh
117
+ - test/test_cli.rb
118
+ homepage: http://github.com/dakotalightning/niso
119
+ licenses:
120
+ - MIT
121
+ metadata: {}
122
+ post_install_message:
123
+ rdoc_options: []
124
+ require_paths:
125
+ - lib
126
+ required_ruby_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ required_rubygems_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ requirements: []
137
+ rubyforge_project:
138
+ rubygems_version: 2.5.1
139
+ signing_key:
140
+ specification_version: 4
141
+ summary: Server provisioning utility
142
+ test_files:
143
+ - test/niso_test_dir/files/nginx/nginx.conf
144
+ - test/niso_test_dir/recipes/nginx.sh
145
+ - test/test_cli.rb