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

Source Code for Module osh.command.install

  1  # osh 
  2  # Copyright (C) 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 [-d INSTALL_DIRECTORY] [-p PACKAGE] DIRECTORY} 
 19   
 20  C{install [-d INSTALL_DIRECTORY] [-p PACKAGE] PYTHON_MODULE ...} 
 21   
 22  Installs Python modules a cluster. The cluster is identified using 
 23  remote execution syntax, for example:: 
 24   
 25      osh @fred [ install ~/foobar.py ] 
 26   
 27  If C{-d} is not 
 28  specified, then installation is to the standard site-packages 
 29  directory (e.g. /usr/lib/python2.4/site-packages). Otherwise, 
 30  installation goes to C{INSTALL_DIRECTORY}. (C{INSTALL_DIRECTORY} 
 31  replaces the entire path, not just the C{/usr} or C{/usr/lib} part of 
 32  the path.)  The modules are identified as individual 
 33  C{PYTHON_MODULE}s, (i.e. filenames ending in C{.py}), or as a 
 34  C{DIRECTORY} containing the modules of interest. In the latter case, 
 35  the contents of sub-directories will be copied also, as sub-packages 
 36  of C{PACKAGE}. 
 37   
 38  Modules are installed into the remote C{site-packages} directory, in 
 39  the subdirectory specified by C{PACKAGE}, (or in C{site-packages} 
 40  directly, if C{PACKAGE} is omitted). 
 41   
 42   
 43  For example, to install the local C{foo.bar} package on cluster 
 44  C{fred}:: 
 45   
 46      osh @fred [ install -p foo.bar ~/myproject/foo/bar ] 
 47   
 48  To install a single module, C{xyz}, directly in C{site-packages}:: 
 49   
 50      osh @fred [ install ~/myproject/util/xyz.py ] 
 51   
 52  Not available through the API. 
 53  """ 
 54   
 55  import os 
 56  import os.path 
 57  import sys 
 58   
 59  import osh.core 
 60  import osh.util 
 61   
 62  import progtrack 
 63   
 64  ssh = osh.util.ssh 
 65  scp = osh.util.scp 
 66   
 67  # CLI 
68 -def _install():
69 return _Install()
70
71 -class _Install(osh.core.RunLocal):
72 73 _install_dir = None 74 _package = None 75 _directory = None 76 _modules = None 77 78 79 # object interface 80
81 - def __init__(self):
82 osh.core.RunLocal.__init__(self, 'd:p:', (1, None))
83 84 # BaseOp interface 85
86 - def doc(self):
87 return __doc__
88
89 - def create_command_state(self, oshthreads):
90 ui = progtrack.ProgressTrackingUI('install') 91 ui.add_column('host', 25) 92 ui.add_column(['find', 'install dir'], 12); 93 ui.add_column('installed', 12) 94 for thread in oshthreads: 95 host = thread.state 96 ui.add_row(host.name) 97 return ui
98
99 - def setup(self):
100 args = self.args() 101 self._install_dir = args.string_arg('-d') 102 self._package = args.string_arg('-p') 103 sources = args.remaining() 104 if len(sources) == 1 and os.path.isdir(sources[0]): 105 self._directory = sources[0] 106 else: 107 for source in sources: 108 if not source.endswith('.py'): 109 self.usage() 110 self._modules = [x for x in sources]
111 112 # Generator interface 113
114 - def execute(self):
115 # UI object actually starts only on first call to start, ignores subsequent calls. 116 if self.thread_state: 117 self.ui.start() 118 try: 119 self.install_remote() 120 finally: 121 self.ui.stop() 122 else: 123 self.install_local()
124 125 126 # internals 127 128 ui = property(lambda self: self.command_state()) 129 130 host = property(lambda self: self.thread_state) 131
132 - def install_local(self):
133 install_dir = self.install_dir((sys.prefix,) + sys.version_info[0:2]) 134 if self._directory: 135 flags = '-Rp' 136 sources = '%s/*' % self._directory 137 elif self._modules: 138 flags = '-p' 139 sources = ' '.join(self._modules) 140 else: 141 assert False 142 os.system('cp %s %s %s' % (flags, sources, install_dir))
143
144 - def install_remote(self):
145 host = self.host 146 ui = self.ui 147 try: 148 # Find install directory 149 stage = 1 150 version_command = "" 151 output, errors = ssh(self.user(), 152 host.identity, 153 host.address, 154 "python -c 'import sys; print (sys.prefix,) + sys.version_info[0:2]'") 155 package_dir = self.package_dir() 156 install_dir = self.install_dir(eval(output[0])) + '/' + package_dir 157 if package_dir != '': 158 ssh(self.user(), 159 host.identity, 160 host.address, 161 'mkdir -p %s' % install_dir) 162 ui.ok(host.name, stage) 163 # Copy files 164 stage = 2 165 if self._directory: 166 flags = '-rp' 167 sources = '%s/*' % self._directory 168 elif self._modules: 169 flags = '-p' 170 sources = ' '.join(self._modules) 171 else: 172 assert False 173 scp(self.user(), host.identity, host.address, flags, sources, install_dir) 174 ui.ok(host.name, stage) 175 except: 176 (exc_type, exc_value, exc_traceback) = sys.exc_info() 177 message = str(exc_value).strip() 178 ui.error(host.name, stage, message)
179
180 - def install_dir(self, install_info):
181 if self._install_dir: 182 return self._install_dir 183 else: 184 return '/%s/lib/python%s.%s/site-packages' % install_info
185
186 - def package_dir(self):
187 if self._package: 188 path = self._package.replace('.', '/') 189 else: 190 path = '' 191 return path
192