vmc_knife 0.0.8 → 0.0.9
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.
- 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
|