Package: instater
instaterAn easy solution for system/dotfile configurationLoosely based off of Ansible for the task and file organizationInstallationpip3installinstaterFor Arch usersUsingyay:yay-SyinstaterUsing makepkg:gitclonehttps://aur.archlinux.org/instater.gitcdinstater
makepkg-sircUsageSee the File Structure Example below to set up variables, files, and tasks.Once asetup.ymlfile is created, it can be run usinginstater# or:instater--setup-filesetup.ymlTo see what changed will be made, but not actually make then, use--dry-run:instater--dry-runFor a complete example, seedotfilesFile Structure ExampleFirst, create asetup.ymlfile:# Lots of ways to prompt for data at the beginning of executionvars_prompt:-name:my_var-name:custom_promptprompt:Enter something here-name:private_varprivate:true-name:private_confirm_varprivate:trueconfirm:true-name:allow_empty_varallow_empty:true# variables that can be used within tasks/files can be populated# from a static file, in this case vars/common.ymlvars_files:-vars/common.yml# variables can be used within the file names-"vars/{{vars_file}}.yml"# All of the tasks to perform are enumeratedtasks:-name:Copy file# {{ username }} is replaced with the variable `username`copy:content:"Thecontentsofanewfileinhere"dest:"/home/{{username}}/Downloads/file1"mode:"600"# if desired, the output of this task can be registered to use as# a condition for subsequent tasksregister:file1_copy-name:Run a command if file1 writtencommand:"touch/home/{{username}}/testfile"when:file1_copy.changedThen, create avars/directory andcommon.ymlwithin:my_test:1some_var:"{{my_test+2}}"vars_file:"second"username:somethingAndvars/second.yml(sincecommon.ymlsetvars_filetosecond):from_second_yml:data in hereNow in all of the tasks,my_test,username,from_second_yml, etc will be
present and accessible.TasksAll 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 subsequentwhenclause, for exampleregister: my_taskcan be used in another task aswhen: my_task.changedwith_fileglob(string, optional): If provided, find all files in the instater
root that match the glob, and create a task with all otherExample ofregisterandwhen:-name:Set locale to en_UScopy:content:"en_US.UTF-8UTF-8\n"dest:/etc/locale.genregister:locale_gen-name:Generate locale filescommand:locale-genwhen:locale_gen.changedExample ofwith_fileglob:-include:"{{task}}"with_fileglob:"applications/*"aur(Arch User Repository, alias ofpacman)Install packages from a Arch User RepositoryArgumentspackages(string, [string]): The packages to install, can be a single package
or a list of packagesbecome(string, optional): A user to become while installing packagesExamples:-name:Install python packageaur:packages:pythonbecome:makepkg-name:Install python librariesaur:packages:-python-setuptools-python-wheelcommandRun arbitrary shell commands (can be risky)Argumentscommand(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 theconditioncommand to match against. If theconditionreturns this
code, thecommandwill 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 commandsNote that the command and conditions may make use of pipes, for examplecurl -s https://get.sdkman.io | bashExamples:-name:Make a curlcommand:command:curl https://google.com-name:Create a file if it doesn't existcommand:command:touch to/filecondition:ls to/filecondition_code:2directory:path-name:Run several commandscommand:command:-echo "This does nothing"-echo "More commands"copyCopy a file, directory, url, or direct string content to a destination file or directoryArgumentsdest(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 a0to 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 todestvalidate(string, optional): A command to run to validate the source file
or content prior to writing it to the destination. Should contain a%swhich will be replaced by a filename to validate. When applied to a
directory, each file is separately validatedExactly one ofsrc,content, orurlmust be providedExamples:-name:Copy a filecopy:src:files/my_file.txtdest:/path/to/destination-name:Copy a directorycopy:src:files/my_directorydest:/path/to/dest-name:Copy and set owner/group/modecopy:src:files/executable.shdest:/usr/local/bin/executable.showner:some_usergroup:some_groupmode:0755-name:Download a urlcopy:url:https://raw.githubusercontent.com/nayaverdier/instater/main/README.mddest:/path/to/instater/README.mdowner:my_usergroup:my_user-name:Copy content directlycopy:content:"{{hostname}}"dest:/etc/hostname-name:Copy and validate sudoers filecopy:src:files/sudoersdest:/etc/sudoersmode:0440validate:/usr/sbin/visudo -csf %s-name:Render jinja template and copycopy:src:files/my_templatedest:/path/to/fileis_template:truedebugLog a debug messageArgumentsdebug(str): The message to logExample-name:Log execution informationdebug:"Instaterrootdirectory:{{instater_dir}}"directoryCreate a directory. Same as passingdirectory: trueto thefiletask.Arguments(seefile)Example-name:Create example directorydirectory:path:"/path/to/directory"-name:Create a user directorydirectory:path:"/home/exampleuser/private_directory"owner:exampleusergroup:exampleusermode:0700fileCreate an empty file, directory, symlink, or hard link on the file system.Argumentspath(string): The path of the file or directory to managetarget(string, optional): When managing asymlinkorhard_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 a0to 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 linkAt most one ofdirectory,symlink, andhard_linkmay be providedExample-name:Create an empty filefile:path:/path/to/file-name:Create an empty file with owner/group/modefile:path:/home/myuser/myfileowner:myusergroup:myusermode:0600-name:Create a symlinkfile:path:/etc/localtimetarget:/usr/share/zoneinfo/America/New_Yorksymlink:true-name:Create a hard linkfile:path:/path/to/new/filetarget:/path/to/existing/filehard_link:true-name:Create a directoryfile:path:/path/to/my/dir/directory:true-name:Create a directory with owner/group/modefile:path:/home/myuser/dir/owner:myusergroup:myusermode:0700directory:truegitClone or update a git repositoryArgumentsrepo(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 commandsExample-name:Clone instatergit:repo:https://github.com/nayaverdier/instaterdest:/home/myuser/Documents/instaterbecome:myuser-name:Clone with truncated historygit:repo:https://github.com/nayaverdier/instaterdest:/home/myuser/Documents/instaterdepth:1become:myusergroupCreate a UNIX groupArgumentsgroup(string): The name of the UNIX group to createExample-name:Create a groupgroup:mygrouphard_linkCreate a hard link to a fileArguments(seefile)Example-name:Create a hard linkhard_link:path:/path/to/new/linked/filetarget:/path/to/existing/fileincludeInclude another YAML file containing tasks, to allow for better organization of
tasksArgumentsinclude(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/*"pacmanInstall Arch Linux packages using thepacman,yay, ormakepkgcommandsArgumentspackages(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(ormakepkgas a fallback)become(string, optional): Whenauris true, install using a specific userExamples:-name:Install python packagepacman:packages:python-name:Install python librariespacman:packages:-python-setuptools-python-wheel-name:Install instaterpacman:packages:-instateraur:truebecome:makepkgserviceStart, enable, or disable a systemctl serviceArgumentsservice(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 enabledExample-name:Enable postgres serviceservice:service:postgresqlstarted:trueenabled:true-name:Start redis serviceservice:service:redisstarted:truesymlinkCreate a symlink to a file or directoryArguments(seefile)Example-name:Create a symlinksymlink:path:/path/to/new/linked/filetarget:/path/to/existing/filetemplateCopy data, transforming the content as a Jinja2 template prior to writing.
Same as passingis_template: truetocopyArguments(seecopy)Example-name:Copy configuration templatetemplate:src:files/some_configdest:"/home/{{username}}/.config/some_config"owner:"{{username}}"group:"{{username}}"mode:0644userCreate a UNIX userArgumentsuser(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 toExample-name:Create primary useruser:user:my_usernameshell:/usr/bin/zshgroups:sudopassword:"{{login_password|password_hash('sha512')}}"when:login_password is defined-name:Create makepkg useruser:user:makepkggroups:makepkgsystem:trueChangelog0.13.1 2023-11-28Add support for python3.120.13.0 2023-06-06Automatically convert int/float from templated variables, instead of being stringsbecomethemakepkguser for runningyay(hardcoded for now)0.12.0 2023-04-24Addpacman_bootstrapped_packagesoption to ignore certain packages from the
manually installed checksAdd--quietor-qflag which does not print any information for skipped
tasks0.11.0 2022-04-24Fixinstater_dirtemplate variable to be a proper absolute path
(previously, relative paths could appear like/path/to/cwd/../another_dir/setup.yml)Add--explainflag to show reasoning for each changed/skipped taskDo not run the pacman package comparison when specifying--tags,
since in that situation the comparison is not complete0.10.0 2022-04-13Addfetch_tagsargument togittask0.9.0 2022-04-12Add check for manually installed pacman packages when using Arch LinuxAdd--skip-tasksargument 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 file0.8.0 2021-11-06command: Support pipes between two commands0.7.0 2021-11-04Better supportwhenargument so that undefined variables are
counted as a falsey variable0.6.0 2021-10-29aur: Fix bug negating the condition for usingyayvsmakepkg0.5.0 2021-10-28Add--versionoption to the CLI to display the Instater versionaur: Now an alias ofpacman, which supportsmakepkgpacman: Addaurandbecomeattributespacman: Add support formakepkgandyayinstallations0.4.0 2021-10-28user: Supportcreate_homeargument0.3.0 2021-10-25BREAKINGUse absolute path for theinstater_dirvariableAdd duration logging for each task and in the overall summaryFix tag rendering to support{{ item }}in tagsAdd afilenamejinja filter to extract filenames without extensionsDocument all tasksaur/pacman: Support checking for package group installationBREAKINGdebug: Remove themsgargument(pass the debug message
directly todebug)BREAKINGget_url: Remove task as it is identical tocopy0.2.0 2021-10-24Initial release was missingtasksmodule, fixed in 0.2.0Fix circular dependency issue when packagedUpdate README with all existing tasks0.1.0 2021-10-24Initial release