NASA Logo
Ocean Color Science Software

ocssw V2022
install_ocssw.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 """
4 Created on Tue Sep 18 11:08:27 2018
5 
6 @author: dshea
7 """
8 
9 from operator import indexOf
10 import sys
11 import re
12 import argparse
13 import os
14 import shutil
15 import subprocess
16 import urllib.parse
17 import hashlib
18 import json
19 import datetime
20 import tempfile
21 import tarfile
22 import smtplib
23 from email.message import EmailMessage
24 
25 #sys.path.insert(0, os.path.dirname(__file__))
26 import manifest as mf
27 
28 # global variables
29 MANIFEST_BASENAME = "manifest.json"
30 BUNDLELIST_BASENAME = "bundleList.json"
31 INSTALL_OCSSW_BASENAME = "install_ocssw.json"
32 versionString = "8.0"
33 baseUrl = "https://oceandata.sci.gsfc.nasa.gov/manifest/tags"
34 manifestCommand = os.path.dirname(__file__) + "/manifest.py"
35 currentThing = 1
36 totalNumThings = 0
37 
38 
42 bundleList = []
43 initialBundleList = [
44  {"name":"root", "dir":".", "help":"random files in the root dir", "extra":"--exclude . --include bundleList.json --include OCSSW_bash.env --include OCSSW.env", "commandLine":True},
45  {"name":"python", "dir":"python", "help":"OCSSW required python modules", "commandLine":True},
46  {"name":"bin_linux_64", "dir":"bin_linux_64", "help":"executables for Linux", "commandLine":False},
47  {"name":"bin_linux_hpc", "dir":"bin_linux_hpc", "help":"executables for Linux HPC", "commandLine":False},
48  {"name":"bin_macosx_intel", "dir":"bin_macosx_intel", "help":"executables for Mac", "commandLine":False},
49  {"name":"bin_macosx_arm64", "dir":"bin_macosx_arm64", "help":"executables for Mac ARM64", "commandLine":False},
50  {"name":"bin_odps", "dir":"bin_odps", "help":"executables for ODPS", "commandLine":False},
51  {"name":"lib_linux_64", "dir":"lib_linux_64", "help":"shared libraries for Linux", "commandLine":False},
52  {"name":"lib_linux_hpc", "dir":"lib_linux_hpc", "help":"shared libraries for Linux HPC", "commandLine":False},
53  {"name":"lib_macosx_intel", "dir":"lib_macosx_intel", "help":"shared libraries for Mac", "commandLine":False},
54  {"name":"lib_macosx_arm64", "dir":"lib_macosx_arm64", "help":"shared libraries for Mac ARM64", "commandLine":False},
55  {"name":"lib_odps", "dir":"lib_odps", "help":"shared libraries for ODPS", "commandLine":False},
56  {"name":"opt_linux_64", "dir":"opt_linux_64", "help":"3rd party library for Linux", "extra": "--exclude src", "commandLine":False},
57  {"name":"opt_linux_hpc", "dir":"opt_linux_hpc", "help":"3rd party library for Linux HPC", "extra": "--exclude src", "commandLine":False},
58  {"name":"opt_macosx_intel", "dir":"opt_macosx_intel", "help":"3rd party library for Mac", "extra": "--exclude src", "commandLine":False},
59  {"name":"opt_macosx_arm64", "dir":"opt_macosx_arm64", "help":"3rd party library for Mac ARM64", "extra": "--exclude src", "commandLine":False},
60  {"name":"opt_odps", "dir":"opt_odps", "help":"3rd party library for ODPS", "extra": "--exclude src", "commandLine":False},
61 
62  {"name":"ocssw_src", "dir":"ocssw_src", "help":"OCSSW source code", "commandLine":False},
63  {"name":"opt_src", "dir":"opt/src", "help":"3rd party library sources", "extra":"--exclude .buildit.db", "commandLine":True},
64 
65  {"name":"afrt", "dir":"share/afrt", "help":"Ahmad-Fraser RT data", "commandLine":True},
66  {"name":"aquaverse", "dir":"share/aquaverse", "help":"Algorithm based on Mixture Density Networks", "commandLine":True},
67  {"name":"avhrr", "dir":"share/avhrr", "help":"AVHRR", "commandLine":True},
68  {"name":"aviris", "dir":"share/aviris", "help":"AVIRIS", "commandLine":True},
69  {"name":"common", "dir":"share/common", "help":"common", "commandLine":True},
70  {"name":"czcs", "dir":"share/czcs", "help":"CZCS", "commandLine":True},
71  {"name":"eval", "dir":"share/eval", "help":"evaluation", "commandLine":True},
72  {"name":"goci", "dir":"share/goci", "help":"GOCI", "commandLine":True},
73  {"name":"harp2", "dir":"share/harp2", "help":"HARP 2 Polarimeter", "commandLine":True},
74  {"name":"hawkeye", "dir":"share/hawkeye", "help":"Hawkeye", "commandLine":True},
75  {"name":"hico", "dir":"share/hico", "help":"HICO", "commandLine":True},
76  {"name":"l5tm", "dir":"share/l5tm", "help":"l5tm", "commandLine":True},
77  {"name":"l7etmp", "dir":"share/l7etmp", "help":"l7etmp", "commandLine":True},
78  {"name":"meris", "dir":"share/meris", "help":"MERIS", "commandLine":True},
79  {"name":"misr", "dir":"share/misr", "help":"MISR", "commandLine":True},
80  {"name":"modis", "dir":"share/modis", "help":"MODIS common", "extra":"--exclude aqua --exclude terra", "commandLine":False},
81  {"name":"modisa", "dir":"share/modis/aqua", "help":"MODIS AQUA", "commandLine":True},
82  {"name":"modist", "dir":"share/modis/terra", "help":"MODIS TERRA", "commandLine":True},
83  {"name":"msi", "dir":"share/msi", "help":"MSI Sentinel 2 common", "extra":"--exclude s2a --exclude s2b", "commandLine":False},
84  {"name":"msis2a", "dir":"share/msi/s2a", "help":"MSI Sentinel 2A", "commandLine":True},
85  {"name":"msis2b", "dir":"share/msi/s2b", "help":"MSI Sentinel 2B", "commandLine":True},
86  {"name":"oci", "dir":"share/oci", "help":"PACE OCI", "commandLine":True},
87  {"name":"ocm1", "dir":"share/ocm1", "help":"OCM1", "commandLine":True},
88  {"name":"ocm2", "dir":"share/ocm2", "help":"OCM2", "commandLine":True},
89  {"name":"ocrvc", "dir":"share/ocrvc", "help":"OC Virtual Constellation", "commandLine":True},
90  {"name":"octs", "dir":"share/octs", "help":"OCTS", "commandLine":True},
91  {"name":"olci", "dir":"share/olci", "help":"OLCI Sentinel 3 common", "extra":"--exclude s3a --exclude s3b", "commandLine":False},
92  {"name":"olcis3a", "dir":"share/olci/s3a", "help":"OLCI Sentinel 3A", "commandLine":True},
93  {"name":"olcis3b", "dir":"share/olci/s3b", "help":"OLCI Sentinel 3B", "commandLine":True},
94  {"name":"oli", "dir":"share/oli", "help":"OLI Landsat", "extra":"--exclude l8 --exclude l9", "commandLine":False},
95  {"name":"olil8", "dir":"share/oli/l8", "help":"OLI Landsat 8", "commandLine":True},
96  {"name":"olil9", "dir":"share/oli/l9", "help":"OLI Landsat 9", "commandLine":True},
97  {"name":"prism", "dir":"share/prism", "help":"PRISM", "commandLine":True},
98  {"name":"sabiamar", "dir":"share/sabiamar", "help":"Sabiamar", "commandLine":True},
99  {"name":"seawifs", "dir":"share/seawifs", "help":"SeaWiFS", "commandLine":True},
100  {"name":"sgli", "dir":"share/sgli", "help":"SGLI", "commandLine":True},
101  {"name":"spexone", "dir":"share/spexone", "help":"SPEX One Polarimeter", "commandLine":True},
102  {"name":"viirs", "dir":"share/viirs", "extra":"--exclude dem --exclude j1 --exclude j2 --exclude npp", "help":"VIIRS common", "commandLine":False},
103  {"name":"viirsdem", "dir":"share/viirs/dem", "help":"VIIRS Digital Elevation", "commandLine":True},
104  {"name":"viirsj1", "dir":"share/viirs/j1", "help":"VIIRS JPSS1", "commandLine":True},
105  {"name":"viirsj2", "dir":"share/viirs/j2", "help":"VIIRS JPSS2", "commandLine":True},
106  {"name":"viirsn", "dir":"share/viirs/npp", "help":"VIIRS NPP", "commandLine":True},
107  {"name":"wv3", "dir":"share/wv3", "help":"WV3", "commandLine":True},
108  {"name":"aerosol", "dir":"share/aerosol", "help":"aerosol processing with dtdb", "commandLine":True},
109  {"name":"cloud", "dir":"share/cloud", "help":"cloud properties processing", "commandLine":True},
110  {"name":"telemetery", "dir":"share/telemetry", "help":"telemetry packet descriptions", "commandLine":True},
111  {"name":"benchmark", "dir":"benchmark", "help":"benchmark MOSIS Aqua, level0 -> level3 Mapped", "commandLine":True},
112  {"name":"viirs_l1_benchmark", "dir":"viirs_l1_benchmark", "help":"VIIRS benchmark data", "commandLine":True},
113  {"name":"viirs_l1_bin_macosx_intel", "dir":"viirs_l1_bin_macosx_intel", "help":"Subset of binary files for VIIRS", "commandLine":False},
114  {"name":"viirs_l1_bin_macosx_arm64", "dir":"viirs_l1_bin_macosx_arm64", "help":"Subset of binary files for VIIRS", "commandLine":False},
115  {"name":"viirs_l1_bin_linux_64", "dir":"viirs_l1_bin_linux_64", "help":"Subset of binary files for VIIRS", "commandLine":False},
116  {"name":"viirs_l1_bin_odps", "dir":"viirs_l1_bin_odps", "help":"Subset of binary files for VIIRS", "commandLine":False}
117 ]
118 
119 # list of bundles that have luts
120 lutBundles = ["seawifs", "modisa", "modist", "viirsn", "viirsj1", "viirsj2", "oci"]
121 
122 
123 def findBundleInfo(bundleName):
124  for bundleInfo in bundleList:
125  if bundleInfo["name"] == bundleName:
126  return bundleInfo
127  return None
128 
129 def getArch():
130  """
131  Return the system arch string.
132  """
133  (sysname, _, _, _, machine) = os.uname()
134  if sysname == 'Darwin':
135  if machine == 'x86_64' or machine == 'i386':
136  return 'macosx_intel'
137  if machine == 'arm64':
138  return 'macosx_arm64'
139  print("unsupported Mac machine =", machine)
140  exit(1)
141  if sysname == 'Linux':
142  if machine == 'x86_64':
143  return 'linux_64'
144  print("Error: can only install OCSSW software on 64bit Linux")
145  exit(1)
146  if sysname == 'Windows':
147  print("Error: can not install OCSSW software on Windows")
148  exit(1)
149  print('***** unrecognized system =', sysname, ', machine =', machine)
150  print('***** defaulting to linux_64')
151  return 'linux_64'
152 
153 def runCommand(command, pipe=False, shellVal=False):
154  if pipe:
155  proc = subprocess.run(command, stdout=subprocess.PIPE, shell=shellVal)
156  else:
157  proc = subprocess.run(command, shell=shellVal)
158  if proc.returncode != 0:
159  print("Error: trying to run = ", command)
160  sys.exit(1)
161  if pipe:
162  return proc.stdout
163 
164 def listTags(options):
165  manifest_options = mf.create_default_options()
166  manifest_options.wget = options.wget
167  mf.list_tags(manifest_options, None)
168 
169 def checkTag(options):
170  manifest_options = mf.create_default_options()
171  manifest_options.tag = options.tag
172  manifest_options.wget = options.wget
173  if not mf.check_tag(manifest_options, None):
174  print("tag=%s," % (options.tag), "Does not exist.")
175  sys.exit(1)
176 
177 def recordInstalledTag(options):
178  installInfo = {}
179  installInfo["tag"] = options.tag
180  installInfo["version"] = versionString
181  installInfo["install_date"] = datetime.datetime.now().isoformat(timespec="seconds")
182 
183  # save as a JSON file
184  if not os.path.isdir(options.install_dir):
185  os.makedirs(options.install_dir)
186 
187  fileName = "%s/%s" % (options.install_dir, INSTALL_OCSSW_BASENAME)
188  with open(fileName, 'w') as outfile:
189  json.dump(installInfo, outfile, indent=4, sort_keys=True)
190 
191 def getInstalledTag(options):
192  installOcsswFilename = "%s/%s" % (options.install_dir, INSTALL_OCSSW_BASENAME)
193  try:
194  # try reading the install_ocssw.json file
195  with open(installOcsswFilename, 'rb') as installOcsswFile:
196  installInfo = json.load(installOcsswFile)
197  return installInfo["tag"]
198  except:
199  # if that does not work, grab the last tag out of the manifest.json file
200  try:
201  manifestFilename = "%s/%s" % (options.install_dir, MANIFEST_BASENAME)
202  with open(manifestFilename, 'rb') as manifestFile:
203  manifest = json.load(manifestFile)
204  return manifest["tags"][-1]
205  except:
206  # if nothing works, do this
207  return "Unknown"
208 
209 def installedTag(options):
210  print("installedTag =", getInstalledTag(options))
211 
212 def installBundle(options, bundleInfo):
213  global currentThing
214  if options.verbose:
215  print()
216  print("Installing (" + str(currentThing), "of", str(totalNumThings) + ") -", bundleInfo["name"], flush=True)
217  currentThing += 1
218 
219  manifest_options = mf.create_default_options()
220  manifest_options.verbose = options.verbose
221  manifest_options.name = bundleInfo["name"]
222  manifest_options.tag = options.tag
223  manifest_options.dest_dir = "%s/%s" % (options.install_dir, bundleInfo["dir"])
224  manifest_options.save_dir = options.save_dir
225  manifest_options.local_dir = options.local_dir
226  manifest_options.wget = options.wget
227 
228  mf.download(manifest_options, None)
229 
230  if options.clean:
231  command = "%s clean %s/%s" % (manifestCommand, options.install_dir, bundleInfo["dir"])
232  if "extra" in bundleInfo:
233  command += " " + bundleInfo["extra"]
234  runCommand(command, shellVal=True)
235 
236 def updateLuts(options, lut):
237  runner = options.install_dir + "/bin/ocssw_runner"
238  if not os.path.isfile(runner):
239  print("Error - bin directory needs to be installed.")
240  exit(1)
241  if options.verbose:
242  print()
243  print("Installing lut -", lut)
244  command = "%s --ocsswroot %s update_luts %s" % (runner, options.install_dir, lut)
245  runCommand(command, shellVal=True)
246 
247 def getBundleListTag(manifestFilename):
248  try:
249  with open(manifestFilename, 'rb') as manifestFile:
250  manifest = json.load(manifestFile)
251  return manifest['files'][BUNDLELIST_BASENAME]['tag']
252  except json.JSONDecodeError:
253  print(manifestFilename, "is not a manifest file")
254  sys.exit(1)
255  except FileNotFoundError:
256  print(manifestFilename, "Not found")
257  sys.exit(1)
258  except KeyError:
259  print(manifestFilename, "is corrupt")
260  sys.exit(1)
261  print("could not find bundeList tag in", manifestFilename)
262  sys.exit(1)
263 
264 def downloadBundleList(options):
265  global bundleList
266 
267  if not options.tag:
268  print("\nWARNING: --tag is required to get the proper bundle list.\n")
269  bundleList = initialBundleList
270  return
271  else:
272  checkTag(options)
273 
274  tempDir = tempfile.TemporaryDirectory(prefix="install_ocssw-")
275  tempBundleFilePath = dest = "%s/%s" % (tempDir.name, BUNDLELIST_BASENAME)
276  if options.local_dir:
277  manifestFilename = "%s/%s/root/%s" % (options.local_dir, options.tag, MANIFEST_BASENAME)
278  bundleFilename = "%s/%s/root/%s" % (options.local_dir, getBundleListTag(manifestFilename),BUNDLELIST_BASENAME)
279  if not os.path.isfile(bundleFilename):
280  print(bundleFilename, "file does not exist")
281  sys.exit(1)
282  shutil.copy(bundleFilename, tempBundleFilePath)
283  elif options.wget:
284  command = "cd %s; wget -q %s/%s/root/%s" % (tempDir.name, options.base_url, options.tag, MANIFEST_BASENAME)
285  runCommand(command, shellVal=True)
286  manifestFilename = "%s/%s" % (tempDir.name, MANIFEST_BASENAME)
287  bundleListUrl = "%s/%s/root/%s" % (options.base_url, getBundleListTag(manifestFilename), BUNDLELIST_BASENAME)
288  command = "cd %s; wget -q %s" % (tempDir.name, bundleListUrl)
289  runCommand(command, shellVal=True)
290  else:
291  manifestUrl = "%s/%s/root/%s" % (options.base_url, options.tag, MANIFEST_BASENAME)
292  parts = urllib.parse.urlparse(manifestUrl)
293  host = parts.netloc
294  request = parts.path
295  status = mf.httpdl(host, request, localpath=tempDir.name, outputfilename=MANIFEST_BASENAME, force_download=True)
296  if status != 0:
297  print("Error downloading", manifestUrl, ": return code =", status)
298  sys.exit(1)
299  manifestFilename = "%s/%s" % (tempDir.name, MANIFEST_BASENAME)
300  bundleListUrl = "%s/%s/root/%s" % (options.base_url, getBundleListTag(manifestFilename), BUNDLELIST_BASENAME)
301  parts = urllib.parse.urlparse(bundleListUrl)
302  host = parts.netloc
303  request = parts.path
304  status = mf.httpdl(host, request, localpath=tempDir.name, outputfilename=BUNDLELIST_BASENAME, force_download=True)
305  if status != 0:
306  print("Error downloading", bundleListUrl, ": return code =", status)
307  sys.exit(1)
308  with open(tempBundleFilePath, 'rb') as bundleListFile:
309  bundleList = json.load(bundleListFile)
310 
311 
312 def downloadFile(options, tag, bundleInfo, fileName, destDir):
313  dest = "%s/%s" % (destDir, fileName)
314  dest_dir = os.path.dirname(dest)
315  if not os.path.isdir(dest_dir):
316  os.makedirs(dest_dir)
317 
318  if options.local_dir:
319  src = "%s/%s/%s/%s" % (options.local_dir, options.tag, bundleInfo["name"], fileName)
320  if options.verbose:
321  print("Copying %s from %s" % (fileName, src))
322  shutil.copy(src, dest)
323  return True
324 
325  url = "%s/%s/%s/%s" % (baseUrl, tag, bundleInfo["name"], fileName)
326  if options.verbose:
327  print("Downloading %s from %s" % (fileName, url))
328  if options.wget:
329  if os.path.isfile(dest):
330  os.remove(dest)
331  command = "cd %s; wget -q %s" % (dest_dir, url)
332  runCommand(command, shellVal=True)
333  else:
334  parts = urllib.parse.urlparse(url)
335  host = parts.netloc
336  request = parts.path
337  status = mf.httpdl(host, request, localpath=dest_dir,
338  outputfilename=os.path.basename(dest),
339  verbose=options.verbose,
340  force_download=True)
341  if status != 0:
342  print("Error downloading", dest, ": return code =", status)
343  return False
344  return True
345 
346 def bundleStatus(options, bundleInfo, fileLst_chg, fileLst_relPath_chg, fileLst_del):
347  returnStatus = True
348  statusTag = "tempStatusTag"
349  #os.chdir(options.install_dir)
350 
351  currentManifest = {}
352  tempDir = tempfile.TemporaryDirectory(prefix="install_ocssw-")
353  currentManifestFilename = "%s/%s" % (tempDir.name, MANIFEST_BASENAME)
354  if downloadFile(options, options.tag, bundleInfo, MANIFEST_BASENAME, tempDir.name):
355  with open(currentManifestFilename, 'rb') as manifestFile:
356  currentManifest = json.load(manifestFile)
357 
358  command = "cd %s; " % (options.install_dir)
359  command += manifestCommand + " generate"
360  command += " -n " + bundleInfo["name"]
361  command += " -t " + statusTag
362  command += " -b " + currentManifestFilename
363  command += " " + bundleInfo["dir"]
364  if "extra" in bundleInfo:
365  command += " " + bundleInfo["extra"]
366 
367  # command = [manifestCommand, "generate",
368  # "-n", bundleInfo["name"],
369  # "-t", statusTag,
370  # "-b", currentManifestFilename,
371  # bundleInfo["dir"]]
372  # if "extra" in bundleInfo:
373  # command += bundleInfo["extra"].split()
374  statusManifest = json.loads(runCommand(command, pipe=True, shellVal=True))
375 
376  if "tags" in currentManifest:
377  tagList = currentManifest["tags"]
378  versionStr = "("
379  if len(tagList) > 1:
380  versionStr += tagList[0] + ".."
381  versionStr += tagList[-1] + ")"
382  print(bundleInfo["name"], versionStr)
383  else:
384  print(bundleInfo["name"])
385 
386 
387 
388  # list new files
389  fileList = []
390  for f, info in statusManifest["files"].items():
391  if ("files" not in currentManifest) or (f not in currentManifest["files"]):
392  fileList.append(f)
393  if options.create_change:
394  fileLst_chg.append("%s/%s/%s" % (options.install_dir, bundleInfo["dir"], f))
395  fileLst_relPath_chg.append("%s/%s" % (bundleInfo["dir"], f))
396  if fileList:
397  returnStatus = False
398  print(" New Files:")
399  for f in fileList:
400  print(" %s/%s" % (bundleInfo["dir"], f))
401 
402  # list modified files
403  fileList = []
404  for f, info in statusManifest["files"].items():
405  if ("files" in currentManifest) and (f in currentManifest["files"]):
406  if "symlink" in currentManifest["files"][f]:
407  # both symlink
408  if "symlink" in info:
409  if info["symlink"] != currentManifest["files"][f]["symlink"]:
410  fileList.append(f)
411  if options.create_change:
412  fileLst_chg.append("%s/%s/%s" % (options.install_dir, bundleInfo["dir"], f))
413  fileLst_relPath_chg.append("%s/%s" % (bundleInfo["dir"], f))
414  # remote symlink
415  else:
416  fileList.append(f)
417  if options.create_change:
418  fileLst_chg.append("%s/%s/%s" % (options.install_dir, bundleInfo["dir"], f))
419  fileLst_relPath_chg.append("%s/%s" % (bundleInfo["dir"], f))
420  # local symlink
421  elif "symlink" in info:
422  fileList.append(f)
423  if options.create_change:
424  fileLst_chg.append("%s/%s/%s" % (options.install_dir, bundleInfo["dir"], f))
425  fileLst_relPath_chg.append("%s/%s" % (bundleInfo["dir"], f))
426  # neither symlink
427  elif info["tag"] != currentManifest["files"][f]["tag"]:
428  localFilename = "%s/%s/%s" % (options.install_dir, bundleInfo["dir"], f)
429  with open(localFilename, "rb") as localFile:
430  bytes = localFile.read()
431  localFileChecksum = hashlib.sha256(bytes).hexdigest()
432  if "checksum" in currentManifest["files"][f]:
433  if localFileChecksum != currentManifest["files"][f]["checksum"]:
434  fileList.append(f)
435  if options.create_change:
436  fileLst_chg.append("%s/%s/%s" % (options.install_dir, bundleInfo["dir"], f))
437  fileLst_relPath_chg.append("%s/%s" % (bundleInfo["dir"], f))
438  if fileList:
439  returnStatus = False
440  print(" Modified Files:")
441  for f in fileList:
442  print(" %s/%s" % (bundleInfo["dir"], f))
443  if options.diff:
444  if "symlink" in currentManifest["files"][f]:
445  # both symlink
446  if "symlink" in "symlink" in statusManifest["files"][f]:
447  print("diff %s remote..local" % (f))
448  print("< " + currentManifest["files"][f]["tag"] + " = " + currentManifest["files"][f]["symlink"])
449  print("---")
450  print("> current dir = " + statusManifest["files"][f]["symlink"])
451  # remote symlink
452  else:
453  print("diff %s remote..local" % (f))
454  print("< " + currentManifest["files"][f]["tag"] + " = " + currentManifest["files"][f]["symlink"])
455  print("---")
456  print("> current dir = Not a symlink")
457  # local symlink
458  elif "symlink" in "symlink" in statusManifest["files"][f]:
459  print("diff %s remote..local" % (f))
460  print("< " + currentManifest["files"][f]["tag"] + " = Not a symlink")
461  print("---")
462  print("> current dir = " + statusManifest["files"][f]["symlink"])
463  #neither symlink
464  else:
465  try:
466  if re.search('root', bundleInfo["name"]):
467  localFilename = "%s/%s" % (options.install_dir, f)
468  else:
469  localFilename = "%s/%s/%s" % (options.install_dir, bundleInfo["dir"], f)
470  with open(localFilename) as file_1:
471  file_1_text = file_1.readlines()
472  remoteFilename = "%s/%s" % (tempDir.name, f)
473  file_tag = currentManifest["files"][f]["tag"]
474  if downloadFile(options, file_tag, bundleInfo, f, tempDir.name):
475  if options.difftool is not None:
476  command = "%s %s %s" % (options.difftool, remoteFilename, localFilename)
477  subprocess.run(command, shell=True)
478  else:
479  print("diff %s remote..local" % (f))
480  command = "diff %s %s" % (remoteFilename, localFilename)
481  subprocess.run(command, shell=True)
482 
483  except:
484  continue
485 
486  # deleted file
487  fileList = []
488  if "files" in currentManifest:
489  for f, info in currentManifest["files"].items():
490  if f not in statusManifest["files"]:
491  fileList.append(f)
492  if options.create_change:
493  # fileLst_del.append("%s/%s/%s" % (options.install_dir, bundleInfo["dir"], f))
494  fileLst_del.append("%s/%s" % (bundleInfo["dir"], f))
495  if fileList:
496  returnStatus = False
497  print(" Deleted Files:")
498  for f in fileList:
499  print(" %s/%s" % (bundleInfo["dir"], f))
500  return returnStatus
501 
502 def status(options):
503  global bundleList
504 
505  # theInstalledTag = getInstalledTag(options)
506  # print("installedTag =", theInstalledTag)
507 
508  # if not options.tag:
509  # options.tag = theInstalledTag
510 
511  theStatus = True
512  bundle_found = False
513  theInstalledTag = ''
514  fileList_change = []
515  #relative path of the fileList_change
516  fileList_relPath_change = []
517  fileList_delete = []
518 
519 
520  #loop through provided bundles e.g. --hico
521  for bundleInfo in bundleList:
522  if hasattr(options, bundleInfo["name"]) and getattr(options, bundleInfo["name"]):
523  # if not re.search("root", bundleInfo["name"]):
524  if not theInstalledTag:
525  theInstalledTag = getInstalledTag(options)
526  print("installedTag =", theInstalledTag)
527 
528  if not options.tag:
529  options.tag = theInstalledTag
530  if os.path.exists("%s/%s/%s" % (options.install_dir, bundleInfo["dir"], MANIFEST_BASENAME)):
531  bundle_found = True
532  if not bundleStatus(options, bundleInfo, fileList_change, fileList_relPath_change, fileList_delete):
533  theStatus = False
534 
535  if not bundle_found:
536  startingDir = os.path.abspath(os.getcwd())
537  for bundleInfo in bundleList:
538  bundleDir = os.path.abspath(os.path.join(options.install_dir, bundleInfo["dir"]))
539  if startingDir not in bundleDir:
540  continue
541  if not re.search("root", bundleInfo["name"]):
542  if not theInstalledTag:
543  theInstalledTag = getInstalledTag(options)
544  print("installedTag =", theInstalledTag)
545 
546  if not options.tag:
547  options.tag = theInstalledTag
548 
549  if os.path.exists("%s/%s/%s" % (options.install_dir, bundleInfo["dir"], MANIFEST_BASENAME)):
550  bundle_found = True
551  if not bundleStatus(options, bundleInfo, fileList_change, fileList_relPath_change, fileList_delete):
552  theStatus = False
553 
554  #loop through all the bundles
555  if not bundle_found:
556  theInstalledTag = getInstalledTag(options)
557  print("installedTag =", theInstalledTag)
558 
559  if not options.tag:
560  options.tag = theInstalledTag
561 
562  for bundleInfo in bundleList:
563  if os.path.exists("%s/%s/%s" % (options.install_dir, bundleInfo["dir"], MANIFEST_BASENAME)):
564  bundle_found = True
565  if not bundleStatus(options, bundleInfo, fileList_change, fileList_relPath_change, fileList_delete):
566  theStatus = False
567 
568  if options.create_change:
569  uid = runCommand("whoami", True)
570  date = datetime.date.today().strftime("%Y-%m-%d")
571  if len(fileList_change) != 0:
572  file_name = options.tag + "_" + date + "_" + str(uid, 'UTF-8').strip()
573  tar_filename = file_name + ".tar"
574  tar = tarfile.open(file_name + ".tar", "w")
575  print("Creating " + tar_filename)
576  for index, name in enumerate(fileList_change):
577  tar.add(name, fileList_relPath_change[index])
578  tar.close()
579 
580  if len(fileList_delete) != 0:
581  remove_filename = file_name + ".remove"
582  print("Creating " + remove_filename)
583  with open(file_name + ".remove", "w") as fp:
584  for name in fileList_delete:
585  # write each item on a new line
586  fp.write("%s\n" % name)
587 
588  if options.deliver_change or options.deliver_email_from is not None:
589  glusteruser_dir = "/glusteruser/analyst/share_delivery"
590 
591  if(os.path.exists(glusteruser_dir)):
592  if len(fileList_change) != 0:
593  print("Copying .tar to /glusteruser/analyst/share_delivery")
594  shutil.copyfile(tar_filename, os.path.join(glusteruser_dir, tar_filename))
595  if len(fileList_delete) != 0:
596  print("Copying .remove files to /glusteruser/analyst/share_delivery")
597  shutil.copyfile(remove_filename, os.path.join(glusteruser_dir, remove_filename))
598 
599  if len(fileList_change) != 0 or len(fileList_delete) != 0:
600  message = EmailMessage()
601  if len(fileList_delete) == 0:
602  print("Sending email to swdevels@oceancolor.gsfc.nasa.gov notifying the delivery of the .tar files")
603  message.set_content(tar_filename)
604  message['Subject'] = '.tar file copied to /glusteruser/analyst/share_delivery'
605  elif len(fileList_change) == 0:
606  print("Sending email to swdevels@oceancolor.gsfc.nasa.gov notifying the delivery of the .remove files")
607  message.set_content(remove_filename)
608  message['Subject'] = '.remove file copied to /glusteruser/analyst/share_delivery'
609  else:
610  print("Sending email to swdevels@oceancolor.gsfc.nasa.gov notifying the delivery of the .tar and .remove files")
611  message.set_content(tar_filename + "\n" + remove_filename)
612  message['Subject'] = '.tar and.remove file copied to /glusteruser/analyst/share_delivery'
613 
614  if options.deliver_email_from is not None:
615  message['From'] = options.deliver_email_from
616  elif options.deliver_change:
617  install_ocssw_config_filename = os.path.join(os.path.expanduser('~'), ".install_ocssw")
618  with open(install_ocssw_config_filename, "r") as file_email:
619  message['From'] = file_email.readlines()[0].strip().split('deliver_email_from=')[1]
620  message['To'] = 'swdevels@oceancolor.gsfc.nasa.gov'
621 
622  smtp_server = smtplib.SMTP('localhost')
623  smtp_server.send_message(message)
624  smtp_server.quit()
625  else:
626  print("You do not have access to /glusteruser/analyst/share_dir")
627 
628 
629  return theStatus
630 
631 def update(options):
632  global bundleList
633  global totalNumThings
634 
635  theInstalledTag = getInstalledTag(options)
636  print("installedTag =", theInstalledTag)
637 
638  # count the number of bundles to install
639  totalNumThings = 0
640  for bundleInfo in bundleList:
641  if os.path.exists("%s/%s/%s" % (options.install_dir, bundleInfo["dir"], MANIFEST_BASENAME)):
642  totalNumThings += 1
643 
644  for bundleInfo in bundleList:
645  if os.path.exists("%s/%s/%s" % (options.install_dir, bundleInfo["dir"], MANIFEST_BASENAME)):
646  installBundle(options, bundleInfo)
647 
648  recordInstalledTag(options)
649 
650 def run():
651  global totalNumThings
652  global bundleList
653 
654  # first make a parser to download the bundleInfo file
655  parser = argparse.ArgumentParser(description="Install OCSSW bundles", add_help=False)
656  parser.add_argument("-t", "--tag", default=None,
657  help="tag that you want to install")
658  parser.add_argument("-b", "--base_url", default=baseUrl,
659  help="remote url for the bundle server")
660  parser.add_argument("-l", "--local_dir", default=None,
661  help="local directory to use for bundle source instead of the bundle server")
662  parser.add_argument("--wget", default=False, action="store_true",
663  help="use wget for file download")
664  parser.add_argument("--list_tags", default=False, action="store_true",
665  help="list the tags that exist on the server")
666  parser.add_argument("--version", default=False, action="store_true",
667  help="print this program's version")
668 
669  options1 = parser.parse_known_args()
670  if not options1[0].list_tags and not options1[0].version:
671  downloadBundleList(options1[0])
672 
673  epilog = """
674  The content of the config file ~/.install_ocssw --
675  deliver_email_from=a valid email address that is on the list of swdevels@oceancolor.gsfc.nasa.gov
676  """
677  # now make the real parser
678  parser = argparse.ArgumentParser(description="Install OCSSW bundles", epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter,)
679  parser.add_argument("--version", default=False, action="store_true",
680  help="print this program's version")
681  parser.add_argument("--list_tags", default=False, action="store_true",
682  help="list the tags that exist on the server")
683  parser.add_argument("--installed_tag", default=False, action="store_true",
684  help="list the currently installed tag")
685  parser.add_argument("--status", default=False, action="store_true",
686  help="compare the main tag manifest to the files in the bundle directories")
687  parser.add_argument("--update", default=False, action="store_true",
688  help="update all installed bundles to the tag given")
689  parser.add_argument("--diff", default=False, action="store_true",
690  help="show the difference between the old and new text files")
691  parser.add_argument("--difftool", default=None,
692  help="show the difference between the old and new text files using diff tool such as meld")
693  parser.add_argument("--create_change", default=False, action="store_true",
694  help="create a tar file of new and modified files and a text file with a list of files to be deleted")
695  parser.add_argument("--deliver_change", default=False, action="store_true",
696  help="create and copy to /glusteruser/analyst/share_delivery/ a tar file of new and modified files and a text file with a list of files to be deleted, and email to swdevels@oceancolor.gsfc.nasa.gov from the email address stored in .install_ocssw")
697  parser.add_argument("--deliver_email_from", default=None,
698  help="create and copy to /glusteruser/analyst/share_delivery/ a tar file of new and modified files and a text file with a list of files to be deleted, and email to swdevels@oceancolor.gsfc.nasa.gov from the email address you provide")
699  parser.add_argument("-t", "--tag", default=None,
700  help="tag that you want to install")
701  parser.add_argument("-i", "--install_dir", default=os.environ.get("OCSSWROOT", None),
702  help="root directory for bundle installation (default=$OCSSWROOT)")
703  parser.add_argument("-b", "--base_url", default=baseUrl,
704  help="remote url for the bundle server")
705  parser.add_argument("-l", "--local_dir", default=None,
706  help="local directory to use for bundle source instead of the bundle server")
707  parser.add_argument("-s", "--save_dir", default=None,
708  help="local directory to save a copy of the downloaded bundles")
709  parser.add_argument("-c", "--clean", default=False, action="store_true",
710  help="delete extra files in the destination directory")
711  parser.add_argument("--wget", default=False, action="store_true",
712  help="use wget for file download")
713  parser.add_argument("-a", "--arch", default=None,
714  help="use this architecture instead of guessing the local machine (linux_64,linux_hpc,macosx_intel,macosx_arm64,odps)")
715  parser.add_argument("-v", "--verbose", action="count", default=0, help="increase output verbosity")
716 
717  # add weird bundle switches
718  parser.add_argument("--bin", default=False, action="store_true",
719  help="install binary executables")
720  parser.add_argument("--opt", default=False, action="store_true",
721  help="install 3rd party programs and libs")
722  parser.add_argument("--src", default=False, action="store_true",
723  help="install source files")
724  parser.add_argument("--luts", default=False, action="store_true",
725  help="install LUT files")
726  parser.add_argument("--viirs_l1_bin", default=False, action="store_true",
727  help="install VIIRS binary executables subset")
728 
729  # add bundles from the bundle list
730  for bundleInfo in bundleList:
731  if bundleInfo["commandLine"]:
732  parser.add_argument("--" + bundleInfo["name"], default=False, action="store_true",
733  help="install " + bundleInfo["help"] + " files")
734 
735  # add argument
736  parser.add_argument("--direct_broadcast", default=False, action="store_true",
737  help="toggle on bundles needed for MODIS direct broadcast")
738  parser.add_argument("--seadas", default=False, action="store_true",
739  help="toggle on the base set of bundles for SeaDAS")
740  parser.add_argument("--odps", default=False, action="store_true",
741  help="toggle on the base set of bundles for ODPS systems")
742  parser.add_argument("--viirs_l1", default=False, action="store_true",
743  help="install everything to run and test the VIIRS executables")
744  parser.add_argument("--all", default=False, action="store_true",
745  help="toggle on all satellite bundles")
746 
747  options = parser.parse_args()
748 
749  # print version
750  if options.version:
751  print(os.path.basename(sys.argv[0]), versionString)
752  sys.exit(0)
753 
754  if options.list_tags:
755  listTags(options)
756  sys.exit(0)
757 
758  if options.installed_tag:
759  installedTag(options)
760  sys.exit(0)
761 
762  # make sure arch is set
763  if not options.arch:
764  if options.odps:
765  options.arch = "odps"
766  else:
767  options.arch = getArch()
768 
769  if options.status:
770  options.diff = False
771  options.create_change = False
772  if status(options):
773  sys.exit(0)
774  else:
775  sys.exit(1)
776 
777  if options.difftool is not None:
778  options.diff = True
779 
780  if options.diff:
781  if status(options):
782  sys.exit(0)
783  else:
784  sys.exit(1)
785 
786  if options.deliver_change or options.deliver_email_from is not None:
787  options.create_change = True
788 
789  if options.create_change:
790  if status(options):
791  sys.exit(0)
792  else:
793  sys.exit(1)
794 
795  if not options.tag:
796  print("--tag is required")
797  sys.exit(1)
798 
799  if not options.install_dir:
800  print("--install_dir is required if OCSSWROOT enviroment variable is not set")
801  sys.exit(1)
802 
803  if options.update:
804  update(options)
805  sys.exit(0)
806 
807  # add convience arguments
808  if options.benchmark:
809  options.seadas = True
810  options.modisa = True
811 
812  if options.viirs_l1:
813  options.root = True
814  options.viirs_l1_bin = True
815  options.viirs_l1_benchmark = True
816  options.opt = True
817  options.luts = True
818  options.common = True
819  options.ocrvc = True
820  options.viirsn = True
821  options.viirsj1 = True
822  options.viirsdem = True
823 
824  if options.direct_broadcast:
825  options.seadas = True
826  options.modisa = True
827  options.modist = True
828 
829  if options.seadas:
830  options.root = True
831  options.bin =True
832  options.opt = True
833  options.luts = True
834  options.common = True
835  options.ocrvc = True
836 
837  if options.odps:
838  options.root = True
839  options.bin =True
840  options.opt = True
841  options.common = True
842  options.ocrvc = True
843  options.all = True
844 
845  if options.all:
846  for bundleInfo in bundleList:
847  if bundleInfo["commandLine"]:
848  if "share/" in bundleInfo["dir"]:
849  setattr(options, bundleInfo["name"], True)
850 
851  # unset silly sensors for ODPS
852  if options.odps:
853  options.opt_src = False
854  if hasattr(options, "benchmark"):
855  options.benchmark = False
856  if hasattr(options, "afrt"):
857  options.afrt = False
858  if hasattr(options, "aquaverse"):
859  options.aquaverse = False
860  options.avhrr = False
861  options.aviris = False
862  options.l5tm = False
863  options.l7etmp = False
864  if hasattr(options, "misr"):
865  options.misr = False
866  options.mos = False
867  options.msi = False
868  if hasattr(options, "msis2a"):
869  options.msis2a = False
870  options.msis2b = False
871  options.ocm1 = False
872  options.ocia = False
873  options.ocip = False
874  options.ocm2 = False
875  options.oli = False
876  if hasattr(options, "olil8"):
877  options.olil8 = False
878  options.olil9 = False
879  options.osmi = False
880  options.prism = False
881  options.sabiamar = False
882  options.sgli = False
883  options.wv3 = False
884  options.benchmark = False
885  if hasattr(options, "viirs_l1_benchmark"):
886  options.viirs_l1_benchmark = False
887 
888  # take care of the sub-sensors
889  if options.modisa or options.modist:
890  options.modis = True
891  if hasattr(options, "msis2a"):
892  if options.msis2a or options.msis2b:
893  options.msi = True
894  if options.viirsn or options.viirsj1:
895  options.viirs = True
896  if hasattr(options, "viirsj2"):
897  if options.viirsj2:
898  options.viirs = True
899  if hasattr(options, "olcis3a"):
900  if options.olcis3a or options.olcis3b:
901  options.olci = True
902  if hasattr(options, "olil8"):
903  if options.olil8 or options.olil9:
904  options.oli = True
905  options.olil8 = True # This is needed since L9 is a symbolic link to L8 LUTS
906 
907  # make sure bin and viirs_l1_bin are not both set
908  if options.bin and options.viirs_l1_bin:
909  print("Error: Can not install --bin and --viirs_l1_bin")
910  sys.exit(1)
911 
912  # turn off binary options if installdir is a git repo
913  if os.path.isdir(options.install_dir + "/.git"):
914  if options.root or options.bin or options.opt or options.viirs_l1_bin:
915  print("Turning off root, bin, opt and viirs_l1_bin since you are installing into a git repo")
916  options.root = False
917  options.bin = False
918  options.opt = False
919  options.viirs_l1_bin = False
920 
921  # always install the python bundle if it exists
922  if hasattr(options, "python"):
923  options.python = True
924 
925  # count the things we are going to install
926  totalNumThings = 0
927  for bundleInfo in bundleList:
928  if hasattr(options, bundleInfo["name"]) and getattr(options, bundleInfo["name"]):
929  totalNumThings += 1
930 
931  # count bin and lib bundles
932  if options.bin:
933  totalNumThings += 2
934 
935  # count viirs_l1_bin and lib bundles
936  if options.viirs_l1_bin:
937  totalNumThings += 2
938 
939  # count the opt bundle
940  if options.opt:
941  totalNumThings += 1
942 
943  # count source bundles (ocssw-src and opt/src)
944  if options.src:
945  totalNumThings += 2
946 
947  # record the installed tag if any bundles are getting installed
948  if totalNumThings > 0:
949  recordInstalledTag(options)
950 
951  # now install the bundles
952 
953  # do the weird bundles
954  if options.bin:
955  bundleName = "bin_" + options.arch
956  bundleInfo = findBundleInfo(bundleName)
957  bundleInfo["dir"] = "bin" # fix the install directory
958  installBundle(options, bundleInfo)
959 
960  if options.viirs_l1_bin:
961  bundleName = "viirs_l1_bin_" + options.arch
962  bundleInfo = findBundleInfo(bundleName)
963  if not bundleInfo:
964  print("Error: tag does not contain the viirs_l1_bin bundles")
965  sys.exit(1)
966  bundleInfo["dir"] = "bin" # fix the install directory
967  installBundle(options, bundleInfo)
968 
969  if options.bin or options.viirs_l1_bin:
970  bundleName = "lib_" + options.arch
971  bundleInfo = findBundleInfo(bundleName)
972  bundleInfo["dir"] = "lib" # fix the install directory
973  installBundle(options, bundleInfo)
974 
975  if options.opt:
976  bundleName = "opt_" + options.arch
977  bundleInfo = findBundleInfo(bundleName)
978  bundleInfo["dir"] = "opt" # fix the install directory
979  installBundle(options, bundleInfo)
980 
981  if options.src:
982  bundleInfo = findBundleInfo("opt_src")
983  installBundle(options, bundleInfo)
984  bundleInfo = findBundleInfo("ocssw_src")
985  installBundle(options, bundleInfo)
986 
987  # do the normal bundles
988  for bundleInfo in bundleList:
989  if hasattr(options, bundleInfo["name"]) and getattr(options, bundleInfo["name"]):
990  installBundle(options, bundleInfo)
991 
992  # update luts
993  if options.luts:
994  commonUpdated = False
995  for bundleInfo in bundleList:
996  if hasattr(options, bundleInfo["name"]) and getattr(options, bundleInfo["name"]):
997  if bundleInfo["name"] in lutBundles:
998  updateLuts(options, bundleInfo["name"])
999  commonUpdated = True
1000  # make sure var/common gets updated
1001  if not commonUpdated:
1002  updateLuts(options, "common")
1003 
1004  print("Done\n")
1005 
1006 if __name__ == "__main__":
1007  sys.exit(run())
def installedTag(options)
def listTags(options)
def getBundleListTag(manifestFilename)
def recordInstalledTag(options)
def update(options)
def findBundleInfo(bundleName)
character(len=1000) if
Definition: names.f90:13
def downloadBundleList(options)
def status(options)
def bundleStatus(options, bundleInfo, fileLst_chg, fileLst_relPath_chg, fileLst_del)
void print(std::ostream &stream, const char *format)
Definition: PrintDebug.hpp:38
def downloadFile(options, tag, bundleInfo, fileName, destDir)
def runCommand(command, pipe=False, shellVal=False)
def getInstalledTag(options)
def installBundle(options, bundleInfo)
def updateLuts(options, lut)
def checkTag(options)
Definition: aerosol.c:136