2 # vim: ai ts=4 sts=4 et sw=4
4 # Copyright (c) 2007 Intel Corporation
6 # This program is free software; you can redistribute it and/or modify it
7 # under the terms of the GNU General Public License as published by the Free
8 # Software Foundation; version 2 of the License
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc., 59
17 # Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 class Platform(object):
37 The SDK is composed of a collection of platforms, where this class
38 represents a specific platform. A platform provides:
39 - a list of packages to install directly into the platform (i.e. to use as
40 a jailroot to isolate building target binaries from the host
42 - a set of fsets that can be installed into a target
44 def __init__(self
, platform_path
, platform_name
, config_info
= None):
45 self
.name
= platform_name
46 self
.path
= platform_path
47 if config_info
!= None:
49 for key
, value
in sorted(config_info
):
50 self
.config_info
[key
] = value
52 raise ValueError(_("Platform called but config_info value not passed in"))
53 # instantiate all fsets
54 self
.fset
= fsets
.FSet()
55 fset_path
= os
.path
.join(self
.path
, 'fsets')
56 for filename
in os
.listdir(fset_path
):
57 # Only load files which end with the .fset extension
58 if not filename
.endswith('.fset'):
60 full_path
= os
.path
.join(fset_path
, filename
)
61 self
.fset
.addFile(full_path
)
63 for section
in [ "platform.%s" % self
.name
, "platform" ]:
64 if mic_cfg
.config
.has_section(section
):
65 # section is now set to the appropriate section
68 print _("Error: No buildroot config file information found!")
71 # determine what packages additional packages need to be installed
72 # in the buildroot roostrap
73 packages
= mic_cfg
.config
.get(section
, "buildroot_extras")
74 self
.buildroot_extras
= packages
.split()
75 # determine what packages need to be installed in the buildroot
76 # (outside the rootstrap archive)
77 packages
= mic_cfg
.config
.get(section
, "buildroot_packages")
78 self
.buildroot_packages
= packages
.split()
79 # determine what mirror to use for the buildroot
80 self
.buildroot_mirror
= mic_cfg
.config
.get(section
, "buildroot_mirror")
81 # determine what codename to use for the buildroot mirror
82 self
.buildroot_codename
= mic_cfg
.config
.get(section
, "buildroot_codename")
83 # determine what components to use for the buildroot mirror
84 components
= mic_cfg
.config
.get(section
, "buildroot_components")
85 self
.buildroot_components
= components
.split()
86 # determine default kernel cmdline options
87 self
.usb_kernel_cmdline
= mic_cfg
.config
.get(section
, "usb_kernel_cmdline")
88 self
.hd_kernel_cmdline
= mic_cfg
.config
.get(section
, "hd_kernel_cmdline")
89 self
.cd_kernel_cmdline
= mic_cfg
.config
.get(section
, "cd_kernel_cmdline")
91 self
.architecture
= mic_cfg
.config
.get(section
, "architecture") or "i386"
93 if self
.config_info
['package_manager'] == 'apt':
94 self
.pkg_manager
= moblin_pkg
.AptPackageManager()
95 self
.createChroot
= self
.aptCreateChroot
96 elif self
.config_info
['package_manager'] == 'yum':
97 self
.pkg_manager
= moblin_pkg
.YumPackageManager()
98 self
.createChroot
= self
.yumCreateChroot
100 raise ValueError(_("package manager value of: '%s' is invalid") % self
.config_info
['package_manager'])
102 self
.target_os
= self
.config_info
['target_os']
105 return ("<Platform Object: \n\tname=%s, \n\tfset=%s, \n\tbuildroot_packages=%s>\n" %
106 (self
.name
, self
.fset
, self
.buildroot_packages
))
109 return "Platform( %s, '%s')" % (self
.path
, self
.name
)
111 def __createRootstrap(self
, chroot_dir
, rootstrap_file
, callback
= None):
112 cmd
= "tar -jcpvf %s -C %s ." % (rootstrap_file
, chroot_dir
)
114 result
= pdk_utils
.execCommand(cmd
, output
= output
, callback
= callback
)
116 print >> sys
.stderr
, _("ERROR: Unable to archive rootstrap!")
117 pdk_utils
.rmtree(chroot_dir
, callback
= callback
)
118 # FIXME: Better exception here
119 raise ValueError(" ".join(output
))
121 def aptCreateChroot(self
, chroot_dir
, use_rootstrap
, callback
= None):
122 """Create chroot in chroot_dir for using APT tools"""
123 if not os
.path
.exists(chroot_dir
):
124 os
.makedirs(chroot_dir
)
125 target_os
= self
.target_os
126 var_dir
= mic_cfg
.config
.get('general', 'var_dir')
127 rootstrap_file
= os
.path
.join(var_dir
, "rootstraps", "apt", target_os
, self
.name
, "rootstrap.tgz")
128 if not os
.path
.exists(rootstrap_file
):
129 if self
.__aptCreateRootstrap
(chroot_dir
, rootstrap_file
, use_rootstrap
, callback
= callback
) == False:
132 cmd
= "tar -jxvf %s -C %s" % (rootstrap_file
, chroot_dir
)
134 result
= pdk_utils
.execCommand(cmd
, output
= output
, callback
= callback
)
136 print >> sys
.stderr
, _("ERROR: Unable to rootstrap %s from %s!") % (rootstrap_file
, self
.name
)
137 pdk_utils
.rmtree(chroot_dir
, callback
= callback
)
138 # FIXME: Better exception here
139 raise ValueError(" ".join(output
))
140 # Setup copies of some useful files from the host into the chroot
141 for filename
in [ 'hosts', 'resolv.conf' ]:
142 source_file
= os
.path
.join("/etc", filename
)
143 target_file
= os
.path
.join(chroot_dir
, 'etc', filename
)
144 pdk_utils
.safeTextFileCopy(source_file
, target_file
, force
= True)
147 def __aptCreateRootstrap(self
, chroot_dir
, rootstrap_file
, use_rootstrap
, callback
= None):
148 codename
= self
.buildroot_codename
149 components
= ",".join(self
.buildroot_components
)
150 mirror
= self
.buildroot_mirror
151 chroot_type_string
= "Platform"
152 basedir
= os
.path
.dirname(rootstrap_file
)
153 if not os
.path
.exists(basedir
):
155 cmd
= "debootstrap --arch %s --include=apt --components=%s %s %s %s" % (self
.architecture
, components
, codename
, chroot_dir
, mirror
)
158 if not os
.path
.isfile("/usr/lib/debootstrap/scripts/%s" % codename
) and not os
.path
.isfile("/usr/share/debootstrap/scripts/%s" % codename
):
159 cmd
+= " /usr/share/pdk/debootstrap-scripts/%s" % codename
160 # Sometimes we see network issues that trigger debootstrap to claim the
161 # apt repository is corrupt. This trick will force up to 10 attempts
162 # before bailing out with an error
166 print _("--------%s rootstrap creation try: %s ----------") % (chroot_type_string
, count
)
167 print _("Execing command: %s") % cmd
168 result
= pdk_utils
.execCommand(cmd
, output
= output
, callback
= callback
)
170 print _("--------%s rootstrap creation completed successfully----------") % chroot_type_string
173 print _("Process Aborted")
175 print _("--------%s rootstrap creation failed result: %s ----------") % (chroot_type_string
, result
)
177 print _("--------For try: %s. Sleeping for %s seconds... -----------------") % (count
, sleeptime
)
178 time
.sleep(sleeptime
)
180 print >> sys
.stderr
, _("ERROR: Unable to generate %s rootstrap!") % chroot_type_string
181 raise ValueError(" ".join(output
))
182 self
.pkg_manager
.cleanPackageCache(chroot_dir
)
183 source_dir
= os
.path
.join(self
.path
, 'sources')
184 for filename
in os
.listdir(source_dir
):
185 source_path
= os
.path
.join(source_dir
, filename
)
186 dest_path
= os
.path
.join(chroot_dir
, 'etc', 'apt', 'sources.list.d', filename
)
187 pdk_utils
.copySourcesListFile(source_path
, dest_path
)
188 source_path
= os
.path
.join(self
.path
, 'preferences')
189 if os
.path
.exists(source_path
):
190 shutil
.copy(source_path
, os
.path
.join(chroot_dir
, 'etc', 'apt'))
191 if use_rootstrap
== True:
192 self
.__createRootstrap
(chroot_dir
, rootstrap_file
, callback
= None)
194 def yumCreateChroot(self
, chroot_dir
, use_rootstrap
, callback
= None):
195 if not os
.path
.exists(chroot_dir
):
196 os
.makedirs(chroot_dir
)
197 target_os
= self
.target_os
198 var_dir
= mic_cfg
.config
.get('general', 'var_dir')
199 rootstrap_file
= os
.path
.join(var_dir
, "rootstraps", "yum", target_os
, "rootstrap.tgz")
200 if not os
.path
.exists(rootstrap_file
):
201 self
.__yumCreateRootstrap
(chroot_dir
, rootstrap_file
, use_rootstrap
, callback
= callback
)
203 cmd
= "tar -jxvf %s -C %s" % (rootstrap_file
, chroot_dir
)
205 result
= pdk_utils
.execCommand(cmd
, output
= output
, callback
= callback
)
207 print >> sys
.stderr
, _("ERROR: Unable to rootstrap %s from %s!") % (rootstrap_file
, name
)
208 pdk_utils
.rmtree(chroot_dir
, callback
= callback
)
209 # FIXME: Better exception here
210 raise ValueError(" ".join(output
))
212 def __yumCreateRootstrap(self
, chroot_dir
, rootstrap_file
, use_rootstrap
, callback
= None):
213 basedir
= os
.path
.dirname(rootstrap_file
)
214 if not os
.path
.exists(basedir
):
216 self
.__yumCreateBase
(chroot_dir
)
217 self
.__yumCreateDevices
(chroot_dir
)
218 self
.__yumDoMounts
(chroot_dir
)
219 # install yum inside the project using the host tools
220 print _("Creating rootstrap directory with yum...")
222 cmd
= 'yum -y --disablerepo=localbase --installroot=%s install yum yum-protectbase' % chroot_dir
223 cmd
= 'yum -y --installroot=%s install yum yum-protectbase' % chroot_dir
224 #cmd = 'yum -y --installroot=%s groupinstall buildsys-build' % chroot_dir
225 print _("Exec command: %s") % cmd
226 result
= pdk_utils
.execCommand(cmd
, output
= output
, callback
= callback
)
228 raise RuntimeError(_("Failed to create Yum based rootstrap"))
229 # nuke all the yum cache to ensure that we get the latest greatest at project creation
230 shutil
.rmtree(os
.path
.join(chroot_dir
, 'var', 'cache', 'yum'))
231 self
.__yumDoUmounts
(chroot_dir
)
232 # Create the rootstrap archive file
233 if use_rootstrap
== True:
234 self
.__createRootstrap
(chroot_dir
, rootstrap_file
, callback
= callback
)
236 def __yumDoMounts(self
, chroot_dir
):
237 for cmd
in ['mount -n -t proc mic_chroot_proc %s/proc' % chroot_dir
,
238 'mount -n -t devpts mic_chroot_devpts %s/dev/pts' % chroot_dir
,
239 'mount -n -t sysfs mic_chroot_sysfs %s/sys' % chroot_dir
,
241 pdk_utils
.execCommand(cmd
)
243 def __yumDoUmounts(self
, chroot_dir
):
244 pdk_utils
.umountAllInPath(chroot_dir
)
246 def __yumCreateBase(self
, chroot_dir
):
257 os
.makedirs(os
.path
.join(chroot_dir
, dirname
))
258 target_etc
= os
.path
.join(chroot_dir
, "etc")
259 # Setup copies of some useful files from the host into the chroot
260 for filename
in [ 'hosts', 'resolv.conf' ]:
261 source_file
= os
.path
.join("/etc", filename
)
262 target_file
= os
.path
.join(target_etc
, filename
)
263 pdk_utils
.safeTextFileCopy(source_file
, target_file
, force
= True)
264 yumconf
= open(os
.path
.join(target_etc
, 'yum.conf'), 'w')
265 print >> yumconf
, """\
267 cachedir=/var/cache/yum
270 logfile=/var/log/yum.log
272 distroverpkg=redhat-release
282 yum_repos_dir
= os
.path
.join(self
.path
, 'yum.repos.d')
283 for filename
in os
.listdir(yum_repos_dir
):
284 source_path
= os
.path
.join(yum_repos_dir
, filename
)
285 dest_path
= os
.path
.join(chroot_dir
, 'etc', 'yum.repos.d', filename
)
286 pdk_utils
.copySourcesListFile(source_path
, dest_path
)
288 def __yumCreateDevices(self
, chroot_dir
):
290 # name, major, minor, mode
291 ('console', 5, 1, (0600 | stat
.S_IFCHR
)),
292 ('null', 1, 3, (0666 | stat
.S_IFCHR
)),
293 ('random', 1, 8, (0666 | stat
.S_IFCHR
)),
294 ('urandom', 1, 9, (0444 | stat
.S_IFCHR
)),
295 ('zero', 1, 5, (0666 | stat
.S_IFCHR
)),
297 for device_name
, major
, minor
, mode
in devices
:
298 device_path
= os
.path
.join(chroot_dir
, 'dev', device_name
)
299 device
= os
.makedev(major
, minor
)
300 os
.mknod(device_path
, mode
, device
)
301 # Seems redundant, but mknod doesn't seem to set the mode to
303 os
.chmod(device_path
, mode
)
305 def update(self
, path
):
306 command
= '-y --installroot=%s update' % (path
)
307 ret
= self
.chroot("/usr/bin/yum", command
)
309 raise OSError(_("Internal error while attempting to run: %s") % command
)
312 def install(self
, path
, packages
):
314 Call into yum to install RPM packages using the specified yum
318 # No packages, so nothing to do
320 command
= '-y --installroot=%s install ' % (path
)
323 ret
= self
.chroot("/usr/bin/yum", command
)
325 raise OSError(_("Internal error while attempting to run: %s") % command
)
328 if __name__
== '__main__':
329 for p
in sys
.argv
[1:]:
330 print Platform('/usr/share/pdk', p
)