workEnv 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +620 -0
- data/bin/wenv +10 -0
- data/lib/WorkEnvs/Action.rb +604 -0
- data/lib/WorkEnvs/Common/Arch.rb +185 -0
- data/lib/WorkEnvs/Common/Config.rb +364 -0
- data/lib/WorkEnvs/Common/Confirm.rb +80 -0
- data/lib/WorkEnvs/Common/DBInterface.rb +608 -0
- data/lib/WorkEnvs/Common/Defines.rb +20 -0
- data/lib/WorkEnvs/Common/Dependencies.rb +206 -0
- data/lib/WorkEnvs/Common/EnvOpts.rb +129 -0
- data/lib/WorkEnvs/Common/Package.rb +116 -0
- data/lib/WorkEnvs/Common/PackageDownloader.rb +760 -0
- data/lib/WorkEnvs/Common/VersionSelector.rb +278 -0
- data/lib/WorkEnvs/Common.rb +10 -0
- data/lib/WorkEnvs/Core.rb +1004 -0
- data/lib/WorkEnvs/Envs/Any.rb +49 -0
- data/lib/WorkEnvs/Envs/Basic.rb +204 -0
- data/lib/WorkEnvs/accessors.rb +147 -0
- data/lib/WorkEnvs/global.rb +749 -0
- data/lib/WorkEnvs.rb +75 -0
- data/workrc-completion.sh +284 -0
- metadata +65 -0
|
@@ -0,0 +1,1004 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
require 'yaml'
|
|
3
|
+
require 'pathname'
|
|
4
|
+
require 'thread'
|
|
5
|
+
require 'base64'
|
|
6
|
+
# User overridable defines
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
module WorkEnvs
|
|
10
|
+
# User login
|
|
11
|
+
USERNAME=`whoami`.chomp()
|
|
12
|
+
|
|
13
|
+
# Defautl directory to put envs to
|
|
14
|
+
WORK_ENVS=(ENV["WORK_ENVS"] != nil && ENV["WORK_ENVS"] != "") ?
|
|
15
|
+
ENV["WORK_ENVS"] : "/work1/#{USERNAME}/work-envs"
|
|
16
|
+
|
|
17
|
+
# Name of environment config file (YAML serialized) within the environment directory
|
|
18
|
+
ENV_CONF=".env_config"
|
|
19
|
+
|
|
20
|
+
# Name of the script to switch into an end
|
|
21
|
+
ENV_SWITCH=".switch_env"
|
|
22
|
+
|
|
23
|
+
# Default expiration date for licenses
|
|
24
|
+
DEFAULT_EXPIRATION_DATE="12/31/2025"
|
|
25
|
+
|
|
26
|
+
# Version of the #Core and #WorkEnv object used for migration
|
|
27
|
+
WORK_ENV_VERSION = 10
|
|
28
|
+
|
|
29
|
+
# Core Env class
|
|
30
|
+
# This is not actually an env but all the methods Env needs to inherit through the WorkEnv class
|
|
31
|
+
# that provide global services accross the env graph
|
|
32
|
+
class Core
|
|
33
|
+
#
|
|
34
|
+
# WEIRD Methods. Object methods used to provide easy access to class methods all the way down
|
|
35
|
+
#
|
|
36
|
+
|
|
37
|
+
# Calls getVersion for all the nodes in the env graph
|
|
38
|
+
#
|
|
39
|
+
# Returns a hash containing each env version
|
|
40
|
+
def getVersion(canFail = false)
|
|
41
|
+
versions = {}
|
|
42
|
+
path = self.genPath()
|
|
43
|
+
WorkEnvs::familyTreeApply(self) {|x|
|
|
44
|
+
envType = WorkEnvs::getEnvType(x)
|
|
45
|
+
begin
|
|
46
|
+
if !@deps_infos.exists?(envType) then
|
|
47
|
+
next
|
|
48
|
+
end
|
|
49
|
+
versions.merge!(x.getVersion(path, canFail)){|key, v1, v2|
|
|
50
|
+
raise("Incoherency for version of #{key}. Have both #{v1} and #{v2}")
|
|
51
|
+
}
|
|
52
|
+
rescue => e
|
|
53
|
+
versions[envType] = :unitialized
|
|
54
|
+
raise e if @setup_options[WENV_OPTS_PARTIAL] != "true"
|
|
55
|
+
end
|
|
56
|
+
}
|
|
57
|
+
return versions
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Calls checkEnv for all the nodes in the env graph that are installed.
|
|
61
|
+
#
|
|
62
|
+
# The goal is to make sure the checkouted files use the expected version
|
|
63
|
+
#
|
|
64
|
+
# Returns if environment valid (if dev or Partial, always valid).
|
|
65
|
+
# Raises an exception if it is not
|
|
66
|
+
def checkEnv(versions = nil)
|
|
67
|
+
#Disable for the moment as this never reported any issues
|
|
68
|
+
return true
|
|
69
|
+
|
|
70
|
+
# return if isDev?()
|
|
71
|
+
# path = self.genPath()
|
|
72
|
+
# WorkEnvs::familyTreeApply(self) {|x|
|
|
73
|
+
# next if versions[WorkEnvs::getEnvType(x)] == nil
|
|
74
|
+
# begin
|
|
75
|
+
# x.checkEnv(self, path,versions)
|
|
76
|
+
# rescue => e
|
|
77
|
+
# raise e if @setup_options[WENV_OPTS_PARTIAL] != "true"
|
|
78
|
+
# end
|
|
79
|
+
# }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
#Check that all packages in the DB with this SHA1 are known by workEnvs
|
|
84
|
+
def checkPackages(downloader, revision, objClass)
|
|
85
|
+
allPackages = WorkEnvs::listAllPackagesWithSiblings(objClass)
|
|
86
|
+
availPackages = downloader.queryMatchingSHA1(revision)
|
|
87
|
+
unknownPackages = availPackages - allPackages
|
|
88
|
+
if unknownPackages.length != 0 then
|
|
89
|
+
STDERR.puts "ERROR: #{objClass} -> Found packages registered with SHA1 #{revision} in the DB but not in WorkEnvs."+
|
|
90
|
+
" Try to update WorkEnvs by running:\n#{WORK_ENV_SCRIPTS_DIR}/wenv --update\n"+
|
|
91
|
+
"If the problem subsists, someone added a new package in the DB but did not register it in the WorkEnvs\n"+
|
|
92
|
+
"Find him and slap him repeatedly with a trout until he fixes it....\n"+
|
|
93
|
+
"Unknown packages are:"
|
|
94
|
+
unknownPackages.each(){|p|
|
|
95
|
+
package = downloader.queryPackage(p, revision, true)
|
|
96
|
+
STDERR.puts"\t#{p} => #{package.pack}"
|
|
97
|
+
}
|
|
98
|
+
exit(1) if ENV["WENV_IGNORE_ERRORS"] == nil
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Analyze the packages from a sub env and look for dependy to other sub envs
|
|
103
|
+
#
|
|
104
|
+
# - classDeps is a list of the sub env class depency description
|
|
105
|
+
# - familyTree is a list of all sub env class that are parents to self
|
|
106
|
+
# - packages is a list of all the available packages provided by this sub env class
|
|
107
|
+
# for this version
|
|
108
|
+
# - info is the Depencies object used during dependcy computation
|
|
109
|
+
#
|
|
110
|
+
# Used only by genPath
|
|
111
|
+
#
|
|
112
|
+
# Throws EmptyQueryException if a dependency to a parent sub class could not be fulfilled
|
|
113
|
+
# or mismatch and existing one.
|
|
114
|
+
def lookupDependencies(downloader, classDeps, familyTree, packages, infos)
|
|
115
|
+
packages.each(){|pack|
|
|
116
|
+
# Match all packages against regexps
|
|
117
|
+
dependencies = nil
|
|
118
|
+
classDeps.each(){|regexp, deps|
|
|
119
|
+
if pack.to_s =~ regexp then
|
|
120
|
+
#Generate dependencies
|
|
121
|
+
dependencies = downloader.listDependencies(pack) if dependencies == nil
|
|
122
|
+
deps.each(){|depTypes, depList|
|
|
123
|
+
depTypes = [ depTypes ] if ! depTypes.kind_of? Array
|
|
124
|
+
depClasses = depTypes.map(){|depType| WorkEnvs::symbolToClass(depType)}
|
|
125
|
+
# There may only be one element not as an array so self wrap it
|
|
126
|
+
if(depList.kind_of? String) then
|
|
127
|
+
depList = [ depList ]
|
|
128
|
+
end
|
|
129
|
+
depList.each(){|dep_name|
|
|
130
|
+
dep_ver = downloader.extractDependency(dependencies, dep_name)
|
|
131
|
+
next if dep_ver == nil
|
|
132
|
+
success = false
|
|
133
|
+
depClasses.each(){|depClass|
|
|
134
|
+
if familyTree.index(depClass) == nil then
|
|
135
|
+
STDERR.puts "DEV WARNING: Found requested dependency from #{pack} to"+
|
|
136
|
+
" #{dep_name} (#{depClass}) (#{dep_ver}) " +
|
|
137
|
+
"but environment #{depClass} is not a valid ancestor"
|
|
138
|
+
end
|
|
139
|
+
begin
|
|
140
|
+
infos.push_version(depClass, dep_ver)
|
|
141
|
+
success = true
|
|
142
|
+
rescue EmptyQueryException
|
|
143
|
+
end
|
|
144
|
+
}
|
|
145
|
+
if success == false then
|
|
146
|
+
STDERR.puts "WARNING: Package #{pack} has dependencies to any of those "+
|
|
147
|
+
"env (#{depClasses}), but no matching packages were found"
|
|
148
|
+
end
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
end
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
end
|
|
155
|
+
private :lookupDependencies
|
|
156
|
+
|
|
157
|
+
# Generate a list of all the packages (including temporary) that should
|
|
158
|
+
# be downloaded and extracted in the env.
|
|
159
|
+
#
|
|
160
|
+
# This looks at the dependencies both in the options (--sha1, --version, --rev-files, etc)
|
|
161
|
+
# and the dependencies from the packages while adding them to the list.
|
|
162
|
+
#
|
|
163
|
+
# It will iterate on all the env dependency tree (except if opts[:no_deps] is true)
|
|
164
|
+
# to generate a complete list.
|
|
165
|
+
#
|
|
166
|
+
# It returns two arrays:
|
|
167
|
+
# - an array of Package object containg all the permanent packages
|
|
168
|
+
# - an array of temporary Package object that might be needed furing the post_setup phase
|
|
169
|
+
def genPackages(downloader, opts)
|
|
170
|
+
packages = []
|
|
171
|
+
temp_packages = []
|
|
172
|
+
infos = opts[:infos]
|
|
173
|
+
|
|
174
|
+
settings = WorkEnvs::settings()
|
|
175
|
+
|
|
176
|
+
#In case of RPC chaining, check the previous one to make sure we won't loop
|
|
177
|
+
prev_rpc_host=""
|
|
178
|
+
begin
|
|
179
|
+
prev_rpc_host = opts[:settings][:control][:rSettings][:settings][:db][:rpc_host]
|
|
180
|
+
rescue => e
|
|
181
|
+
# Ignore errors
|
|
182
|
+
end
|
|
183
|
+
# Try to do it remotely but do not recurse infinitely
|
|
184
|
+
if settings[:db][:rpc_host] != nil && prev_rpc_host != settings[:db][:rpc_host] then
|
|
185
|
+
msgs = nil
|
|
186
|
+
host = settings[:db][:rpc_host]
|
|
187
|
+
begin
|
|
188
|
+
rOpts={}
|
|
189
|
+
rOpts[:settings] = WorkEnvs::settings()
|
|
190
|
+
rOpts[:opts] = opts
|
|
191
|
+
|
|
192
|
+
# Force type when used with wenv update
|
|
193
|
+
# Wenv query has already set this but it's
|
|
194
|
+
# the same value as @type
|
|
195
|
+
rOpts[:opts][:type] = @type
|
|
196
|
+
objs, msgs = WorkEnvs::remoteRun(host, "query",
|
|
197
|
+
' -R "' + WorkEnvs::serialize(rOpts) + '"')
|
|
198
|
+
hash = objs[0]
|
|
199
|
+
packages = hash[:packages]
|
|
200
|
+
temp_packages = hash[:temp_packages]
|
|
201
|
+
puts "INFO: Computed dependencies remotely on #{host}"
|
|
202
|
+
puts msgs
|
|
203
|
+
return packages, temp_packages
|
|
204
|
+
rescue => e
|
|
205
|
+
#Fail, fall back to original mode
|
|
206
|
+
puts "INFO: Fail to resolve depencies remotely. Running locally (#{e.to_s})"
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
familyTree = WorkEnvs::familyTreeList(self)
|
|
211
|
+
|
|
212
|
+
packageRef={}
|
|
213
|
+
|
|
214
|
+
WorkEnvs::familyTreeApply(self, false){|x|
|
|
215
|
+
envType = WorkEnvs::getEnvType(x)
|
|
216
|
+
packName = WorkEnvs::getMainPackage(x)
|
|
217
|
+
|
|
218
|
+
# We hit rock bottom or empty env
|
|
219
|
+
next if packName == ""
|
|
220
|
+
|
|
221
|
+
# If we allow partial env and have no deps on this package, just skip it
|
|
222
|
+
next if infos.partialEnv == true && !infos.exists?(envType)
|
|
223
|
+
# Find the revision from the dep
|
|
224
|
+
if infos.exists?(envType) then
|
|
225
|
+
revision = infos.get_sha1(envType)
|
|
226
|
+
if revision !~ /^[a-f0-9]{40}$/ then
|
|
227
|
+
raise("Invalid #{WorkEnvs::getMainPackage(x)} version '#{infos.get(envType)}'")
|
|
228
|
+
end
|
|
229
|
+
else
|
|
230
|
+
if opts[:shutUp] != true && !x.isDev?() && opts[:no_deps] != true then
|
|
231
|
+
puts "WARNING: Found no dependency to #{envType.to_s}. Skipping..."
|
|
232
|
+
end
|
|
233
|
+
next
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
classPackages = WorkEnvs::getPackages(x)
|
|
237
|
+
classDeps = WorkEnvs::getDependencies(x)
|
|
238
|
+
classDeps = {} if opts[:no_deps] == true
|
|
239
|
+
|
|
240
|
+
# First let us check that we know of every package registered with this SHA1 in the db
|
|
241
|
+
# This is just for sanity
|
|
242
|
+
checkPackages(downloader, revision, x)
|
|
243
|
+
|
|
244
|
+
WorkEnvs::dputs("Looking at #{envType} packages:")
|
|
245
|
+
isExternal = (opts[:envOpts] != nil && opts[:envOpts][WENV_OPTS_EXTERNAL].to_s == "true") ? true : false
|
|
246
|
+
# Get required external (and internal if enabled) list of packages
|
|
247
|
+
required = classPackages[:external][:required] + (isExternal ? [] : classPackages[:internal][:required])
|
|
248
|
+
# Get extra external (and internal if enabled) list of packages
|
|
249
|
+
# Extra means it's OK if not available
|
|
250
|
+
extras = classPackages[:external][:extras] + (isExternal ? [] : classPackages[:internal][:extras])
|
|
251
|
+
|
|
252
|
+
# Generate the list of truly available package and their full package name
|
|
253
|
+
# for both required and extras, and both permanent and temporary
|
|
254
|
+
local_packages = downloader.getPackagesName(required, extras, revision)
|
|
255
|
+
local_temp_packages = downloader.getPackagesName(classPackages[:temporary][:required],
|
|
256
|
+
classPackages[:temporary][:extras], revision)
|
|
257
|
+
|
|
258
|
+
all_packages = local_packages + local_temp_packages
|
|
259
|
+
if isExternal
|
|
260
|
+
# Still check the internal packages for dependencies
|
|
261
|
+
all_packages += downloader.getPackagesName(classPackages[:internal][:required],
|
|
262
|
+
classPackages[:internal][:extras], revision)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
if opts[:skipDeps] != true then
|
|
266
|
+
# Check in the package list we generated if there are RPM/Deb
|
|
267
|
+
# dependencies that matches env Class description.
|
|
268
|
+
# This is how dependencies are propagated when working only with package
|
|
269
|
+
# and without any rev_file/sub-sha1 options
|
|
270
|
+
lookupDependencies(downloader, classDeps, familyTree, all_packages, infos)
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
# Sanity checks to make sure there are never two sub envs that pull the same package
|
|
275
|
+
# in two different version
|
|
276
|
+
#
|
|
277
|
+
# packageRef basically store the full name of the packahe
|
|
278
|
+
# If another envs pull sthe exact same one it's OK
|
|
279
|
+
# If it pull the same packahe name but with a different full name (ie different version or
|
|
280
|
+
# due to a weird rebuild after tag changes), let it know and crash
|
|
281
|
+
(local_packages + local_temp_packages).each(){|pack|
|
|
282
|
+
if packageRef[pack.name] == nil then
|
|
283
|
+
packageRef[pack.name] = { :pack => pack.pack, :env => x }
|
|
284
|
+
next
|
|
285
|
+
end
|
|
286
|
+
extname = File.extname(pack.pack)
|
|
287
|
+
next if extname != ".deb" && extname != ".rpm"
|
|
288
|
+
if packageRef[pack.name][:pack] != pack.pack then
|
|
289
|
+
raise("Env pulls both #{packageRef[pack.name][:pack]} (#{packageRef[pack.name][:env]}) and "+
|
|
290
|
+
"#{pack.pack} (#{x}) which are not compatible")
|
|
291
|
+
end
|
|
292
|
+
}
|
|
293
|
+
packages += local_packages
|
|
294
|
+
temp_packages += local_temp_packages
|
|
295
|
+
|
|
296
|
+
}
|
|
297
|
+
packages.uniq!
|
|
298
|
+
temp_packages.uniq!
|
|
299
|
+
|
|
300
|
+
checkGitDeps(downloader, infos) if opts[:checkGitDependencies]
|
|
301
|
+
|
|
302
|
+
return packages, temp_packages
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# Checks that dependencies extracted from the packages math the Git dependencies.
|
|
306
|
+
def checkGitDeps(downloader, infos)
|
|
307
|
+
git_repo = WorkEnvs::settings[:db][:git_repo]
|
|
308
|
+
WorkEnvs::familyTreeApply(self){|x|
|
|
309
|
+
envClass = x
|
|
310
|
+
envType = WorkEnvs::getEnvType(x)
|
|
311
|
+
version = infos.get_version(envType)
|
|
312
|
+
next if version == nil
|
|
313
|
+
|
|
314
|
+
gitRepo = WorkEnvs::getGitRepo(x).to_s()
|
|
315
|
+
next if gitRepo == ""
|
|
316
|
+
|
|
317
|
+
parentList = WorkEnvs::familyTreeListClass(x)
|
|
318
|
+
|
|
319
|
+
dInfos = downloader.queryDepInfosFromVersion(x, version, true)
|
|
320
|
+
sha1 = dInfos[:sha1]
|
|
321
|
+
|
|
322
|
+
remoteRepo = gitRepo.gsub(/^.*:/, '')
|
|
323
|
+
revFiles = runCmd("ssh #{git_repo} ls-tree #{remoteRepo} #{sha1} -- valid/hudson/rev_files/", !VERBOSE)
|
|
324
|
+
revFiles.split("\n").each(){|revFileLine|
|
|
325
|
+
cols = revFileLine.split(" ")
|
|
326
|
+
revFile = File.basename(cols[3])
|
|
327
|
+
revClasses = WorkEnvs::revFileToClasses(revFile)
|
|
328
|
+
next if revClasses == nil
|
|
329
|
+
|
|
330
|
+
revClasses.each(){|revClass|
|
|
331
|
+
revType = WorkEnvs::getEnvType(revClass)
|
|
332
|
+
# Continue if this is not a parent env...
|
|
333
|
+
next if parentList.index(revClass) == nil
|
|
334
|
+
|
|
335
|
+
puts "Checking #{envType} => #{revType}"
|
|
336
|
+
objSha1 = cols[2]
|
|
337
|
+
revSha1 = runCmd("ssh #{git_repo} cat-file #{remoteRepo} -p #{objSha1}", !VERBOSE)
|
|
338
|
+
|
|
339
|
+
revPack = downloader.queryPackageVersion(WorkEnvs::getMainPackage(revClass), revSha1, false)
|
|
340
|
+
expected = infos.get_version(revType)
|
|
341
|
+
|
|
342
|
+
#Skip if everything is OK
|
|
343
|
+
next if expected == revPack && expected.to_s != ""
|
|
344
|
+
|
|
345
|
+
expected = "<N/A>" if expected.to_s == ""
|
|
346
|
+
revPack = "<???>" if revPack.to_s == ""
|
|
347
|
+
puts "WARNING: On #{envType} => #{revType}\n" +
|
|
348
|
+
"\tRPM requires: #{expected} / Rev files requires: #{revPack} (SHA1 = #{revSha1})"
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
# Generate the env specific part of the switch env script
|
|
355
|
+
#
|
|
356
|
+
# Iterates on all the env dependency tree and call the switchEnv method of each class.
|
|
357
|
+
#
|
|
358
|
+
# Note that switchEnv is not called for classes that have not been updated
|
|
359
|
+
# (no dependency to them even if in the dependency tree)
|
|
360
|
+
#
|
|
361
|
+
# Returns an array of commands to be written in the switchEnv script
|
|
362
|
+
def genSwitchEnv()
|
|
363
|
+
path = self.genPath()
|
|
364
|
+
commands=[]
|
|
365
|
+
WorkEnvs::familyTreeApply(self) {|x|
|
|
366
|
+
next if (@deps_infos == nil ||
|
|
367
|
+
!@deps_infos.exists?(WorkEnvs::getEnvType(x))) && !x.isDev?() && !self.isDev?()
|
|
368
|
+
begin
|
|
369
|
+
ret = x.switchEnv(self, "${WORK_ENV_PATH}")
|
|
370
|
+
commands = [ "##{x.to_s}" ] + ret + [ "" ] + commands
|
|
371
|
+
rescue => e
|
|
372
|
+
raise e if @setup_options[WENV_OPTS_PARTIAL] != "true"
|
|
373
|
+
end
|
|
374
|
+
}
|
|
375
|
+
return commands
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
# Default footer commands to output in the switch env script.
|
|
379
|
+
#
|
|
380
|
+
# - Autoload workEnv bash completion
|
|
381
|
+
# - Load global workEnv bashrc if it exists
|
|
382
|
+
# - Load env specific bashrc if it exists
|
|
383
|
+
# - Check Env coherency
|
|
384
|
+
def genEnvFooter()
|
|
385
|
+
array = []
|
|
386
|
+
array << "#Env Footer"
|
|
387
|
+
array << "[ -f ${WORK_ENV_SCRIPTS_DIR}/workrc-completion.sh ] && source ${WORK_ENV_SCRIPTS_DIR}/workrc-completion.sh"
|
|
388
|
+
array << "[ -f #{WORK_ENV_GLOBAL_DIR}/bashrcs/.bashrc ] && source #{WORK_ENV_GLOBAL_DIR}/bashrcs/.bashrc"
|
|
389
|
+
array << "[ -f #{WORK_ENV_GLOBAL_DIR}/bashrcs/${WORK_ENV_CURRENT} ] && source #{WORK_ENV_GLOBAL_DIR}/bashrcs/${WORK_ENV_CURRENT}"
|
|
390
|
+
array << "if [ -f $WORK_ENV_SCRIPTS_DIR/checkEnv ]; then ruby $WORK_ENV_SCRIPTS_DIR/checkEnv || exit 1; fi"
|
|
391
|
+
return array
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
# Top level function to generate a switchEnv script.
|
|
395
|
+
#
|
|
396
|
+
# Call #genSwitchEnv and #genEnvFooter then dumps the strings to the appropriate file
|
|
397
|
+
def genSwitchEnvScript()
|
|
398
|
+
cmds = genSwitchEnv() +
|
|
399
|
+
genEnvFooter()
|
|
400
|
+
output = File.open(self.genPath() + "/" + ENV_SWITCH, "w")
|
|
401
|
+
cmds.each(){|x|
|
|
402
|
+
output.puts x
|
|
403
|
+
}
|
|
404
|
+
output.close()
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
# Call the pre_setup method for each envClass
|
|
408
|
+
#
|
|
409
|
+
# Iterates on all the env dependency tree and calls the pre_setup method.
|
|
410
|
+
# Method is not called for dev env classes nor for uninitialized env classes
|
|
411
|
+
def pre_setup(opts, packages, temp_packages)
|
|
412
|
+
#Pre-setup in reverse order so we start from the trunk and install inherited env first
|
|
413
|
+
WorkEnvs::familyTreeApply(self, true){|x|
|
|
414
|
+
next if !@deps_infos.exists?(WorkEnvs::getEnvType(x)) && !x.isDev?()
|
|
415
|
+
next if x.singleton_methods().index(:pre_setup) == nil
|
|
416
|
+
x.pre_setup(opts, packages, temp_packages)
|
|
417
|
+
}
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
# Call the post_setup method for each envClass
|
|
421
|
+
#
|
|
422
|
+
# Iterates on all the env dependency tree and calls the post_setup method.
|
|
423
|
+
# Method is not called for dev env classes nor for uninitialized env classes
|
|
424
|
+
def post_setup(opts = {})
|
|
425
|
+
#Post setup in reverse order so we start from the trunk and install inherited env first
|
|
426
|
+
WorkEnvs::familyTreeApply(self, true){|x|
|
|
427
|
+
next if !@deps_infos.exists?(WorkEnvs::getEnvType(x)) && !x.isDev?()
|
|
428
|
+
next if x.singleton_methods().index(:post_setup) == nil
|
|
429
|
+
x.post_setup(opts)
|
|
430
|
+
}
|
|
431
|
+
genSwitchEnvScript()
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
# Call the pre_install method for each envClass
|
|
435
|
+
#
|
|
436
|
+
# Iterates on all the env dependency tree and calls the pre_install method.
|
|
437
|
+
# Method is not called for dev env classes nor for uninitialized env classes
|
|
438
|
+
def pre_install(opts, packages, temp_packages)
|
|
439
|
+
#Pre Install in reverse order so we start from the trunk and install inherited env first
|
|
440
|
+
WorkEnvs::familyTreeApply(self, true){|x|
|
|
441
|
+
next if !@deps_infos.exists?(WorkEnvs::getEnvType(x)) && !x.isDev?()
|
|
442
|
+
next if x.singleton_methods().index(:pre_install) == nil
|
|
443
|
+
x.pre_install(opts, packages, temp_packages)
|
|
444
|
+
}
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
# Call the post_install method for each envClass
|
|
448
|
+
#
|
|
449
|
+
# Iterates on all the env dependency tree and calls the post_install method.
|
|
450
|
+
# Method is not called for dev env classes nor for uninitialized env classes
|
|
451
|
+
def post_install(opts, packages, temp_packages)
|
|
452
|
+
#Post Install in reverse order so we start from the trunk and install inherited env first
|
|
453
|
+
WorkEnvs::familyTreeApply(self, true){|x|
|
|
454
|
+
next if !@deps_infos.exists?(WorkEnvs::getEnvType(x)) && !x.isDev?()
|
|
455
|
+
next if x.singleton_methods().index(:post_install) == nil
|
|
456
|
+
x.post_install(opts, packages, temp_packages)
|
|
457
|
+
}
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
#
|
|
461
|
+
# COMMON Methods. Same for all types of env.
|
|
462
|
+
#
|
|
463
|
+
|
|
464
|
+
# Return a if env has a dev type
|
|
465
|
+
#
|
|
466
|
+
# Dev env do not neet to be initialized to be switched to
|
|
467
|
+
def isDev?()
|
|
468
|
+
return self.class.isDev?()
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
# Rename an env
|
|
472
|
+
#
|
|
473
|
+
# Move the env directory and update the object name proprery
|
|
474
|
+
def rename(name)
|
|
475
|
+
raise("Cannot rename an environment with the same name...") if name == WorkEnvs::labelNameToStr(@label, @name)
|
|
476
|
+
raise("An environment named '#{name}' already exists") if WorkEnvs::existsEnv?(name)
|
|
477
|
+
label, name = WorkEnvs::strToLabelName(name)
|
|
478
|
+
runCmd("mv #{genPath()} "+
|
|
479
|
+
" #{WorkEnvs::getDirPathFromLabel(label)}/#{name}")
|
|
480
|
+
@name = name
|
|
481
|
+
@label = label
|
|
482
|
+
self.dump()
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
# Returns if the env can be switched to (env is initialized)
|
|
486
|
+
def isSwitchable?()
|
|
487
|
+
return true if @deps_infos != nil && @deps_infos.partialEnv == true
|
|
488
|
+
|
|
489
|
+
@versions.each() {|name, version|
|
|
490
|
+
if version == :uninitialized then
|
|
491
|
+
return false
|
|
492
|
+
end
|
|
493
|
+
}
|
|
494
|
+
return true
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
# Check that at least one version/SHA1 was required in the options
|
|
498
|
+
def check_version(opts = {})
|
|
499
|
+
downloader = get_downloader()
|
|
500
|
+
project = WorkEnvs::getMainPackage(self)
|
|
501
|
+
if opts[:version] != nil || opts[:sha1] != nil then
|
|
502
|
+
return downloader, opts[:infos].get_sha1(name)
|
|
503
|
+
elsif opts[:infos] != nil && !opts[:infos].empty?
|
|
504
|
+
return downloader, nil
|
|
505
|
+
else
|
|
506
|
+
raise("Neither version or SHA1 provided")
|
|
507
|
+
end
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
# Return a string with the patch to the environment directory
|
|
511
|
+
def genPath()
|
|
512
|
+
path = WorkEnvs::getDirPathFromLabel(@label) + "/" + @name
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
# Backup the environment config in its workspace
|
|
516
|
+
#
|
|
517
|
+
# This serializes the env as a YAML object into the environment directory
|
|
518
|
+
def dump()
|
|
519
|
+
|
|
520
|
+
raise("No path for environment") if @name.to_s() == ""
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
desc = File.open(genPath() + "/" + ENV_CONF, "w+")
|
|
524
|
+
|
|
525
|
+
label = @label
|
|
526
|
+
@label = nil
|
|
527
|
+
desc.puts self.to_yaml()
|
|
528
|
+
desc.close()
|
|
529
|
+
@label = label
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
# Returns a string that describe the env
|
|
533
|
+
#
|
|
534
|
+
# - lType == :name
|
|
535
|
+
# - name
|
|
536
|
+
# - lType == :short
|
|
537
|
+
# - name
|
|
538
|
+
# - type
|
|
539
|
+
# - machine
|
|
540
|
+
# - expiration
|
|
541
|
+
# - lType == :long
|
|
542
|
+
# - name
|
|
543
|
+
# - type
|
|
544
|
+
# - machine
|
|
545
|
+
# - expiration
|
|
546
|
+
# - versions info
|
|
547
|
+
# - setup options
|
|
548
|
+
def to_s(lType = :long)
|
|
549
|
+
lType = :long if lType == nil
|
|
550
|
+
case lType
|
|
551
|
+
when :short, :long
|
|
552
|
+
# Convert an environment to string so they can be printed
|
|
553
|
+
maxLen = WorkEnvs::getEnvNames().inject(0){|x, y| x > y.length ? x : y.length}
|
|
554
|
+
_versions = @versions
|
|
555
|
+
prefix=""
|
|
556
|
+
type = @type.to_s
|
|
557
|
+
name = WorkEnvs::labelNameToStr(@label, @name)
|
|
558
|
+
str = "* " +name.ljust(maxLen) + type.center(20) + @machine.to_s.center(15) + @expiration.to_s.center(15)
|
|
559
|
+
|
|
560
|
+
sub_shift = "".ljust(maxLen+20+15+15+5)
|
|
561
|
+
|
|
562
|
+
if lType == :long then
|
|
563
|
+
str+= "\t{"
|
|
564
|
+
_versions.each(){|key, val|
|
|
565
|
+
str += prefix +" :" + key.to_s + " => " + val.to_s + ""
|
|
566
|
+
prefix = "\n" + sub_shift + "\t "
|
|
567
|
+
}
|
|
568
|
+
str += " }"
|
|
569
|
+
if @setup_options != nil && @setup_options.empty? == false then
|
|
570
|
+
str+= "\n" + sub_shift + "\t{ "
|
|
571
|
+
comma = ""
|
|
572
|
+
@setup_options.each(){|name, val|
|
|
573
|
+
str += comma + name + "=" + val
|
|
574
|
+
comma = ", "
|
|
575
|
+
}
|
|
576
|
+
str += " }"
|
|
577
|
+
end
|
|
578
|
+
end
|
|
579
|
+
return str
|
|
580
|
+
when :name
|
|
581
|
+
str = WorkEnvs::labelNameToStr(@label, @name)
|
|
582
|
+
return str
|
|
583
|
+
else
|
|
584
|
+
raise("Unknown listing type #{lType}")
|
|
585
|
+
end
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
# List the latest top packages from the env type
|
|
589
|
+
#
|
|
590
|
+
# Query the latest limit packages defining this env (from the branch branch if non nil)
|
|
591
|
+
#
|
|
592
|
+
# Returns an array of EnvPackage
|
|
593
|
+
def getPackages(downloader, branch=nil, limit=100000)
|
|
594
|
+
branch='%' if branch.nil? || branch.length == 0
|
|
595
|
+
|
|
596
|
+
limit = 100000 if limit == 0
|
|
597
|
+
packages = downloader.queryPackages(WorkEnvs::getMainPackage(self), branch,
|
|
598
|
+
limit, WorkEnvs::getBlackList(self))
|
|
599
|
+
return packages
|
|
600
|
+
end
|
|
601
|
+
|
|
602
|
+
# Call getPackages and display the results on STDOUT
|
|
603
|
+
def listPackages(downloader, quantity, branch=nil)
|
|
604
|
+
puts "Getting package list..."
|
|
605
|
+
packages = getPackages(downloader, branch, quantity)
|
|
606
|
+
(packages.length - 1).downto(0){|x|
|
|
607
|
+
elnt = packages[x]
|
|
608
|
+
puts elnt
|
|
609
|
+
}
|
|
610
|
+
end
|
|
611
|
+
|
|
612
|
+
# Create a PackageDownloader with settings matching this env
|
|
613
|
+
def get_downloader(opts={})
|
|
614
|
+
machine = @machine
|
|
615
|
+
tables = @db_tables
|
|
616
|
+
begin
|
|
617
|
+
if opts[:settings][:arch][:machine] != nil then
|
|
618
|
+
arch = WorkEnvs::getArch(opts[:settings][:arch][:machine])
|
|
619
|
+
|
|
620
|
+
puts "INFO: Overriding environment arch with '#{arch[:label]}'" if machine != arch[:label]
|
|
621
|
+
machine = arch[:label]
|
|
622
|
+
end
|
|
623
|
+
rescue
|
|
624
|
+
# Probably no settings available
|
|
625
|
+
end
|
|
626
|
+
begin
|
|
627
|
+
if opts[:settings][:db][:package_default_table] != nil then
|
|
628
|
+
new_table = DBInterface::toTable(opts[:settings][:db][:package_default_table])
|
|
629
|
+
|
|
630
|
+
puts "INFO: Overriding environment table with '#{new_table}'" if tables != new_table
|
|
631
|
+
tables = new_table
|
|
632
|
+
end
|
|
633
|
+
rescue
|
|
634
|
+
# Probably no settings available
|
|
635
|
+
end
|
|
636
|
+
return WorkEnvs::PackageDownloader.new(machine, tables, !VERBOSE)
|
|
637
|
+
end
|
|
638
|
+
|
|
639
|
+
# Wrapper around genPackages
|
|
640
|
+
#
|
|
641
|
+
# Basically calls genPackages with a few extra checks.
|
|
642
|
+
#
|
|
643
|
+
# This is mostly use for get_dependencies or by queryEnv to generate raw object
|
|
644
|
+
# when using the RPC mode to solve dependencies
|
|
645
|
+
#
|
|
646
|
+
# Returns:
|
|
647
|
+
# - PackageDownloaded used to call genPackages
|
|
648
|
+
# - an array of permanent Package
|
|
649
|
+
# - an array of temporary Package
|
|
650
|
+
def get_dependencies_raw(opts={})
|
|
651
|
+
downloader, package_sha1 = check_version(opts)
|
|
652
|
+
|
|
653
|
+
# Check package server is up
|
|
654
|
+
downloader.checkRepo()
|
|
655
|
+
|
|
656
|
+
packages = []
|
|
657
|
+
temp_packages = []
|
|
658
|
+
packages, temp_packages = genPackages(downloader, opts)
|
|
659
|
+
|
|
660
|
+
packages.uniq!
|
|
661
|
+
temp_packages.uniq!
|
|
662
|
+
return downloader, packages, temp_packages
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
# Wrapper around get_dependencies_raw
|
|
666
|
+
#
|
|
667
|
+
# Calls get_dependencies_raw but convert the Package list to path to the packages
|
|
668
|
+
#
|
|
669
|
+
# Used by queryEnv to generate a list of URL to the package to download
|
|
670
|
+
# Returns:
|
|
671
|
+
# - PackageDownloaded used to call genPackages
|
|
672
|
+
# - an array of permanent package paths (String)
|
|
673
|
+
# - an array of temporary package paths (String)
|
|
674
|
+
def get_dependencies(opts = {})
|
|
675
|
+
downloader, packages, temp_packages = get_dependencies_raw(opts)
|
|
676
|
+
packages.each(){|p| downloader.getPackagePath(p)}
|
|
677
|
+
temp_packages.each(){|p| downloader.getPackagePath(p)}
|
|
678
|
+
return packages, temp_packages
|
|
679
|
+
end
|
|
680
|
+
|
|
681
|
+
# Download and extract the packages listed in packages AND temp_packages.
|
|
682
|
+
#
|
|
683
|
+
# temp_packages are extracted in a temporary dir.
|
|
684
|
+
# The dirpath will be stored in opts[:tempDir]
|
|
685
|
+
#
|
|
686
|
+
# The function returns an array of all the downloaded/extracted package that need to
|
|
687
|
+
# be install on the system. This is done by checking install package
|
|
688
|
+
# flags and DKMS options
|
|
689
|
+
def download_extract(downloader, opts, packages, temp_packages)
|
|
690
|
+
puts "Downloading and installing packages:"
|
|
691
|
+
|
|
692
|
+
# Check package server is up
|
|
693
|
+
downloader.checkRepo()
|
|
694
|
+
|
|
695
|
+
package_to_be_installed=[]
|
|
696
|
+
|
|
697
|
+
if WorkEnvs::settings[:db][:unthreaded] == false
|
|
698
|
+
semaphore = Mutex.new
|
|
699
|
+
threads = []
|
|
700
|
+
begin
|
|
701
|
+
processorCount = `cat /proc/cpuinfo 2> /dev/null | grep processor | wc -l`.chomp().to_i() / 2
|
|
702
|
+
processorCount = 1 if processorCount < 1
|
|
703
|
+
rescue
|
|
704
|
+
processorCount = 4
|
|
705
|
+
end
|
|
706
|
+
1.upto(processorCount) {
|
|
707
|
+
threads << Thread.new {
|
|
708
|
+
while true do
|
|
709
|
+
pack = nil
|
|
710
|
+
semaphore.synchronize {
|
|
711
|
+
pack = packages.pop()
|
|
712
|
+
}
|
|
713
|
+
break if pack == nil
|
|
714
|
+
downloader.downloadAndExtract(pack, true, !pack.shouldKeep(opts))
|
|
715
|
+
if pack.shouldInstall(opts) then
|
|
716
|
+
semaphore.synchronize {
|
|
717
|
+
package_to_be_installed << pack
|
|
718
|
+
}
|
|
719
|
+
end
|
|
720
|
+
|
|
721
|
+
end
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
threads.each(){|thr| thr.join}
|
|
725
|
+
else
|
|
726
|
+
packages.each() {|pack|
|
|
727
|
+
downloader.downloadAndExtract(pack, true, !pack.shouldKeep(opts))
|
|
728
|
+
if pack.shouldInstall(opts) then
|
|
729
|
+
package_to_be_installed << pack
|
|
730
|
+
end
|
|
731
|
+
}
|
|
732
|
+
end
|
|
733
|
+
|
|
734
|
+
opts[:tempDir] = create_tmp_dir()
|
|
735
|
+
puts "Downloading and installing temporary packages (To be removed post-install):"
|
|
736
|
+
Dir.chdir(opts[:tempDir])
|
|
737
|
+
temp_packages.each() {|pack|
|
|
738
|
+
downloader.downloadAndExtract(pack, true, true)
|
|
739
|
+
}
|
|
740
|
+
Dir.chdir(opts[:dir])
|
|
741
|
+
|
|
742
|
+
return package_to_be_installed
|
|
743
|
+
end
|
|
744
|
+
|
|
745
|
+
# Cleanup and env
|
|
746
|
+
#
|
|
747
|
+
# Remove all files from the env and mark it as uninitialized.
|
|
748
|
+
# This also calls the cleanup method from the env Class tree.
|
|
749
|
+
def cleanup(opts)
|
|
750
|
+
path=genPath()
|
|
751
|
+
#Cleanup in order
|
|
752
|
+
|
|
753
|
+
WorkEnvs::familyTreeApply(self){|x|
|
|
754
|
+
next if x.singleton_methods().index(:cleanup) == nil
|
|
755
|
+
x.cleanup(opts)
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
#Deconfigure previous package to be sure
|
|
759
|
+
@versions.each(){|name, val|
|
|
760
|
+
@versions[name] = :uninitialized
|
|
761
|
+
}
|
|
762
|
+
@deps_infos = nil
|
|
763
|
+
@properties = {}
|
|
764
|
+
self.dump()
|
|
765
|
+
|
|
766
|
+
runCmd("chmod -R +w #{path}", !VERBOSE)
|
|
767
|
+
# Remove previous checkout
|
|
768
|
+
runCmd("rm -f #{path}/*.rpm #{path}/*.deb", !VERBOSE)
|
|
769
|
+
runCmd("rm -Rf #{path}/usr", !VERBOSE)
|
|
770
|
+
runCmd("rm -Rf #{path}/lib", !VERBOSE)
|
|
771
|
+
runCmd("rm -Rf #{path}/etc", !VERBOSE)
|
|
772
|
+
runCmd("rm -Rf #{path}/mppa", !VERBOSE)
|
|
773
|
+
runCmd("rm -Rf #{path}/*", !VERBOSE)
|
|
774
|
+
end
|
|
775
|
+
|
|
776
|
+
#
|
|
777
|
+
# Update configure and install a new envs
|
|
778
|
+
#
|
|
779
|
+
# Update phases are:
|
|
780
|
+
# - Generate package list
|
|
781
|
+
# - CLEANUP:
|
|
782
|
+
# - Cleanup per Env
|
|
783
|
+
# - Cleanup env globally (reset class and remove all files)
|
|
784
|
+
#
|
|
785
|
+
# - PRE_SETUP: Call pre_setup per Env
|
|
786
|
+
# - SETUP: Download and extract all packages
|
|
787
|
+
# - PRE_INSTALL: Call pre_install per Env
|
|
788
|
+
# - INSTALL: (yum install) all packages required (DKMS, etc.)
|
|
789
|
+
# - POST_SETUP:
|
|
790
|
+
# - Call post_setup per Env
|
|
791
|
+
# - Generate switch env script
|
|
792
|
+
# - Update the class and save to disk
|
|
793
|
+
def update(opts = {})
|
|
794
|
+
opts[:endDate] = DEFAULT_EXPIRATION_DATE if opts[:endDate] == nil
|
|
795
|
+
opts[:release] = @db_tables.join(":")
|
|
796
|
+
|
|
797
|
+
|
|
798
|
+
opts[:srcDir] = Dir.pwd()
|
|
799
|
+
opts[:self] = self
|
|
800
|
+
|
|
801
|
+
# Checkout a new set of packages in the environment workspace
|
|
802
|
+
path=genPath()
|
|
803
|
+
opts[:dir] = path
|
|
804
|
+
|
|
805
|
+
raise("Nothing to update") if (opts[:infos] == nil || opts[:infos].empty?) && !isDev?()
|
|
806
|
+
infos = opts[:infos]
|
|
807
|
+
|
|
808
|
+
if isDev?() then
|
|
809
|
+
puts "INFO: Updating a development environment"
|
|
810
|
+
end
|
|
811
|
+
|
|
812
|
+
downloader = get_downloader(opts)
|
|
813
|
+
|
|
814
|
+
puts "==========================================================="
|
|
815
|
+
puts "Update requested with these environments:"
|
|
816
|
+
puts infos.to_s
|
|
817
|
+
puts "==========================================================="
|
|
818
|
+
puts "Looking for their dependencies....."
|
|
819
|
+
|
|
820
|
+
prevOptions = @setup_options
|
|
821
|
+
|
|
822
|
+
@setup_options = opts[:envOpts]
|
|
823
|
+
#If we had hudson specs and no version for our current env, allow partial stuff
|
|
824
|
+
if infos.partialEnv != false && !infos.exists?(WorkEnvs::getEnvType(self))
|
|
825
|
+
@setup_options[WENV_OPTS_PARTIAL] = "true"
|
|
826
|
+
end
|
|
827
|
+
infos.partialEnv = true if @setup_options[WENV_OPTS_PARTIAL] == "true"
|
|
828
|
+
|
|
829
|
+
packages, temp_packages = genPackages(downloader, opts)
|
|
830
|
+
|
|
831
|
+
puts "==========================================================="
|
|
832
|
+
puts "Installing these requested environments (pulled by dependency):"
|
|
833
|
+
puts "Dependencies:\n"
|
|
834
|
+
puts infos.to_s
|
|
835
|
+
puts "==========================================================="
|
|
836
|
+
|
|
837
|
+
do_cleanup = true
|
|
838
|
+
do_setup = true
|
|
839
|
+
do_install = true
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
if !isDev?() && infos == @deps_infos && prevOptions == opts[:envOpts] &&
|
|
843
|
+
!(opts[:force_update] == true ||
|
|
844
|
+
(opts[:force_update_if_not_const] == true && opts[:envOpts][WENV_OPTS_CONST].to_s != "true"))
|
|
845
|
+
# Be lazy and check if we really need to update
|
|
846
|
+
# When true, this means that all the proper packages are already extracted. We just
|
|
847
|
+
# need to force the reinstallation of installPackages
|
|
848
|
+
do_cleanup = false
|
|
849
|
+
do_setup = false
|
|
850
|
+
end
|
|
851
|
+
if opts[:doNotUpdate] == true then
|
|
852
|
+
do_cleanup = false
|
|
853
|
+
do_setup = false
|
|
854
|
+
end
|
|
855
|
+
|
|
856
|
+
if do_cleanup then
|
|
857
|
+
# CLEANUP
|
|
858
|
+
cleanup(opts)
|
|
859
|
+
end
|
|
860
|
+
|
|
861
|
+
Dir.chdir(opts[:dir])
|
|
862
|
+
install_deps = nil
|
|
863
|
+
@deps_infos = YAMLLoad(infos.to_yaml())
|
|
864
|
+
@deps_infos.downloader = nil
|
|
865
|
+
|
|
866
|
+
# PRE SETUP
|
|
867
|
+
pre_setup(opts, packages, temp_packages)
|
|
868
|
+
|
|
869
|
+
# Save package list in opts.
|
|
870
|
+
opts[:packages] = []
|
|
871
|
+
(packages | temp_packages).each do |package|
|
|
872
|
+
opts[:packages].push package
|
|
873
|
+
end
|
|
874
|
+
|
|
875
|
+
# If we only want install packages, filter out all the unneeded ones
|
|
876
|
+
if !do_setup then
|
|
877
|
+
alt_pack = []
|
|
878
|
+
|
|
879
|
+
packages.each() {|pack|
|
|
880
|
+
alt_pack << pack if pack.shouldInstall(opts)
|
|
881
|
+
}
|
|
882
|
+
packages = alt_pack
|
|
883
|
+
temp_packages = []
|
|
884
|
+
end
|
|
885
|
+
|
|
886
|
+
# SETUP
|
|
887
|
+
install_deps, packages_to_install =
|
|
888
|
+
download_extract(downloader, opts, packages, temp_packages)
|
|
889
|
+
|
|
890
|
+
|
|
891
|
+
# INSTALL
|
|
892
|
+
if do_install && !packages_to_install.empty? then
|
|
893
|
+
pre_install(opts, packages, temp_packages)
|
|
894
|
+
downloader.installPackages(packages_to_install)
|
|
895
|
+
post_install(opts, packages, temp_packages)
|
|
896
|
+
end
|
|
897
|
+
|
|
898
|
+
# POST SETUP
|
|
899
|
+
if do_setup then
|
|
900
|
+
post_setup(opts)
|
|
901
|
+
end
|
|
902
|
+
|
|
903
|
+
Dir.chdir(opts[:srcDir])
|
|
904
|
+
runCmd("rm -Rf #{opts[:tempDir]}", true)
|
|
905
|
+
|
|
906
|
+
@expiration = opts[:endDate]
|
|
907
|
+
|
|
908
|
+
if do_setup then
|
|
909
|
+
@versions = getVersion()
|
|
910
|
+
end
|
|
911
|
+
@setup_options = opts[:envOpts]
|
|
912
|
+
@machine = downloader.arch[:label]
|
|
913
|
+
@table = downloader.table
|
|
914
|
+
# Dump the updated env at we're good to go
|
|
915
|
+
self.dump()
|
|
916
|
+
|
|
917
|
+
if @setup_options[WENV_OPTS_CONST].to_s() == "true"
|
|
918
|
+
Dir.chdir(opts[:dir])
|
|
919
|
+
runCmd("chmod -Rf -w #{path}/*; true", !VERBOSE)
|
|
920
|
+
end
|
|
921
|
+
|
|
922
|
+
return true
|
|
923
|
+
end
|
|
924
|
+
|
|
925
|
+
# Self migration method to update default values
|
|
926
|
+
def migrate()
|
|
927
|
+
case @version
|
|
928
|
+
when nil
|
|
929
|
+
# Very old pre rename Env have their own migrate function
|
|
930
|
+
|
|
931
|
+
#Compat to migrate old envs
|
|
932
|
+
if @machine == nil then
|
|
933
|
+
arch = WorkEnvs::getArch()
|
|
934
|
+
@machine = arch[:label]
|
|
935
|
+
end
|
|
936
|
+
if @release == nil
|
|
937
|
+
@release = false
|
|
938
|
+
end
|
|
939
|
+
if @setup_options == nil
|
|
940
|
+
@setup_options = WorkEnvs::EnvOpts.new()
|
|
941
|
+
end
|
|
942
|
+
@version = 1
|
|
943
|
+
when 1
|
|
944
|
+
@properties = {}
|
|
945
|
+
@version = 2
|
|
946
|
+
when 2
|
|
947
|
+
if @machine == nil then
|
|
948
|
+
arch = WorkEnvs::getArch()
|
|
949
|
+
@machine = arch[:label]
|
|
950
|
+
end
|
|
951
|
+
@version = 3
|
|
952
|
+
when 3
|
|
953
|
+
# New inheritance scheme. We cannot change our hierarchy but it should keep working anyway
|
|
954
|
+
@version = 4
|
|
955
|
+
when 4
|
|
956
|
+
# New switch env script
|
|
957
|
+
genSwitchEnvScript() if isSwitchable?() == true
|
|
958
|
+
@version = 5
|
|
959
|
+
when 5
|
|
960
|
+
case @release
|
|
961
|
+
when nil, false, "false"
|
|
962
|
+
@release = "package"
|
|
963
|
+
when true, "true"
|
|
964
|
+
@release = "releases"
|
|
965
|
+
end
|
|
966
|
+
@version = 6
|
|
967
|
+
when 6
|
|
968
|
+
@release = [ @release ]
|
|
969
|
+
@version = 7
|
|
970
|
+
when 7
|
|
971
|
+
@db_tables = @release
|
|
972
|
+
@version = 8
|
|
973
|
+
when 8
|
|
974
|
+
@ignore_conflicts = false
|
|
975
|
+
@version = 9
|
|
976
|
+
when 9
|
|
977
|
+
if @deps_infos then
|
|
978
|
+
infos = Dependencies.new
|
|
979
|
+
|
|
980
|
+
downloader = WorkEnvs::PackageDownloader.new(@machine, @db_tables, !VERBOSE)
|
|
981
|
+
infos.downloader = downloader
|
|
982
|
+
|
|
983
|
+
@deps_infos.each(){|s, v|
|
|
984
|
+
envClass = WorkEnvs::symbolToClass(s)
|
|
985
|
+
infos.push_version(envClass, v, false)
|
|
986
|
+
}
|
|
987
|
+
infos.downloader = nil
|
|
988
|
+
@deps_infos = infos
|
|
989
|
+
end
|
|
990
|
+
@version = 10
|
|
991
|
+
when WORK_ENV_VERSION
|
|
992
|
+
# End of recursion, we're up to date
|
|
993
|
+
return self
|
|
994
|
+
else
|
|
995
|
+
raise("Unknown version for env #{@name}")
|
|
996
|
+
end
|
|
997
|
+
# Save edit to the environment due to migration
|
|
998
|
+
self.dump()
|
|
999
|
+
|
|
1000
|
+
# Keep migrating until we reach the right version
|
|
1001
|
+
return self.migrate()
|
|
1002
|
+
end
|
|
1003
|
+
end
|
|
1004
|
+
end
|