HWRF  trunk@4391
cluster.py
1 """!Provides information about the cluster on which this job is running"""
2 
3 ##@var __all__
4 #List of symbols exported by "from produtil.cluster import *"
5 __all__=['Cluster','where','longname','name','group_quotas','acl_support',
6  'no_access_control','use_acl_for_rstdata','ncepprod',
7  'NOAAJet','NOAAGAEA','NOAAZeus','NOAAWCOSS']
8 
9 import time, socket, os
10 
11 ##@var DO_NOT_SET
12 # Special values for parameters that should not be set.
13 DO_NOT_SET=object()
14 
15 class Cluster(object):
16  """!Stores information about a computer cluster. """
17  def __init__(self,group_quotas,acl_support,production,name,longname,
18  use_acl_for_rstdata=None):
19  """!Sets all public member variables. All are mandatory except
20  use_acl_for_rstdata. The default for use_acl_for_Rstdata is
21  the logical AND of group_quotas and acl_support."""
22  self.group_quotas=bool(group_quotas)
23  self.acl_support=bool(acl_support)
24  if production is not DO_NOT_SET:
25  self.production=bool(production)
26  self.name=str(name)
27  self.longname=str(longname)
28  if use_acl_for_rstdata is None:
29  use_acl_for_rstdata=self.group_quotas and self.acl_support
30  self.use_acl_for_rstdata=use_acl_for_rstdata
31 
32  ##@var group_quotas
33  # True if group membership is used to manage disk
34  # quotas. If this is True, then the scripts should never copy the
35  # group ID when copying files.
36 
37  ##@var acl_support
38  # True if the system uses Access Control Lists (ACLs)
39  # to control access to files.
40 
41  ##@var use_acl_for_rstdata
42  # True if the scripts should use ACLs to
43  # protect restricted access data. If this is True, the scripts
44  # should copy ACLs when copying files. The produtil.acl supplies a
45  # way to do that on some Linux machines.
46 
47  ##@var production
48  # True if this system is production (real-time
49  # forecasting) environment, and False otherwise. Most systems
50  # should set this to False.
51 
52  ##@var name
53  # a short name of this cluster. Must be a valid Python
54  # identifier string.
55 
56  ##@var longname
57  # a long name of this cluster.
58 
59 ##@var here
60 # The Cluster object for the local cluster. Do not modify.
61 here=None
62 
63 def set_cluster(there):
64  """!Sets the current cluster (module-level "here" variable) to the
65  given value. Bad things may happen if this is not a subclass of
66  Cluster.
67  #@param there A Cluster object for this local cluster."""
68  global here
69  here=there
70 
71 def where():
72  """!Guesses what cluster the program is running on, and if it
73  cannot, returns a cluster named "noname" with reasonable defaults.
74  The result is stored in the module scope "here" variable."""
75  global here
76  if here is None:
77  if os.path.exists('/pan2'):
78  here=NOAAJet()
79  elif os.path.exists('/glade'):
80  here=UCARYellowstone()
81  elif os.path.exists('/data') and os.path.exists('/scratch') and \
82  os.path.exists('/home'):
83  here=WisconsinS4()
84  elif os.path.exists('/scratch3'):
85  theia=False
86  with open('/proc/cpuinfo','rt') as f:
87  for line in f.readlines(1000):
88  if line.find('E5-2690')>=0:
89  theia=True
90  break
91  if theia:
92  here=NOAATheia()
93  else:
94  here=NOAAZeus()
95  elif os.path.exists('/ptmpd2'):
96  here=NOAAWCOSS()
97  elif os.path.exists('/gpfs/hps/nco'):
98  here=WCOSSCray()
99  else:
100  here=Cluster(False,False,False,'noname','noname')
101  return here
102 
103 def longname():
104  """!Synonym for here.longname. Will call the "where()" function if
105  "here" is uninitialized."""
106  if here is None: where()
107  return here.longname
108 
109 def name():
110  """!Synonym for here.name. Will call the "where()" function if
111  "here" is uninitialized."""
112  if here is None: where()
113  return here.name
114 
116  """!Synonym for here.group_quotas. Will call the "where()" function if
117  "here" is uninitialized."""
118  if here is None: where()
119  return here.group_quotas
120 
122  """!Synonym for here.acl_support. Will call the "where()" function if
123  "here" is uninitialized."""
124  if here is None: where()
125  return here.acl_support
126 
128  """!True if the cluster provides no means to control access to
129  files. This is true if the cluster uses group ids for quotas, and
130  provides no access control list support."""
131  if here is None: where()
132  return here.group_quotas and not here.use_acl_for_rstdata
133 
135  """!Synonym for here.use_acl_for_rstdata. Will call the "where()"
136  function if "here" is uninitialized."""
137  if here is None: where()
138  return here.use_acl_for_rstdata
139 
140 def ncepprod():
141  """!Are we on NCEP production?
142 
143  @returns True if the present machine is the NCEP production
144  machine. Note that this function may read a text file when it is
145  called, and the return value may change during the execution of
146  the program if the program is running during a production switch."""
147  if here is None: where()
148  return here.production and ( here.name=='tide' or here.name=='gyre' )
149 
151  """!The NOAA Jet Cluster
152 
153  Represents the NOAA Jet cluster, which has non-functional ACL
154  support. Will report that ACLs are supported, but should not be
155  used. Also, group quotas are in use. That means that there is no
156  means by which to restrict access control, so no_access_control()
157  will return True."""
158  def __init__(self):
159  """!constructor for NOAAJet"""
160  super(NOAAJet,self).__init__(True,True,False,'jet',
161  'jet.rdhpcs.noaa.gov',False)
162 
164  """!Represents the NOAA GAEA cluster. Allows ACLs to be used for
165  restricted data, and specifies that group quotas are in use."""
166  def __init__(self):
167  """!constructor for NOAAGAEA"""
168  super(NOAAGAEA,self).__init__(True,True,False,'gaea',
169  'gaea.rdhpcs.noaa.gov')
170 
172  """!Represents the NOAA Zeus cluster. Allows ACLs to be used for
173  restricted data, and specifies that group quotas are in use."""
174  def __init__(self):
175  """!Constructor for NOAAZeus"""
176  super(NOAAZeus,self).__init__(True,True,False,'zeus',
177  'zeus.rdhpcs.noaa.gov')
178 
180  """!Represents the Yellowstone cluster. Does not allow ACLs,
181  assumes group quotas."""
182  def __init__(self):
183  """!Constructor for UCARYellowstone"""
184  super(UCARYellowstone,self).__init__(
185  True,False,False,'yellowstone','yellowstone.ucar.edu')
186 
188  """!Represents the S4 cluster. Does not allow ACLs, assumes group
189  quotas."""
190  def __init__(self):
191  """!Constructor for WisconsinS4"""
192  super(WisconsinS4,self).__init__(
193  True,False,False,'s4','s4.ssec.wisc.edu')
194 
196  """Represents the NOAA Theia cluster. Does not allow ACLs,
197  assumes no group quotas (fileset quotas instead)."""
198  def __init__(self):
199  super(NOAATheia,self).__init__(
200  False,False,False,'theia','theia.rdhpcs.noaa.gov')
201 
203  """!Represents the NOAA WCOSS clusters, Tide, Gyre and the test
204  system Eddy.
205 
206  Automatically determines which WCOSS the program is on based on
207  the first letter of socket.gethostname(). Will report no ACL
208  support, and no group quotas. Hence, the cluster should use group
209  IDs for access control.
210 
211  The production accessor is no longer a public member variable: it
212  is now a property, which may open the /etc/prod file. The result
213  of the self.production property is cached for up to
214  prod_cache_time seconds. That time can be specified in the
215  constructor, and defaults to 30 seconds."""
216  def __init__(self,prod_cache_time=30,name=None):
217  """!Creates a NOAAWCOSS object, and optionally specifies the
218  time for which the result of self.production should be cached.
219  Default: 30 seconds.
220  @param prod_cache_time how long to cache the prod vs. dev information, in seconds"""
221  if name is None:
222  host1=socket.gethostname()[0:1]
223  if host1=='t': name='tide'
224  elif host1=='g': name='gyre'
225  else: name='eddy'
226  super(NOAAWCOSS,self).__init__(False,False,DO_NOT_SET,name,
227  name+'.ncep.noaa.gov')
228  self._production=None
229  self._lastprod=0
230  self._prod_cache_time=int(prod_cache_time)
231  def uncache(self):
232  """!Clears the cached value of self.production so the next call
233  will return up-to-date information."""
234  self._production=None
235  self._lastprod=0
236  @property
237  def production(self):
238  """!Is this the WCOSS production machine?
239 
240  The return value may change during the execution of this
241  program if a production switch happened. In addition, the
242  check requires opening and parsing the /etc/prod file, so the
243  runtime is likely several milliseconds when the cache times
244  out. To force a refresh of this information, call
245  self.uncache() first."""
246  now=int(time.time())
247  if self._production is None or now-self._lastprod>self._prod_cache_time:
248  tide = self.name=='tide'
249  gyre = self.name=='gyre'
250  prod=False
251  with open('/etc/prod','/rt') as f:
252  for line in f:
253  if line.find('tide')>=0: prod=tide
254  if line.find('gyre')>=0: prod=gyre
255  self._production=prod
256  self._lastprod=int(time.time())
257  return prod
258  else:
259  return self._production
260 
262  """!This subclass of NOAAWCOSS handles the new Cray portions of WCOSS.
263  Presently, it always reports the name "luna" and says it is not production."""
264  def __init__(self,name=None):
265  """!Create a new WCOSSCray object describing this cluster as a Cray machine.
266  @property name The name of the cluster. Default: "luna" """
267  if name is None: name='luna'
268  super(WCOSSCray,self).__init__(name=name)
269  @property
270  def production(self):
271  """!Is this the WCOSS production machine? No. Returns False."""
272  return False
273  def uncache(self):
274  """!Does nothing. This is here to disable NOAAWCOSS.uncache()"""
The NOAA Jet Cluster.
Definition: cluster.py:150
def __init__
Creates a NOAAWCOSS object, and optionally specifies the time for which the result of self...
Definition: cluster.py:216
def no_access_control()
True if the cluster provides no means to control access to files.
Definition: cluster.py:127
Represents the NOAA WCOSS clusters, Tide, Gyre and the test system Eddy.
Definition: cluster.py:202
def where()
Guesses what cluster the program is running on, and if it cannot, returns a cluster named "noname" wi...
Definition: cluster.py:71
def ncepprod()
Are we on NCEP production?
Definition: cluster.py:140
def uncache(self)
Does nothing.
Definition: cluster.py:273
def __init__(self)
Constructor for WisconsinS4.
Definition: cluster.py:190
Represents the S4 cluster.
Definition: cluster.py:187
def uncache(self)
Clears the cached value of self.production so the next call will return up-to-date information...
Definition: cluster.py:231
def __init__(self)
constructor for NOAAJet
Definition: cluster.py:158
def use_acl_for_rstdata()
Synonym for here.use_acl_for_rstdata.
Definition: cluster.py:134
group_quotas
True if group membership is used to manage disk quotas.
Definition: cluster.py:22
def production(self)
Is this the WCOSS production machine?
Definition: cluster.py:237
def __init__(self)
Constructor for UCARYellowstone.
Definition: cluster.py:182
def __init__
Sets all public member variables.
Definition: cluster.py:18
def __init__(self)
Constructor for NOAAZeus.
Definition: cluster.py:174
acl_support
True if the system uses Access Control Lists (ACLs) to control access to files.
Definition: cluster.py:23
Stores information about a computer cluster.
Definition: cluster.py:15
def set_cluster(there)
Sets the current cluster (module-level "here" variable) to the given value.
Definition: cluster.py:63
def acl_support()
Synonym for here.acl_support.
Definition: cluster.py:121
use_acl_for_rstdata
True if the scripts should use ACLs to protect restricted access data.
Definition: cluster.py:30
def group_quotas()
Synonym for here.group_quotas.
Definition: cluster.py:115
Represents the NOAA GAEA cluster.
Definition: cluster.py:163
def __init__(self)
constructor for NOAAGAEA
Definition: cluster.py:166
Represents the Yellowstone cluster.
Definition: cluster.py:179
def name()
Synonym for here.name.
Definition: cluster.py:109
This subclass of NOAAWCOSS handles the new Cray portions of WCOSS.
Definition: cluster.py:261
def longname()
Synonym for here.longname.
Definition: cluster.py:103
production
True if this system is production (real-time forecasting) environment, and False otherwise.
Definition: cluster.py:25
name
a short name of this cluster.
Definition: cluster.py:26
longname
a long name of this cluster.
Definition: cluster.py:27
Represents the NOAA Zeus cluster.
Definition: cluster.py:171
def production(self)
Is this the WCOSS production machine? No.
Definition: cluster.py:270