intercity 0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4346069156d4528cad92d302592e311863be9843
4
+ data.tar.gz: c6dbeca166824234eabbe224612c630fba460880
5
+ SHA512:
6
+ metadata.gz: 75b1708376987be21b2ba56ebf0d46f75a64bf99962b1bdbe7aa59c513cb5ab758f2efd23bdd61f84405fd8a337ccc9eac87904c93d30f4c76ae911b922a0d81
7
+ data.tar.gz: ee8ef91c1e479adc7af2b2aa475eb1f0c309c872c60cc993bfcbf5bddacbc071f17f133492a1ea458231b4b450d1bd511270c192717b6503424302aced383a75
checksums.yaml.gz.sig ADDED
Binary file
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *.json
2
+ *.gem
data/README.md ADDED
@@ -0,0 +1,55 @@
1
+ Intercity CLI
2
+ =============
3
+
4
+ Command-line interface for configuring a VPS to run Ruby on Rails.
5
+
6
+ Installation
7
+ ------------
8
+
9
+ ```
10
+ $ gem install intercity
11
+ ```
12
+
13
+ Usage
14
+ -----
15
+
16
+ Install a clean Ubuntu server and add MySQL:
17
+
18
+ ```
19
+ $ intercity server install IPADDRESS
20
+ $ intercity mysql install --server=IPADDRESS
21
+ ```
22
+
23
+ Then create an application on your server:
24
+
25
+ ```
26
+ $ intercity application create intercity --server=IPADDRESS --domain-name=myapp.com
27
+ ```
28
+
29
+ You can edit environment variables for your app like this:
30
+
31
+ ```
32
+ $ intercity application edit intercity --server=IPADDRESS # Edit ENV vars
33
+ ```
34
+
35
+ Finally, set up Capistrano in your app and deploy with:
36
+
37
+ ```
38
+ $ cd ~/myapp
39
+ $ cap production deploy
40
+ ```
41
+
42
+ All commands
43
+ ------------
44
+
45
+ ```
46
+ $ intercity server install IPADDRESS
47
+
48
+ $ intercity mysql list --server=IPADDRESS
49
+ $ intercity mysql install --server=IPADDRESS
50
+
51
+ $ intercity application add APPNAME --server=IPADDRESS --domain-name=myapp.com
52
+ $ intercity application update APPNAME --server=IPADDRESS --domain-name=myapp.com
53
+ $ intercity application edit APPNAME --server=IPADDRESS # For editing the ENV vars
54
+ $ intercity application list --server=IPADDRESS
55
+ ```
data/bin/intercity ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "intercity/cli"
4
+ IntercityCLI::Main.start(ARGV)
@@ -0,0 +1,21 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDijCCAnKgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMRcwFQYDVQQDDA5taWNo
3
+ aWVsLnNpa2tlczEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQB
4
+ GRYDY29tMB4XDTE0MTIyNDEyNTQzM1oXDTE1MTIyNDEyNTQzM1owRTEXMBUGA1UE
5
+ AwwObWljaGllbC5zaWtrZXMxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmS
6
+ JomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJXr
7
+ ZzV/gU/XPk6hhBs/iSn+HYGLHYnaEtVkNliKZKWLr7arKGM5pneM9rub8VaA9iKE
8
+ N2swxHngobSDouYBJcxlQabCWx8htD4nSlOXWTfFeR78jhfYS2VyysQ0dnHSjE9c
9
+ KXa8EHcg0YNPpWqWoGemb4iJENnqcGGLY67RBhkHsWj5BJO84e4hS8vsUYyAiAbV
10
+ 3nO5+5EmnkWQB2fVDTL3tjY1yOdzfyvaIifwt9aKVwY0YPORIlm9RI4wtQRv9NFq
11
+ ONyougmLd5vVWp6jO1+9O6TxayzDccJLGuGB6Tw94BQo3o50yoLZew44A7VT3XC2
12
+ LQg3n8Pzuow9MtTRrC0CAwEAAaOBhDCBgTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE
13
+ sDAdBgNVHQ4EFgQUbb9Rb7oi1MDVYRSgxiQ33szdVCswIwYDVR0RBBwwGoEYbWlj
14
+ aGllbC5zaWtrZXNAZ21haWwuY29tMCMGA1UdEgQcMBqBGG1pY2hpZWwuc2lra2Vz
15
+ QGdtYWlsLmNvbTANBgkqhkiG9w0BAQUFAAOCAQEABVgqI2u309QC/Dgpas1eefZ5
16
+ ihSC1O8VE+5sKd+VZ3COciOAL5me1EcmHdpp+SXZv54E4IPMkLJIaeRhLN+3BzhB
17
+ +FxZuMOFHsaRFrYJhvyiZ1YaA30Rrv7Ac2Z9b19+++mKVSwwoMfTCYUHbNX1e8gy
18
+ 50GjXI5RjqXz8goJnASe1sx12Dm6Hi5fWZxdnIJIU4EJGqSyfEQNDcOOILRvihdp
19
+ +MPuiRlaQjfZy/soMMERP/wuGpw6Ce94ITJ56wjQgl3YhqQPoE76KgRu4b4YwKhx
20
+ H7APPQD4vksmpWYDCN7llFs/nPaYM6lkxy7bcHRQxaA/km9IF+0iwbhv9mDdDQ==
21
+ -----END CERTIFICATE-----
data/intercity.gemspec ADDED
@@ -0,0 +1,16 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'intercity'
3
+ s.version = '0.1'
4
+ s.date = '2015-01-24'
5
+ s.summary = 'Command-line interface for hosting Rails apps on your server.'
6
+ s.authors = ['Michiel Sikkes']
7
+ s.email = 'michiel.sikkes@gmail.com'
8
+ s.files = `git ls-files -z`.split("\x0")
9
+ s.homepage = 'https://intercityup.com'
10
+ s.license = 'MIT'
11
+ s.executables << 'intercity'
12
+ s.require_paths = ["lib"]
13
+ s.cert_chain = ["certs/michiels.pem"]
14
+ s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem") if $0 =~ /gem\z/
15
+ s.add_runtime_dependency 'thor', '~> 0.19'
16
+ end
@@ -0,0 +1,149 @@
1
+ require "thor"
2
+ require "sshkit"
3
+
4
+ module IntercityCLI
5
+ class Application < Thor
6
+ require "sshkit/dsl"
7
+
8
+ map "create" => :add
9
+ map "update" => :add
10
+
11
+ desc "list", "Lists all the application deployments on the server"
12
+ option :user, default: "root"
13
+ option :server, type: :string, required: true
14
+ def list()
15
+ configuration = IntercityCLI::Configuration.new()
16
+
17
+ server = options[:server]
18
+ user = options[:user]
19
+ on server do |host|
20
+ host.user = user
21
+
22
+ applications = capture("ls /u/apps")
23
+ puts applications
24
+ end
25
+ end
26
+
27
+ desc "edit APPLICATION", "Edit ENV variables for application"
28
+ option :user, default: "root"
29
+ option :server, type: :string, required: true
30
+ def edit(application)
31
+ address = options[:server]
32
+
33
+ configuration = IntercityCLI::Configuration.new()
34
+ node_file = File.join(configuration.config_directory, "#{address}.json")
35
+
36
+ user = options[:user]
37
+
38
+ raw_json = File.read(node_file)
39
+ json = JSON.parse(raw_json)
40
+
41
+ json["active_applications"][application]["env_vars"] ||= {}
42
+
43
+ env_vars = json["active_applications"][application]["env_vars"]
44
+
45
+ temp_contents = []
46
+ env_vars.each do |key, val|
47
+ temp_contents << [key,val].join("=")
48
+ end
49
+
50
+ tmp_file = temp_contents.join("\n")
51
+
52
+ tmp_filename = "tmp_" + SecureRandom.hex()
53
+ File.open(tmp_filename, "w") do |f|
54
+ f.write(tmp_file)
55
+ end
56
+
57
+ file_stamp_before_editing = File.mtime(tmp_filename)
58
+ response = system("$EDITOR #{tmp_filename}")
59
+
60
+ if file_stamp_before_editing != File.mtime(tmp_filename)
61
+ new_vars = {}
62
+ new_vars_file = File.read(tmp_filename)
63
+ new_vars_file.each_line() do |line|
64
+ key, value = line.strip.split("=")
65
+ new_vars[key] = value
66
+ end
67
+ File.unlink(tmp_filename)
68
+
69
+ raw_json = File.read(node_file)
70
+ json = JSON.parse(raw_json)
71
+
72
+ json["active_applications"][application]["env_vars"] = new_vars
73
+ File.open(node_file, "w") do |f|
74
+ f.write(JSON.pretty_generate(json))
75
+ end
76
+
77
+ server = address
78
+ user = options[:user]
79
+ on server do |host|
80
+ with debian_frontend: :noninteractive do
81
+ host.user = user
82
+
83
+ upload! node_file , "/root/server_config.json"
84
+
85
+ execute 'chef-client -z -j ~/server_config.json -o "recipe[rails::env_vars]"'
86
+ end
87
+ end
88
+ else
89
+ File.unlink(tmp_filename)
90
+ end
91
+ end
92
+
93
+ desc "add APPLICATION", "Adds an application to a server"
94
+ option :user, default: "root"
95
+ option :server, type: :string, required: true
96
+ option :domain_name, type: :string, required: true
97
+ option :rails_environment, type: :string, default: "production"
98
+ option :database_adapter, type: :string, default: "mysql2"
99
+ option :database_name, type: :string, default: SecureRandom.hex(6)
100
+ option :database_user, type: :string, default: SecureRandom.hex(6)
101
+ option :database_password, type: :string, default: SecureRandom.hex()
102
+ option :database_host, type: :string, default: "127.0.0.1"
103
+ option :ruby_version, type: :string, default: "2.1.3"
104
+ def add(application)
105
+ address = options[:server]
106
+ if File.exists?("#{address}.json")
107
+ raw_json = File.read("#{address}.json")
108
+ json = JSON.parse(raw_json)
109
+ else
110
+ raise "No configuration file for this server yet! Please create one by running:\n\n$ intercity server install <ip address>\n\n"
111
+ end
112
+
113
+ json["active_applications"] ||= {}
114
+
115
+ json["active_applications"][application] ||= {}
116
+
117
+ json["active_applications"][application].merge!(
118
+ {
119
+ "domain_names" => [options[:domain_name]],
120
+ "rails_env" => options[:rails_environment],
121
+ "database_info" => {
122
+ "adapter" => options[:database_adapter],
123
+ "host" => options[:database_host],
124
+ "username" => options[:database_user],
125
+ "password" => options[:database_password],
126
+ "database" => options[:database_name]
127
+ },
128
+ "ruby_version" => options[:ruby_version]
129
+ }
130
+ )
131
+
132
+ File.open("#{address}.json", "w") do |f|
133
+ f.write(JSON.pretty_generate(json))
134
+ end
135
+
136
+ server = address
137
+ user = options[:user]
138
+ on server do |host|
139
+ with debian_frontend: :noninteractive do
140
+ host.user = user
141
+
142
+ upload! "#{address}.json", "/root/server_config.json"
143
+
144
+ execute 'chef-client -z -j ~/server_config.json -o "recipe[rails::passenger],recipe[rails::databases]"'
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,78 @@
1
+ require "thor"
2
+ require "json"
3
+ require "sshkit"
4
+
5
+ module IntercityCLI
6
+ class MySQL < Thor
7
+ require "sshkit/dsl"
8
+
9
+ desc "list", "Lists MySQL databases on IPADDRESS"
10
+ option :user, default: "root"
11
+ option :server, type: :string, required: true
12
+ def list
13
+ address = options[:server]
14
+
15
+ configuration = IntercityCLI::Configuration.new()
16
+ node_file = File.join(configuration.config_directory, "#{address}.json")
17
+
18
+ raw_json = File.read(node_file)
19
+ json = JSON.parse(raw_json)
20
+
21
+ root_password = json["mysql"]["server_root_password"]
22
+
23
+ puts "Local Configuration"
24
+ puts "==================="
25
+
26
+ json["active_applications"].each do |app, config|
27
+ database_info = config["database_info"]
28
+ puts database_info.inspect
29
+ end
30
+
31
+ puts
32
+
33
+ user = options[:user]
34
+ on address do |host|
35
+ host.user = user
36
+
37
+ puts "On MySQL Server"
38
+ puts "==============="
39
+
40
+ databases = capture("mysql -u root --password=#{root_password} -e \"show databases;\"")
41
+ puts databases
42
+ end
43
+ end
44
+
45
+ desc "install IPADDRESS", "Installs MySQL at IPADDRESS"
46
+ option :user, default: "root"
47
+ option :root_password, default: SecureRandom.hex(), type: :string
48
+ def install(address)
49
+ configuration = IntercityCLI::Configuration.new()
50
+ node_file = File.join(configuration.config_directory, "#{address}.json")
51
+
52
+ if File.exists?(node_file)
53
+ raw_json = File.read(node_file)
54
+ json = JSON.parse(raw_json)
55
+ else
56
+ json = {mysql: {
57
+ server_root_password: options[:root_password]
58
+ }}
59
+ end
60
+
61
+ File.open(node_file, "w") do |f|
62
+ f.write(JSON.pretty_generate(json))
63
+ end
64
+
65
+ server = address
66
+ user = options[:user]
67
+ on server do |host|
68
+ with debian_frontend: :noninteractive do
69
+ host.user = user
70
+
71
+ upload! "#{address}.json", "/root/server_config.json"
72
+
73
+ execute 'chef-client -z -j ~/server_config.json -o recipe[mysql::server]'
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,31 @@
1
+ require "thor"
2
+ require "sshkit"
3
+
4
+ module IntercityCLI
5
+ class Server < Thor
6
+ require "sshkit/dsl"
7
+
8
+ desc "install IPADDRESS", "Installs server at IPADDRESS"
9
+ option :user, type: :string, default: "root"
10
+ def install(address)
11
+ server = address
12
+ user = options[:user]
13
+ on server do |host|
14
+ with debian_frontend: :noninteractive do
15
+ host.user = user
16
+
17
+ execute "apt-get update"
18
+
19
+ # Install Chef via Omnibus
20
+ execute "curl -L https://www.chef.io/chef/install.sh | sudo bash"
21
+
22
+ # Install chef-repo
23
+ execute "wget https://github.com/intercity/chef-repo/releases/download/v2.3.0/cookbooks-2.3.0.tar.gz"
24
+ execute "tar zxf cookbooks-2.3.0.tar.gz"
25
+
26
+ execute "chef-client -z"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ require "thor"
2
+ require "intercity/cli/server"
3
+ require "intercity/cli/mysql"
4
+ require "intercity/cli/application"
5
+
6
+ module IntercityCLI
7
+
8
+ class Main < Thor
9
+ class_option :verbose, type: :boolean
10
+
11
+ desc "server SUBCOMMAND ARGS", "subcommands to install and configure a server"
12
+ subcommand "server", Server
13
+
14
+ desc "mysql SUBCOMMAND ARGS", "subcommands to manage mysql"
15
+ subcommand "mysql", MySQL
16
+
17
+ desc "application SUBCOMMAND ARGS", "subcommands to manage applications"
18
+ subcommand "application", Application
19
+ end
20
+
21
+ class Configuration
22
+ def initialize()
23
+ if !Dir.exists?("nodes")
24
+ Dir.mkdir("nodes")
25
+ end
26
+ end
27
+
28
+ def config_directory
29
+ File.expand_path("nodes")
30
+ end
31
+ end
32
+ end
data.tar.gz.sig ADDED
Binary file
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: intercity
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Michiel Sikkes
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDijCCAnKgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMRcwFQYDVQQDDA5taWNo
14
+ aWVsLnNpa2tlczEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQB
15
+ GRYDY29tMB4XDTE0MTIyNDEyNTQzM1oXDTE1MTIyNDEyNTQzM1owRTEXMBUGA1UE
16
+ AwwObWljaGllbC5zaWtrZXMxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmS
17
+ JomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJXr
18
+ ZzV/gU/XPk6hhBs/iSn+HYGLHYnaEtVkNliKZKWLr7arKGM5pneM9rub8VaA9iKE
19
+ N2swxHngobSDouYBJcxlQabCWx8htD4nSlOXWTfFeR78jhfYS2VyysQ0dnHSjE9c
20
+ KXa8EHcg0YNPpWqWoGemb4iJENnqcGGLY67RBhkHsWj5BJO84e4hS8vsUYyAiAbV
21
+ 3nO5+5EmnkWQB2fVDTL3tjY1yOdzfyvaIifwt9aKVwY0YPORIlm9RI4wtQRv9NFq
22
+ ONyougmLd5vVWp6jO1+9O6TxayzDccJLGuGB6Tw94BQo3o50yoLZew44A7VT3XC2
23
+ LQg3n8Pzuow9MtTRrC0CAwEAAaOBhDCBgTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE
24
+ sDAdBgNVHQ4EFgQUbb9Rb7oi1MDVYRSgxiQ33szdVCswIwYDVR0RBBwwGoEYbWlj
25
+ aGllbC5zaWtrZXNAZ21haWwuY29tMCMGA1UdEgQcMBqBGG1pY2hpZWwuc2lra2Vz
26
+ QGdtYWlsLmNvbTANBgkqhkiG9w0BAQUFAAOCAQEABVgqI2u309QC/Dgpas1eefZ5
27
+ ihSC1O8VE+5sKd+VZ3COciOAL5me1EcmHdpp+SXZv54E4IPMkLJIaeRhLN+3BzhB
28
+ +FxZuMOFHsaRFrYJhvyiZ1YaA30Rrv7Ac2Z9b19+++mKVSwwoMfTCYUHbNX1e8gy
29
+ 50GjXI5RjqXz8goJnASe1sx12Dm6Hi5fWZxdnIJIU4EJGqSyfEQNDcOOILRvihdp
30
+ +MPuiRlaQjfZy/soMMERP/wuGpw6Ce94ITJ56wjQgl3YhqQPoE76KgRu4b4YwKhx
31
+ H7APPQD4vksmpWYDCN7llFs/nPaYM6lkxy7bcHRQxaA/km9IF+0iwbhv9mDdDQ==
32
+ -----END CERTIFICATE-----
33
+ date: 2015-01-24 00:00:00.000000000 Z
34
+ dependencies:
35
+ - !ruby/object:Gem::Dependency
36
+ name: thor
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '0.19'
42
+ type: :runtime
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '0.19'
49
+ description:
50
+ email: michiel.sikkes@gmail.com
51
+ executables:
52
+ - intercity
53
+ extensions: []
54
+ extra_rdoc_files: []
55
+ files:
56
+ - ".gitignore"
57
+ - README.md
58
+ - bin/intercity
59
+ - certs/michiels.pem
60
+ - intercity.gemspec
61
+ - lib/intercity/cli.rb
62
+ - lib/intercity/cli/application.rb
63
+ - lib/intercity/cli/mysql.rb
64
+ - lib/intercity/cli/server.rb
65
+ homepage: https://intercityup.com
66
+ licenses:
67
+ - MIT
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 2.2.2
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: Command-line interface for hosting Rails apps on your server.
89
+ test_files: []
metadata.gz.sig ADDED
@@ -0,0 +1,2 @@
1
+ &y�Qۊ�B&g� AF} ��!�� 7���.����
2
+ o��O!{�D��i��A��0kE�T�T:(���a�����z��C,X�Cg���$�-�0�*zȦ�xx���xH�d1�f��y�����>��j�?�rQ�]yM�rƅ��w(�4ƈ�-����I�(ㇻ����+S����W�Ч�X79�H�2�A?�޶�f��ujΨɫ�aAgn�m�cnPH;�E�M�,��8o[��<ЕX�QS����F�#�͂