• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

xapi-project / xen-api / 10190262928

01 Aug 2024 01:21AM UTC coverage: 77.92% (+30.5%) from 47.434%
10190262928

Pull #5896

github

web-flow
Merge pull request #5899 from stephenchengCloud/private/stephenche/CP-49148

CP-49148: Remove unused xc.py
Pull Request #5896: Python3 update feature merge

1413 of 1525 new or added lines in 27 files covered. (92.66%)

3582 of 4597 relevant lines covered (77.92%)

0.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.33
/python3/tests/rootless_container.py
1
"""rootless_container.py: Create a rootless container on any Linux and GitHub CI"""
2
import ctypes
1✔
3
import os
1✔
4

5
# Unshare the user namespace, so that the calling process is moved into a new
6
# user namespace which is not shared with any previously existing process.
7
# Needed so that the current user id can be mapped to 0 for getting a new
8
# mount namespace.
9
CLONE_NEWUSER = 0x10000000
1✔
10
# Unshare the mount namespace, so that the calling process has a private copy
11
# of its root directory namespace which is not shared with any other process:
12
CLONE_NEWNS = 0x00020000
1✔
13
# Flags for mount(2):
14
MS_BIND = 4096
1✔
15
MS_REC = 16384
1✔
16
MS_PRIVATE = 1 << 18
1✔
17

18

19
def unshare(flags):  # type:(int) -> None
1✔
20
    """Wrapper for the library call to unshare Linux kernel namespaces"""
21
    lib = ctypes.CDLL(None, use_errno=True)
1✔
22
    lib.unshare.argtypes = [ctypes.c_int]
1✔
23
    rc = lib.unshare(flags)
1✔
24
    if rc != 0:  # pragma: no cover
25
        errno = ctypes.get_errno()
26
        raise OSError(errno, os.strerror(errno), flags)
27

28

29
def mount(source="none", target="", fs="", flags=0, options=""):
1✔
30
    # type:(str, str, str, int, str) -> None
31
    """Wrapper for the library call mount(). Supports Python2.7 and Python3.x"""
32
    lib = ctypes.CDLL(None, use_errno=True)
1✔
33
    lib.mount.argtypes = (
1✔
34
        ctypes.c_char_p,
35
        ctypes.c_char_p,
36
        ctypes.c_char_p,
37
        ctypes.c_ulong,
38
        ctypes.c_char_p,
39
    )
40
    result = lib.mount(
1✔
41
        source.encode(), target.encode(), fs.encode(), flags, options.encode()
42
    )
43
    if result < 0:  # pragma: no cover
44
        errno = ctypes.get_errno()
45
        raise OSError(
46
            errno,
47
            "mount " + target + " (" + options + "): " + os.strerror(errno),
48
        )
49

50

51
def umount(target):  # type:(str) -> None
1✔
52
    """Wrapper for the Linux umount system call, supports Python2.7 and Python3.x"""
NEW
53
    lib = ctypes.CDLL(None, use_errno=True)
×
NEW
54
    result = lib.umount(ctypes.c_char_p(target.encode()))
×
55
    if result < 0:  # pragma: no cover
56
        errno = ctypes.get_errno()
57
        raise OSError(errno, "umount " + target + ": " + os.strerror(errno))
58

59

60
def enter_private_mount_namespace():
1✔
61
    """Enter a private mount and user namespace with the user and simulate uid 0
62

63
    Some code like mount() requires to be run as root. The container simulates
64
    root-like privileges and a new mount namespace that allows mount() in it.
65

66
    Implements the equivalent of `/usr/bin/unshare --map-root-user --mount`
67
    """
68

69
    # Read the actual user and group ids before entering the new user namespace:
70
    real_uid = os.getuid()
1✔
71
    real_gid = os.getgid()
1✔
72
    unshare(CLONE_NEWUSER | CLONE_NEWNS)
1✔
73
    # Setup user map to map the user id to behave like uid 0:
74
    with open("/proc/self/uid_map", "wb") as proc_self_user_map:
1✔
75
        proc_self_user_map.write(b"0 %d 1" % real_uid)
1✔
76
    with open("/proc/self/setgroups", "wb") as proc_self_set_groups:
1✔
77
        proc_self_set_groups.write(b"deny")
1✔
78
    # Setup group map for the user's gid to behave like gid 0:
79
    with open("/proc/self/gid_map", "wb") as proc_self_group_map:
1✔
80
        proc_self_group_map.write(b"0 %d 1" % real_gid)
1✔
81
    # Private root mount in the mount namespace top support mounting a private tmpfs:
82
    mount(target="/", flags=MS_REC | MS_PRIVATE)
1✔
83
    return True
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc