def init_volume(self, context): """ Create new dir on host, put a file in it, set $context context recursively and check it was set properly. :param context: Desired volume context :return: path to new directory """ if self.config['use_system_tmp']: tmp = '/var/tmp' else: tmp = self.tmpdir volume = tempfile.mkdtemp(prefix=self.__class__.__name__, dir=tmp) if docker_daemon.user_namespaces_enabled(): os.chown(volume, docker_daemon.user_namespaces_uid(), docker_daemon.user_namespaces_gid()) self.sub_stuff['volumes'].add(volume) host_file = os.path.join(volume, "hostfile") open(host_file, 'w').write("01") set_selinux_context(volume, context, True) _context = get_selinux_context(volume) self.failif(context not in _context, "Newly set context was not set" " properly (set %s, get %s)" % (context, _context)) self.check_context_recursive(volume, _context) return volume
def check_context_recursive(self, path, context): """ Check all files in given $path have the context $context """ for pwd, _, filenames in os.walk(path): for filename in filenames: full_filepath = os.path.join(pwd, filename) actual = get_selinux_context(full_filepath) self.failif_ne(actual, context, "SELinux context of file %s" % full_filepath)
def touch_and_check(self, cont, volume, filename, context_pre, should_fail, context_eq): """ Touch file $filename using $cont, check it passed/fail and then verify context is (not) the same as $context_pre. Also verify all files have the same context. :param cont: dkrcmd instance :param volume: Path to shared volume (on host) :param filename: filename to touch on guest (relative to shared volume) :param context_pre: Reference context :param should_fail: Should the file creation fail? :param context_eq: Should the context be equal to reference one? :return: new context """ self.logdebug("Volume: %s Context: %s", volume, get_selinux_context(volume)) self.logdebug("Touching /tmp/test/%s in container" % filename) # Some filesystems don't synchronize directory cache flushes if # pagecache for a file isn't also dirty. Always updating # content is easier that checking filesystem from inside a container. os.write(cont.stdin, "date > /tmp/test/%s\necho RET: $?\n" % filename) match = wait_for_output(lambda: cont.stdout, r'RET:\s+0$', timeout=10) if should_fail: self.failif(match, "File creation passed unexpectedly:" "\n%s" % cont.stdout) else: self.failif(not match, "Unable to create file:\n%s" % cont.stdout) context_post = get_selinux_context(volume) if context_eq: self.failif_ne(context_post, context_pre, "Selinux context") else: self.failif(context_pre == context_post, "Selinux context had not " "change (%s)." % context_post) self.check_context_recursive(volume, context_post) return context_post
def run_once(self): super(private, self).run_once() # Prepare a volume volume_dir = self.init_volume(self.config['selinux_host']) context0 = get_selinux_context(volume_dir) # Start first container cont1 = self.init_container("%s:/tmp/test:Z" % volume_dir) context1 = self.touch_and_check(cont1, volume_dir, 'guest1', context0, False, False) # Start second container cont2 = self.init_container("%s:/tmp/test" % volume_dir) self.touch_and_check(cont2, volume_dir, 'guest2', context1, True, True) # Create another one from first container self.touch_and_check(cont1, volume_dir, 'guest1_2', context1, False, True) self.check_all_files(volume_dir, ('hostfile', 'guest1', 'guest1_2'))
def init_volume(self, context): """ Create new dir on host, put a file in it, set $context context recursively and check it was set properly. :param context: Desired volume context :return: path to new directory """ if self.config['use_system_tmp']: tmp = '/var/tmp' else: tmp = self.tmpdir volume = tempfile.mkdtemp(prefix=self.__class__.__name__, dir=tmp) self.sub_stuff['volumes'].add(volume) host_file = os.path.join(volume, "hostfile") open(host_file, 'w').write("01") set_selinux_context(volume, context, True) _context = get_selinux_context(volume) self.failif(context not in _context, "Newly set context was not set" " properly (set %s, get %s)" % (context, _context)) self.check_context_recursive(volume, _context) return volume