just learned about this project erjic that does seccomp+bwrap sandboxing https://codeberg.org/prisixia/erjic the interface is really nicely designed and i believe will fit the needs of my build system perfectly
-
they mentioned they use it for running games which is so great to hear bc that's exactly the kind of end-user application that typical sandboxing mechanisms don't care about whatsoever and which (like compilers) have very strong dependencies upon which files they can access
@hipsterelectron
speaking of games, it should come with a script that sets up a sandboxed Wine desktop
(might be out of scope but still) -
when brett cannon (the maintainer of the
packaginglibrary who ensures pypi uses the backdooredMETADATAformat) wrote PEP 751 in collusion with astral (the startup that stole my zip file work without credit and sold to openai), he made sure to erase this work, because PEP 751 is a TOML format (and this is the crux of the distinction i'm making)TOML is not stable and not widely supported, but let's ignore that. the important quality of TOML is that it has multiple equivalent representations and absolutely no normalization mechanism. this means you can't reliably checksum it.
consider for a moment if being able to determine whether a lockfile has been changed might be useful in any way.
-
TOML is not stable and not widely supported, but let's ignore that. the important quality of TOML is that it has multiple equivalent representations and absolutely no normalization mechanism. this means you can't reliably checksum it.
consider for a moment if being able to determine whether a lockfile has been changed might be useful in any way.
PEP 751 is a useful case study in conflation of b2b and b2c because it describes mutually contradictory goals. first off, i claim a lockfile is not user-facing: it is the output of a process invocation (pip, uv, poetry, etc) and intended to be consumed by another process. brett cannon instead courageously fights for user empowerment and describes the lockfile as something a user is expected to audit by hand (so it's their fault if they didn't read it closely enough and get hacked). this motivates the TOML format.
-
PEP 751 is a useful case study in conflation of b2b and b2c because it describes mutually contradictory goals. first off, i claim a lockfile is not user-facing: it is the output of a process invocation (pip, uv, poetry, etc) and intended to be consumed by another process. brett cannon instead courageously fights for user empowerment and describes the lockfile as something a user is expected to audit by hand (so it's their fault if they didn't read it closely enough and get hacked). this motivates the TOML format.
@hipsterelectron lmao
-
TOML is not stable and not widely supported, but let's ignore that. the important quality of TOML is that it has multiple equivalent representations and absolutely no normalization mechanism. this means you can't reliably checksum it.
consider for a moment if being able to determine whether a lockfile has been changed might be useful in any way.
@hipsterelectron if you're already using a structured data format you might as well destructure it into its dictionary representation for doing the comparison right
-
@hipsterelectron if you're already using a structured data format you might as well destructure it into its dictionary representation for doing the comparison right
@hipsterelectron i also wouldnt want my lockfiles to use the canonical / stripped json version but to be pretty-printed instead, of which the formatting can vary
-
PEP 751 is a useful case study in conflation of b2b and b2c because it describes mutually contradictory goals. first off, i claim a lockfile is not user-facing: it is the output of a process invocation (pip, uv, poetry, etc) and intended to be consumed by another process. brett cannon instead courageously fights for user empowerment and describes the lockfile as something a user is expected to audit by hand (so it's their fault if they didn't read it closely enough and get hacked). this motivates the TOML format.
in fact, the TOML format is appropriate for exactly that b2c case! we use it in pants: https://www.pantsbuild.org/stable/docs/getting-started/initial-configuration users of pants have a
pants.tomlat the repo root for this reason.what about subprojects? so pants is a monorepo build tool, and per-directory BUILD files cover project-specific config. BUILD files are restricted python code, because we need to support loops and other logic. this is one major advantage over autoconf, in which key-value configuration parameters are determined by user-provided shell scripts. this makes autoconf-based builds impossible to introspect or interop with other tooling
-
in fact, the TOML format is appropriate for exactly that b2c case! we use it in pants: https://www.pantsbuild.org/stable/docs/getting-started/initial-configuration users of pants have a
pants.tomlat the repo root for this reason.what about subprojects? so pants is a monorepo build tool, and per-directory BUILD files cover project-specific config. BUILD files are restricted python code, because we need to support loops and other logic. this is one major advantage over autoconf, in which key-value configuration parameters are determined by user-provided shell scripts. this makes autoconf-based builds impossible to introspect or interop with other tooling
pants does maintain the same distinction as autoconf in its separation of "maintainer-defined" vs "packager-defined" configuration. in my automake C projects (see e.g. https://codeberg.org/cosmicexplorer/delulu), you'll see i build the
configurescript myself and track it in the repo, while a packager can invoke my prebuilt script from a tarball or git checkout.correspondingly, the
pants.tomldefines configuration values i control, but the packager can override or extend these values via environment variables or cli args. see https://www.pantsbuild.org/stable/docs/using-pants/key-concepts/options for more -
pants does maintain the same distinction as autoconf in its separation of "maintainer-defined" vs "packager-defined" configuration. in my automake C projects (see e.g. https://codeberg.org/cosmicexplorer/delulu), you'll see i build the
configurescript myself and track it in the repo, while a packager can invoke my prebuilt script from a tarball or git checkout.correspondingly, the
pants.tomldefines configuration values i control, but the packager can override or extend these values via environment variables or cli args. see https://www.pantsbuild.org/stable/docs/using-pants/key-concepts/options for morethese handoffs between release artifacts (dist tarball, git checkout) correspond to handoffs between interacting groups of human beings (codebase maintainers "upstream" to "downstream" packagers). "upstream" and "downstream" are often used informally to mean two distinct handoffs:
- between codebases that depend upon upstream,
- distro packagers which consume a whole dependency graph.
i have frequently castigated and derided cargo for failing to distinguish between these two.
-
these handoffs between release artifacts (dist tarball, git checkout) correspond to handoffs between interacting groups of human beings (codebase maintainers "upstream" to "downstream" packagers). "upstream" and "downstream" are often used informally to mean two distinct handoffs:
- between codebases that depend upon upstream,
- distro packagers which consume a whole dependency graph.
i have frequently castigated and derided cargo for failing to distinguish between these two.
previously (in conversation with junyer, the late RE2 maintainer) i had arrived upon the motto "build xor pkg" (see e.g. https://circumstances.run/@hipsterelectron/115241855909691763) to codify what (imho) pants and spack do right: separating packaging concerns from build concerns:
- a package manager (pip, spack, npm, poetry, and every linux distro) describes relationships across codebases (and therefore necessarily defines an interdependent ecosystem).
- a build tool covers one specific codebase. it is a tool for maintainers to describe their code, to develop the code, and to generate release artifacts (which are definitionally consumed by package managers).
-
when brett cannon (the maintainer of the
packaginglibrary who ensures pypi uses the backdooredMETADATAformat) wrote PEP 751 in collusion with astral (the startup that stole my zip file work without credit and sold to openai), he made sure to erase this work, because PEP 751 is a TOML format (and this is the crux of the distinction i'm making)@hipsterelectron I guess they have no issue with bare python not being able to write toml files if the tooling use rust.
-
previously (in conversation with junyer, the late RE2 maintainer) i had arrived upon the motto "build xor pkg" (see e.g. https://circumstances.run/@hipsterelectron/115241855909691763) to codify what (imho) pants and spack do right: separating packaging concerns from build concerns:
- a package manager (pip, spack, npm, poetry, and every linux distro) describes relationships across codebases (and therefore necessarily defines an interdependent ecosystem).
- a build tool covers one specific codebase. it is a tool for maintainers to describe their code, to develop the code, and to generate release artifacts (which are definitionally consumed by package managers).
you might wonder whether a shared library or an executable is consumed by package managers in the same way as a python wheel. in fact, a shared library is a packaging format defined by the dynamic linker, and the dynamic linker is in fact a package manager defined by by the libc. an executable is in (typically) ELF or mach-o format, and the OS executable interpreter is the package manager consuming that output.
-
you might wonder whether a shared library or an executable is consumed by package managers in the same way as a python wheel. in fact, a shared library is a packaging format defined by the dynamic linker, and the dynamic linker is in fact a package manager defined by by the libc. an executable is in (typically) ELF or mach-o format, and the OS executable interpreter is the package manager consuming that output.
@hipsterelectron static executable is a distro? :galaxybrain:
-
you might wonder whether a shared library or an executable is consumed by package managers in the same way as a python wheel. in fact, a shared library is a packaging format defined by the dynamic linker, and the dynamic linker is in fact a package manager defined by by the libc. an executable is in (typically) ELF or mach-o format, and the OS executable interpreter is the package manager consuming that output.
these are not the kind of analogies introduced in high school physics, which describe ballistic trajectories without air resistance or gravitational potential difference or the curvature of the earth. the OS executable interpreter is literally a package manager and the libc dynamic linker is also literally a manage manager.
the OS in particular is notable because it maps a binary executable into a format suitable for the MMU and instruction stream required by the CPU. the compiler is of course complicit in this—the ELF format is translated by the kernel into an instruction stream for the CPU. during this process the data is read from the filesystem into RAM, because the CPU operates upon RAM.
-
just learned about this project erjic that does seccomp+bwrap sandboxing https://codeberg.org/prisixia/erjic the interface is really nicely designed and i believe will fit the needs of my build system perfectly
@hipsterelectron Have you seen https://gitlab.exherbo.org/sydbox/sydbox ? xD
-
these are not the kind of analogies introduced in high school physics, which describe ballistic trajectories without air resistance or gravitational potential difference or the curvature of the earth. the OS executable interpreter is literally a package manager and the libc dynamic linker is also literally a manage manager.
the OS in particular is notable because it maps a binary executable into a format suitable for the MMU and instruction stream required by the CPU. the compiler is of course complicit in this—the ELF format is translated by the kernel into an instruction stream for the CPU. during this process the data is read from the filesystem into RAM, because the CPU operates upon RAM.
every phone and desktop OS i know of employs a concept of memory paging which conflates the filesystem and active memory, which is why shared libraries (including the libc itself) are so useful—when the process needs to execute some generic operation, the CPU instruction pointer (translated by the MMU, which is configured by the OS) can jump into a page shared across multiple processes. since the instruction pointer can only operate over data (aka "code") in RAM, sharing that data means less memory is needed to execute multiple processes at once.
-
every phone and desktop OS i know of employs a concept of memory paging which conflates the filesystem and active memory, which is why shared libraries (including the libc itself) are so useful—when the process needs to execute some generic operation, the CPU instruction pointer (translated by the MMU, which is configured by the OS) can jump into a page shared across multiple processes. since the instruction pointer can only operate over data (aka "code") in RAM, sharing that data means less memory is needed to execute multiple processes at once.
i am forcing myself not to derail into a discussion of task scheduling, but "multiple processes at once" does in fact specifically mean multiple live processes executing in parallel through some form of timesharing mechanism (i ignore kernel threads here). the essentially round-robin preemption model with process-specific nice values (ignoring threads) used by linux and all BSDs i know of wants to share as much memory as possible across processes, because at all times it is trying to execute them all at once.
that's kind of a strange assumption, isn't it?
-
previously (in conversation with junyer, the late RE2 maintainer) i had arrived upon the motto "build xor pkg" (see e.g. https://circumstances.run/@hipsterelectron/115241855909691763) to codify what (imho) pants and spack do right: separating packaging concerns from build concerns:
- a package manager (pip, spack, npm, poetry, and every linux distro) describes relationships across codebases (and therefore necessarily defines an interdependent ecosystem).
- a build tool covers one specific codebase. it is a tool for maintainers to describe their code, to develop the code, and to generate release artifacts (which are definitionally consumed by package managers).
@hipsterelectron so, where does this philosophy place CPack and rpmbuild, respectively?
As a person who writes software and uses CMake as a build system and also has to package (and rebuild) other people’s software with rpmbuild, I have _opinions_. -
i am forcing myself not to derail into a discussion of task scheduling, but "multiple processes at once" does in fact specifically mean multiple live processes executing in parallel through some form of timesharing mechanism (i ignore kernel threads here). the essentially round-robin preemption model with process-specific nice values (ignoring threads) used by linux and all BSDs i know of wants to share as much memory as possible across processes, because at all times it is trying to execute them all at once.
that's kind of a strange assumption, isn't it?
once you execute a process (via
execvlp(), orposix_spawn(), or whatever) it's immediately off to the races! that process is added to the big soup of other processes. you can't even stop it without sending a signal—which doesn't pause it, but kills it. the process itself needs to decide to open up a semaphore or pipe you gave it in order to pause its execution.think about it: isn't this a form of cooperative scheduling? when you can't rein in a subprocess except by killing it entirely? how often do you genuinely want a subprocess to execute however long it wants—unless you yourself control the code and force it to yield?
-
once you execute a process (via
execvlp(), orposix_spawn(), or whatever) it's immediately off to the races! that process is added to the big soup of other processes. you can't even stop it without sending a signal—which doesn't pause it, but kills it. the process itself needs to decide to open up a semaphore or pipe you gave it in order to pause its execution.think about it: isn't this a form of cooperative scheduling? when you can't rein in a subprocess except by killing it entirely? how often do you genuinely want a subprocess to execute however long it wants—unless you yourself control the code and force it to yield?
we will now terminate this tangent, but the point of this is: shared libraries (a packaging mechanism) are motivated by sharing memory among parallel process executions. your hardworking beloved distro packager is able to package software to use shared libraries (they "control the code" in that sense) as much as possible, in order to enable their end users to use the OS efficiently in unexpected ways (watching videos, making music, building LLVM).