Package osh :: Package command :: Module install
[frames] | no frames]

Source Code for Module osh.command.install

  1  # osh 
  2  # Copyright (C) 2005 Jack Orenstein <jao@geophile.com> 
  3  # 
  4  # This program is free software; you can redistribute it and/or modify 
  5  # it under the terms of the GNU General Public License as published by 
  6  # the Free Software Foundation; either version 2 of the License, or 
  7  # (at your option) any later version. 
  8  # 
  9  # This program is distributed in the hope that it will be useful, 
 10  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 12  # GNU General Public License for more details. 
 13  # 
 14  # You should have received a copy of the GNU General Public License 
 15  # along with this program; if not, write to the Free Software 
 16  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 17   
 18  """C{install [-c CLUSTER] [-d INSTALL_DIRECTORY] [-p PACKAGE] DIRECTORY} 
 19   
 20  C{install [-c CLUSTER] [-d INSTALL_DIRECTORY] [-p PACKAGE] PYTHON_MODULE ...} 
 21   
 22  Installs Python modules to each node of C{CLUSTER}.  If C{-d} is not 
 23  specified, then installation is to the standard site-packages 
 24  directory (e.g. /usr/lib/python2.4/site-packages). Otherwise, 
 25  installation goes to C{INSTALL_DIRECTORY}. (C{INSTALL_DIRECTORY} 
 26  replaces the entire path, not just the C{/usr} or C{/usr/lib} part of 
 27  the path.)  The modules are identified as individual 
 28  C{PYTHON_MODULE}s, (i.e. filenames ending in C{.py}), or as a 
 29  C{DIRECTORY} containing the modules of interest. In the latter case, 
 30  the contents of sub-directories will be copied also, as sub-packages 
 31  of C{PACKAGE}. 
 32   
 33  Modules are installed into the remote C{site-packages} directory, in 
 34  the subdirectory specified by C{PACKAGE}, (or in C{site-packages} 
 35  directly, if C{PACKAGE} is omitted). 
 36   
 37   
 38  For example, to install the local C{foo.bar} package on cluster 
 39  C{fred}:: 
 40   
 41      osh install -c fred -p foo.bar ~/myproject/foo/bar 
 42   
 43  To install a single module, C{xyz}, directly in C{site-packages}:: 
 44   
 45      osh install -c fred ~/myproject/util/xyz.py 
 46   
 47  If C{CLUSTER} is omitted, then installation is done locally.  
 48   
 49  Not available through the API. 
 50  """ 
 51   
 52  import os 
 53  import os.path 
 54  import sys 
 55   
 56  import osh.core 
 57  import osh.spawn 
 58  import progtrack 
 59   
 60  Spawn = osh.spawn.Spawn 
 61  SpawnSSH = osh.spawn.SpawnSSH 
 62  collect_lines = osh.spawn.collect_lines 
 63   
 64  # CLI 
65 -def _install():
66 return _Install()
67
68 -def _scp(user, host, flags, source, target):
69 err_lines = [] 70 scp_command = 'scp %s %s %s@%s:%s' % (flags, source, user, host, target) 71 Spawn(scp_command, 72 None, 73 None, 74 collect_lines(err_lines)).run() 75 if len(err_lines) > 0: 76 raise Exception(' '.join(err_lines))
77
78 -def _ssh(user, host, command):
79 out_lines = [] 80 SpawnSSH(user, 81 host, 82 command, 83 None, 84 collect_lines(out_lines), 85 None).run() 86 return out_lines
87
88 -class _Install(osh.core.RemoteOp):
89 90 _install_dir = None 91 _ui = None 92 _package = None 93 _directory = None 94 _modules = None 95 96 97 # object interface 98
99 - def __init__(self):
100 osh.core.RemoteOp.__init__(self, 'c:d:p:', (1, None))
101 102 # BaseOp interface 103
104 - def doc(self):
105 return __doc__
106
107 - def setup(self):
108 osh.core.RemoteOp.setup(self, 109 False # cluster_required = False 110 ) 111 self._install_dir = self.args().string_arg('-d') 112 self._package = self.args().string_arg('-p') 113 sources = self.args().remaining() 114 if len(sources) == 1 and os.path.isdir(sources[0]): 115 self._directory = sources[0] 116 else: 117 for source in sources: 118 if not source.endswith('.py'): 119 self.usage() 120 self._modules = [x for x in sources]
121 122 123 # Generator interface 124
125 - def execute(self):
126 if self.cluster(): 127 self._ui = progtrack.ProgressTrackingUI('install') 128 self._ui.add_column('host', 25) 129 self._ui.add_column(['find', 'install dir'], 12); 130 self._ui.add_column('installed', 12) 131 for host in self.hosts(): 132 self._ui.add_row(host.name) 133 self._ui.start() 134 try: 135 osh.core.RemoteOp.execute(self) 136 finally: 137 self._ui.stop() 138 else: 139 self.install_local()
140 141 142 # RemoteOp interface 143
144 - def action(self, host):
145 try: 146 # Find install directory 147 stage = 1 148 version_command = "" 149 output = _ssh(self.user(), 150 host.address, 151 "python -c 'import sys; print (sys.prefix,) + sys.version_info[0:2]'") 152 package_dir = self.package_dir() 153 install_dir = self.install_dir(eval(output[0])) + '/' + package_dir 154 if package_dir != '': 155 _ssh(self.user(), 156 host.address, 157 'mkdir -p %s' % install_dir) 158 159 self._ui.ok(host.name, stage) 160 # Copy files 161 stage = 2 162 if self._directory: 163 flags = '-rp' 164 sources = '%s/*' % self._directory 165 elif self._modules: 166 flags = '-p' 167 sources = ' '.join(self._modules) 168 else: 169 assert False 170 _scp(self.user(), host.address, flags, sources, install_dir) 171 self._ui.ok(host.name, stage) 172 except: 173 (exc_type, exc_value, exc_traceback) = sys.exc_info() 174 message = str(exc_value).strip() 175 self._ui.error(host.name, stage, message)
176 177 178 # For use by this class 179
180 - def install_local(self):
181 install_dir = self.install_dir((sys.prefix,) + sys.version_info[0:2]) 182 if self._directory: 183 flags = '-Rp' 184 sources = '%s/*' % self._directory 185 elif self._modules: 186 flags = '-p' 187 sources = ' '.join(self._modules) 188 else: 189 assert False 190 os.system('cp %s %s %s' % (flags, sources, install_dir))
191
192 - def install_dir(self, install_info):
193 if self._install_dir: 194 return self._install_dir 195 else: 196 return '/%s/lib/python%s.%s/site-packages' % install_info
197
198 - def package_dir(self):
199 if self._package: 200 path = self._package.replace('.', '/') 201 else: 202 path = '' 203 return path
204