vmc_knife 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +159 -0
- data/lib/vmc_knife/cli_extensions.rb +9 -1
- data/lib/vmc_knife/commands/knife_cmds.rb +33 -13
- data/lib/vmc_knife/data_services.rb +216 -62
- data/lib/vmc_knife/json_expander.rb +58 -17
- data/lib/vmc_knife/mongo/mongo_cmd.js.erb +24 -0
- data/lib/vmc_knife/vmc_knife.rb +57 -41
- data/lib/vmc_knife.rb +12 -12
- metadata +5 -4
data/README.md
CHANGED
@@ -11,4 +11,163 @@ Run the deployment file via a web-interface.
|
|
11
11
|
prepare a vmc deployment file.
|
12
12
|
vmc_knife vmc_deployment_file.json
|
13
13
|
|
14
|
+
## Installation
|
15
|
+
ssh into a Cloudfoundry VM
|
16
|
+
load the cloudfoundry profile and install the gem:
|
14
17
|
|
18
|
+
source /home/ubuntu/.cloudfoundry_deployment_local
|
19
|
+
gem install vmc_knife
|
20
|
+
|
21
|
+
Or to install from source:
|
22
|
+
|
23
|
+
git clone https://github.com/hmalphettes/vmc-knife.git
|
24
|
+
cd vmc-knife
|
25
|
+
gem build vmc_knife.gemspec
|
26
|
+
gem install vmc_knife
|
27
|
+
|
28
|
+
## Example:
|
29
|
+
Create a recipe with the mongodb app example and the sinatra example app.
|
30
|
+
|
31
|
+
Make a new file example_recipe.json
|
32
|
+
|
33
|
+
Enter:
|
34
|
+
|
35
|
+
{
|
36
|
+
"sub_domain": "vcap.me",
|
37
|
+
"target": "api.vcap.me",
|
38
|
+
"email": "vcap@vcap.me",
|
39
|
+
"password": "vcap",
|
40
|
+
"recipes": [
|
41
|
+
{
|
42
|
+
"name": "example_recipe",
|
43
|
+
"data_services": {
|
44
|
+
"mongo1": {
|
45
|
+
"name": "a_mongo",
|
46
|
+
"vendor": "mongodb"
|
47
|
+
}
|
48
|
+
},
|
49
|
+
"applications": {
|
50
|
+
"example_mongo": {
|
51
|
+
"name": "mongo_db_demo",
|
52
|
+
"uris": [
|
53
|
+
"mongodb-on-cf-demo.#{this['sub_domain']}"
|
54
|
+
],
|
55
|
+
"staging": {
|
56
|
+
"stack": "ruby19",
|
57
|
+
"model": "rails3"
|
58
|
+
},
|
59
|
+
"resources": {
|
60
|
+
"memory": 256
|
61
|
+
},
|
62
|
+
"services": [
|
63
|
+
"#{this['recipes'][0]['data_services']['mongo1']['name']}"
|
64
|
+
],
|
65
|
+
"env": [
|
66
|
+
"DERIVED_VALUE_EXAMPLE=http://#{this['recipes'][0]['applications']['example_mongo']['uris'][0]}"
|
67
|
+
],
|
68
|
+
"repository": {
|
69
|
+
"url": "https://github.com/mccrory/cloud-foundry-mongodb-demo.git",
|
70
|
+
"branch":"master"
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
]
|
76
|
+
}
|
77
|
+
|
78
|
+
Navigate to the folder where the recipe is located.
|
79
|
+
And use vmc_knife:
|
80
|
+
|
81
|
+
vmc_knife login
|
82
|
+
vmc_knife configure-apps
|
83
|
+
vmc_knife upload-apps
|
84
|
+
vmc_knife start-apps
|
85
|
+
|
86
|
+
The console will look like this:
|
87
|
+
|
88
|
+
ubuntu@ubuntu:~/tmp$ vmc_knife configure-apps
|
89
|
+
Applications selected mongo_db_demo
|
90
|
+
Data-services selected a_mongo
|
91
|
+
{
|
92
|
+
"applications": {
|
93
|
+
"mongo_db_demo": {
|
94
|
+
"name": "Create mongo_db_demo",
|
95
|
+
"services": {
|
96
|
+
"add": [
|
97
|
+
"a_mongo"
|
98
|
+
]
|
99
|
+
},
|
100
|
+
"env": {
|
101
|
+
"add": [
|
102
|
+
"DERIVED_VALUE_EXAMPLE=http://mongodb-on-cf-demo.vcap.me"
|
103
|
+
]
|
104
|
+
},
|
105
|
+
"uris": {
|
106
|
+
"add": [
|
107
|
+
"mongodb-on-cf-demo.vcap.me"
|
108
|
+
]
|
109
|
+
},
|
110
|
+
"memory": " => 256"
|
111
|
+
}
|
112
|
+
}
|
113
|
+
}
|
114
|
+
Creating mongo_db_demo with {:name=>"mongo_db_demo", "resources"=>{"memory"=>256}, "staging"=>{"model"=>"rails3", "stack"=>"ruby19"}, "uris"=>["mongodb-on-cf-demo.vcap.me"], "services"=>["a_mongo"], "env"=>["DERIVED_VALUE_EXAMPLE=http://mongodb-on-cf-demo.vcap.me"]}
|
115
|
+
|
116
|
+
ubuntu@ubuntu:~/tmp$ vmc_knife upload-apps
|
117
|
+
Applications selected mongo_db_demo
|
118
|
+
Data-services selected a_mongo
|
119
|
+
Dir.entries(/home/ubuntu/vmc_knife_downloads/mongo_db_demo).size 2
|
120
|
+
remote: Counting objects: 85, done.
|
121
|
+
remote: Compressing objects: 100% (65/65), done.
|
122
|
+
remote: Total 85 (delta 4), reused 84 (delta 4)
|
123
|
+
Unpacking objects: 100% (85/85), done.
|
124
|
+
fatal: Not a git repository (or any of the parent directories): .git
|
125
|
+
Uploading Application mongo_db_demo from /home/ubuntu/vmc_knife_downloads/mongo_db_demo:
|
126
|
+
Copying the files
|
127
|
+
Done copying the files
|
128
|
+
Checking for available resources: About to compute the fingerprints
|
129
|
+
Finished computing the fingerprints
|
130
|
+
Invoking check_resources with the fingerprints
|
131
|
+
OK
|
132
|
+
Processing resources: OK
|
133
|
+
Packing application: OK
|
134
|
+
Uploading (255K): client.upload_app about to start
|
135
|
+
Uploading (255K): OK
|
136
|
+
Done client.upload_app
|
137
|
+
Push Status: OK
|
138
|
+
|
139
|
+
|
140
|
+
|
141
|
+
### Updating an app:
|
142
|
+
|
143
|
+
For example edit the memory parameter of the app. Then call:
|
144
|
+
|
145
|
+
vmc_knife configure-apps
|
146
|
+
vmc_knife restart-apps example_mongo
|
147
|
+
|
148
|
+
Note that vmc_knife's start/stop/restart only sends the command to vcap's cloud_controller.
|
149
|
+
It does not try to poll it to see if the command was successful.
|
150
|
+
|
151
|
+
Delete data-services and apps in the recipe:
|
152
|
+
|
153
|
+
vmc_knife delete-all
|
154
|
+
|
155
|
+
|
156
|
+
### Accessing the data-services:
|
157
|
+
Assuming that vmc_knife is able to locate the cloud_controller.yml and mongo binary:
|
158
|
+
|
159
|
+
vmc_knife data-shell mongo1
|
160
|
+
|
161
|
+
will drop the user to the mongo shell:
|
162
|
+
|
163
|
+
ubuntu@ubuntu:~/tmp$ vmc_knife data-shell mongo1
|
164
|
+
Applications selected mongo_db_demo
|
165
|
+
Data-services selected a_mongo
|
166
|
+
Executing /home/ubuntu/cloudfoundry/.deployments/intalio_devbox/deploy/mongodb/bin/mongo -u 6e409825-31f6-4a47-8eef-11f49e763a9a -p 153c52d6-26ab-467b-9c1d-bc1b071a5c86 192.168.0.138:25001/db
|
167
|
+
MongoDB shell version: 1.8.1
|
168
|
+
connecting to: 192.168.0.138:25001/db
|
169
|
+
>
|
170
|
+
|
171
|
+
With postgresql export and import are supported.
|
172
|
+
|
173
|
+
Todo: take advantage of the new vmc-tunnel.
|
@@ -168,6 +168,14 @@ class VMC::Cli::KnifeRunner < VMC::Cli::Runner
|
|
168
168
|
else
|
169
169
|
set_cmd(:knifeapps, :data_drop, @args.size) # too many
|
170
170
|
end
|
171
|
+
when 'data-shrink'
|
172
|
+
usage('vmc_knife data-shrink [<data-service-name>] [<tables-collection-regexp>]')
|
173
|
+
@args.shift # consumes the argument.
|
174
|
+
if @args.size <= 3
|
175
|
+
set_cmd(:knifeapps, :data_shrink, @args.size)
|
176
|
+
else
|
177
|
+
set_cmd(:knifeapps, :data_shrink, @args.size) # too many
|
178
|
+
end
|
171
179
|
when 'data-import'
|
172
180
|
usage('vmc_knife data-import [<data-service-name>] [<tables-collection-regexp>]')
|
173
181
|
@args.shift # consumes the argument.
|
@@ -185,7 +193,7 @@ class VMC::Cli::KnifeRunner < VMC::Cli::Runner
|
|
185
193
|
set_cmd(:knifeapps, :data_export, @args.size) # too many
|
186
194
|
end
|
187
195
|
when 'help'
|
188
|
-
display "vmc_knife expand-manifest|login|start/stop/restart-apps|upload-apps|configure-all|configure-recipes|configure-apps|configure-services|delete-all|configure-vcap|configure-vcap-mdns|configure-vcap-etc-hosts|data-shell [<manifest_path>]"
|
196
|
+
display "vmc_knife expand-manifest|login|start/stop/restart-apps|upload-apps|configure-all|configure-recipes|configure-apps|configure-services|delete-all|configure-vcap|configure-vcap-mdns|configure-vcap-etc-hosts|data-shell|data-export/import/shrink/drop [<manifest_path>]"
|
189
197
|
else
|
190
198
|
super
|
191
199
|
end
|
@@ -5,8 +5,10 @@ module VMC::KNIFE::Cli
|
|
5
5
|
#loads the manifest file.
|
6
6
|
#when the path is not specified, look in the current directory.
|
7
7
|
#when the path is a directory, look for the first json file it can find.
|
8
|
+
#if it still find nothing then use the default which is the value of the environment variable VMC_KNIFE_DEFAULT_RECIPE
|
8
9
|
#the json file actually loaded is set as the attribute @manifest_path
|
9
10
|
def load_manifest(manifest_file_path=nil)
|
11
|
+
was_nil = true if manifest_file_path.nil?
|
10
12
|
manifest_file_path = Dir.pwd if manifest_file_path.nil?
|
11
13
|
if File.directory? manifest_file_path
|
12
14
|
#look for the first .json file if possible that is not an expanded.json
|
@@ -17,7 +19,12 @@ module VMC::KNIFE::Cli
|
|
17
19
|
end
|
18
20
|
return VMC::KNIFE::JSON_EXPANDER.expand_json @manifest_path
|
19
21
|
end
|
20
|
-
|
22
|
+
if was_nil && !ENV['VMC_KNIFE_DEFAULT_RECIPE'].nil?
|
23
|
+
raise "Can't load the default recipe VMC_KNIFE_DEFAULT_RECIPE=#{ENV['VMC_KNIFE_DEFAULT_RECIPE']}" unless File.exists? ENV['VMC_KNIFE_DEFAULT_RECIPE']
|
24
|
+
load_manifest ENV['VMC_KNIFE_DEFAULT_RECIPE']
|
25
|
+
else
|
26
|
+
raise "Unable to find a *.json file in #{manifest_file_path}"
|
27
|
+
end
|
21
28
|
else
|
22
29
|
@manifest_path = manifest_file_path
|
23
30
|
return VMC::KNIFE::JSON_EXPANDER.expand_json @manifest_path
|
@@ -171,10 +178,12 @@ module VMC::Cli::Command
|
|
171
178
|
include VMC::KNIFE::Cli
|
172
179
|
|
173
180
|
def configure_applications(app_names_regexp=nil,manifest_file_path=nil)
|
174
|
-
configure(nil,nil,app_names_regexp,manifest_file_path
|
181
|
+
configure(nil,nil,app_names_regexp,manifest_file_path,
|
182
|
+
{:apps_only=>true})
|
175
183
|
end
|
176
184
|
def configure_services(services_names_regexp=nil,manifest_file_path=nil)
|
177
|
-
configure(nil,nil,services_names_regexp,manifest_file_path
|
185
|
+
configure(nil,nil,services_names_regexp,manifest_file_path,
|
186
|
+
{:data_only=>true})
|
178
187
|
end
|
179
188
|
def configure_recipes(recipe_names_regexp=nil,manifest_file_path=nil)
|
180
189
|
configure(recipe_names_regexp,nil,nil,manifest_file_path)
|
@@ -199,40 +208,51 @@ module VMC::Cli::Command
|
|
199
208
|
end
|
200
209
|
|
201
210
|
def upload_applications(app_names_regexp=nil,manifest_file_path=nil)
|
202
|
-
recipe_configuror(:upload,nil,app_names_regexp,nil,manifest_file_path
|
211
|
+
recipe_configuror(:upload,nil,app_names_regexp,nil,manifest_file_path,
|
212
|
+
{:apps_only=>true})
|
203
213
|
end
|
204
214
|
def start_applications(app_names_regexp=nil,manifest_file_path=nil)
|
205
|
-
recipe_configuror(:start,nil,app_names_regexp,nil,manifest_file_path
|
215
|
+
recipe_configuror(:start,nil,app_names_regexp,nil,manifest_file_path,
|
216
|
+
{:apps_only=>true})
|
206
217
|
end
|
207
218
|
def stop_applications(app_names_regexp=nil,manifest_file_path=nil)
|
208
|
-
recipe_configuror(:stop,nil,app_names_regexp,nil,manifest_file_path
|
219
|
+
recipe_configuror(:stop,nil,app_names_regexp,nil,manifest_file_path,
|
220
|
+
{:apps_only=>true})
|
209
221
|
end
|
210
222
|
def restart_applications(app_names_regexp=nil,manifest_file_path=nil)
|
211
|
-
recipe_configuror(:restart,nil,app_names_regexp,nil,manifest_file_path
|
223
|
+
recipe_configuror(:restart,nil,app_names_regexp,nil,manifest_file_path,
|
224
|
+
{:apps_only=>true})
|
212
225
|
end
|
213
226
|
def delete_all(app_names_regexp=nil,manifest_file_path=nil)
|
214
227
|
recipe_configuror(:delete,nil,app_names_regexp,nil,manifest_file_path)
|
215
228
|
end
|
216
229
|
def data_shell(data_names_regexp=nil,manifest_file_path=nil)
|
217
|
-
recipe_configuror(:shell,nil,nil,data_names_regexp,manifest_file_path
|
230
|
+
recipe_configuror(:shell,nil,nil,data_names_regexp,manifest_file_path,
|
231
|
+
{:data_only=>true})
|
218
232
|
end
|
219
233
|
def data_credentials(data_names_regexp=nil,manifest_file_path=nil)
|
220
|
-
recipe_configuror(:credentials,nil,nil,data_names_regexp,manifest_file_path
|
234
|
+
recipe_configuror(:credentials,nil,nil,data_names_regexp,manifest_file_path,
|
235
|
+
{:data_only=>true})
|
221
236
|
end
|
222
237
|
def data_apply_privileges(data_names_regexp=nil,manifest_file_path=nil)
|
223
|
-
recipe_configuror(:apply_privileges,nil,nil,data_names_regexp,manifest_file_path
|
238
|
+
recipe_configuror(:apply_privileges,nil,nil,data_names_regexp,manifest_file_path,
|
239
|
+
{:data_only=>true})
|
224
240
|
end
|
225
241
|
def data_import(data_names_regexp=nil,app_name=nil,file_names=nil,manifest_file_path=nil)
|
226
242
|
recipe_configuror(:import,nil,nil,data_names_regexp,manifest_file_path,
|
227
|
-
{:file_names=>file_names, :app_name=>app_name})
|
243
|
+
{:file_names=>file_names, :app_name=>app_name, :data_only=>true})
|
228
244
|
end
|
229
245
|
def data_export(data_names_regexp=nil,app_name=nil,file_names=nil,manifest_file_path=nil)
|
230
246
|
recipe_configuror(:export,nil,nil,data_names_regexp,manifest_file_path,
|
231
|
-
{:file_names=>file_names, :app_name=>app_name})
|
247
|
+
{:file_names=>file_names, :app_name=>app_name, :data_only=>true})
|
232
248
|
end
|
233
249
|
def data_drop(data_names_regexp=nil,collection_or_table_names=nil,manifest_file_path=nil)
|
234
250
|
recipe_configuror(:drop,nil,nil,data_names_regexp,manifest_file_path,
|
235
|
-
{:collection_or_table_names=>collection_or_table_names})
|
251
|
+
{:collection_or_table_names=>collection_or_table_names, :data_only=>true})
|
252
|
+
end
|
253
|
+
def data_shrink(data_names_regexp=nil,collection_or_table_names=nil,manifest_file_path=nil)
|
254
|
+
recipe_configuror(:shrink,nil,nil,data_names_regexp,manifest_file_path,
|
255
|
+
{:collection_or_table_names=>collection_or_table_names, :data_only=>true})
|
236
256
|
end
|
237
257
|
|
238
258
|
def recipe_configuror(method_sym_name,recipes_regexp=nil,app_names_regexp=nil,service_names_regexp=nil,manifest_file_path=nil,opts=nil)
|
@@ -2,6 +2,8 @@ require 'yaml'
|
|
2
2
|
require "interact"
|
3
3
|
require 'tempfile'
|
4
4
|
require 'tmpdir'
|
5
|
+
require 'pathname'
|
6
|
+
require 'erb'
|
5
7
|
|
6
8
|
module VMC
|
7
9
|
module KNIFE
|
@@ -10,16 +12,21 @@ module VMC
|
|
10
12
|
PSQL_RAW_RES_ARGS="-P format=unaligned -P footer=off -P tuples_only=on"
|
11
13
|
|
12
14
|
# Reads the cloud_controller config file for the connection parameters to ccdb.
|
13
|
-
def self.get_ccdb_credentials(ccdb_yml_path="#{ENV['
|
15
|
+
def self.get_ccdb_credentials(ccdb_yml_path="#{ENV['CLOUD_FOUNDRY_CONFIG_PATH']}/cloud_controller.yml", db_type='production')
|
14
16
|
cc_conf = File.open( ccdb_yml_path ) do |yf| YAML::load( yf ) end
|
15
17
|
db = cc_conf['database_environment'][db_type]
|
16
18
|
db
|
17
19
|
end
|
18
20
|
|
19
|
-
def self.get_postgresql_node_credentials(postgresql_node_yml_path="#{ENV['
|
21
|
+
def self.get_postgresql_node_credentials(postgresql_node_yml_path="#{ENV['CLOUD_FOUNDRY_CONFIG_PATH']}/postgresql_node.yml")
|
20
22
|
db = File.open( postgresql_node_yml_path ) do |yf| YAML::load( yf ) end
|
21
23
|
db['postgresql']
|
22
24
|
end
|
25
|
+
|
26
|
+
def self.get_mongodb_node_config(mongodb_node_yml_path="#{ENV['CLOUD_FOUNDRY_CONFIG_PATH']}/mongodb_node.yml")
|
27
|
+
db = File.open( mongodb_node_yml_path ) do |yf| YAML::load( yf ) end
|
28
|
+
db
|
29
|
+
end
|
23
30
|
|
24
31
|
def self.get_app_id(app_name)
|
25
32
|
db=get_ccdb_credentials()
|
@@ -96,21 +103,31 @@ module VMC
|
|
96
103
|
end
|
97
104
|
|
98
105
|
# command_files or command.
|
99
|
-
def self.data_service_console(credentials_hash, commands_file="",as_admin=false)
|
106
|
+
def self.data_service_console(credentials_hash, commands_file="",as_admin=false,exec_name=nil)
|
100
107
|
if credentials_hash['db'] #so far it has always been equal to 'db'
|
101
108
|
# It is a mongo service
|
102
109
|
#/home/ubuntu/cloudfoundry/.deployments/intalio_devbox/deploy/mongodb/bin/mongo 127.0.0.1:25003/db
|
103
110
|
#-u c417f26c-6f49-4dd5-a208-216107279c7a -p 8ab08355-6509-48d5-974f-27c853b842f5
|
104
111
|
# Todo: compute the mongoshell path (?)
|
105
|
-
|
106
|
-
|
112
|
+
exec_name ||= 'mongo'
|
113
|
+
mongo_shell=get_mongo_exec(exec_name)
|
114
|
+
if exec_name == 'mongo'
|
115
|
+
db_arg = "/#{credentials_hash['db']}"
|
116
|
+
elsif exec_name == 'mongodump'
|
117
|
+
db_arg = "" # dump all the databases including 'admin' which contains the users.
|
118
|
+
else
|
119
|
+
db_arg = "--db #{credentials_hash['db']}"
|
120
|
+
end
|
121
|
+
cmd = "#{mongo_shell} -u #{credentials_hash['username']} -p #{credentials_hash['password']} #{credentials_hash['hostname']}:#{credentials_hash['port']}#{db_arg}"
|
107
122
|
puts "Executing #{cmd}"
|
108
123
|
if commands_file
|
109
|
-
if
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
124
|
+
if mongo_shell == 'mongo'
|
125
|
+
if File.exists? commands_file
|
126
|
+
# not supported yet.
|
127
|
+
commands_file = "--eval \"#{`cat commands_file`}"
|
128
|
+
else
|
129
|
+
commands_file = "--eval \"#{commands_file}\""
|
130
|
+
end
|
114
131
|
end
|
115
132
|
`#{cmd} #{commands_file}`
|
116
133
|
else
|
@@ -133,16 +150,24 @@ module VMC
|
|
133
150
|
end
|
134
151
|
end
|
135
152
|
|
136
|
-
def self.
|
137
|
-
mongo
|
138
|
-
|
139
|
-
|
140
|
-
|
153
|
+
def self.get_mongo_exec(exec_name=nil)
|
154
|
+
exec_name||='mongo'
|
155
|
+
mongo_bin_folder=File.dirname(get_mongodb_node_config()['mongod_path'])
|
156
|
+
File.join(mongo_bin_folder,exec_name)
|
157
|
+
end
|
158
|
+
|
159
|
+
# Returns the path to the mongodb db files. /var/vcap/services/mongodb/
|
160
|
+
def self.get_mongodb_base_dir(mongodb_node_yml_path=nil)
|
161
|
+
mongodb_node_yml_path||="#{ENV['CLOUD_FOUNDRY_CONFIG_PATH']}/mongodb_node.yml"
|
162
|
+
db = File.open( mongodb_node_yml_path ) do |yf| YAML::load( yf ) end
|
163
|
+
base_dir = db['base_dir']
|
141
164
|
end
|
142
165
|
|
143
166
|
def self.as_regexp(arg)
|
144
167
|
if arg != nil && arg.kind_of?(String) && !arg.strip.empty?
|
145
168
|
Regexp.new(arg)
|
169
|
+
elsif arg.kind_of?(Regexp)
|
170
|
+
arg
|
146
171
|
end
|
147
172
|
end
|
148
173
|
|
@@ -183,6 +208,12 @@ module VMC
|
|
183
208
|
data_service.drop(collection_or_table_names)
|
184
209
|
end
|
185
210
|
end
|
211
|
+
def shrink()
|
212
|
+
collection_or_table_names = @opts[:collection_or_table_names] if @opts
|
213
|
+
@data_services.each do |data_service|
|
214
|
+
data_service.shrink(collection_or_table_names)
|
215
|
+
end
|
216
|
+
end
|
186
217
|
|
187
218
|
end
|
188
219
|
|
@@ -212,73 +243,103 @@ module VMC
|
|
212
243
|
raise "Unable to locate the database file to import." if files.empty?
|
213
244
|
file = files.first
|
214
245
|
end
|
215
|
-
|
216
|
-
|
217
|
-
|
246
|
+
|
247
|
+
|
248
|
+
tmp_download_filename="_download_.zip"
|
249
|
+
data_download_dir="#{ENV['HOME']}/vmc_knife_downloads/data_#{@wrapped['name']}"
|
250
|
+
current_wd=Dir.pwd
|
251
|
+
FileUtils.mkdir_p data_download_dir
|
252
|
+
Dir.chdir(data_download_dir) do
|
218
253
|
if file =~ /^https?:\/\// || file =~ /^ftp:\/\//
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
254
|
+
basename = Pathname.new(URI.parse(file).path).basename.to_s
|
255
|
+
else
|
256
|
+
file=File.expand_path(file,current_wd)
|
257
|
+
basename = File.basename(file).to_s
|
258
|
+
end
|
259
|
+
if Dir.entries(Dir.pwd).size == 2
|
260
|
+
if file =~ /^https?:\/\// || file =~ /^ftp:\/\//
|
261
|
+
wget_args = @wrapped['director']['wget_args']
|
262
|
+
if wget_args.nil?
|
263
|
+
wget_args_str = ""
|
264
|
+
elsif wget_args.kind_of? Array
|
265
|
+
wget_args_str = wget_args.join(' ')
|
266
|
+
elsif wget_args.kind_of? String
|
267
|
+
wget_args_str = wget_args
|
268
|
+
end
|
269
|
+
`wget #{wget_args_str} --output-document=#{basename} #{file}`
|
270
|
+
if $? != 0
|
271
|
+
`rm #{data_download_dir}/#{basename}`
|
272
|
+
raise "Unable to successfully download #{file}"
|
273
|
+
end
|
274
|
+
else
|
275
|
+
`cp #{file} #{basename}`
|
232
276
|
end
|
233
|
-
`wget #{wget_args_str} --output-document=#{tempfile.path} #{url}`
|
234
|
-
file = tempfile.path
|
235
277
|
end
|
236
278
|
#unzip if necessary (in progress)
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
tmp_dir = Dir.mktmpdir
|
248
|
-
Dir.chdir(tmp_dir.path)
|
249
|
-
`unzip #{file}`
|
279
|
+
is_unzipped=true
|
280
|
+
p "unzip #{basename}"
|
281
|
+
if /\.tgz$/ =~ basename || /\.tar\.gz$/ =~ basename
|
282
|
+
`tar zxvf #{basename}`
|
283
|
+
elsif /\.tar$/ =~ basename
|
284
|
+
`tar xvf #{basename}`
|
285
|
+
elsif /\.zip$/ =~ basename
|
286
|
+
`unzip #{basename}`
|
287
|
+
else
|
288
|
+
is_unzipped=false
|
250
289
|
end
|
251
|
-
|
252
|
-
|
290
|
+
|
291
|
+
if is_unzipped
|
292
|
+
#`rm #{basename}`
|
253
293
|
files = Dir.glob("*.sql") if is_postgresql
|
254
294
|
files = Dir.glob("*.bson") if is_mongodb
|
255
295
|
files ||= Dir.glob("*")
|
256
296
|
raise "Can't find the db-dump file." if files.empty?
|
257
297
|
file = files.first
|
298
|
+
else
|
299
|
+
file = basename
|
258
300
|
end
|
259
|
-
|
301
|
+
|
260
302
|
if is_postgresql
|
303
|
+
p "chmod o+w #{file}"
|
261
304
|
`chmod o+w #{file}`
|
262
|
-
|
305
|
+
creds=credentials(app_name)
|
263
306
|
if /\.sql$/ =~ file
|
264
307
|
other_params="--file #{file} --quiet"
|
265
|
-
cmd = VMC::KNIFE.pg_connect_cmd(
|
308
|
+
cmd = VMC::KNIFE.pg_connect_cmd(creds, 'psql',as_admin=false, other_params)
|
266
309
|
#`psql --dbname #{dbname} --file #{file} --clean --quiet --username #{rolename}`
|
267
310
|
else
|
268
311
|
other_params="--clean --no-acl --no-privileges --no-owner #{file}"
|
269
|
-
cmd = VMC::KNIFE.pg_connect_cmd(
|
312
|
+
cmd = VMC::KNIFE.pg_connect_cmd(creds, 'pg_restore',false, other_params)
|
270
313
|
#`pg_restore --dbname=#{dbname} --username=#{username} --no-acl --no-privileges --no-owner #{file}`
|
271
314
|
end
|
272
315
|
puts cmd
|
273
316
|
puts `#{cmd}`
|
274
317
|
`chmod o-w #{file}`
|
318
|
+
elsif is_mongodb
|
319
|
+
|
320
|
+
# see if we go through the filesystem to shrink or
|
321
|
+
# if we are only interested in the data itself.
|
322
|
+
base_dir=VMC::KNIFE.get_mongodb_base_dir()
|
323
|
+
instance_name=creds['name']
|
324
|
+
dbpath=File.join(base_dir, instance_name, 'data')
|
325
|
+
mongod_lock=File.join(dbpath,'mongo.lock')
|
326
|
+
|
327
|
+
if File.exists?(mongod_lock) && File.size(mongod_lock)>0
|
328
|
+
# the mongodb instance is currently working. connect to it and do the work.
|
329
|
+
# in that case import the 'db' alone. don't do the 'admin'
|
330
|
+
VMC::KNIFE.data_service_console(creds, File.dirname(file),false,'mongorestore')
|
331
|
+
else
|
332
|
+
# the mongodb instance is not currently working
|
333
|
+
# go directly on the filesystem
|
334
|
+
`rm -rf #{dbpath}`
|
335
|
+
`mkdir -p #{dbpath}`
|
336
|
+
#sudo mongorestore --dbpath /var/lib/mongodb
|
337
|
+
mongorestore_exec=VMC::KNIFE.get_mongo_exec('mongorestore')
|
338
|
+
`#{mongorestore_exec} --dbpath #{dbpath} #{File.dirname(File.dirname(file))}`
|
339
|
+
end
|
275
340
|
else
|
276
|
-
raise "Unsupported type of data-service. Postgresql
|
341
|
+
raise "Unsupported type of data-service. Postgresql and mongodb are the only supported services at the moment."
|
277
342
|
end
|
278
|
-
ensure
|
279
|
-
file.unlink if is_tmp # deletes the temp file
|
280
|
-
tmp_dir.unlink if tmp_dir # deletes the temp directory
|
281
|
-
Dir.chdir(current_wd)
|
282
343
|
end
|
283
344
|
end
|
284
345
|
|
@@ -286,19 +347,55 @@ module VMC
|
|
286
347
|
if is_postgresql
|
287
348
|
if file.nil?
|
288
349
|
extension = @wrapped['director']['file_extension'] if @wrapped['director']
|
289
|
-
extension
|
350
|
+
extension ||= "sql"
|
290
351
|
file = "#{name()}.#{extension}"
|
291
352
|
end
|
292
353
|
`touch #{file}`
|
293
354
|
`chmod o+w #{file}`
|
294
355
|
puts "Exports the database #{credentials(app_name)['name']} in #{file}"
|
295
|
-
|
296
|
-
#sudo -u postgres env PGPASSWORD=$PGPASSWORD
|
356
|
+
#sudo -u postgres env PGPASSWORD=intalio DBNAME=intalio DUMPFILE=intalio_dump.sql pg_dump --format=p --file=$DUMPFILE --no-owner --clean --blobs --no-acl --oid --no-tablespaces $DBNAME
|
357
|
+
#sudo -u postgres env PGPASSWORD=$PGPASSWORD DUMPFILE=$DUMPFILE pg_dump --format=p --file=$DUMPFILE --no-owner --clean --blobs --no-acl --oid --no-tablespaces $DBNAME
|
297
358
|
|
298
359
|
cmd = VMC::KNIFE.pg_connect_cmd(credentials(app_name), 'pg_dump', false, "--format=p --file=#{file} --no-owner --clean --oids --blobs --no-acl --no-privileges --no-tablespaces")
|
299
360
|
puts cmd
|
300
361
|
puts `#{cmd}`
|
301
362
|
`chmod o-w #{file}`
|
363
|
+
elsif is_mongodb
|
364
|
+
if file.nil?
|
365
|
+
extension = @wrapped['director']['file_extension'] if @wrapped['director']
|
366
|
+
extension ||= "bson.tar.gz"
|
367
|
+
file = "#{name()}.#{extension}"
|
368
|
+
end
|
369
|
+
creds=credentials(app_name)
|
370
|
+
puts "Exports the database #{creds['name']} in #{file}"
|
371
|
+
#mongodump --host localhost:27017
|
372
|
+
mongodump_exec=VMC::KNIFE.get_mongo_exec('mongodump')
|
373
|
+
# see if we go through the filesystem or through the network:
|
374
|
+
base_dir=VMC::KNIFE.get_mongodb_base_dir()
|
375
|
+
instance_name=creds['name']
|
376
|
+
dbpath=File.join(base_dir, instance_name, 'data')
|
377
|
+
mongod_lock=File.join(dbpath,'mongo.lock')
|
378
|
+
if File.exists?(mongod_lock) && File.size(mongod_lock)>0
|
379
|
+
cmd = "#{mongodump_exec} -u #{credentials_hash['username']} -p #{credentials_hash['password']} --host #{credentials_hash['hostname']}:#{credentials_hash['port']}"
|
380
|
+
else
|
381
|
+
cmd = "#{mongodump_exec} --dbpath #{dbpath}"
|
382
|
+
end
|
383
|
+
puts cmd
|
384
|
+
puts `#{cmd}`
|
385
|
+
|
386
|
+
# this produces a dump folder in the working directory.
|
387
|
+
# let's zip it:
|
388
|
+
if /\.zip$/ =~ extension
|
389
|
+
# just zip
|
390
|
+
`zip -r #{file} dump/`
|
391
|
+
elsif /\.tar$/ =~ extension
|
392
|
+
# just tar
|
393
|
+
`tar cvf #{file} dump/`
|
394
|
+
else
|
395
|
+
# tar-gzip by default
|
396
|
+
`tar czvf #{file} dump/`
|
397
|
+
end
|
398
|
+
`rm -rf dump`
|
302
399
|
end
|
303
400
|
end
|
304
401
|
|
@@ -309,7 +406,11 @@ module VMC
|
|
309
406
|
def is_mongodb()
|
310
407
|
credentials()['db'] != nil
|
311
408
|
end
|
312
|
-
|
409
|
+
|
410
|
+
# Make sure that all users who can connect to the DB can also access
|
411
|
+
# the tables.
|
412
|
+
# This workarounds the privilege issue reported here:
|
413
|
+
#
|
313
414
|
def apply_privileges()
|
314
415
|
if is_postgresql()
|
315
416
|
cmd_acl="GRANT CREATE ON SCHEMA PUBLIC TO PUBLIC;\
|
@@ -320,6 +421,32 @@ module VMC
|
|
320
421
|
end
|
321
422
|
end
|
322
423
|
|
424
|
+
# shrink the size of the databses on the file system.
|
425
|
+
# Specifically act on the mongodb instances when they are stopped.
|
426
|
+
def shrink(collection_or_table_names=nil)
|
427
|
+
return unless is_mongodb
|
428
|
+
creds=credentials()
|
429
|
+
base_dir=VMC::KNIFE.get_mongodb_base_dir()
|
430
|
+
instance_name=creds['name']
|
431
|
+
dbpath=File.join(base_dir, instance_name, 'data')
|
432
|
+
mongod_lock=File.join(dbpath,'mongo.lock')
|
433
|
+
raise "Can't shrink #{name}; the mongodb is currently running" if File.exists?(mongod_lock) && File.size(mongod_lock)>0
|
434
|
+
mongodump_exec=VMC::KNIFE.get_mongo_exec('mongodump')
|
435
|
+
raise "Can't find mongodump" unless File.exist? mongodump_exec
|
436
|
+
mongorestore_exec=VMC::KNIFE.get_mongo_exec('mongorestore')
|
437
|
+
raise "Can't find mongorestore" unless File.exist? mongorestore_exec
|
438
|
+
cmd = "#{mongodump_exec} --dbpath #{dbpath}"
|
439
|
+
puts "#{cmd}"
|
440
|
+
puts `#{cmd}`
|
441
|
+
|
442
|
+
`rm -rf #{dbpath}`
|
443
|
+
`mkdir #{dbpath}`
|
444
|
+
cmd = "#{mongorestore_exec} --dbpath #{dbpath} dump/"
|
445
|
+
puts "#{cmd}"
|
446
|
+
puts `#{cmd}`
|
447
|
+
`rm -rf dump`
|
448
|
+
end
|
449
|
+
|
323
450
|
def drop(collection_or_table_names=nil)
|
324
451
|
if is_postgresql
|
325
452
|
sel_tables = "SELECT table_name FROM information_schema.tables WHERE table_schema='public'"
|
@@ -351,8 +478,35 @@ module VMC
|
|
351
478
|
puts cmd
|
352
479
|
puts `#{cmd}`
|
353
480
|
elsif is_mongodb
|
481
|
+
# generate the command file from the erb template.
|
482
|
+
filter = ".*"
|
483
|
+
filterIsNegated = "false";
|
484
|
+
skipSystem = "true";
|
485
|
+
if collection_or_table_names
|
486
|
+
if collection_or_table_names.start_with?('!')
|
487
|
+
filterIsNegated = "true";
|
488
|
+
filter = collection_or_table_names[1..-1]
|
489
|
+
else
|
490
|
+
filter = collection_or_table_names
|
491
|
+
end
|
492
|
+
end
|
493
|
+
# this command is applied to each collection.
|
494
|
+
# the name of the variable is 'collection' as can bee seen in the erb file.
|
495
|
+
cmd="collection.drop();"
|
496
|
+
|
497
|
+
file = Tempfile.new('dropcollections')
|
498
|
+
begin
|
499
|
+
File.open(file.path, 'w') do |f2|
|
500
|
+
template = ERB.new File.new("#{VMCKNIFE::ROOT_REL}/vmc_knife/mongo/mongo_cmd.js.erb").read, nil, "%"
|
501
|
+
f2.puts template.result(binding)
|
502
|
+
end
|
503
|
+
puts shell(file.path)
|
504
|
+
ensure
|
505
|
+
file.unlink # deletes the temp file
|
506
|
+
end
|
507
|
+
|
354
508
|
#TODO: iterate over the collections and drop them according to the filter.
|
355
|
-
raise "TODO: Unsupported operation 'drop' for the data-service #{name()}"
|
509
|
+
#raise "TODO: Unsupported operation 'drop' for the data-service #{name()}"
|
356
510
|
else
|
357
511
|
puts "Unsupported operation 'drop' for the data-service #{name()}"
|
358
512
|
end
|
@@ -10,7 +10,8 @@ module VMC
|
|
10
10
|
def self.ip_auto(interface='eth0')
|
11
11
|
res=`ifconfig | sed -n '/#{interface}/{n;p;}' | grep 'inet addr:' | grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}' | head -1`
|
12
12
|
if interface == 'eth0' && (res.nil? || res.strip.empty?)
|
13
|
-
res =
|
13
|
+
res = ip_auto "wlan0"
|
14
|
+
res = res[0] if res
|
14
15
|
if res.strip.empty?
|
15
16
|
#nevermind fetch the first IP you can find that is not 127.0.0.1
|
16
17
|
res=`ifconfig | grep 'inet addr:' | grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}' | head -1`
|
@@ -20,10 +21,10 @@ module VMC
|
|
20
21
|
unless res.empty?
|
21
22
|
# gets the Mask
|
22
23
|
line=`ifconfig | grep 'inet addr:#{res}' | awk '{ print $1}' | head -1`
|
23
|
-
puts "parsing ip and mask in line #{line}"
|
24
|
+
# puts "parsing ip and mask in line #{line}"
|
24
25
|
mask=`ifconfig | grep 'inet addr:#{res}' | grep -v '127.0.0.1' | cut -d: -f4 | awk '{ print $1}' | head -1`
|
25
26
|
mask.strip!
|
26
|
-
puts "got ip #{res} and mask #{mask}"
|
27
|
+
# puts "got ip #{res} and mask #{mask}"
|
27
28
|
return [ res, mask ]
|
28
29
|
end
|
29
30
|
end
|
@@ -50,16 +51,16 @@ module VMC
|
|
50
51
|
# Makes up to 10 passes evaluating ruby in the values that contain #{}.
|
51
52
|
def self.expand_json(file_path)
|
52
53
|
raise "The file #{file_path} does not exist" unless File.exists? file_path
|
53
|
-
data =
|
54
|
+
data = File.open(file_path, "r") do |infile| JSON.parse infile.read end
|
54
55
|
#puts "got data #{data.to_json}"
|
55
56
|
passes = 0
|
56
|
-
while passes <
|
57
|
+
while passes < 150
|
57
58
|
#puts "pass #{passes}"
|
58
59
|
break unless expand_data(data,data)
|
59
60
|
passes += 1
|
60
61
|
end
|
61
|
-
puts data.to_json unless passes <
|
62
|
-
raise "More than 100 passes evaluating the ruby template in the json file" unless passes < 100
|
62
|
+
puts data.to_json unless passes < 150
|
63
|
+
raise "More than 100 passes evaluating the ruby template in the json file current state #{JSON.pretty_generate data}" unless passes < 100
|
63
64
|
#puts "got data #{data.to_json}"
|
64
65
|
|
65
66
|
data
|
@@ -90,22 +91,52 @@ module VMC
|
|
90
91
|
end
|
91
92
|
elsif current.kind_of? Array
|
92
93
|
index = 0
|
94
|
+
current_evalled = Array.new
|
95
|
+
do_flatten=false
|
93
96
|
current.each do | v |
|
94
97
|
if v.kind_of? String
|
95
98
|
if /\#{.+}/ =~ v
|
96
99
|
at_least_one_eval = true
|
97
100
|
begin
|
98
|
-
|
99
|
-
|
101
|
+
evalled_ret = eval_v(v,data,current)
|
102
|
+
if evalled_ret.kind_of? Array
|
103
|
+
# we choose to support our use cases to flatten the arrays.
|
104
|
+
# never mind the lists of list for now.
|
105
|
+
do_flatten = true
|
106
|
+
evalled_ret.each do |nitem|
|
107
|
+
current_evalled[index] = nitem
|
108
|
+
index+=1
|
109
|
+
end
|
110
|
+
elsif evalled_ret.nil? # skip the nil for the next pass
|
111
|
+
current_evalled[index] = v
|
112
|
+
else
|
113
|
+
current_evalled[index] = evalled_ret
|
114
|
+
end
|
100
115
|
rescue => e
|
101
|
-
raise "Error thrown evaluating #{v}: #{e.inspect}"
|
116
|
+
raise "Error thrown evaluating #{v}; current state #{JSON.pretty_generate data}: #{e.inspect}"
|
102
117
|
end
|
118
|
+
else
|
119
|
+
current_evalled[index] = v
|
103
120
|
end
|
104
|
-
else
|
105
|
-
at_least_one_eval ||= expand_data(data,v)
|
121
|
+
# else
|
122
|
+
# at_least_one_eval ||= expand_data(data,v)
|
106
123
|
end
|
107
124
|
index+=1
|
108
125
|
end
|
126
|
+
|
127
|
+
# we don't support list of lists if there is a doubt when running the eval.
|
128
|
+
if at_least_one_eval
|
129
|
+
current_evalled.flatten! if do_flatten
|
130
|
+
current.clear
|
131
|
+
current.concat current_evalled
|
132
|
+
end
|
133
|
+
|
134
|
+
current.each do | v |
|
135
|
+
unless v.kind_of? String
|
136
|
+
at_least_one_eval ||= expand_data(data,v)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
109
140
|
end
|
110
141
|
at_least_one_eval
|
111
142
|
end
|
@@ -113,16 +144,26 @@ module VMC
|
|
113
144
|
# internal eval a reference.
|
114
145
|
# the reference is always wrapped in a json string.
|
115
146
|
# however if it is purely a ruby script ("#{ruby here}" ) we unwrap it
|
116
|
-
|
117
|
-
def self.eval_v(v,data,current)
|
118
|
-
#puts "evalling #{v}"
|
147
|
+
def self.eval_v(v,data,current,recurse=0)
|
119
148
|
if /^\#{([^}]*)}$/ =~ v
|
120
149
|
val = $1
|
121
150
|
else
|
122
151
|
val = '"'+v+'"'
|
123
152
|
end
|
124
|
-
|
125
|
-
|
153
|
+
module_eval <<-"END"
|
154
|
+
def self.eval_block_from_template(this,current)
|
155
|
+
#{val}
|
156
|
+
end
|
157
|
+
END
|
158
|
+
evalled = eval_block_from_template(data,current)
|
159
|
+
return nil if evalled.nil?
|
160
|
+
if evalled.kind_of?(String) && /\#{([^}]*)}/ =~ evalled
|
161
|
+
if recurse < 20
|
162
|
+
evalled = eval_v(evalled,data,current,recurse+1)
|
163
|
+
else
|
164
|
+
return nil
|
165
|
+
end
|
166
|
+
end
|
126
167
|
evalled
|
127
168
|
end
|
128
169
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
// Applies a command to all collections that name matches a particular filter
|
2
|
+
var skipSystem = <%= skipSystem %>;
|
3
|
+
var filter = /<%= filter %>/;
|
4
|
+
var filterIsNegated = <%= filterIsNegated %>;
|
5
|
+
var collectionNames = db.getCollectionNames();
|
6
|
+
for (var i = 0; i < collectionNames.length; i++ ) {
|
7
|
+
var name = collectionNames[i];
|
8
|
+
if (!(/^system/).test(name) || !skipSystem) {
|
9
|
+
var collection = null;
|
10
|
+
if (filter.test(name)) {
|
11
|
+
if (!filterIsNegated) {
|
12
|
+
collection=db.getCollection(name);
|
13
|
+
}
|
14
|
+
} else {
|
15
|
+
if (filterIsNegated) {
|
16
|
+
collection=db.getCollection(name);
|
17
|
+
}
|
18
|
+
}
|
19
|
+
if (collection) {
|
20
|
+
print("Applying to " + collection.getName());
|
21
|
+
<%= cmd %>
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
data/lib/vmc_knife/vmc_knife.rb
CHANGED
@@ -23,9 +23,6 @@ module VMC
|
|
23
23
|
def sub_domain()
|
24
24
|
@wrapped['sub_domain']
|
25
25
|
end
|
26
|
-
def target()
|
27
|
-
@wrapped['target']
|
28
|
-
end
|
29
26
|
def user()
|
30
27
|
@wrapped['user']
|
31
28
|
end
|
@@ -211,8 +208,10 @@ module VMC
|
|
211
208
|
@applications = @applications + recipe.applications(application_sel)
|
212
209
|
@data_services = @data_services + recipe.data_services(service_sel)
|
213
210
|
end
|
214
|
-
app_names = @applications.collect {|app| app.name }
|
215
|
-
service_names = @data_services.collect {|service| service.name }
|
211
|
+
app_names = @applications.collect {|app| app.name } unless @opts && @opts[:data_only]
|
212
|
+
service_names = @data_services.collect {|service| service.name } unless @opts && @opts[:apps_only]
|
213
|
+
app_names ||= Array.new
|
214
|
+
service_names ||= Array.new
|
216
215
|
if app_names.empty? && service_names.empty?
|
217
216
|
puts "No applications and data-services were selected."
|
218
217
|
else
|
@@ -431,10 +430,12 @@ module VMC
|
|
431
430
|
return unless @application_json['repository']
|
432
431
|
url = @application_json['repository']['url']
|
433
432
|
Dir.chdir(ENV['HOME']) do
|
434
|
-
|
435
|
-
|
433
|
+
tmp_download_filename="_download_.zip"
|
434
|
+
app_download_dir="vmc_knife_downloads/#{@application_json['name']}"
|
435
|
+
`rm -rf #{app_download_dir}` if File.exist? "#{app_download_dir}/#{tmp_download_filename}"
|
436
|
+
FileUtils.mkdir_p app_download_dir
|
437
|
+
Dir.chdir(app_download_dir) do
|
436
438
|
if Dir.entries(Dir.pwd).size == 2
|
437
|
-
puts "Dir.entries(#{Dir.pwd}).size #{Dir.entries(Dir.pwd).size}"
|
438
439
|
#empty directory.
|
439
440
|
if /\.git$/ =~ url
|
440
441
|
`git clone #{url} --depth 1`
|
@@ -442,28 +443,31 @@ module VMC
|
|
442
443
|
if branch
|
443
444
|
`git checkout #{branch}`
|
444
445
|
else
|
445
|
-
branch=master
|
446
|
+
branch='master'
|
446
447
|
end
|
447
448
|
`git pull origin #{branch}`
|
448
449
|
else
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
450
|
+
begin
|
451
|
+
wget_args = @application_json['repository']['wget_args']
|
452
|
+
if wget_args.nil?
|
453
|
+
wget_args_str = ""
|
454
|
+
elsif wget_args.kind_of? Array
|
455
|
+
wget_args_str = wget_args.join(' ')
|
456
|
+
elsif wget_args.kind_of? String
|
457
|
+
wget_args_str = wget_args
|
458
|
+
end
|
459
|
+
`wget #{wget_args_str} --output-document=#{tmp_download_filename} #{url}`
|
460
|
+
raise "Unable to download #{url}" unless $? == 0
|
461
|
+
if /\.tgz$/ =~ url || /\.tar\.gz$/ =~ url
|
462
|
+
`tar zxvf #{tmp_download_filename}`
|
463
|
+
elsif /\.tar$/ =~ url
|
464
|
+
`tar xvf #{tmp_download_filename}`
|
465
|
+
else
|
466
|
+
`unzip #{tmp_download_filename}`
|
467
|
+
end
|
468
|
+
ensure
|
469
|
+
`rm #{tmp_download_filename}`
|
465
470
|
end
|
466
|
-
`rm _download_.zip`
|
467
471
|
end
|
468
472
|
end
|
469
473
|
Dir.chdir(@application_json['repository']['sub_dir']) if @application_json['repository']['sub_dir']
|
@@ -531,23 +535,30 @@ module VMC
|
|
531
535
|
end
|
532
536
|
|
533
537
|
def update_name_pending()
|
534
|
-
|
538
|
+
curr_name=current[:name] || current['name']
|
539
|
+
if curr_name.nil?
|
535
540
|
return "Create #{@application_json['name']}"
|
536
541
|
end
|
537
|
-
if @application_json['name'] !=
|
538
|
-
return "#{
|
542
|
+
if @application_json['name'] != curr_name
|
543
|
+
return "#{curr_name} => #{@application_json['name']}"
|
539
544
|
end
|
540
545
|
end
|
541
546
|
def update_memory_pending()
|
542
|
-
old_mem = current[:resources][:memory]
|
547
|
+
old_mem = current[:resources][:memory] if current[:resources]
|
548
|
+
old_mem ||= current['resources']['memory'] if current['resources']
|
543
549
|
new_mem = @application_json['resources']['memory'] unless @application_json['resources'].nil?
|
544
550
|
if old_mem != new_mem
|
545
551
|
return "#{old_mem} => #{new_mem}"
|
546
552
|
end
|
547
553
|
end
|
548
554
|
def update_staging_pending()
|
549
|
-
|
550
|
-
|
555
|
+
if current[:staging] # sym style: real vmc.
|
556
|
+
old_model = current[:staging][:model]
|
557
|
+
old_stack = current[:staging][:stack]
|
558
|
+
elsif current['staging'] # string style: testing.
|
559
|
+
old_model = current['staging']['model']
|
560
|
+
old_stack = current['staging']['stack']
|
561
|
+
end
|
551
562
|
new_model = @application_json['staging']['model'] unless @application_json['staging'].nil?
|
552
563
|
new_stack = @application_json['staging']['stack'] unless @application_json['staging'].nil?
|
553
564
|
if old_model != new_model
|
@@ -562,17 +573,17 @@ module VMC
|
|
562
573
|
return { "stack" => stack_change, "model" => model_change }
|
563
574
|
end
|
564
575
|
def update_services_pending()
|
565
|
-
old_services = current[:services]
|
576
|
+
old_services = current[:services] || current['services']
|
566
577
|
new_services = @application_json['services']
|
567
578
|
diff_lists(old_services,new_services)
|
568
579
|
end
|
569
580
|
def update_env_pending()
|
570
|
-
old_services = current[:env]
|
581
|
+
old_services = current[:env] || current['env']
|
571
582
|
new_services = @application_json['env']
|
572
583
|
diff_lists(old_services,new_services)
|
573
584
|
end
|
574
585
|
def update_uris_pending()
|
575
|
-
old_services = current[:uris]
|
586
|
+
old_services = current[:uris] || current['uris']
|
576
587
|
new_services = @application_json['uris']
|
577
588
|
diff_lists(old_services,new_services)
|
578
589
|
end
|
@@ -729,6 +740,7 @@ module VMC
|
|
729
740
|
end
|
730
741
|
|
731
742
|
# This is really a server-side feature.
|
743
|
+
# This is deprecated; use the dns_publisher vcap module instead.
|
732
744
|
# Regenerates the urls to publish as aliases.
|
733
745
|
# use vmc apps to read the uris of each app and also the manifest.
|
734
746
|
class VCAPUpdateAvahiAliases
|
@@ -789,14 +801,18 @@ module VMC
|
|
789
801
|
end
|
790
802
|
def execute()
|
791
803
|
return unless update_pending()
|
792
|
-
|
793
|
-
|
794
|
-
|
804
|
+
# if the dns_publisher module is present let's not do this one.
|
805
|
+
# the dns_publisher does a better job at mdns
|
806
|
+
unless File.exist? "#{ENV['CLOUD_FOUNDRY_CONFIG_PATH']}/dns_publisher.yml"
|
807
|
+
File.open(@config, "w") do |file|
|
808
|
+
all_uris().each do |uri|
|
809
|
+
file.puts uri + "\n"
|
810
|
+
end
|
795
811
|
end
|
812
|
+
#configured so that we don't need root privileges on /etc/avahi/aliases:
|
813
|
+
#the backticks don't work; system() works:
|
814
|
+
system('avahi-publish-aliases') if @do_exec
|
796
815
|
end
|
797
|
-
#configured so that we don't need root privileges on /etc/avahi/aliases:
|
798
|
-
#the backticks don't work; system() works:
|
799
|
-
system('avahi-publish-aliases') if @do_exec
|
800
816
|
end
|
801
817
|
def update_pending()
|
802
818
|
already = already_published_uris()
|
data/lib/vmc_knife.rb
CHANGED
@@ -1,23 +1,23 @@
|
|
1
|
-
module VMCKNIFE
|
2
|
-
|
3
|
-
|
4
|
-
require "#{ROOT_REL}/restclient/restclient_add_timeout.rb"
|
1
|
+
module VMCKNIFE
|
2
|
+
ROOT_REL = File.expand_path(File.dirname(__FILE__))
|
3
|
+
end
|
4
|
+
require "#{VMCKNIFE::ROOT_REL}/restclient/restclient_add_timeout.rb"
|
5
5
|
|
6
6
|
|
7
7
|
module VMC
|
8
8
|
module Cli
|
9
9
|
module Command
|
10
|
-
autoload :Knife, "#{ROOT_REL}/vmc_knife/commands/knife_cmds"
|
11
|
-
autoload :Knifeapps, "#{ROOT_REL}/vmc_knife/commands/knife_cmds"
|
12
|
-
autoload :Knifemisc, "#{ROOT_REL}/vmc_knife/commands/knife_cmds"
|
10
|
+
autoload :Knife, "#{VMCKNIFE::ROOT_REL}/vmc_knife/commands/knife_cmds"
|
11
|
+
autoload :Knifeapps, "#{VMCKNIFE::ROOT_REL}/vmc_knife/commands/knife_cmds"
|
12
|
+
autoload :Knifemisc, "#{VMCKNIFE::ROOT_REL}/vmc_knife/commands/knife_cmds"
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
|
18
|
-
require "#{ROOT_REL}/vmc_knife/json_expander"
|
19
|
-
require "#{ROOT_REL}/vmc_knife/vmc_helper"
|
20
|
-
require "#{ROOT_REL}/vmc_knife/vmc_knife"
|
21
|
-
require "#{ROOT_REL}/vmc_knife/data_services"
|
18
|
+
require "#{VMCKNIFE::ROOT_REL}/vmc_knife/json_expander"
|
19
|
+
require "#{VMCKNIFE::ROOT_REL}/vmc_knife/vmc_helper"
|
20
|
+
require "#{VMCKNIFE::ROOT_REL}/vmc_knife/vmc_knife"
|
21
|
+
require "#{VMCKNIFE::ROOT_REL}/vmc_knife/data_services"
|
22
22
|
|
23
|
-
require "#{ROOT_REL}/vmc_knife/cli_extensions"
|
23
|
+
require "#{VMCKNIFE::ROOT_REL}/vmc_knife/cli_extensions"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vmc_knife
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 13
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 9
|
10
|
+
version: 0.0.9
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Intalio Pte
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2012-01-11 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: vmc
|
@@ -108,6 +108,7 @@ files:
|
|
108
108
|
- lib/vmc_knife/commands/knife_cmds.rb
|
109
109
|
- lib/vmc_knife/data_services.rb
|
110
110
|
- lib/vmc_knife/json_expander.rb
|
111
|
+
- lib/vmc_knife/mongo/mongo_cmd.js.erb
|
111
112
|
- lib/vmc_knife/version.rb
|
112
113
|
- lib/vmc_knife/vmc_helper.rb
|
113
114
|
- lib/vmc_knife/vmc_knife.rb
|