pymtt
 All Classes Namespaces Files Functions Variables Groups
ModuleCmd.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #
3 # Copyright (c) 2015-2018 Intel, Inc. All rights reserved.
4 # $COPYRIGHT$
5 #
6 # Additional copyrights may follow
7 #
8 # $HEADER$
9 #
10 
11 from __future__ import print_function
12 from future import standard_library
13 standard_library.install_aliases()
14 import sys
15 import select
16 import os
17 from io import StringIO
18 from BaseMTTUtility import *
19 
20 ## @addtogroup Utilities
21 # @{
22 # @section ModuleCmd
23 # Load/Unload an environmental module
24 # @}
26  def __init__(self):
27  BaseMTTUtility.__init__(self)
28  self.env_module_wrapper = None
29  self.env_module_link = None
30  self.options = {}
31  return
32 
33  def print_name(self):
34  return "ModuleCmd"
35 
36  def print_options(self, testDef, prefix):
37  lines = testDef.printOptions(self.options)
38  for line in lines:
39  print(prefix + line)
40  return
41 
42  def setCommand(self, options):
43  # Check first if the --env-module-wrapper switch was used. If not, then check for the LMOD_PKG environment variable.
44  if options['env_module_wrapper'] is not None:
45  self.env_module_wrapper = options['env_module_wrapper']
46  if not os.path.isfile(self.env_module_wrapper):
47  if options['verbose'] or options['debug'] :
48  print("Environment module python wrapper not found: " + self.env_module_wrapper)
49  return
50  else:
51  try:
52  mod_pkg = os.environ['MODULESHOME']
53  if os.path.isfile(os.path.join(mod_pkg, "init/env_modules_python.py")) :
54  self.env_module_wrapper = os.path.join(mod_pkg, "init/env_modules_python.py")
55  elif os.path.isfile(os.path.join(mod_pkg, "init/python.py")) :
56  self.env_module_wrapper = os.path.join(mod_pkg, "init/python.py")
57  else:
58  if options['verbose'] or options['debug'] :
59  print("The --env-module-wrapper switch was not used and module python support via os.environ['MODULESHOME']/init/env_modules_python.py was not found")
60  return
61  except KeyError:
62  if options['verbose'] or options['debug'] :
63  print("The --env-module-wrapper switch was not used and module python support via os.environ['MODULESHOME'] was not found")
64  return
65  try:
66  # scratchdir defaults to mttscratch if not set
67  self.env_module_link = os.path.join(options['scratchdir'], "env_modules_python.py")
68  if os.path.isfile(self.env_module_link) or os.path.islink(self.env_module_link):
69  os.remove(self.env_module_link)
70  # create a soft link that includes the .py extension; the tcl python module file does not include this
71  os.symlink(self.env_module_wrapper, self.env_module_link)
72  except:
73  print("Unable to link to " + self.env_module_wrapper)
74  print("Since we are unable to meet this basic user directive,")
75  print("we will now abort")
76  sys.exit(1)
77  return
78 
79  def loadModules(self, modules, testDef):
80  # Logging of results from the environment modules usage is the responsibility of the plugin that is making use of this utility.
81  if self.env_module_wrapper is None:
82  # cannot perform this operation
83  return (1, None, "Module capability was not found")
84 
85  # Load the lmod python module() definition
86  sys.path.insert(0, os.path.dirname(self.env_module_link))
87  try:
88  from env_modules_python import module
89  except:
90  return (1, None, "No module named env_modules_python found")
91 
92  # We have to run this in the same python context for it to take effect and be propagated to future children
93  # Redirect the sys.stdout and sys.stderr for the module loads and unloads.
94  saved_stdout = sys.stdout
95  saved_stderr = sys.stderr
96  load_stdout = sys.stdout = StringIO()
97  load_stderr = sys.stderr = StringIO()
98 
99  modules = modules.split()
100  for mod in modules:
101  mod = mod.strip()
102  try:
103  module("load", mod)
104  except:
105  # If a module name is not found the module python flow will trigger this exception.
106  return (1, None, "Attempt to load environment module " + mod + " failed")
107 
108  # Restore sys.stdout and sys.stderr
109  sys.stdout = saved_stdout
110  sys.stderr = saved_stderr
111 
112  status = load_stderr.seek(0, os.SEEK_END)
113  stdout = load_stdout.getvalue()
114  stderr = load_stderr.getvalue()
115  load_stdout.close()
116  load_stderr.close()
117  return (status, stdout, stderr)
118 
119  def unloadModules(self, modules, testDef):
120  if self.env_module_wrapper is None:
121  # cannot perform this operation
122  return (1, None, "Module capability was not found")
123 
124  # Load the lmod python module() definition
125  sys.path.insert(0, os.path.dirname(self.env_module_link))
126  try:
127  from env_modules_python import module
128  except:
129  return (1, None, "No module named env_modules_python found")
130 
131  # We have to run this in the same python context for it to take effect and be propagated to future children
132  # Redirect the sys.stdout and sys.stderr for the module loads and unloads.
133  saved_stdout = sys.stdout
134  saved_stderr = sys.stderr
135  unload_stdout = sys.stdout = StringIO()
136  unload_stderr = sys.stderr = StringIO()
137 
138  modules = modules.split()
139  for mod in modules:
140  mod = mod.strip()
141  try:
142  module("unload", mod)
143  except:
144  # Unlike the load, the module python flow will not cause an exception if the module can not be found.
145  # Add this to catch any other unexpected exceptions.
146  return (1, None, "Attempt to unload environment module " + mod + " failed")
147 
148  # Restore sys.stdout and sys.stderr
149  sys.stdout = saved_stdout
150  sys.stderr = saved_stderr
151 
152  status = unload_stderr.seek(0, os.SEEK_END)
153  stdout = unload_stdout.getvalue()
154  stderr = unload_stderr.getvalue()
155  unload_stdout.close()
156  unload_stderr.close()
157  return (status, stdout, stderr)