[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