π Ubuntu setup utility.
Automate the steps you run after installing Ubuntu in a declarative way.
- Ubuntu 16.04 or later (Python >= 3.5)
Refer to the development guide for more information.
Setup configuration is stored in declarative setup.yaml
files. They consist
of three types of elements: actions, categories and metadata.
Categories and metadata are optional features, meaning you can create a
completely valid and functional setup.yaml
files by using actions only:
$folders:
- ~/Apps
- ~/Projects
$apt-packages:
- fish
- cowsay
$snap-packages:
- vscode
- discord
$scriptlet: |
echo "Hello world :D"
$scripts:
- myscript.sh
As you might have guessed, keys beginning with $
(e.g. $folders
,
$apt-packages
) and their values are called actions. They represent setup
instructions in your configuration.
Their names (or keys), schemata and functionalities are defined by plugins. There is a set of built-in plugins that ship with ubup.
If you cannot find an existing plugin that fits your need, you can ...
- write your own bash script ...
- inline via the
scriptlet
plugin - in a seperate file, referencing it using the
scripts
plugin
- inline via the
- create your own custom plugin
Sequence matters in many cases and therefore the order of actions is preserved when ubup performs your setup.
To archive a more organized structure, you can use optional categories.
apps:
$snap-packages:
- chromium
- vlc
appimages:
foo:
$scriptlet: |
# ...
bar:
# ...
# ...
All keys that don't start with $
and that are not metadata keys are
treated as categories. Their main purpose is to support a better structure.
Categories can contain subcategories or actions and the order of categories is preserved.
Optionally, you can specify some additional metadata:
author: John Doe <john.doe@example.com>
description: |
My personal setup configuration.
...
setup:
foo: # category
$apt-packages: # action
# ...
Where setup
contains the root for all categories and actions.
You may not mix metadata with actions or categories and metadata keys
are not allowed to be reused as category names.
Supported metadata keys are:
author: <str>
: The author of the configuration filedescription: <str>
: A description of the configuration file
To perform your setup, simply run
ubup
in the folder that contains your setup.yaml
.
Install a set of packages via apt
.
$apt-packages:
- foo
- bar
# ...
Copy files or folders. This plugin will not create missing target
directories. Use the folders
plugin to ensure that target directories
exist.
You can use ~
or $HOME
as placeholders for the home directory
and $USER
as placeholder for the username of the current user.
Relative paths are relative to the directory containing the setup.yaml
.
$copy:
source: target
foo/*.txt: ~/Documents
test.txt: /opt/foo/bar
Install a set of Flatpak packages.
The list may contain the following types of elements:
.flatpakref
filename or url.flatpak
filename or url- A directory for more options:
package: <.flatpakref url or filename>
(required)remote: <str>
: The remote repository to look for the app or runtime (optional)target: <system|user>
: Whether to install the flatpak for the current user or system-wide (optional, default issystem
)type: <ref|bundle|app|runtime>
: Whether to look for an app, runtime, bundle or ref (optional)ref
: look for a.flatpakref
filebundle
: look for a.flatpak
bundleapp
: look for an app with the given name in aremote
repositoryruntime
: look for a runtime with the given name in aremote
repository
$flatpak-packages:
- foo.flatpak
- bar.flatpakref
- https://example.com/foo.flatpakref
- package: https://example.com/bar.flatpakref
type: ref
target: user
- package: org.freedesktop.Platform
remote: flathub
type: runtime
Add a set of remote Flatpak repositories. Each repository is defined as a dictionary with the following keys:
name: <str>
: The local name of the repository (required)location: <str>
: Url to a remote.flatpakrepo
(required)target: <system|user>
: Whether to install the repository for the current user or system-wide (optional, default issystem
)
$flatpak-repositories:
- name: flathub
location: https://flathub.org/repo/flathub.flatpakrepo
target: system
Create a set of folders unless they already exist.
You can use ~
or $HOME
as placeholders for the home directory
and $USER
as placeholder for the username of the current user.
$folders:
- foo
- bar
# ...
Download GitHub release assets. Each asset is defined as a dictionary with the following keys:
repo: <user>/<repo>
: GitHub repositoryrelease
: GitHub release (tag orlatest
)asset
: Asset to download (either the full filename or a regex)target
: Target filename to save the asset as
$github-releases:
- repo: user/repo
release: v1.2.3
asset: MyAsset-[0-9.]+.zip
target: ~/Documents/MyAsset.zip
Add a set of PPAs unless they are already active.
PPAs must be provided in the format user/ppa
as opposed to ppa:user/ppa
since the action name $ppas
makes it obvious that the repository to add
is a ppa.
$ppas:
- foo/bar
- alexlarsson/flatpak
# ...
Run an inline bash script snippet.
$scriptlet: |
echo "Hello World"
# ...
Run a set of separate bash scripts.
$scripts:
- hello.sh
- scripts/foo.sh
- scripts/bar.sh
Install a set of snap packages.
You can either just define the names of the packages to install or provide a dictionary with additional options:
package: <str>
: Name of the package to install or.snap
filename (required)classic: <true|false>
: Toggle classic confinement (optional)channel: <track>/<risk level>/<branch>
: Snap channel (optional)jailmode: <true|false>
: Toggle enforcement of strict confinement (optional)devmode: <true|false>
: Toggle developer mode confinement (optional)dangerous: <true|false>
: Install the given snap file even if there are no signatures for it (optional)
$snap-packages:
- foo
- package: bar
classic: true
channel: latest/stable
jailmode: false
devmode: false
Missing something? Create a pull request to add your plugin!
Custom plugins can be created in a folder called plugins
next to the setup.yaml
.
This folder may contain a set of Python files (*.py
).
Each Python file may contain one or more
Python classes with a class name ending with Plugin
(e.g. BarPlugin
,
MyPlugin
and even Plugin
are valid plugin class names).
Note: There is one exception: you may not call your plugin class
AbstractPlugin
. If you do so, the class will be simply ignored.
ubup provides a lightweight plugin API which can be imported using
import ubup.plugins
It mainly provides the abstract base class AbstractPlugin
which serves as the skeleton for custom (as well as built-in)
plugins.
Hint:
from ubup.plugins import AbstractPlugin
is equivalent to
from ubup import AbstractPlugin
A hello world plugin plugins/hello-world.py
is as simple as:
from ubup import AbstractPlugin
class HelloPlugin(AbstractPlugin):
key = 'hello'
schema = str
def perform(self):
print("Hello {}!".format(self.config))
key
must be a unique name you will later reference the plugin
by in your setup.yaml
.
schema
must be set to a valid Python data structure that
will be validated using the Python schema library.
perform
must define whatever you want to run when your
plugin is performed.
self.config
holds the user configuration.
This would be a valid setup.yaml
for this example plugin:
$hello: world
self.config
will contain the string "world"
.
This wouldn't be a valid configuration for this example plugin:
$hello:
- a
- b
- c
because we set schema = str
.
If you think your plugin could be useful for other users as well, please feel encouraged to create a pull request to add it as built-in plugin!
The same goes for extending or improving existing plugins, of course.
ubup has experimental support for performing setups remotely via SSH.
To try it out, run:
ubup --remote "user@hostname"
This option is basically just a shortcut running the SSH commands you might run manually to copy ubup and your setup instructions to the remote and to run it.
Therefore there are some limitations:
- Only works properly with password-less logins
- Is disabled when ubup is ran from source
The latter is necessary because ubup temporarily copies itself to the remote machine.
This software is not endorsed by or affiliated with Ubuntu or Canonical. Ubuntu and Canonical are registered trademarks of Canonical Ltd.
Licensed unter the terms of the MIT license.