summaryrefslogtreecommitdiffstats
path: root/scripts/lib/mic/rt_util.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lib/mic/rt_util.py')
-rw-r--r--scripts/lib/mic/rt_util.py223
1 files changed, 223 insertions, 0 deletions
diff --git a/scripts/lib/mic/rt_util.py b/scripts/lib/mic/rt_util.py
new file mode 100644
index 0000000000..2a31f4a218
--- /dev/null
+++ b/scripts/lib/mic/rt_util.py
@@ -0,0 +1,223 @@
1#!/usr/bin/python -tt
2#
3# Copyright (c) 2009, 2010, 2011 Intel, Inc.
4#
5# This program is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License as published by the Free
7# Software Foundation; version 2 of the License
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12# for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc., 59
16# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18from __future__ import with_statement
19import os
20import sys
21import glob
22import re
23import shutil
24import subprocess
25
26from mic import bootstrap, msger
27from mic.conf import configmgr
28from mic.utils import errors, proxy
29from mic.utils.fs_related import find_binary_path, makedirs
30from mic.chroot import setup_chrootenv, cleanup_chrootenv
31
32expath = lambda p: os.path.abspath(os.path.expanduser(p))
33
34def bootstrap_mic(argv=None):
35
36
37 def mychroot():
38 os.chroot(rootdir)
39 os.chdir(cwd)
40
41 # by default, sys.argv is used to run mic in bootstrap
42 if not argv:
43 argv = sys.argv
44 if argv[0] not in ('/usr/bin/mic', 'mic'):
45 argv[0] = '/usr/bin/mic'
46
47 cropts = configmgr.create
48 bsopts = configmgr.bootstrap
49 distro = bsopts['distro_name'].lower()
50
51 rootdir = bsopts['rootdir']
52 pkglist = bsopts['packages']
53 cwd = os.getcwd()
54
55 # create bootstrap and run mic in bootstrap
56 bsenv = bootstrap.Bootstrap(rootdir, distro, cropts['arch'])
57 bsenv.logfile = cropts['logfile']
58 # rootdir is regenerated as a temp dir
59 rootdir = bsenv.rootdir
60
61 if 'optional' in bsopts:
62 optlist = bsopts['optional']
63 else:
64 optlist = []
65
66 try:
67 msger.info("Creating %s bootstrap ..." % distro)
68 bsenv.create(cropts['repomd'], pkglist, optlist)
69
70 # bootstrap is relocated under "bootstrap"
71 if os.path.exists(os.path.join(rootdir, "bootstrap")):
72 rootdir = os.path.join(rootdir, "bootstrap")
73
74 bsenv.dirsetup(rootdir)
75 sync_mic(rootdir)
76
77 #FIXME: sync the ks file to bootstrap
78 if "/" == os.path.dirname(os.path.abspath(configmgr._ksconf)):
79 safecopy(configmgr._ksconf, rootdir)
80
81 msger.info("Start mic in bootstrap: %s\n" % rootdir)
82 bindmounts = get_bindmounts(cropts)
83 ret = bsenv.run(argv, cwd, rootdir, bindmounts)
84
85 except errors.BootstrapError, err:
86 msger.warning('\n%s' % err)
87 if msger.ask("Switch to native mode and continue?"):
88 return
89 raise
90 except RuntimeError, err:
91 #change exception type but keep the trace back
92 value, tb = sys.exc_info()[1:]
93 raise errors.BootstrapError, value, tb
94 else:
95 sys.exit(ret)
96 finally:
97 bsenv.cleanup()
98
99def get_bindmounts(cropts):
100 binddirs = [
101 os.getcwd(),
102 cropts['tmpdir'],
103 cropts['cachedir'],
104 cropts['outdir'],
105 cropts['local_pkgs_path'],
106 ]
107 bindfiles = [
108 cropts['logfile'],
109 configmgr._ksconf,
110 ]
111
112 for lrepo in cropts['localrepos']:
113 binddirs.append(lrepo)
114
115 bindlist = map(expath, filter(None, binddirs))
116 bindlist += map(os.path.dirname, map(expath, filter(None, bindfiles)))
117 bindlist = sorted(set(bindlist))
118 bindmounts = ';'.join(bindlist)
119 return bindmounts
120
121
122def get_mic_binpath():
123 fp = None
124 try:
125 import pkg_resources # depends on 'setuptools'
126 except ImportError:
127 pass
128 else:
129 dist = pkg_resources.get_distribution('mic')
130 # the real script is under EGG_INFO/scripts
131 if dist.has_metadata('scripts/mic'):
132 fp = os.path.join(dist.egg_info, "scripts/mic")
133
134 if fp:
135 return fp
136
137 # not found script if 'flat' egg installed
138 try:
139 return find_binary_path('mic')
140 except errors.CreatorError:
141 raise errors.BootstrapError("Can't find mic binary in host OS")
142
143
144def get_mic_modpath():
145 try:
146 import mic
147 except ImportError:
148 raise errors.BootstrapError("Can't find mic module in host OS")
149 path = os.path.abspath(mic.__file__)
150 return os.path.dirname(path)
151
152def get_mic_libpath():
153 # TBD: so far mic lib path is hard coded
154 return "/usr/lib/mic"
155
156# the hard code path is prepared for bootstrap
157def sync_mic(bootstrap, binpth = '/usr/bin/mic',
158 libpth='/usr/lib',
159 pylib = '/usr/lib/python2.7/site-packages',
160 conf = '/etc/mic/mic.conf'):
161 _path = lambda p: os.path.join(bootstrap, p.lstrip('/'))
162
163 micpaths = {
164 'binpth': get_mic_binpath(),
165 'libpth': get_mic_libpath(),
166 'pylib': get_mic_modpath(),
167 'conf': '/etc/mic/mic.conf',
168 }
169
170 if not os.path.exists(_path(pylib)):
171 pyptn = '/usr/lib/python?.?/site-packages'
172 pylibs = glob.glob(_path(pyptn))
173 if pylibs:
174 pylib = pylibs[0].replace(bootstrap, '')
175 else:
176 raise errors.BootstrapError("Can't find python site dir in: %s" %
177 bootstrap)
178
179 for key, value in micpaths.items():
180 try:
181 safecopy(value, _path(eval(key)), False, ["*.pyc", "*.pyo"])
182 except (OSError, IOError), err:
183 raise errors.BootstrapError(err)
184
185 # auto select backend
186 conf_str = file(_path(conf)).read()
187 conf_str = re.sub("pkgmgr\s*=\s*.*", "pkgmgr=auto", conf_str)
188 with open(_path(conf), 'w') as wf:
189 wf.write(conf_str)
190
191 # chmod +x /usr/bin/mic
192 os.chmod(_path(binpth), 0777)
193
194 # correct python interpreter
195 mic_cont = file(_path(binpth)).read()
196 mic_cont = "#!/usr/bin/python\n" + mic_cont
197 with open(_path(binpth), 'w') as wf:
198 wf.write(mic_cont)
199
200
201def safecopy(src, dst, symlinks=False, ignore_ptns=()):
202 if os.path.isdir(src):
203 if os.path.isdir(dst):
204 dst = os.path.join(dst, os.path.basename(src))
205 if os.path.exists(dst):
206 shutil.rmtree(dst, ignore_errors=True)
207
208 src = src.rstrip('/')
209 # check common prefix to ignore copying itself
210 if dst.startswith(src + '/'):
211 ignore_ptns = list(ignore_ptns) + [ os.path.basename(src) ]
212
213 ignores = shutil.ignore_patterns(*ignore_ptns)
214 try:
215 shutil.copytree(src, dst, symlinks, ignores)
216 except (OSError, IOError):
217 shutil.rmtree(dst, ignore_errors=True)
218 raise
219 else:
220 if not os.path.isdir(dst):
221 makedirs(os.path.dirname(dst))
222
223 shutil.copy2(src, dst)