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 logswhen
(string, optional): A Jinja2 statement to determine whether the task should be skipped. If the statement evaluates toTrue
, 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 subsequentwhen
clause, for exampleregister: my_task
can be used in another task aswhen: 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 packagesbecome
(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 executecondition
(string, optional): A command to run prior to thecommand
, as a condition for whether or not it should actually be executedcondition_code
(int, optional): The return code from thecondition
command to match against. If thecondition
returns this code, thecommand
will be executed. Defaults to 0become
(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 tosrc
(string, optional): The source file or directory to copycontent
(string, optional): The exact content that should be copied to the desturl
(string, optional): A url to GET and use as the contentowner
(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 separatelygroup
(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 separatelymode
(string, integer, optional): The file permissions to set on the destination. Note that if a YAML integer is provided, it must start with a0
to be parsed as octalis_template
(bool, optional): If set to true, the content will be rendered using Jinja2 and all available variables before comparing or writing todest
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 managetarget
(string, optional): When managing asymlink
orhard_link
, the target file or directory to point toowner
(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 separatelygroup
(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 separatelymode
(string, integer, optional): The file permissions to set on the destination. Note that if a YAML integer is provided, it must start with a0
to be parsed as octaldirectory
(boolean, optional): If set totrue
, create a directorysymlink
(boolean, optional): If set totrue
, create a symlinkhard_link
(boolean, optional): If set totrue
, 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 clonedest
(string): The destination path to clone intodepth
(integer, optional): Creates a shallow clone with truncated historyfetch_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 packagesaur
(boolean, optional): If set to true, the packages will be installed from the Arch User Repository usingyay
(ormakepkg
as a fallback)become
(string, optional): Whenaur
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 managestarted
(boolean, optional): If set totrue
, start the serviceenabled
(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 createsystem
(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 createdpassword
(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 usergroups
(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
themakepkg
user for runningyay
(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 togit
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 usingyay
vsmakepkg
0.5.0 2021-10-28
- Add
--version
option to the CLI to display the Instater version aur
: Now an alias ofpacman
, which supportsmakepkg
pacman
: Addaur
andbecome
attributespacman
: Add support formakepkg
andyay
installations
0.4.0 2021-10-28
user
: Supportcreate_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 themsg
argument(pass the debug message directly todebug
) - BREAKING
get_url
: Remove task as it is identical tocopy
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file instater-0.13.1.tar.gz
.
File metadata
- Download URL: instater-0.13.1.tar.gz
- Upload date:
- Size: 25.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.7.17
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | d683885a645d06fbe223e48c820faa375bdffa4a5fe5ae2b90df2febd9af5de7 |
|
MD5 | c8ef981406ac5c29d96086167fe7bbc1 |
|
BLAKE2b-256 | 836ff6322aaeb9e742aeba598ae414ec081d2861a662f57a461b8b816d2f25c0 |
File details
Details for the file instater-0.13.1-py3-none-any.whl
.
File metadata
- Download URL: instater-0.13.1-py3-none-any.whl
- Upload date:
- Size: 26.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.7.17
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 858ac3ede166b0bbaedacc413df29b7e796944dcdbf131a2d7cc17209e2bc7f5 |
|
MD5 | 3923d96d6805b3e6fcb0075b5cf0dc19 |
|
BLAKE2b-256 | 6f1a1469a4c51d9cef46c7da26c5af7914ea3febe52f3e80fc46be8ce0616f11 |