1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
70
72
73 _install_dir = None
74 _package = None
75 _directory = None
76 _modules = None
77
78
79
80
83
84
85
88
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
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
113
115
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
127
128 ui = property(lambda self: self.command_state())
129
130 host = property(lambda self: self.thread_state)
131
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
145 host = self.host
146 ui = self.ui
147 try:
148
149 stage = 1
150 version_command = ""
151 output, errors = ssh(self.user(),
152 host.address,
153 "python -c 'import sys; print (sys.prefix,) + sys.version_info[0:2]'")
154 package_dir = self.package_dir()
155 install_dir = self.install_dir(eval(output[0])) + '/' + package_dir
156 if package_dir != '':
157 ssh(self.user(),
158 host.address,
159 'mkdir -p %s' % install_dir)
160 ui.ok(host.name, stage)
161
162 stage = 2
163 if self._directory:
164 flags = '-rp'
165 sources = '%s/*' % self._directory
166 elif self._modules:
167 flags = '-p'
168 sources = ' '.join(self._modules)
169 else:
170 assert False
171 scp(self.user(), host.address, flags, sources, install_dir)
172 ui.ok(host.name, stage)
173 except:
174 (exc_type, exc_value, exc_traceback) = sys.exc_info()
175 message = str(exc_value).strip()
176 ui.error(host.name, stage, message)
177
179 if self._install_dir:
180 return self._install_dir
181 else:
182 return '/%s/lib/python%s.%s/site-packages' % install_info
183
185 if self._package:
186 path = self._package.replace('.', '/')
187 else:
188 path = ''
189 return path
190