inception-server 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.chef/knife.rb +4 -0
- data/.gitignore +21 -0
- data/.kitchen.yml +47 -0
- data/.rspec +3 -0
- data/.travis.yml +18 -0
- data/Berksfile +8 -0
- data/Berksfile.lock +9 -0
- data/ChangeLog.md +20 -0
- data/Gemfile +27 -0
- data/Guardfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +126 -0
- data/Rakefile +66 -0
- data/TODO.md +25 -0
- data/bin/inception +8 -0
- data/bin/inception-server +8 -0
- data/config/ssh/kitchen-aws +23 -0
- data/cookbooks/bosh_inception/README.md +15 -0
- data/cookbooks/bosh_inception/attributes/default.rb +25 -0
- data/cookbooks/bosh_inception/files/default/Gemfile.cf +5 -0
- data/cookbooks/bosh_inception/files/default/Gemfile.micro +5 -0
- data/cookbooks/bosh_inception/metadata.rb +32 -0
- data/cookbooks/bosh_inception/recipes/default.rb +16 -0
- data/cookbooks/bosh_inception/recipes/install_bosh.rb +37 -0
- data/cookbooks/bosh_inception/recipes/install_ruby.rb +10 -0
- data/cookbooks/bosh_inception/recipes/mount_store_volume.rb +24 -0
- data/cookbooks/bosh_inception/recipes/packages.rb +23 -0
- data/cookbooks/bosh_inception/recipes/setup_dotfog.rb +29 -0
- data/cookbooks/bosh_inception/recipes/setup_git.rb +34 -0
- data/cookbooks/bosh_inception/recipes/useful_dirs.rb +13 -0
- data/inception-server.gemspec +43 -0
- data/lib/inception/cli.rb +141 -0
- data/lib/inception/cli_helpers/display.rb +26 -0
- data/lib/inception/cli_helpers/interactions.rb +15 -0
- data/lib/inception/cli_helpers/prepare_deploy_settings.rb +89 -0
- data/lib/inception/cli_helpers/provider.rb +14 -0
- data/lib/inception/cli_helpers/settings.rb +53 -0
- data/lib/inception/inception_server.rb +304 -0
- data/lib/inception/inception_server_cookbook.rb +90 -0
- data/lib/inception/next_deploy_actions.rb +20 -0
- data/lib/inception/providers/README.md +5 -0
- data/lib/inception/providers/clients/aws_provider_client.rb +144 -0
- data/lib/inception/providers/clients/fog_provider_client.rb +185 -0
- data/lib/inception/providers/clients/openstack_provider_client.rb +84 -0
- data/lib/inception/providers/constants/aws_constants.rb +25 -0
- data/lib/inception/providers/constants/openstack_constants.rb +12 -0
- data/lib/inception/providers.rb +28 -0
- data/lib/inception/version.rb +3 -0
- data/lib/inception.rb +9 -0
- data/nodes/.gitkeep +0 -0
- data/spec/assets/.gitkeep +0 -0
- data/spec/assets/gitconfig +5 -0
- data/spec/assets/settings/aws-before-server.yml +14 -0
- data/spec/assets/settings/aws-created-server.yml +31 -0
- data/spec/integration/.gitkeep +0 -0
- data/spec/integration/aws/aws_basic_spec.rb +38 -0
- data/spec/spec_helper.rb +50 -0
- data/spec/support/aws/aws_helpers.rb +73 -0
- data/spec/support/settings_helper.rb +20 -0
- data/spec/support/stdout_capture.rb +17 -0
- data/spec/unit/.gitkeep +0 -0
- data/spec/unit/cli_delete_spec.rb +39 -0
- data/spec/unit/cli_deploy_aws_spec.rb +83 -0
- data/spec/unit/cli_ssh_spec.rb +80 -0
- data/spec/unit/inception_server_cookbook_spec.rb +62 -0
- data/spec/unit/inception_server_spec.rb +58 -0
- data/spec/unit/providers/aws_spec.rb +198 -0
- data/test/integration/default/bats/discover_user.bash +2 -0
- data/test/integration/default/bats/dotfog.bats +11 -0
- data/test/integration/default/bats/install_ruby.bats +8 -0
- data/test/integration/default/bats/useful_dirs.bats +8 -0
- data/test/integration/default/bats/user.bats +9 -0
- data/test/integration/default/bats/verify_bosh.bats +18 -0
- data/test/integration/default/bats/verify_git.bats +18 -0
- metadata +361 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
if node.fog.empty?
|
2
|
+
file "/home/#{node.user.username}/.fog" do
|
3
|
+
owner "root"
|
4
|
+
group "root"
|
5
|
+
mode "0755"
|
6
|
+
action :delete
|
7
|
+
end
|
8
|
+
else
|
9
|
+
ruby_block "create .fog file" do
|
10
|
+
block do
|
11
|
+
credentials = node.fog.inject({}) do |options, (key, value)|
|
12
|
+
options[(key.to_sym rescue key) || key] = value
|
13
|
+
options
|
14
|
+
end
|
15
|
+
fog_file = { default: credentials }
|
16
|
+
dotfog = File.expand_path("/home/#{node.user.username}/.fog")
|
17
|
+
File.open(dotfog, "w") do |f|
|
18
|
+
f << fog_file.to_yaml
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
file "/home/#{node.user.username}/.fog" do
|
24
|
+
owner node.user.username
|
25
|
+
group node.user.username
|
26
|
+
mode "0600"
|
27
|
+
action :touch
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#
|
2
|
+
# Cookbook Name:: bosh_inception
|
3
|
+
# Recipe:: git_config
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013 Dr Nic Williams, Stark & Wayne, LLC
|
6
|
+
#
|
7
|
+
# MIT License
|
8
|
+
#
|
9
|
+
|
10
|
+
include_recipe "hub"
|
11
|
+
|
12
|
+
execute "git config user.name" do
|
13
|
+
command "git config --global --replace-all user.name '#{node.git.name}'"
|
14
|
+
user node.user.username
|
15
|
+
group node.user.username
|
16
|
+
action :run
|
17
|
+
environment ({'HOME' => "/home/#{node.user.username}"})
|
18
|
+
end
|
19
|
+
|
20
|
+
execute "git config user.email" do
|
21
|
+
command "git config --global --replace-all user.email '#{node.git.email}'"
|
22
|
+
user node.user.username
|
23
|
+
group node.user.username
|
24
|
+
action :run
|
25
|
+
environment ({'HOME' => "/home/#{node.user.username}"})
|
26
|
+
end
|
27
|
+
|
28
|
+
execute "git config color.ui" do
|
29
|
+
command "git config --global color.ui true"
|
30
|
+
user node.user.username
|
31
|
+
group node.user.username
|
32
|
+
action :run
|
33
|
+
environment ({'HOME' => "/home/#{node.user.username}"})
|
34
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
%w[microboshes microboshes/deployments deployments releases repos stemcells systems tmp bosh_cache].each do |dir|
|
2
|
+
directory "/var/vcap/store/#{dir}" do
|
3
|
+
owner node.user.username
|
4
|
+
group node.user.username
|
5
|
+
mode "0755"
|
6
|
+
recursive true
|
7
|
+
action :create
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
link "/home/#{node.user.username}/.bosh_cache" do
|
12
|
+
to "/var/vcap/store/bosh_cache"
|
13
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'inception/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "inception-server"
|
8
|
+
spec.version = Inception::VERSION
|
9
|
+
spec.authors = ["Dr Nic Williams"]
|
10
|
+
spec.email = ["drnicwilliams@gmail.com"]
|
11
|
+
spec.description = %q{Create an inception server for Bosh & general inception of new universes}
|
12
|
+
spec.summary = %q{CLI, with chef recipes, for creating and preparing an inception server for deploying/developing a Bosh universe.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "thor"
|
22
|
+
spec.add_dependency "highline"
|
23
|
+
spec.add_dependency "escape"
|
24
|
+
spec.add_dependency "json"
|
25
|
+
spec.add_dependency "readwritesettings", "~> 3.0"
|
26
|
+
|
27
|
+
# for inception/providers
|
28
|
+
spec.add_dependency "fog"
|
29
|
+
spec.add_dependency "cyoi" # choose your own infrastructure
|
30
|
+
|
31
|
+
# for running cookbooks on inception server
|
32
|
+
spec.add_dependency "knife-solo", "~> 0.3.0.pre4"
|
33
|
+
|
34
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
35
|
+
spec.add_development_dependency "rake"
|
36
|
+
|
37
|
+
# gems for the ruby unit & integration tests
|
38
|
+
spec.add_development_dependency "rspec"
|
39
|
+
|
40
|
+
# gems for the cookbook tests
|
41
|
+
spec.add_development_dependency "test-kitchen", "~> 1.0.0.alpha.6"
|
42
|
+
spec.add_development_dependency "berkshelf"
|
43
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require "thor"
|
2
|
+
require "highline"
|
3
|
+
require "fileutils"
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
# to prompt user for infrastructure choice/credentials
|
7
|
+
require "cyoi/cli/provider"
|
8
|
+
|
9
|
+
# for the #sh helper
|
10
|
+
require "rake"
|
11
|
+
require "rake/file_utils"
|
12
|
+
|
13
|
+
require "escape"
|
14
|
+
require "inception/cli_helpers/display"
|
15
|
+
require "inception/cli_helpers/interactions"
|
16
|
+
require "inception/cli_helpers/provider"
|
17
|
+
require "inception/cli_helpers/settings"
|
18
|
+
require "inception/cli_helpers/prepare_deploy_settings"
|
19
|
+
|
20
|
+
module Inception
|
21
|
+
class Cli < Thor
|
22
|
+
include FileUtils
|
23
|
+
include Inception::CliHelpers::Display
|
24
|
+
include Inception::CliHelpers::Interactions
|
25
|
+
include Inception::CliHelpers::Provider
|
26
|
+
include Inception::CliHelpers::Settings
|
27
|
+
include Inception::CliHelpers::PrepareDeploySettings
|
28
|
+
|
29
|
+
desc "deploy", "Create/upgrade a Bosh inception server"
|
30
|
+
def deploy
|
31
|
+
migrate_old_settings
|
32
|
+
configure_provider
|
33
|
+
prepare_deploy_settings
|
34
|
+
perform_deploy
|
35
|
+
converge_cookbooks
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "delete", "Destroy target Bosh inception server, volumes & release the IP address"
|
39
|
+
# method_option :"non-interactive", aliases: ["-n"], type: :boolean, desc: "Don't ask questions, just get crankin'"
|
40
|
+
def delete
|
41
|
+
migrate_old_settings
|
42
|
+
perform_delete(options[:"non-interactive"])
|
43
|
+
end
|
44
|
+
|
45
|
+
desc "ssh [COMMAND]", "Open an ssh session to the inception server [do nothing if local machine is the inception server]"
|
46
|
+
long_desc <<-DESC
|
47
|
+
If a command is supplied, it will be run, otherwise a session will be opened.
|
48
|
+
DESC
|
49
|
+
def ssh(cmd=nil)
|
50
|
+
migrate_old_settings
|
51
|
+
run_ssh_command_or_open_tunnel(cmd)
|
52
|
+
end
|
53
|
+
|
54
|
+
desc "tmux", "Open an ssh (with tmux) session to the inception server [do nothing if local machine is inception server]"
|
55
|
+
long_desc <<-DESC
|
56
|
+
Opens a connection using ssh and attaches to the most recent tmux session;
|
57
|
+
giving you persistance across disconnects.
|
58
|
+
DESC
|
59
|
+
def tmux
|
60
|
+
migrate_old_settings
|
61
|
+
run_ssh_command_or_open_tunnel(["-t", "tmux attach || tmux new-session"])
|
62
|
+
end
|
63
|
+
|
64
|
+
no_tasks do
|
65
|
+
def configure_provider
|
66
|
+
save_settings!
|
67
|
+
provider_cli = Cyoi::Cli::Provider.new([settings_dir])
|
68
|
+
provider_cli.execute!
|
69
|
+
reload_settings!
|
70
|
+
end
|
71
|
+
|
72
|
+
# update settings.git.name/git.email from local ~/.gitconfig if available
|
73
|
+
# provision public IP address for inception server if not allocated one
|
74
|
+
# Note: helper methods are in inception/cli_helpers/prepare_deploy_settings.rb
|
75
|
+
def prepare_deploy_settings
|
76
|
+
header "Preparing deployment settings"
|
77
|
+
update_git_config
|
78
|
+
provision_or_reuse_public_ip_address_for_inception unless settings.exists?("inception.provisioned.ip_address")
|
79
|
+
recreate_key_pair_for_inception unless settings.exists?("inception.key_pair.private_key")
|
80
|
+
recreate_private_key_file_for_inception
|
81
|
+
validate_deploy_settings
|
82
|
+
setup_next_deploy_actions
|
83
|
+
end
|
84
|
+
|
85
|
+
def perform_deploy
|
86
|
+
header "Provision inception server"
|
87
|
+
server = InceptionServer.new(provider_client, settings.inception, settings_ssh_dir)
|
88
|
+
server.create
|
89
|
+
ensure
|
90
|
+
# after any error handling, still save the current InceptionServer state back into settings.inception
|
91
|
+
settings["inception"] = server.export_attributes
|
92
|
+
save_settings!
|
93
|
+
end
|
94
|
+
|
95
|
+
def setup_next_deploy_actions
|
96
|
+
settings["next_deploy_actions"] ||= {}
|
97
|
+
@next_deploy_actions = NextDeployActions.new(settings.next_deploy_actions, options)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Perform converge chef cookbooks upon inception server
|
101
|
+
# Does not update settings
|
102
|
+
def converge_cookbooks
|
103
|
+
if @next_deploy_actions.skip_chef_converge?
|
104
|
+
header "Prepare inception server", skip: "Requested to be skipped on this deploy."
|
105
|
+
else
|
106
|
+
header "Prepare inception server"
|
107
|
+
server = InceptionServer.new(provider_client, settings.inception, settings_ssh_dir)
|
108
|
+
cookbook = InceptionServerCookbook.new(server, settings, settings_dir)
|
109
|
+
cookbook.prepare
|
110
|
+
settings.set("cookbook.prepared", true)
|
111
|
+
save_settings!
|
112
|
+
cookbook.converge
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def perform_delete(non_interactive)
|
117
|
+
server = InceptionServer.new(provider_client, settings.inception, settings_ssh_dir)
|
118
|
+
header "Deleting inception server, volumes and releasing IP address"
|
119
|
+
server.delete_all
|
120
|
+
ensure
|
121
|
+
# after any error handling, still save the current InceptionServer state back into settings.inception
|
122
|
+
settings["inception"] = server.export_attributes
|
123
|
+
settings.delete("cookbook")
|
124
|
+
save_settings!
|
125
|
+
end
|
126
|
+
|
127
|
+
def run_ssh_command_or_open_tunnel(cmd)
|
128
|
+
recreate_private_key_file_for_inception
|
129
|
+
unless settings.exists?("inception.provisioned.host")
|
130
|
+
exit "inception server has not finished launching; run to complete: inception deploy"
|
131
|
+
end
|
132
|
+
|
133
|
+
server = InceptionServer.new(provider_client, settings.inception, settings_ssh_dir)
|
134
|
+
username = settings.inception.provisioned.username
|
135
|
+
host = settings.inception.provisioned.host
|
136
|
+
result = system Escape.shell_command(["ssh", "-i", server.private_key_path, "#{username}@#{host}", cmd].flatten.compact)
|
137
|
+
exit result
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Inception::CliHelpers
|
2
|
+
module Display
|
3
|
+
# Display header for a new section of the bootstrapper
|
4
|
+
def header(title, options={})
|
5
|
+
say "" # golden whitespace
|
6
|
+
if skipping = options[:skipping]
|
7
|
+
say "Skipping #{title}", [:yellow, :bold]
|
8
|
+
say skipping
|
9
|
+
else
|
10
|
+
say title, [:green, :bold]
|
11
|
+
end
|
12
|
+
say "" # more golden whitespace
|
13
|
+
end
|
14
|
+
|
15
|
+
def error(message)
|
16
|
+
say message, :red
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
def confirm(message)
|
21
|
+
say "Confirming: #{message}", green
|
22
|
+
say "" # bonus golden whitespace
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Inception::CliHelpers
|
2
|
+
module Interactions
|
3
|
+
def cyan; "\033[36m" end
|
4
|
+
def clear; "\033[0m" end
|
5
|
+
def bold; "\033[1m" end
|
6
|
+
def red; "\033[31m" end
|
7
|
+
def green; "\033[32m" end
|
8
|
+
def yellow; "\033[33m" end
|
9
|
+
|
10
|
+
# Helper to access HighLine for ask & menu prompts
|
11
|
+
def hl
|
12
|
+
@hl ||= HighLine.new
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Inception::CliHelpers
|
2
|
+
module PrepareDeploySettings
|
3
|
+
def update_git_config
|
4
|
+
gitconfig = File.expand_path("~/.gitconfig")
|
5
|
+
if File.exists?(gitconfig)
|
6
|
+
say "Using your git user.name (#{`git config -f #{gitconfig} user.name`.strip})"
|
7
|
+
settings.set("git.name", `git config -f #{gitconfig} user.name`.strip)
|
8
|
+
settings.set("git.email", `git config -f #{gitconfig} user.email`.strip)
|
9
|
+
save_settings!
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Attempt to provision a new public IP; if none available,
|
14
|
+
# then look for a pre-provisioned public IP that's not assigned
|
15
|
+
# to a server; else error. The user needs to go get more
|
16
|
+
# public IP addresses in this region.
|
17
|
+
def provision_or_reuse_public_ip_address_for_inception
|
18
|
+
say "Acquiring a public IP address... "
|
19
|
+
if public_ip = provider_client.provision_or_reuse_public_ip_address
|
20
|
+
say public_ip, :green
|
21
|
+
settings.set("inception.provisioned.ip_address", public_ip)
|
22
|
+
save_settings!
|
23
|
+
else
|
24
|
+
say "none available.", :red
|
25
|
+
error "Please rustle up at least one public IP address and try again."
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def default_server_name
|
30
|
+
"inception"
|
31
|
+
end
|
32
|
+
|
33
|
+
def default_key_pair_name
|
34
|
+
default_server_name
|
35
|
+
end
|
36
|
+
|
37
|
+
def recreate_key_pair_for_inception
|
38
|
+
key_pair_name = settings.set_default("inception.key_pair.name", default_key_pair_name)
|
39
|
+
provider_client.delete_key_pair_if_exists(key_pair_name)
|
40
|
+
key_pair = provider_client.create_key_pair(key_pair_name)
|
41
|
+
settings.set("inception.key_pair.private_key", key_pair.private_key)
|
42
|
+
settings.set("inception.key_pair.public_key", key_pair.public_key) # might be provided
|
43
|
+
settings.set("inception.key_pair.fingerprint", key_pair.fingerprint)
|
44
|
+
save_settings!
|
45
|
+
end
|
46
|
+
|
47
|
+
def private_key_path_for_inception
|
48
|
+
@private_key_path_for_inception ||= File.join(settings_dir, "ssh", settings.inception.key_pair.name)
|
49
|
+
end
|
50
|
+
|
51
|
+
# The keys for the inception server originate from the provider and are cached in
|
52
|
+
# the manifest. The private key is stored locally; the public key is placed
|
53
|
+
# on the inception server.
|
54
|
+
def recreate_private_key_file_for_inception
|
55
|
+
mkdir_p(File.dirname(private_key_path_for_inception))
|
56
|
+
File.chmod(0700, File.dirname(private_key_path_for_inception))
|
57
|
+
File.open(private_key_path_for_inception, "w") { |file| file << settings.inception.key_pair.private_key }
|
58
|
+
File.chmod(0600, private_key_path_for_inception)
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
# Required settings:
|
63
|
+
# * git.name
|
64
|
+
# * git.email
|
65
|
+
def validate_deploy_settings
|
66
|
+
begin
|
67
|
+
settings.git.name
|
68
|
+
settings.git.email
|
69
|
+
rescue ReadWriteSettings::MissingSetting => e
|
70
|
+
error "Please setup local git user.name & user.email config; or specify git.name & git.email in settings.yml"
|
71
|
+
end
|
72
|
+
|
73
|
+
begin
|
74
|
+
settings.provider.name
|
75
|
+
settings.provider.credentials
|
76
|
+
rescue ReadWriteSettings::MissingSetting => e
|
77
|
+
error "Wooh there, we need provider.name & provider.credentials in settings.yml to proceed."
|
78
|
+
end
|
79
|
+
|
80
|
+
begin
|
81
|
+
settings.inception.provisioned.ip_address
|
82
|
+
settings.inception.key_pair.name
|
83
|
+
settings.inception.key_pair.private_key
|
84
|
+
rescue ReadWriteSettings::MissingSetting => e
|
85
|
+
error "Wooh there, we need inception.provisioned.ip_address, inception.key_pair.name, & inception.key_pair.private_key in settings.yml to proceed."
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Inception::CliHelpers
|
2
|
+
module Provider
|
3
|
+
def provider_client
|
4
|
+
@provider_client ||= begin
|
5
|
+
Inception::Providers.provider_client(settings.provider)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
# If the +provider_client+ uses fog, then this will return its +fog_compute+ client object
|
10
|
+
def fog_compute
|
11
|
+
provider_client.respond_to?(:fog_compute) ? provider_client.fog_compute : nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require "readwritesettings"
|
2
|
+
|
3
|
+
module Inception::CliHelpers
|
4
|
+
module Settings
|
5
|
+
include FileUtils
|
6
|
+
|
7
|
+
# The base directory for holding the manifest settings file
|
8
|
+
# and private keys
|
9
|
+
#
|
10
|
+
# Defaults to ~/.inception_server; and can be overridden with either:
|
11
|
+
# * $SETTINGS - to a folder (supported method)
|
12
|
+
def settings_dir
|
13
|
+
@settings_dir ||= File.expand_path(ENV["SETTINGS"] || "~/.inception_server")
|
14
|
+
end
|
15
|
+
|
16
|
+
def settings_ssh_dir
|
17
|
+
File.join(settings_dir, "ssh")
|
18
|
+
end
|
19
|
+
|
20
|
+
def settings_path
|
21
|
+
@settings_path ||= File.join(settings_dir, "settings.yml")
|
22
|
+
end
|
23
|
+
|
24
|
+
def settings
|
25
|
+
@settings ||= begin
|
26
|
+
unless File.exists?(settings_path)
|
27
|
+
mkdir_p(settings_ssh_dir)
|
28
|
+
File.open(settings_path, "w") { |file| file << "--- {}" }
|
29
|
+
end
|
30
|
+
chmod(0600, settings_path)
|
31
|
+
chmod(0700, settings_ssh_dir) if File.directory?(settings_ssh_dir)
|
32
|
+
ReadWriteSettings.new(settings_path)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Saves current nested ReadWriteSettings into pure Hash-based YAML file
|
37
|
+
# Recreates accessors on ReadWriteSettings object (since something has changed)
|
38
|
+
def save_settings!
|
39
|
+
File.open(settings_path, "w") { |f| f << settings.to_nested_hash.to_yaml }
|
40
|
+
settings.create_accessors!
|
41
|
+
end
|
42
|
+
|
43
|
+
def reload_settings!
|
44
|
+
@settings = nil
|
45
|
+
settings
|
46
|
+
end
|
47
|
+
|
48
|
+
def migrate_old_settings
|
49
|
+
settings
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|