Compare commits

..

No commits in common. "0d8ef8a67c19d8d3e60b3e99203612531fb2e883" and "c3297b2aa048fcf9dacd18ed9f56af01fb4cb1f6" have entirely different histories.

3 changed files with 37 additions and 74 deletions

View File

@ -5,7 +5,6 @@ from builder.lib import utils
from builder.component import user
from builder.lib.config import ArchBuilderConfigError
from builder.lib.context import ArchBuilderContext
from builder.lib.cgroup import CGroup
log = getLogger(__name__)
@ -15,7 +14,6 @@ def chroot_run(
cwd: str = None,
env: dict = None,
stdin: str | bytes = None,
cgroup: CGroup = None,
) -> int:
"""
Chroot into rootfs and run programs
@ -26,7 +24,7 @@ def chroot_run(
path = ctx.get_rootfs()
args = ["chroot", path]
args.extend(utils.parse_cmd_args(cmd))
return ctx.run_external(args, cwd, env, stdin, cgroup)
return ctx.run_external(args, cwd, env, stdin)
def proc_mkdir(ctx: ArchBuilderContext, file: dict, path: str):
@ -78,17 +76,8 @@ def check_allowed(path: str, action: str):
1. /etc/ is used for administrator configs
2. /boot/ is used for system boot up, you can put bootloaders configs into this folder
3. /var/ is used for daemons runtime states
3. /usr/lib/modules/ is used for kernel modules (custom kernel)
3. /usr/lib/firmware/ is used for system firmware (custom firmware)
"""
allow_list = (
"/etc/",
"/boot/",
"/var/",
"/usr/lib/modules",
"/usr/lib/firmware",
)
if not path.startswith(allow_list):
if not path.startswith(("/etc/", "/boot/", "/var/")):
raise ArchBuilderConfigError(f"{action} {path} is not allowed")
@ -96,8 +85,8 @@ def add_file(ctx: ArchBuilderContext, file: dict):
# at least path content
if "path" not in file:
raise ArchBuilderConfigError("no path set in file")
if "content" not in file and "source" not in file:
raise ArchBuilderConfigError("no content or source set in file")
if "content" not in file:
raise ArchBuilderConfigError("no content set in file")
root = ctx.get_rootfs()
path: str = file["path"]
if path.startswith("/"): path = path[1:]
@ -109,9 +98,6 @@ def add_file(ctx: ArchBuilderContext, file: dict):
# follow symbolic links
follow = file["follow"] if "follow" in file else True
# source is a folder
folder = file["folder"] if "folder" in file else False
# files mode
mode = int(file["mode"]) if "mode" in file else 0o0644
@ -123,27 +109,15 @@ def add_file(ctx: ArchBuilderContext, file: dict):
# resolve to rootfs
real = os.path.join(root, path)
if "content" in file:
if not follow and os.path.exists(real): os.remove(real)
log.debug(f"create file {real}")
with open(real, "wb") as f:
content: str = file["content"]
log.debug(
"write to %s with %s",
real, content.strip()
)
f.write(content.encode(encode))
elif "source" in file:
src: str = file["source"]
if not src.startswith("/"):
src = os.path.join(ctx.dir, src)
log.debug(f"copy {src} to {real}")
if folder:
shutil.copytree(src, real, symlinks=follow)
else:
shutil.copyfile(src, real, follow_symlinks=follow)
else:
assert False
if not follow and os.path.exists(real): os.remove(real)
log.debug(f"create file {real}")
with open(real, "wb") as f:
content: str = file["content"]
log.debug(
"write to %s with %s",
real, content.strip()
)
f.write(content.encode(encode))
log.debug(f"chmod file {real} to {mode:04o}")
os.chmod(real, mode=mode)
log.debug(f"chown file {real} to {uid}:{gid}")

View File

@ -1,7 +1,7 @@
import os
from logging import getLogger
from builder.lib.context import ArchBuilderContext
from builder.lib.mount import MountTab
from builder.lib.mount import MountTab, MountPoint
log = getLogger(__name__)
@ -49,6 +49,25 @@ def undo_mounts(ctx: ArchBuilderContext):
raise RuntimeError("mount points not cleanup")
def do_mount(
ctx: ArchBuilderContext,
source: str,
target: str,
fstype: str,
options: str
):
"""
Add a mount point
"""
mnt = MountPoint()
mnt.source = source
mnt.target = target
mnt.fstype = fstype
mnt.options = options
mnt.mount()
ctx.mounted.insert(0, mnt)
def init_mount(ctx: ArchBuilderContext):
"""
Setup mount points for rootfs
@ -61,7 +80,7 @@ def init_mount(ctx: ArchBuilderContext):
os.symlink(target, real)
def root_mount(source, target, fstype, options):
real = os.path.realpath(os.path.join(root, target))
ctx.mount(source, real, fstype, options)
do_mount(ctx, source, real, fstype, options)
try:
# ensure mount point is clean
mnts = MountTab.parse_mounts()

View File

@ -7,7 +7,7 @@ from builder.lib.cpu import cpu_arch_get
from builder.lib.utils import parse_cmd_args
from builder.lib.subscript import dict_get
from builder.lib.loop import loop_detach
from builder.lib.mount import MountTab, MountPoint
from builder.lib.mount import MountTab
from builder.lib.cgroup import CGroup
from builder.lib.subscript import SubScript
from builder.lib.shadow import PasswdFile, GroupFile
@ -142,8 +142,7 @@ class ArchBuilderContext:
/,
cwd: str = None,
env: dict = None,
stdin: str | bytes = None,
cgroup: CGroup = None,
stdin: str | bytes = None
) -> int:
"""
Run external command
@ -154,8 +153,7 @@ class ArchBuilderContext:
log.debug(f"running external command {argv}")
fstdin = None if stdin is None else PIPE
proc = Popen(args, cwd=cwd, env=env, stdin=fstdin)
if cgroup is None: cgroup = self.cgroup
cgroup.add_pid(proc.pid)
self.cgroup.add_pid(proc.pid)
if stdin:
if type(stdin) is str: stdin = stdin.encode()
proc.stdin.write(stdin)
@ -189,31 +187,3 @@ class ArchBuilderContext:
ss = SubScript()
self.config = deepcopy(self.config_orig)
ss.parse(self.config)
def mount(
self,
source: str,
target: str,
fstype: str,
options: str,
) -> MountPoint:
"""
Add a mount point
"""
mnt = MountPoint()
mnt.source = source
mnt.target = os.path.realpath(target)
mnt.fstype = fstype
mnt.options = options
mnt.mount()
self.mounted.insert(0, mnt)
return mnt
def umount(self, path: str):
"""
Remove a mount point
"""
real = os.path.realpath(path)
if not os.path.ismount(real): return
for mnt in self.mounted.find_target(real):
self.mounted.remove(mnt)