4 Created on Wed Aug 22 15:11:27 2018
17 MANIFEST_BASENAME =
"manifest.json"
18 BUNDLELIST_BASENAME =
"bundleList.json"
24 configInfoFilename =
".manifest_ocssw.json"
27 manifestCommand = os.path.dirname(__file__) +
"/manifest.py"
28 manifestFilename =
"manifest.json"
31 remoteHosts = [
"ocssw@gs616-container101"]
32 remoteRepoDir =
"/manifest/tags"
39 {
"name":
"root",
"dir":
".",
"help":
"random files in the root dir",
"extra":
"--exclude . --include bundleList.json --include OCSSW_bash.env --include OCSSW.env",
"commandLine":
True},
40 {
"name":
"bin_linux_64",
"dir":
"bin_linux_64",
"help":
"executables for Linux",
"commandLine":
False},
41 {
"name":
"bin_macosx_intel",
"dir":
"bin_macosx_intel",
"help":
"executables for Mac",
"commandLine":
False},
42 {
"name":
"bin_odps",
"dir":
"bin_odps",
"help":
"executables for ODPS",
"commandLine":
False},
43 {
"name":
"lib_linux_64",
"dir":
"lib_linux_64",
"help":
"shared libraries for Linux",
"commandLine":
False},
44 {
"name":
"lib_macosx_intel",
"dir":
"lib_macosx_intel",
"help":
"shared libraries for Mac",
"commandLine":
False},
45 {
"name":
"lib_odps",
"dir":
"lib_odps",
"help":
"shared libraries for ODPS",
"commandLine":
False},
46 {
"name":
"opt_linux_64",
"dir":
"opt_linux_64",
"help":
"3rd party library for Linux",
"extra":
"--exclude src",
"commandLine":
False},
47 {
"name":
"opt_macosx_intel",
"dir":
"opt_macosx_intel",
"help":
"3rd party library for Mac",
"extra":
"--exclude src",
"commandLine":
False},
48 {
"name":
"opt_odps",
"dir":
"opt_odps",
"help":
"3rd party library for ODPS",
"extra":
"--exclude src",
"commandLine":
False},
50 {
"name":
"ocssw_src",
"dir":
"ocssw_src",
"help":
"OCSSW source code",
"commandLine":
False},
51 {
"name":
"opt_src",
"dir":
"opt/src",
"help":
"3rd party library sources",
"extra":
"--exclude .buildit.db",
"commandLine":
True},
53 {
"name":
"afrt",
"dir":
"share/afrt",
"help":
"Ahmad-Fraser RT data",
"commandLine":
True},
54 {
"name":
"aquaverse",
"dir":
"share/aquaverse",
"help":
"Algorithm based on Mixture Density Networks",
"commandLine":
True},
55 {
"name":
"avhrr",
"dir":
"share/avhrr",
"help":
"AVHRR",
"commandLine":
True},
56 {
"name":
"aviris",
"dir":
"share/aviris",
"help":
"AVIRIS",
"commandLine":
True},
57 {
"name":
"common",
"dir":
"share/common",
"help":
"common",
"commandLine":
True},
58 {
"name":
"czcs",
"dir":
"share/czcs",
"help":
"CZCS",
"commandLine":
True},
59 {
"name":
"eval",
"dir":
"share/eval",
"help":
"evaluation",
"commandLine":
True},
60 {
"name":
"goci",
"dir":
"share/goci",
"help":
"GOCI",
"commandLine":
True},
61 {
"name":
"hawkeye",
"dir":
"share/hawkeye",
"help":
"Hawkeye",
"commandLine":
True},
62 {
"name":
"hico",
"dir":
"share/hico",
"help":
"HICO",
"commandLine":
True},
63 {
"name":
"l5tm",
"dir":
"share/l5tm",
"help":
"l5tm",
"commandLine":
True},
64 {
"name":
"l7etmp",
"dir":
"share/l7etmp",
"help":
"l7etmp",
"commandLine":
True},
65 {
"name":
"meris",
"dir":
"share/meris",
"help":
"MERIS",
"commandLine":
True},
66 {
"name":
"misr",
"dir":
"share/misr",
"help":
"MISR",
"commandLine":
True},
67 {
"name":
"modis",
"dir":
"share/modis",
"help":
"MODIS common",
"extra":
"--exclude aqua --exclude terra",
"commandLine":
False},
68 {
"name":
"modisa",
"dir":
"share/modis/aqua",
"help":
"MODIS AQUA",
"commandLine":
True},
69 {
"name":
"modist",
"dir":
"share/modis/terra",
"help":
"MODIS TERRA",
"commandLine":
True},
70 {
"name":
"mos",
"dir":
"share/mos",
"help":
"MOS",
"commandLine":
True},
71 {
"name":
"msi",
"dir":
"share/msi",
"help":
"MSI Sentinel 2 common",
"extra":
"--exclude s2a --exclude s2b",
"commandLine":
False},
72 {
"name":
"msis2a",
"dir":
"share/msi/s2a",
"help":
"MSI Sentinel 2A",
"commandLine":
True},
73 {
"name":
"msis2b",
"dir":
"share/msi/s2b",
"help":
"MSI Sentinel 2B",
"commandLine":
True},
74 {
"name":
"oci",
"dir":
"share/oci",
"help":
"PACE OCI",
"commandLine":
True},
75 {
"name":
"ocia",
"dir":
"share/ocia",
"help":
"PACE OCI AVIRIS",
"commandLine":
True},
76 {
"name":
"ocip",
"dir":
"share/ocip",
"help":
"PACE OCI PRISM",
"commandLine":
True},
77 {
"name":
"ocis",
"dir":
"share/ocis",
"help":
"PACE OCI Simulated data",
"commandLine":
True},
78 {
"name":
"ocm1",
"dir":
"share/ocm1",
"help":
"OCM1",
"commandLine":
True},
79 {
"name":
"ocm2",
"dir":
"share/ocm2",
"help":
"OCM2",
"commandLine":
True},
80 {
"name":
"ocrvc",
"dir":
"share/ocrvc",
"help":
"OC Virtual Constellation",
"commandLine":
True},
81 {
"name":
"octs",
"dir":
"share/octs",
"help":
"OCTS",
"commandLine":
True},
82 {
"name":
"olci",
"dir":
"share/olci",
"help":
"OLCI Sentinel 3 common",
"extra":
"--exclude s3a --exclude s3b",
"commandLine":
False},
83 {
"name":
"olcis3a",
"dir":
"share/olci/s3a",
"help":
"OLCI Sentinel 3A",
"commandLine":
True},
84 {
"name":
"olcia3b",
"dir":
"share/olci/s3b",
"help":
"OLCI Sentinel 3B",
"commandLine":
True},
85 {
"name":
"oli",
"dir":
"share/oli",
"help":
"OLI Landsat",
"extra":
"--exclude l8 --exclude l9",
"commandLine":
False},
86 {
"name":
"olil8",
"dir":
"share/oli/l8",
"help":
"OLI Landsat 8",
"commandLine":
True},
87 {
"name":
"olil9",
"dir":
"share/oli/l9",
"help":
"OLI Landsat 9",
"commandLine":
True},
88 {
"name":
"osmi",
"dir":
"share/osmi",
"help":
"OSMI",
"commandLine":
True},
89 {
"name":
"prism",
"dir":
"share/prism",
"help":
"PRISM",
"commandLine":
True},
90 {
"name":
"sabiamar",
"dir":
"share/sabiamar",
"help":
"Sabiamar",
"commandLine":
True},
91 {
"name":
"seawifs",
"dir":
"share/seawifs",
"help":
"SeaWiFS",
"commandLine":
True},
92 {
"name":
"sgli",
"dir":
"share/sgli",
"help":
"SGLI",
"commandLine":
True},
93 {
"name":
"spexone_remotap",
"dir":
"share/spexone/remotap",
"help":
"SPEX One RemoTAP",
"commandLine":
True},
94 {
"name":
"viirs",
"dir":
"share/viirs",
"extra":
"--exclude dem --exclude j1 --exclude j2 --exclude npp",
"help":
"VIIRS common",
"commandLine":
False},
95 {
"name":
"viirsdem",
"dir":
"share/viirs/dem",
"help":
"VIIRS Digital Elevation",
"commandLine":
True},
96 {
"name":
"viirsj1",
"dir":
"share/viirs/j1",
"help":
"VIIRS JPSS1",
"commandLine":
True},
97 {
"name":
"viirsj2",
"dir":
"share/viirs/j2",
"help":
"VIIRS JPSS2",
"commandLine":
True},
98 {
"name":
"viirsn",
"dir":
"share/viirs/npp",
"help":
"VIIRS NPP",
"commandLine":
True},
99 {
"name":
"wv3",
"dir":
"share/wv3",
"help":
"WV3",
"commandLine":
True},
100 {
"name":
"aerosol",
"dir":
"share/aerosol",
"help":
"aerosol processing with dtdb",
"commandLine":
True},
101 {
"name":
"cloud",
"dir":
"share/cloud",
"help":
"cloud properties processing",
"commandLine":
True},
102 {
"name":
"benchmark",
"dir":
"benchmark",
"help":
"benchmark MOSIS Aqua, level0 -> level3 Mapped",
"commandLine":
True},
103 {
"name":
"viirs_l1_benchmark",
"dir":
"viirs_l1_benchmark",
"help":
"VIIRS benchmark data",
"commandLine":
True},
104 {
"name":
"viirs_l1_bin_macosx_intel",
"dir":
"viirs_l1_bin_macosx_intel",
"help":
"Subset of binary files for VIIRS",
"commandLine":
False},
105 {
"name":
"viirs_l1_bin_linux_64",
"dir":
"viirs_l1_bin_linux_64",
"help":
"Subset of binary files for VIIRS",
"commandLine":
False},
106 {
"name":
"viirs_l1_bin_odps",
"dir":
"viirs_l1_bin_odps",
"help":
"Subset of binary files for VIIRS",
"commandLine":
False}
110 newParser = subparsers.add_parser(
'init', help=
"Initialize the directory to be the root of the OCSSW manifest bundles")
111 newParser.add_argument(
"dir", help=
"directory to initialize", nargs=
'?', default=
'.')
112 newParser.set_defaults(func=init_dir)
115 newParser = subparsers.add_parser(
'status', help=
"List the files that differ from the manifest")
116 newParser.add_argument(
"tag", nargs=
'?', help=
"tag name to use")
117 newParser.set_defaults(func=status)
120 newParser = subparsers.add_parser(
'push', help=
"Create a new tag and push to the server")
121 newParser.add_argument(
"tag", help=
"tag name to use")
122 newParser.add_argument(
"-o",
"--overwrite", default=
False, action=
"store_true", help=
"overwrite the tag if it already exists")
123 newParser.set_defaults(func=push)
126 newParser = subparsers.add_parser(
'pull', help=
"Download a tag from the server")
127 newParser.add_argument(
"tag", help=
"tag name to use")
128 newParser.add_argument(
"-c",
"--clean", default=
False, action=
"store_true", help=
"clean the directory after downloading")
129 newParser.set_defaults(func=pull)
132 newParser = subparsers.add_parser(
'list', help=
"List the tags on the remote system")
133 newParser.set_defaults(func=list_tags)
139 if os.path.exists(options.dir):
140 if not os.path.isdir(options.dir):
141 print(
"Error:", options.dir,
"exists and is not a directory")
143 os.mkdir(options.dir)
145 fileName = os.path.join(os.path.abspath(options.dir), configInfoFilename)
146 if os.path.exists(fileName):
147 print(
"Error: manifest_ocssw config file", fileName,
"already exists")
151 configInfo[
"baseDir"] = os.path.abspath(options.dir)
152 configInfo[
"tag"] =
"Unknown"
155 with open(fileName,
'w')
as outfile:
156 json.dump(configInfo, outfile, indent=4, sort_keys=
True)
158 fileName = os.path.join(os.path.abspath(options.dir),
"bundleList.json")
159 with open(fileName,
'w')
as outfile:
160 json.dump(initialBundleList, outfile, indent=4, sort_keys=
True)
165 proc = subprocess.run(command, stdout=subprocess.PIPE, shell=shellVal)
167 proc = subprocess.run(command, shell=shellVal)
168 if proc.returncode != 0:
169 print(
"Error: trying to run = ", command)
176 command = [
"ssh",
"-q", remoteHosts[0],
"[ -d %s/%s ]" % (remoteRepoDir, tag) ]
177 proc = subprocess.run(command)
178 if proc.returncode == 0:
185 command = [
"ssh",
"-q", remoteHosts[0],
"[ -d %s/%s/%s ]" % (remoteRepoDir, tag, name) ]
186 proc = subprocess.run(command)
187 if proc.returncode == 0:
194 for info
in bundleList:
195 if info[
"name"] == name:
203 bundleDir = os.path.abspath(os.path.join(configInfo[
"baseDir"], bundleInfo[
"dir"]))
204 if startingDir
not in bundleDir:
207 print(bundleInfo[
"name"], end=
' ', flush=
True)
209 statusTag =
"tempStatusTag"
210 os.chdir(configInfo[
"baseDir"])
213 if hasattr(options,
"tag")
and options.tag:
216 command = [
"scp",
"-q",
"%s:%s/%s/%s/%s" % (remoteHosts[0], remoteRepoDir, options.tag, bundleInfo[
"name"], manifestFilename),
"/tmp"]
218 with open(
"/tmp/" + manifestFilename,
'rb')
as manifest:
219 currentManifest = json.load(manifest)
220 os.remove(
"/tmp/" + manifestFilename)
222 print(
"Warning: bundle %s does not exist in tag %s on server." % (bundleInfo[
"name"], options.tag))
224 print(
"Error: tag:", options.tag,
"does not exist on server")
229 command = [
"scp",
"-q",
"%s:%s/%s/%s/%s" % (remoteHosts[0], remoteRepoDir, configInfo[
"tag"], bundleInfo[
"name"], manifestFilename),
"/tmp"]
231 with open(
"/tmp/" + manifestFilename,
'rb')
as manifest:
232 currentManifest = json.load(manifest)
233 os.remove(
"/tmp/" + manifestFilename)
235 if not os.path.isdir(bundleInfo[
"dir"]):
236 print(
"Warning: bundle directory %s does not exist." % (bundleInfo[
"dir"]))
239 command = [manifestCommand,
"generate",
240 "-n", bundleInfo[
"name"],
243 if "extra" in bundleInfo:
244 command += bundleInfo[
"extra"].split()
245 statusManifest = json.loads(
runCommand(command, pipe=
True))
247 if "tags" in currentManifest:
248 tagList = currentManifest[
"tags"]
251 versionStr += tagList[0] +
".."
252 versionStr += tagList[-1] +
")"
259 for f, info
in statusManifest[
"files"].items():
260 if (
"files" not in currentManifest)
or (f
not in currentManifest[
"files"]):
265 print(
" %s/%s" % (bundleInfo[
"dir"], f))
269 for f, info
in statusManifest[
"files"].items():
270 if (
"files" in currentManifest)
and (f
in currentManifest[
"files"]):
271 if info[
"tag"] != currentManifest[
"files"][f][
"tag"]:
274 print(
" Modified Files:")
276 print(
" %s/%s" % (bundleInfo[
"dir"], f))
280 if "files" in currentManifest:
281 for f, info
in currentManifest[
"files"].items():
282 if f
not in statusManifest[
"files"]:
285 print(
" Deleted Files:")
287 print(
" %s/%s" % (bundleInfo[
"dir"], f))
291 os.chdir(configInfo[
"baseDir"])
292 command = [manifestCommand,
"generate",
293 "-n", bundleInfo[
"name"],
296 if "extra" in bundleInfo:
297 command += bundleInfo[
"extra"].split()
298 newManifest = json.loads(
runCommand(command, pipe=
True))
300 print(bundleInfo[
"name"])
301 os.chdir(bundleInfo[
"dir"])
305 for f, info
in newManifest[
"files"].items():
306 if info[
"tag"] == options.tag:
310 filesWereDeleted =
False
312 command = [
"scp",
"-q",
"%s:%s/%s/%s/%s" % (remoteHosts[0], remoteRepoDir, configInfo[
"tag"], bundleInfo[
"name"], manifestFilename),
"/tmp"]
314 with open(
"/tmp/" + manifestFilename,
'rb')
as manifest:
315 currentManifest = json.load(manifest)
317 for f, info
in currentManifest[
"files"].items():
318 if f
not in newManifest[
"files"]:
319 filesWereDeleted =
True
321 os.remove(
"/tmp/" + manifestFilename)
323 if fileList
or filesWereDeleted:
325 with open(manifestFilename,
'w')
as outfile:
326 json.dump(newManifest, outfile, indent=4, sort_keys=
True)
329 tmpFilename =
"/tmp/changeList.txt"
330 with open(tmpFilename,
'w')
as changeFile:
331 changeFile.write(manifestFilename)
332 changeFile.write(
"\n")
334 if not os.path.islink(f):
336 changeFile.write(
"\n")
339 for host
in remoteHosts:
340 command = [
"ssh",
"-q", host,
"mkdir -p %s/%s/%s" % (remoteRepoDir, options.tag, bundleInfo[
"name"]) ]
343 command = [
"rsync",
"-hav",
"--files-from=" + tmpFilename,
".",
"%s:%s/%s/%s/" % (host, remoteRepoDir, options.tag, bundleInfo[
"name"]) ]
345 os.remove(tmpFilename)
348 print(
" No files Changed, creating symbolic link")
351 command = [manifestCommand,
"add-tag", options.tag]
352 newManifest = json.loads(
runCommand(command, pipe=
True))
353 with open(manifestFilename,
'w')
as outfile:
354 json.dump(newManifest, outfile, indent=4, sort_keys=
True)
356 firstTag = newManifest[
'tags'][0]
359 for host
in remoteHosts:
360 command = [
"ssh",
"-q", host,
"mkdir -p %s/%s" % (remoteRepoDir, options.tag)]
363 command = [
"scp",
"-q", manifestFilename,
"%s:%s/%s/%s/%s" % (host, remoteRepoDir, firstTag, bundleInfo[
"name"], manifestFilename) ]
366 command = [
"ssh",
"-q", host,
"ln -s %s/%s/%s %s/%s/%s" %
367 (remoteRepoDir, firstTag, bundleInfo[
"name"],
368 remoteRepoDir, options.tag, bundleInfo[
"name"]) ]
372 print(bundleInfo[
"name"])
374 os.chdir(configInfo[
"baseDir"])
375 command = [manifestCommand,
"download",
376 "-n", bundleInfo[
"name"],
378 "-d", bundleInfo[
"dir"]]
381 command = [manifestCommand,
"clean", bundleInfo[
"dir"]]
382 if "extra" in bundleInfo:
383 command += bundleInfo[
"extra"].split()
386 print(
"Warning: Bundle %s does not exist in tag %s on the server" %(bundleInfo[
"name"], options.tag))
388 if os.path.isdir(bundleInfo[
"dir"]):
389 print(
"Cleaning bundle directory", bundleInfo[
"dir"])
390 shutil.rmtree(bundleInfo[
"dir"])
393 command = [
"ssh",
"-q", remoteHosts[0],
"ls " + remoteRepoDir]
401 parser = argparse.ArgumentParser(description=
"Work on the minifest directories for OCSSW")
402 parser.set_defaults(func=status)
403 subparsers = parser.add_subparsers()
411 options = parser.parse_args()
414 if options.func == init_dir:
415 options.func(options)
419 if options.func == list_tags:
420 options.func(options)
424 if options.func == push:
426 if options.overwrite:
427 for host
in remoteHosts:
428 command = [
"ssh",
"-q", host,
"rm -rf " + remoteRepoDir +
"/" + options.tag]
431 print(
"Error: tag", options.tag,
"exists.")
432 print(
"Use --overwrite (-o) to continue (will delete old version)")
436 baseDir = os.path.abspath(os.getcwd())
437 startingDir = baseDir
438 while(baseDir !=
"/"):
439 fileName = os.path.join(baseDir, configInfoFilename)
440 if os.path.exists(fileName):
441 with open(fileName,
'rb')
as configFile:
442 configInfo = json.load(configFile)
443 if configInfo[
"baseDir"] != baseDir:
444 print(
"Error: config file has been moved")
445 print(
" real baseDir = ", baseDir)
446 print(
" configFile baseDir =", configInfo[
"baseDir"])
450 baseDir = os.path.dirname(baseDir)
452 print(
"Error: manifest_ocssw config file not found in current or parent directories")
453 print(
" Run: manifest_ocssw init")
456 print(
"current tag =", configInfo[
"tag"])
459 localBundleList =
None
460 localBundleListFile =
"%s/%s" % (baseDir, BUNDLELIST_BASENAME)
461 if not os.path.isfile(localBundleListFile):
462 print(
"Must have a %s file in the root directory" % (BUNDLELIST_BASENAME))
464 with open(localBundleListFile,
'rb')
as jsonFile:
465 localBundleList = json.load(jsonFile)
466 if not localBundleList:
467 print(
"Must have a valid %s file in the root directory" % (BUNDLELIST_BASENAME))
471 remoteBundleList =
None
472 remoteBundleListFile =
"/tmp/%s" % (BUNDLELIST_BASENAME)
473 remoteManifest =
None
474 remoteManifestFile =
"/tmp/%s" % (MANIFEST_BASENAME)
475 tag = configInfo[
"tag"]
476 if options.func == pull:
478 elif options.func == status:
479 if hasattr(options,
"tag")
and options.tag:
484 command = [
"scp",
"-q",
"%s:%s/%s/root/%s" %
485 (remoteHosts[0], remoteRepoDir, tag, MANIFEST_BASENAME),
488 with open(remoteManifestFile,
'rb')
as jsonFile:
489 remoteManifest = json.load(jsonFile)
490 os.remove(remoteManifestFile)
493 command = [
"scp",
"-q",
"%s:%s/%s/root/%s" %
494 (remoteHosts[0], remoteRepoDir, remoteManifest[
'files'][BUNDLELIST_BASENAME][
'tag'],
495 BUNDLELIST_BASENAME), remoteBundleListFile]
497 with open(remoteBundleListFile,
'rb')
as jsonFile:
498 remoteBundleList = json.load(jsonFile)
499 os.remove(remoteBundleListFile)
502 for bundleInfo
in localBundleList:
504 print(
"New local bundle -", bundleInfo[
"name"])
508 for bundleInfo
in remoteBundleList:
510 print(
"Deleted local bundle -", bundleInfo[
"name"])
512 bundleList = localBundleList
513 if options.func == pull:
514 bundleList = remoteBundleList
518 for bundleInfo
in bundleList:
519 options.func(options, bundleInfo)
522 if options.func == push
or options.func == pull:
523 configInfo[
"tag"] = options.tag
526 fileName = os.path.join(baseDir, configInfoFilename)
527 with open(fileName,
'w')
as outfile:
528 json.dump(configInfo, outfile, indent=4, sort_keys=
True)
533 if __name__ ==
"__main__":