1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
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
89
90 _install_dir = None
91 _ui = None
92 _package = None
93 _directory = None
94 _modules = None
95
96
97
98
101
102
103
106
108 osh.core.RemoteOp.setup(self,
109 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
124
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
143
145 try:
146
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
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
179
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
193 if self._install_dir:
194 return self._install_dir
195 else:
196 return '/%s/lib/python%s.%s/site-packages' % install_info
197
199 if self._package:
200 path = self._package.replace('.', '/')
201 else:
202 path = ''
203 return path
204