Server Operations¶
The server module takes care of os-level state. Targets POSIX compatibility, tested on Linux/BSD.
Facts used in these operations: files.Directory, files.FindInFile, server.Groups, server.Home, server.Hostname, server.Kernel, server.KernelModules, files.Link, server.Locales, server.Mounts, server.Os, server.Sysctl, server.Users, server.Which.
server.group¶
Add/remove system groups.
server.group(group: str, present=True, system=False, gid: int | str | None=None, **kwargs)
group: name of the group to ensure
present: whether the group should be present or not
system: whether to create a system group
gid: use a specific groupid number
- System users:
System users don’t exist on BSD, so the argument is ignored for BSD targets.
Examples:
server.group(
name="Create docker group",
group="docker",
)
# multiple groups
for group in ["wheel", "lusers"]:
server.group(
name=f"Create the group {group}",
group=group,
)
- Note:
This operation also inherits all global arguments.
server.hostname¶
Set the system hostname using hostnamectl or hostname on older systems.
server.hostname(hostname: str, hostname_file: str | None=None, **kwargs)
hostname: the hostname that should be set
hostname_file: the file that permanently sets the hostname
- Hostname file:
The hostname file only matters no systems that do not have
hostnamectl, which is part ofsystemd.By default pyinfra will auto detect this by targeting
/etc/hostnameon Linux and/etc/mynameon OpenBSD.To completely disable writing the hostname file, set
hostname_file=False.
Example:
server.hostname(
name="Set the hostname",
hostname="server1.example.com",
)
- Note:
This operation also inherits all global arguments.
server.locale¶
Enable/Disable locale.
server.locale(locale: str, present=True, **kwargs)
locale: name of the locale to enable/disable
present: whether this locale should be present or not
Examples:
server.locale(
name="Ensure en_GB.UTF-8 locale is not present",
locale="en_GB.UTF-8",
present=False,
)
server.locale(
name="Ensure en_GB.UTF-8 locale is present",
locale="en_GB.UTF-8",
)
- Note:
This operation also inherits all global arguments.
server.modprobe¶
Load/unload kernel modules.
server.modprobe(module: str, present=True, force=False, **kwargs)
module: name of the module to manage
present: whether the module should be loaded or not
force: whether to force any add/remove modules
Example:
server.modprobe(
name="Silly example for modprobe",
module="floppy",
)
- Note:
This operation also inherits all global arguments.
server.mount¶
Manage mounted filesystems.
server.mount(
path: str, mounted=True, options: list[str] | None=None, device: str | None=None,
fs_type: str | None=None, **kwargs,
)
path: the path of the mounted filesystem
mounted: whether the filesystem should be mounted
options: the mount options
- Options:
If the currently mounted filesystem does not have all of the provided options it will be remounted with the options provided.
/etc/fstab:This operation does not attempt to modify the on disk fstab file - for that you should use the files.line operation.
- Note:
This operation also inherits all global arguments.
server.packages¶
Add or remove system packages. This command checks for the presence of all the system package managers pyinfra can handle and executes the relevant operation.
server.packages(packages: str | list[str], present=True, **kwargs)
packages: list of packages to ensure
present: whether the packages should be installed
Example:
server.packages(
name="Install Vim and vimpager",
packages=["vimpager", "vim"],
)
- Note:
This operation also inherits all global arguments.
server.reboot¶
Stateless operation
This operation will always execute commands and is not idempotent.
Reboot the server and wait for reconnection.
server.reboot(delay=10, interval=1, reboot_timeout=300, **kwargs)
delay: number of seconds to wait before attempting reconnect
interval: interval (s) between reconnect attempts
reboot_timeout: total time before giving up reconnecting
Example:
server.reboot(
name="Reboot the server and wait to reconnect",
delay=60,
reboot_timeout=600,
)
- Note:
This operation also inherits all global arguments.
server.script¶
Stateless operation
This operation will always execute commands and is not idempotent.
Upload and execute a local script on the remote host.
server.script(src: str, args=(), **kwargs)
src: local script filename to upload & execute
args: iterable to pass as arguments to the script
Example:
# Note: This assumes there is a file in files/hello.bash locally.
server.script(
name="Hello",
src="files/hello.bash",
)
# Example passing arguments to the script
server.script(
name="Hello",
src="files/hello.bash",
args=("do-something", "with-this"),
)
- Note:
This operation also inherits all global arguments.
server.script_template¶
Stateless operation
This operation will always execute commands and is not idempotent.
Generate, upload and execute a local script template on the remote host.
server.script_template(src: str, args=(), **kwargs)
src: local script template filename
Example:
# Example showing how to pass python variable to a script template file.
# The .j2 file can use `{{ some_var }}` to be interpolated.
# To see output need to run pyinfra with '-v'
# Note: This assumes there is a file in templates/hello2.bash.j2 locally.
some_var = 'blah blah blah '
server.script_template(
name="Hello from script",
src="templates/hello2.bash.j2",
some_var=some_var,
)
- Note:
This operation also inherits all global arguments.
server.security_limit¶
Edit /etc/security/limits.conf configuration.
server.security_limit(domain: str, limit_type: str, item: str, value: int, **kwargs)
domain: the domain (user, group, or wildcard) for the limit
limit_type: the type of limit (hard or soft)
item: the item to limit (e.g., nofile, nproc)
value: the value for the limit
Example:
security_limit(
name="Set nofile limit for all users",
domain='*',
limit_type='soft',
item='nofile',
value=1024,
)
- Note:
This operation also inherits all global arguments.
server.service¶
Manage the state of services. This command checks for the presence of all the Linux init systems pyinfra can handle and executes the relevant operation.
server.service(
service: str, running=True, restarted=False, reloaded=False, command: str | None=None,
enabled: bool | None=None, **kwargs,
)
service: name of the service to manage
running: whether the service should be running
restarted: whether the service should be restarted
reloaded: whether the service should be reloaded
command: custom command execute
enabled: whether this service should be enabled/disabled on boot
Example:
server.service(
name="Enable open-vm-tools service",
service="open-vm-tools",
enabled=True,
)
- Note:
This operation also inherits all global arguments.
server.shell¶
Stateless operation
This operation will always execute commands and is not idempotent.
Run raw shell code on server during a deploy. If the command would modify data that would be in a fact, the fact would not be updated since facts are only run at the start of a deploy.
server.shell(commands: str | list[str], **kwargs)
commands: command or list of commands to execute on the remote server
Example:
server.shell(
name="Run lxd auto init",
commands=["lxd init --auto"],
)
- Note:
This operation also inherits all global arguments.
server.sysctl¶
Edit sysctl configuration.
server.sysctl(
key: str, value: str | int | list[str | int], persist=False,
persist_file="/etc/sysctl.conf", **kwargs,
)
key: name of the sysctl setting to ensure
value: the value or list of values the sysctl should be
persist: whether to write this sysctl to the config
persist_file: file to write the sysctl to persist on reboot
Example:
server.sysctl(
name="Change the fs.file-max value",
key="fs.file-max",
value=100000,
persist=True,
)
- Note:
This operation also inherits all global arguments.
server.user¶
Add/remove/update system users & their ssh authorized_keys.
server.user(
user: str, present=True, home: str | None=None, shell: str | None=None,
group: str | None=None, groups: list[str] | None=None, append=False,
public_keys: str | list[str] | None=None, delete_keys=False, ensure_home=True,
create_home=False, system=False, uid: int | None=None, comment: str | None=None,
unique=True, password: str | None=None, **kwargs,
)
user: name of the user to ensure
present: whether this user should exist
home: the users home directory
shell: the users shell
group: the users primary group
groups: the users secondary groups
append: whether to add user to groups, w/o losing membership of other groups
public_keys: list of public keys to attach to this user,
homemust be specifieddelete_keys: whether to remove any keys not specified in
public_keysensure_home: whether to ensure the
homedirectory existscreate_home: whether user create new user home directories from the system skeleton
system: whether to create a system account
uid: use a specific userid number
comment: the user GECOS comment
unique: prevent creating users with duplicate UID
password: set the encrypted password for the user
- Home directory:
When
ensure_homeorpublic_keysare provided,homedefaults to/home/{name}. Whencreate_homeisTrueany newly created users will be created with the-mflag to build a new home directory from the systems skeleton directory.- Public keys:
These can be provided as strings containing the public key or as a path to a public key file which pyinfra will read.
Examples:
server.user(
name="Ensure user is removed",
user="kevin",
present=False,
)
server.user(
name="Ensure myweb user exists",
user="myweb",
shell="/bin/bash",
)
# multiple users
for user in ["kevin", "bob"]:
server.user(
name=f"Ensure user {user} is removed",
user=user,
present=False,
)
- Note:
This operation also inherits all global arguments.
server.wait¶
Stateless operation
This operation will always execute commands and is not idempotent.
Waits for a port to come active on the target machine. Requires netstat, checks every second.
server.wait(port: int, **kwargs)
port: port number to wait for
Example:
server.wait(
name="Wait for webserver to start",
port=80,
)
- Note:
This operation also inherits all global arguments.
pyinfra 3.x