[PATCH mock] Bind-mount a precreated /dev filesystem instead of using mknod(2)
Michael E Brown
Michael_E_Brown at dell.com
Mon May 7 17:31:59 UTC 2007
On Sat, May 05, 2007 at 07:30:40PM +0200, Enrico Scholz wrote:
> This patch adds a 'dev-template' configuration options which points to a
> directory with a preconfigured /dev directory. This makes it possible to
> use mock in environments where 'mknod(2)' operations are prohibited (e.g.
> in vservers).
>
> Usually, this directory is a mounted read-only and e.g. a cramfs. The
> 'create-template.sh' script will create such a cramfs image which must be
> added to the host's /etc/fstab e.g. as
>
> | /usr/share/mock/mock-dev.ramfs /usr/share/mock/dev-template cramfs dev
>
> and added to mock configuration as
>
> | config_opts['dev-template'] = '/usr/share/mock/dev-template'
1) Need to add default config option for this in
setup_default_config_opts().
2) need to discuss spec file changes, because, as you say, they cannot
go in like that.
--
Michael
>
>
> The changes in the spec file are suggestions only and the cramfs image
> can not be created during the normal build because it requires superuser
> capabilities.
>
> Signed-off-by: Enrico Scholz <enrico.scholz at informatik.tu-chemnitz.de>
> ---
>
> Makefile | 2 ++
> create-template.sh | 29 ++++++++++++++++++++++
> mock-dev.ramfs | Bin
> mock.py | 69 +++++++++++++++++++++++++++++-----------------------
> mock.spec | 16 ++++++++++++
> 5 files changed, 85 insertions(+), 31 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index bee4ad4..a2a5d0b 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -21,6 +21,8 @@ subdirs:
> install:
> install -D mock.py $(DESTDIR)/usr/libexec/mock.py
> install -D mock-yum $(DESTDIR)/usr/libexec/mock-yum
> + install -D -m644 mock-dev.ramfs $(DESTDIR)/usr/share/mock/mock-dev.ramfs
> + install -d -m755 $(DESTDIR)/usr/share/mock/dev-template
> mkdir -p $(DESTDIR)/var/lib/mock
> for d in $(SUBDIRS); do make DESTDIR=`cd $(DESTDIR); pwd` -C $$d install; [ $$? = 0 ] || exit 1; done
>
> diff --git a/create-template.sh b/create-template.sh
> new file mode 100755
> index 0000000..75e2529
> --- /dev/null
> +++ b/create-template.sh
> @@ -0,0 +1,29 @@
> +#! /bin/bash
> +
> +MKNOD=mknod
> +MKCRAMFS=/sbin/mkfs.cramfs
> +
> +set -e
> +
> +d=$(mktemp -t -d mockdev.XXXXXX)
> +trap "rm -rf $d" EXIT
> +
> +dev=$d/dev
> +mkdir -p $dev
> +
> +$MKNOD -m666 $dev/null c 1 3
> +$MKNOD -m644 $dev/urandom c 1 9
> +$MKNOD -m644 $dev/random c 1 8
> +$MKNOD -m666 $dev/full c 1 7
> +$MKNOD -m666 $dev/ptmx c 5 2
> +$MKNOD -m666 $dev/tty c 5 0
> +$MKNOD -m666 $dev/zero c 1 5
> +
> +ln -s /proc/self/fd $dev/fd
> +ln -s /proc/self/fd/0 $dev/stdin
> +ln -s /proc/self/fd/1 $dev/stdout
> +ln -s /proc/self/fd/2 $dev/stderr
> +
> +mkdir $dev/pts
> +
> +$MKCRAMFS $dev "$1"
> diff --git a/mock-dev.ramfs b/mock-dev.ramfs
> new file mode 100644
> index 0000000..03851ca
> Binary files /dev/null and b/mock-dev.ramfs differ
> diff --git a/mock.py b/mock.py
> index b06156c..3762324 100644
> --- a/mock.py
> +++ b/mock.py
> @@ -497,6 +497,10 @@ class Root:
> # mount /proc
> self._mount('proc', 'proc', 'proc')
>
> + # mount /dev
> + if self.config.get('dev-template'):
> + self._mount('none --bind -o ro', self.config['dev-template'], 'dev')
> +
> # mount /dev/pts
> self._mount('devpts', 'dev/pts', 'dev/pts')
>
> @@ -536,7 +540,38 @@ class Root:
> # poof, no more file
> if os.path.exists(mf):
> os.unlink(mf)
> +
> + def __mknodall(self):
> + # we need stuff
> + devices = [('null', 'c', '1', '3', '666'),
> + ('urandom', 'c', '1', '9', '644'),
> + ('random', 'c', '1', '9', '644'),
> + ('full', 'c', '1', '7', '666'),
> + ('ptmx', 'c', '5', '2', '666'),
> + ('tty', 'c', '5', '0', '666'),
> + ('zero', 'c', '1', '5', '666')]
> +
> + for (dev, devtype, major, minor, perm) in devices:
> + devpath = os.path.join(self.rootdir, 'dev', dev)
> + cmd = '%s %s -m %s %s %s %s' % (self.config['mknod'],
> + devpath, perm, devtype, major, minor)
> + if not os.path.exists(devpath):
> + (retval, output) = self.do_elevated(cmd)
> + if retval != 0:
> + raise RootError, "could not mknod error was: %s" % output
> +
> + # link fd to ../proc/self/fd
> + devpath = os.path.join(self.rootdir, 'dev/fd')
> + if not os.path.exists(devpath):
> + os.symlink('../proc/self/fd', devpath)
>
> + fd = 0
> + for item in ('stdin', 'stdout', 'stderr'):
> + devpath = os.path.join(self.rootdir, 'dev', item)
> + if not os.path.exists(devpath):
> + fdpath = os.path.join('../proc/self/fd', str(fd))
> + os.symlink(fdpath, devpath)
> + fd += 1
>
> def do(self, command):
> """execute given command outside of chroot"""
> @@ -679,39 +714,11 @@ class Root:
> os.path.join(self.rootdir, 'var/tmp'),
> os.path.join(self.rootdir, 'etc/yum.repos.d')]:
> self._ensure_dir(item)
> -
> - self._mountall()
>
> - # we need stuff
> - devices = [('null', 'c', '1', '3', '666'),
> - ('urandom', 'c', '1', '9', '644'),
> - ('random', 'c', '1', '9', '644'),
> - ('full', 'c', '1', '7', '666'),
> - ('ptmx', 'c', '5', '2', '666'),
> - ('tty', 'c', '5', '0', '666'),
> - ('zero', 'c', '1', '5', '666')]
> -
> - for (dev, devtype, major, minor, perm) in devices:
> - devpath = os.path.join(self.rootdir, 'dev', dev)
> - cmd = '%s %s -m %s %s %s %s' % (self.config['mknod'],
> - devpath, perm, devtype, major, minor)
> - if not os.path.exists(devpath):
> - (retval, output) = self.do_elevated(cmd)
> - if retval != 0:
> - raise RootError, "could not mknod error was: %s" % output
> + self._mountall()
>
> - # link fd to ../proc/self/fd
> - devpath = os.path.join(self.rootdir, 'dev/fd')
> - if not os.path.exists(devpath):
> - os.symlink('../proc/self/fd', devpath)
> -
> - fd = 0
> - for item in ('stdin', 'stdout', 'stderr'):
> - devpath = os.path.join(self.rootdir, 'dev', item)
> - if not os.path.exists(devpath):
> - fdpath = os.path.join('../proc/self/fd', str(fd))
> - os.symlink(fdpath, devpath)
> - fd += 1
> + if not self.config.get('dev-template'):
> + self.__mknodall()
>
> for item in [os.path.join(self.rootdir, 'etc', 'mtab'),
> os.path.join(self.rootdir, 'etc', 'fstab'),
> diff --git a/mock.spec b/mock.spec
> index db59881..309e290 100644
> --- a/mock.spec
> +++ b/mock.spec
> @@ -33,6 +33,7 @@ if [ -f fedora-%{fedora}-%{_target_cpu}-core.cfg ]; then
> fi
> %endif
>
> +
> # if we haven't created a default link yet, try to do so as devel
> if [ ! -f default.cfg ]; then
> if [ -f fedora-development-%{_target_cpu}-core.cfg ]; then
> @@ -54,6 +55,12 @@ if [ $1 -eq 1 ]; then
> groupadd -r mock >/dev/null 2>&1 || :
> fi
>
> +%post
> +mkdir -p -m0755 %_datadir/mock/dev-template
> +
> +%preun
> +test $1 != 0 || rmdir %_datadir/mock/dev-template || :
> +
> %files
> %defattr(-, root, root)
> %doc README ChangeLog buildsys-build.spec
> @@ -65,6 +72,15 @@ fi
> %attr(02775, root, mock) %dir /var/lib/mock
> %{_libdir}/libselinux-mock.so
>
> +# Do not ship the dev-template directory; it might be mounted during
> +# upgrades which will cpio errors. Adding it to %%_netsharedpath is a
> +# solution but requires manual editing of /etc/rpm/macros.
> +#
> +# Hence, create and remove this directory in scriptlets
> +%dir %_datadir/mock
> +%dir %_datadir/mock/*.ramfs
> +%ghost %dir %_datadir/mock/dev-template
> +
> %changelog
> * Mon Jan 8 2007 Clark Williams <williams at redhat.com>
> - Added Josh Boyer's EPEL config files
>
> --
> Fedora-buildsys-list mailing list
> Fedora-buildsys-list at redhat.com
> https://www.redhat.com/mailman/listinfo/fedora-buildsys-list
More information about the Fedora-buildsys-list
mailing list