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

em users: System users don’t exist on BSD, so the argument is ignored for BSD targets.

amples:**

ode:: python

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

name file: The hostname file only matters no systems that do not have hostnamectl, which is part of systemd.

By default pyinfra will auto detect this by targeting /etc/hostname on Linux and /etc/myname on OpenBSD.

To completely disable writing the hostname file, set hostname_file=False.

ample:**

ode:: python

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

amples:**

ode:: python

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

ample:**

ode:: python

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

ons: If the currently mounted filesystem does not have all of the provided options it will be remounted with the options provided.

tc/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

ample:**

ode:: python

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

ample:**

ode:: python

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

ample:**

ode:: python

# 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

ample:**

ode:: python

# 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

ample:**

ode:: python

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

ample:**

ode:: python

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

ample:**

ode:: python

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

ample:**

ode:: python

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, home must be specified delete_keys**: whether to remove any keys not specified in public_keys ensure_home**: whether to ensure the home directory exists create_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

directory:

When ensure_home or public_keys are provided, home defaults to /home/{name}. When create_home is True any newly created users will be created with the -m flag to build a new home directory from the systems skeleton directory.

ic keys: These can be provided as strings containing the public key or as a path to a public key file which pyinfra will read.

amples:**

ode:: python

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.user_authorized_keys

Manage authorized_keys of system users.

server.user_authorized_keys(
    user: str, public_keys: str | list[str], group: str | None=None, delete_keys=False,
    authorized_key_directory: str | None=None, authorized_key_filename: str | None=None,
    **kwargs,
)

user**: name of the user to ensure public_keys**: list of public keys to attach to this user, home must be specified group**: the users primary group delete_keys**: whether to remove any keys not specified in public_keys

ic keys: These can be provided as strings containing the public key or as a path to a public key file which pyinfra will read.

amples:**

ode:: python

server.user_authorized_keys(

name=”Ensure user has a public key”, user=”kevin”, public_keys=[“ed25519…”],

) 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

ample:**

ode:: python

server.wait(

name=”Wait for webserver to start”, port=80,

) Note:

This operation also inherits all global arguments.