Skip to main content

An easy solution for system/dotfile configuration

Project description

instater

An easy solution for system/dotfile configuration

Loosely based off of Ansible for the task and file organization

Installation

pip3 install instater

For Arch users

Using yay:

yay -Sy instater

Using makepkg:

git clone https://aur.archlinux.org/instater.git
cd instater
makepkg -sirc

Usage

See the File Structure Example below to set up variables, files, and tasks.

Once a setup.yml file is created, it can be run using

instater

# or:
instater --setup-file setup.yml

To see what changed will be made, but not actually make then, use --dry-run:

instater --dry-run

For a complete example, see dotfiles

File Structure Example

First, create a setup.yml file:

# Lots of ways to prompt for data at the beginning of execution
vars_prompt:
- name: my_var
- name: custom_prompt
  prompt: Enter something here
- name: private_var
  private: true
- name: private_confirm_var
  private: true
  confirm: true
- name: allow_empty_var
  allow_empty: true

# variables that can be used within tasks/files can be populated
# from a static file, in this case vars/common.yml
vars_files:
- vars/common.yml
# variables can be used within the file names
- "vars/{{ vars_file }}.yml"

# All of the tasks to perform are enumerated
tasks:
- name: Copy file
  # {{ username }} is replaced with the variable `username`
  copy:
    content: "The contents of a new file in here"
    dest: "/home/{{ username }}/Downloads/file1"
    mode: "600"
  # if desired, the output of this task can be registered to use as
  # a condition for subsequent tasks
  register: file1_copy
- name: Run a command if file1 written
  command: "touch /home/{{ username }}/testfile"
  when: file1_copy.changed

Then, create a vars/ directory and common.yml within:

my_test: 1
some_var: "{{ my_test + 2 }}"
vars_file: "second"
username: something

And vars/second.yml (since common.yml set vars_file to second):

from_second_yml: data in here

Now in all of the tasks, my_test, username, from_second_yml, etc will be present and accessible.

Tasks

All tasks support the following arguments:

  • name (string, optional): The name of the task, included in logs
  • when (string, optional): A Jinja2 statement to determine whether the task should be skipped. If the statement evaluates to True, the task will be executed. Example: my_variable == 'foo'
  • register (string, optional): A variable to store task results under. Can be used in conjunction with a subsequent when clause, for example register: my_task can be used in another task as when: my_task.changed
  • with_fileglob (string, optional): If provided, find all files in the instater root that match the glob, and create a task with all other

Example of register and when:

- name: Set locale to en_US
  copy:
    content: "en_US.UTF-8 UTF-8\n"
    dest: /etc/locale.gen
  register: locale_gen

- name: Generate locale files
  command: locale-gen
  when: locale_gen.changed

Example of with_fileglob:

- include: "{{ task }}"
  with_fileglob: "applications/*"

aur (Arch User Repository, alias of pacman)

Install packages from a Arch User Repository

Arguments

  • packages (string, [string]): The packages to install, can be a single package or a list of packages
  • become (string, optional): A user to become while installing packages

Examples:

- name: Install python package
  aur:
    packages: python
  become: makepkg
- name: Install python libraries
  aur:
    packages:
    - python-setuptools
    - python-wheel

command

Run arbitrary shell commands (can be risky)

Arguments

  • command (string, [string]): The command or commands to execute
  • condition (string, optional): A command to run prior to the command, as a condition for whether or not it should actually be executed
  • condition_code (int, optional): The return code from the condition command to match against. If the condition returns this code, the command will be executed. Defaults to 0
  • become (string, optional): A user to become while running the commands (including the condition command)
  • directory (string, optional): The working directory to use while running the commands

Note that the command and conditions may make use of pipes, for example curl -s https://get.sdkman.io | bash

Examples:

- name: Make a curl
  command:
    command: curl https://google.com
- name: Create a file if it doesn't exist
  command:
    command: touch to/file
    condition: ls to/file
    condition_code: 2
    directory: path
- name: Run several commands
  command:
    command:
    - echo "This does nothing"
    - echo "More commands"

copy

Copy a file, directory, url, or direct string content to a destination file or directory

Arguments

  • dest (string): The destination file or directory to write to
  • src (string, optional): The source file or directory to copy
  • content (string, optional): The exact content that should be copied to the dest
  • url (string, optional): A url to GET and use as the content
  • owner (string, optional): The owner to set on the file. Note that if a parent directory must be created, it may not be given this owner and should be created separately
  • group (string, optional): The group to set on the file. Note that if a parent directory must be created, it may not be given this group and should be created separately
  • mode (string, integer, optional): The file permissions to set on the destination. Note that if a YAML integer is provided, it must start with a 0 to be parsed as octal
  • is_template (bool, optional): If set to true, the content will be rendered using Jinja2 and all available variables before comparing or writing to dest
  • validate (string, optional): A command to run to validate the source file or content prior to writing it to the destination. Should contain a %s which will be replaced by a filename to validate. When applied to a directory, each file is separately validated

Exactly one of src, content, or url must be provided

Examples:

- name: Copy a file
  copy:
    src: files/my_file.txt
    dest: /path/to/destination
- name: Copy a directory
  copy:
    src: files/my_directory
    dest: /path/to/dest
- name: Copy and set owner/group/mode
  copy:
    src: files/executable.sh
    dest: /usr/local/bin/executable.sh
    owner: some_user
    group: some_group
    mode: 0755
- name: Download a url
  copy:
    url: https://raw.githubusercontent.com/nayaverdier/instater/main/README.md
    dest: /path/to/instater/README.md
    owner: my_user
    group: my_user
- name: Copy content directly
  copy:
    content: "{{ hostname }}"
    dest: /etc/hostname
- name: Copy and validate sudoers file
  copy:
    src: files/sudoers
    dest: /etc/sudoers
    mode: 0440
    validate: /usr/sbin/visudo -csf %s
- name: Render jinja template and copy
  copy:
    src: files/my_template
    dest: /path/to/file
    is_template: true

debug

Log a debug message

Arguments

  • debug (str): The message to log

Example

- name: Log execution information
  debug: "Instater root directory: {{ instater_dir }}"

directory

Create a directory. Same as passing directory: true to the file task.

Arguments

(see file)

Example

- name: Create example directory
  directory:
    path: "/path/to/directory"
- name: Create a user directory
  directory:
    path: "/home/exampleuser/private_directory"
    owner: exampleuser
    group: exampleuser
    mode: 0700

file

Create an empty file, directory, symlink, or hard link on the file system.

Arguments

  • path (string): The path of the file or directory to manage
  • target (string, optional): When managing a symlink or hard_link, the target file or directory to point to
  • owner (string, optional): The owner to set on the file. Note that if a parent directory must be created, it may not be given this owner and should be created separately
  • group (string, optional): The group to set on the file. Note that if a parent directory must be created, it may not be given this group and should be created separately
  • mode (string, integer, optional): The file permissions to set on the destination. Note that if a YAML integer is provided, it must start with a 0 to be parsed as octal
  • directory (boolean, optional): If set to true, create a directory
  • symlink (boolean, optional): If set to true, create a symlink
  • hard_link (boolean, optional): If set to true, create a hard link

At most one of directory, symlink, and hard_link may be provided

Example

- name: Create an empty file
  file:
    path: /path/to/file
- name: Create an empty file with owner/group/mode
  file:
    path: /home/myuser/myfile
    owner: myuser
    group: myuser
    mode: 0600
- name: Create a symlink
  file:
    path: /etc/localtime
    target: /usr/share/zoneinfo/America/New_York
    symlink: true
- name: Create a hard link
  file:
    path: /path/to/new/file
    target: /path/to/existing/file
    hard_link: true
- name: Create a directory
  file:
    path: /path/to/my/dir/
    directory: true
- name: Create a directory with owner/group/mode
  file:
    path: /home/myuser/dir/
    owner: myuser
    group: myuser
    mode: 0700
    directory: true

git

Clone or update a git repository

Arguments

  • repo (string): The git repo uri to clone
  • dest (string): The destination path to clone into
  • depth (integer, optional): Creates a shallow clone with truncated history
  • fetch_tags (boolean, optional): Whether or not to fetch git tags (defaults to true)
  • become (string, optional): The UNIX user that should be used to run git commands

Example

- name: Clone instater
  git:
    repo: https://github.com/nayaverdier/instater
    dest: /home/myuser/Documents/instater
    become: myuser
- name: Clone with truncated history
  git:
    repo: https://github.com/nayaverdier/instater
    dest: /home/myuser/Documents/instater
    depth: 1
    become: myuser

group

Create a UNIX group

Arguments

  • group (string): The name of the UNIX group to create

Example

- name: Create a group
  group: mygroup

hard_link

Create a hard link to a file

Arguments

(see file)

Example

- name: Create a hard link
  hard_link:
    path: /path/to/new/linked/file
    target: /path/to/existing/file

include

Include another YAML file containing tasks, to allow for better organization of tasks

Arguments

  • include (string): The path of the YAML file to include (relative to the setup.yml)

Example

- include: tasks/something.yml
- include: "{{ item }}"
  with_fileglob: "tasks/applications/*"

pacman

Install Arch Linux packages using the pacman, yay, or makepkg commands

Arguments

  • packages (string, [string]): The packages to install, can be a single package or a list of packages
  • aur (boolean, optional): If set to true, the packages will be installed from the Arch User Repository using yay (or makepkg as a fallback)
  • become (string, optional): When aur is true, install using a specific user

Examples:

- name: Install python package
  pacman:
    packages: python
- name: Install python libraries
  pacman:
    packages:
    - python-setuptools
    - python-wheel
- name: Install instater
  pacman:
    packages:
      - instater
    aur: true
    become: makepkg

service

Start, enable, or disable a systemctl service

Arguments

  • service (string): The name of the service to manage
  • started (boolean, optional): If set to true, start the service
  • enabled (boolean, optional): Whether or not the service should be enabled

Example

- name: Enable postgres service
  service:
    service: postgresql
    started: true
    enabled: true
- name: Start redis service
  service:
    service: redis
    started: true

symlink

Create a symlink to a file or directory

Arguments

(see file)

Example

- name: Create a symlink
  symlink:
    path: /path/to/new/linked/file
    target: /path/to/existing/file

template

Copy data, transforming the content as a Jinja2 template prior to writing. Same as passing is_template: true to copy

Arguments

(see copy)

Example

- name: Copy configuration template
  template:
    src: files/some_config
    dest: "/home/{{ username }}/.config/some_config"
    owner: "{{ username }}"
    group: "{{ username }}"
    mode: 0644

user

Create a UNIX user

Arguments

  • user (string): The name of the user to create
  • system (boolean, optional): Whether or not this user is a system user (only used when the user needs to be created)
  • create_home (boolean, optional): Whether or not a home directory for this user should be created
  • password (string, optional): A hashed password to set as the user's password (only used when the user needs to be created )
  • shell (string, optional): The login shell to use for the user
  • groups (string, [string]): The group or groups to add the user to

Example

- name: Create primary user
  user:
    user: my_username
    shell: /usr/bin/zsh
    groups: sudo
    password: "{{ login_password | password_hash('sha512') }}"
  when: login_password is defined
- name: Create makepkg user
  user:
    user: makepkg
    groups: makepkg
    system: true

Changelog

0.13.1 2023-11-28

  • Add support for python3.12

0.13.0 2023-06-06

  • Automatically convert int/float from templated variables, instead of being strings
  • become the makepkg user for running yay (hardcoded for now)

0.12.0 2023-04-24

  • Add pacman_bootstrapped_packages option to ignore certain packages from the manually installed checks
  • Add --quiet or -q flag which does not print any information for skipped tasks

0.11.0 2022-04-24

  • Fix instater_dir template variable to be a proper absolute path (previously, relative paths could appear like /path/to/cwd/../another_dir/setup.yml)
  • Add --explain flag to show reasoning for each changed/skipped task
  • Do not run the pacman package comparison when specifying --tags, since in that situation the comparison is not complete

0.10.0 2022-04-13

  • Add fetch_tags argument to git task

0.9.0 2022-04-12

  • Add check for manually installed pacman packages when using Arch Linux
  • Add --skip-tasks argument to skip all tasks (useful for the pacman package check)
  • Fix bug where relative paths were not resolving when instater was run from a directory other than the one containing the setup.yml file

0.8.0 2021-11-06

  • command: Support pipes between two commands

0.7.0 2021-11-04

  • Better support when argument so that undefined variables are counted as a falsey variable

0.6.0 2021-10-29

  • aur: Fix bug negating the condition for using yay vs makepkg

0.5.0 2021-10-28

  • Add --version option to the CLI to display the Instater version
  • aur: Now an alias of pacman, which supports makepkg
  • pacman: Add aur and become attributes
  • pacman: Add support for makepkg and yay installations

0.4.0 2021-10-28

  • user: Support create_home argument

0.3.0 2021-10-25

  • BREAKING Use absolute path for the instater_dir variable
  • Add duration logging for each task and in the overall summary
  • Fix tag rendering to support {{ item }} in tags
  • Add a filename jinja filter to extract filenames without extensions
  • Document all tasks
  • aur/pacman: Support checking for package group installation
  • BREAKING debug: Remove the msg argument(pass the debug message directly to debug)
  • BREAKING get_url: Remove task as it is identical to copy

0.2.0 2021-10-24

  • Initial release was missing tasks module, fixed in 0.2.0
  • Fix circular dependency issue when packaged
  • Update README with all existing tasks

0.1.0 2021-10-24

  • Initial release

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

instater-0.13.1.tar.gz (25.2 kB view hashes)

Uploaded Source

Built Distribution

instater-0.13.1-py3-none-any.whl (26.2 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page