Features
feature.clone
Copies a subtree of an existing layer into the one under construction. To the extent possible, filesystem metadata are preserved.
Parameters
src_layer: str (selectable)
Buck target pointing to source image.layer
.
This image must contain the contents to be cloned
path: Optional[str] (selectable) = None
src_path: Optional[str] (selectable) = None
Root path to clone from in src_layer
dst_path: Optional[str] (selectable) = None
Root path to clone into in the layer being built
user: Optional[str] = None
Set owning user on all files and directories
If not set, the same username is used between src_layer
and the
layer being built
group: Optional[str] = None
Set owning group on all files and directories
If not set, the same group name is used between src_layer
and the
layer being built
This copies from src_path
in the src_layer
to dst_path
in this layer.
If both paths are the same, you can just set path
and it will serve as
both the source and destination paths.
Trailing slashes on both paths are significant
The three supported cases are:
s/rc
->dest/
createsdest/rc
s/rc/
->dest/
createsdest/(children of rc)
s/rc
->dest
createsdest
More explicitly:
- A trailing slash in
src_path
means "use thersync
convention":- Do not clone the source directory, but only its contents.
dest_path
must be a pre-existing dir, and it must end in/
- A trailing slash in
dst_path
means that it's a pre-existing directory (e.g. made byensure_dirs_exist
), andclone
will only write to:dst/(basename of src_path)
ifsrc_path
lacks a trailing/
dst/(children of src_path)
ifsrc_path
has a trailing/
Known deviations from perfect cloning
Most likely, SELinux attrs change.
UID/GID remapping
src_layer
and the destination layer must have the same user/group names
available, but those names do not need to map to the same ids. uid/gids will
be remapped to the appropriate numeric id of that user/group in the
destination layer.
When to use this?
Often, instead of using this, you should prefer
layer_mount
, which allows you to compose
independent pieces of the filesystem at runtime, without incurring the
cost of publishing images with a lot of duplicated content.
If you're trying to copy the output of a regular Buck target, instead use
feature.install
.
feature.dnf_module_enable
Enable this DNF module before resolving the DNF transaction
Parameters
name: str (selectable)
stream: str (selectable)
See this page for more details about modules https://docs.fedoraproject.org/en-US/modularity/using-modules/
feature.ensure_dir_symlink
Create a symlink to a directory.
Parameters
link: str (selectable)
target: str (selectable)
unsafe_dangling_symlink: bool = False
Trailing /
s are not allowed, unlike ln
where it is significant.
feature.ensure_dirs_exist
Equivalent to ensure_subdirs_exist("/", dirs, ...)
.
Parameters
dirs: str (selectable)
mode: int | str = 493
user: str = "root"
group: str = "root"
feature.ensure_file_symlink
Create a symlink to a file.
Parameters
link: str (selectable)
target: str (selectable)
unsafe_dangling_symlink: bool = False
Trailing /
s are not allowed, unlike ln
where it is significant.
feature.ensure_subdirs_exist
Ensure directories exist in the image (analogous to mkdir -p
).
Parameters
into_dir: str (selectable)
Parent directory (must already exist)
subdirs_to_create: str (selectable)
Subdirectories to create under into_dir
These subdirectories may already exist in the image. If so, they
will be checked to ensure that the mode
and user:group
matches
what is declared here.
mode: int | str (selectable) = 493
set file mode bits of the newly-created directories
user: str (selectable) = "root"
set owning user of the newly-created directories
group: str (selectable) = "root"
set owning group of the newly-created directories
feature.extract_buck_binary
Extract a buck-built binary and all of its runtime dependencies into the target layer.
Parameters
src: str (selectable)
binary target
dst: str (selectable)
path to install it to in the image
strip: bool (selectable) = True
strip debug info from the binary and discard it
This copies the binary and all of it's .so
dependencies from the host
filesystem. Any mismatched contents in these dependencies will cause an
image build failure.
This feature exists only for building extremely stripped down environments like initrds, where things like the fbcode runtime is unavailable.
In 99% of cases you actually want to just give your binary to
feature.install
feature.extract_from_layer
Extract a binary and all of its runtime dependencies from layer
into the target layer.
Parameters
layer: str (selectable)
antlir2 layer target to extract from
binaries: list[selector | str] (selectable)
list of file paths to extract
This copies the binary and all of it's .so
dependencies from the host
filesystem. Any mismatched contents in these dependencies will cause an
image build failure.
This feature exists only for building extremely stripped down environments like initrds, where things like the fbcode runtime is unavailable.
In 99% of cases you actually just want to use
feature.install
or
feature.rpms_install
feature.feature_new
Create a target representing a collection of one or more image features.
Parameters
name: str
features: typing.Any
visibility: typing.Any = None
features
is a list that can contain either:
- inline (aka unnamed) features created with macros like
install()
- labels referring to other
feature
targets
feature.genrule
Parameters
cmd: Optional[list[selector | str]] (selectable) = None
bash: Optional[str] (selectable) = None
user: str (selectable) = "nobody"
bind_repo_ro: bool (selectable) = False
mount_platform: bool (selectable) = False
feature.group_add
Add a group entry to /etc/group
Parameters
groupname: str (selectable)
gid: Optional[int] (selectable) = None
uidmap: str = "default"
Group add semantics generally follow groupadd
. If groupname or GID
conflicts with existing entries, image build will fail.
feature.hardlink
Create a hardlink to a file.
Parameters
link: str (selectable)
target: str (selectable)
feature.host_mount
Parameters
source: str
is_directory: bool
mountpoint: Optional[str] = None
feature.install
Install a file or directory into the image.
Parameters
src: str (selectable)
source file or buck target
dst: str (selectable)
mode: Optional[int | str] (selectable) = None
mode to set on the installed file
In most cases this can be left unset and antlir2 will choose the
most reasonable default based on the source.
Buck-built binaries will automatically be marked as executable.
These defaults can be manually overriden by default_permissions
.
user: int | str (selectable) = "root"
owner of the installed contents
group: int | str (selectable) = "root"
owner of the installed contents
xattrs: dict[str, str] (selectable) = {}
extended attributes to set on the installed contents
never_use_dev_binary_symlink: bool = False
always install a binary as a regular file
In most cases this means that your binary will not be runnable in
@mode/dev
builds, but it guarantees that the binary will always be
a regular file and never a symlink.
split_debuginfo: bool = True
strip debuginfo from the binary and place it into /usr/lib/debug
always_use_gnu_debuglink: bool = False
setcap: Optional[str] = None
add file capabilities to the installed file
Specified in the form described in cap_from_text(3)
.
default_permissions: default_permissions = record[default_permissions](binary=None, file=None, directory=None)
Default fallback permissions when mode is unset
feature.install_text
Parameters
text: str (selectable)
dst: str (selectable)
mode: Optional[int | str] (selectable) = None
user: int | str (selectable) = "root"
group: int | str (selectable) = "root"
xattrs: dict[str, str] (selectable) = {}
feature.layer_mount
Parameters
source: str (selectable)
mountpoint: Optional[str] = None
feature.remove
Recursively remove a file or directory
Parameters
path: str
must_exist: bool = True
must_be_empty: bool = False
These are allowed to remove paths inherited from the parent layer, or those installed in this layer.
By default, it is an error if the specified path is missing from the image,
though this can be avoided by setting must_exist=False
.
feature.requires
Add rule-level requirements on image layers.
Parameters
files: list[str] = []
groups: list[str] = []
users: list[str] = []
Currently this supports requiring users, groups and files to exist in the layer
being built. This feature doesn't materialize anything in the built image, but it
will cause a compiler error if any of the required features that are
requested do not exist in either the parent_layer
or the layer being
built.
An example of a reasonable use-case of this functionality is defining a
macro that generates systemd units that run as a specific user, where
requires
can be used for additional compile-time safety that the user,
groups or files do indeed exist.
feature.rpms_install
Install RPMs by identifier or .rpm src
Parameters
rpms: list[str] = []
subjects: list[selector | str] (selectable) = []
deps: list[selector | str] (selectable) = []
subjects_src: Optional[str] (selectable) = None
Elements in rpms
can be an rpm name like "systemd"
, a NEVR like
"systemd-251.4-1.2.hs+fb.el8"
(or anything that resolves as a DNF
subject)
or a buck target that produces a .rpm
artifact.
If you want to select
RPMs, you must explicitly use subjects
(for DNF
subjects) or deps
(for buck targets).
feature.rpms_remove
Remove RPMs if they are installed, fail if they are not installed.
Parameters
rpms: list[selector | str] (selectable)
Elements in rpms
can be any rpm specifier (name, NEVR, etc). If the rpm is
not installed, this feature will fail.
Dependencies of these rpms may also be removed, but only if no explicitly-installed RPM depends on them (in this case, the goal cannot be solved and the image build will fail unless you remove those rpms as well).
feature.rpms_remove_if_exists
Remove RPMs if they are installed
Parameters
rpms: list[selector | str] (selectable)
Elements in rpms
can be any rpm specifier (name, NEVR, etc). If the rpm is
not installed, this feature is a no-op.
Dependencies of these rpms may also be removed, but only if no explicitly-installed RPM depends on them (in this case, the goal cannot be solved and the image build will fail unless you remove those rpms as well).
feature.rpms_upgrade
Force an upgrade (if possible, which includes respecting versionlock!) of these rpms.
Parameters
rpms: list[str] = []
subjects: list[selector | str] (selectable) = []
deps: list[selector | str] (selectable) = []
subjects_src: Optional[str] (selectable) = None
See feature.rpms_install
for explanations of each
argument.
feature.standard_user
A convenient function that wraps group_add
, user_add
, and home dir creation logic. The parent directory of home_dir
must already exist.
Parameters
username: str
groupname: str
uid: Optional[int] = None
gid: Optional[int] = None
uidmap: str = "default"
home_dir: Optional[str] = None
shell: str = "/bin/bash"
supplementary_groups: list[str] = []
feature.tarball
Parameters
src: str
into_dir: str
force_root_ownership: bool = False
strip_components: int = 0
feature.user_add
Add a user entry to /etc/passwd.
Parameters
username: str (selectable)
primary_group: str (selectable)
home_dir: str (selectable)
uid: Optional[int] (selectable) = None
uidmap: str = "default"
shell: str (selectable) = "/sbin/nologin"
supplementary_groups: list[selector | str] (selectable) = []
comment: Optional[str] = None
Example usage:
feature.group_add(groupname = "myuser")
feature.user_add(
username = "myuser",
primary_group = "myuser",
home_dir = "/home/myuser",
)
feature.ensure_dirs_exist(
dirs = "/home/myuser",
mode = 0o755,
user = "myuser",
group = "myuser",
)
Unlike shadow-utils useradd
, this item does not automatically create the new
user's initial login group or home directory.
- If
username
oruid
conflicts with existing entries, image build will fail. primary_group
andsupplementary_groups
are specified as groupnames.home_dir
must exist
feature.usermod
Modify an existing entry in the /etc/passwd and /etc/group databases
Parameters
username: str (selectable)
add_supplementary_groups: list[selector | str] (selectable) = []