feat: added new roles to match daily driver desktop; full idempotency; several fixes and tweaks; re-added hosts in inventory
This commit is contained in:
parent
555fde4351
commit
726b7668f9
65 changed files with 10012 additions and 377 deletions
15
.editorconfig
Normal file
15
.editorconfig
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
charset = utf-8
|
||||||
|
max_line_length = 160
|
||||||
|
|
||||||
|
[*.{py,py3}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[*.{yml,yaml,json}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
*.ttf filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.png filter=lfs diff=lfs merge=lfs -text
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -7,5 +7,4 @@ collections/ansible_collections/*/*/logs/*
|
||||||
!collections/ansible_collections/*/*/tests/config.yml
|
!collections/ansible_collections/*/*/tests/config.yml
|
||||||
vault.yml
|
vault.yml
|
||||||
inventory/inventory.yml
|
inventory/inventory.yml
|
||||||
inventory/host_vars/*
|
|
||||||
!.gitkeep
|
!.gitkeep
|
||||||
|
|
66
README.md
66
README.md
|
@ -6,8 +6,11 @@
|
||||||
- Python3.9+,
|
- Python3.9+,
|
||||||
- PIP,
|
- PIP,
|
||||||
- Virtualenv
|
- Virtualenv
|
||||||
|
|
||||||
|
***Dependencies installed using the `Installation` instructions***
|
||||||
- [Task](https://taskfile.dev/),
|
- [Task](https://taskfile.dev/),
|
||||||
- Debian packages:
|
- Debian packages:
|
||||||
|
- curl
|
||||||
- libcurl4-openssl-dev,
|
- libcurl4-openssl-dev,
|
||||||
- libssl-dev,
|
- libssl-dev,
|
||||||
- libcairo2,
|
- libcairo2,
|
||||||
|
@ -22,9 +25,8 @@
|
||||||
## Installation
|
## Installation
|
||||||
```shell
|
```shell
|
||||||
# Debian amd64
|
# Debian amd64
|
||||||
|
|
||||||
TASK_VERSION=3.29.1;
|
|
||||||
sudo apt install -y \
|
sudo apt install -y \
|
||||||
|
curl \
|
||||||
libcurl4-openssl-dev \
|
libcurl4-openssl-dev \
|
||||||
libssl-dev \
|
libssl-dev \
|
||||||
libcairo2 \
|
libcairo2 \
|
||||||
|
@ -32,18 +34,46 @@ sudo apt install -y \
|
||||||
libffi-dev \
|
libffi-dev \
|
||||||
python3-virtualenv \
|
python3-virtualenv \
|
||||||
python3-dev;
|
python3-dev;
|
||||||
wget https://github.com/go-task/task/releases/download/v"${TASK_VERSION}"/task_linux_amd64.deb;
|
TASK_VERSION=$(curl -fsSL -XGET https://api.github.com/repos/go-task/task/releases/latest | grep tag_name | tr -d ' ",' | cut -d ':' -f 2)
|
||||||
|
curl -fsSLO https://github.com/go-task/task/releases/download/"${TASK_VERSION}"/task_linux_amd64.deb;
|
||||||
sudo dpkg -i task_linux_amd64.deb;
|
sudo dpkg -i task_linux_amd64.deb;
|
||||||
task venv;
|
rm task_linux_amd64.deb;
|
||||||
```
|
```
|
||||||
|
|
||||||
## General Setup
|
## Setup
|
||||||
|
```shell
|
||||||
|
# Generate default ansible configuration
|
||||||
|
./scripts/generate_ansible_config.sh > "${HOME}"/.ansible.cfg
|
||||||
|
|
||||||
|
# Setup Python virtualenv
|
||||||
|
task venv:setup
|
||||||
|
|
||||||
|
# Prepare and edit your inventory as needed
|
||||||
|
cp inventory/inventory.yml.dist inventory/inventory.yml
|
||||||
|
|
||||||
|
# Prepare and edit the global vault as needed
|
||||||
|
cp inventory/vault.yml.dist inventory/vault.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
```shell
|
||||||
|
# encrypt vault
|
||||||
|
task venv -- ansible-vault encrypt configuration/host_vars/vault.yml
|
||||||
|
# decrypt vault if needed
|
||||||
|
task venv -- ansible-vault decrypt configuration/host_vars/vault.yml
|
||||||
|
# run ansible command with vault-encrypted data for one specific host
|
||||||
|
task venv -- ansible-playbook --ask-vault-password -l my_host playbooks/test.yml
|
||||||
|
# run a specific role, e.g. security, for a host
|
||||||
|
task venv -- ansible --ask-vault-password -m import_role --args 'name=nullified.infrastructure.security' my_host
|
||||||
|
```
|
||||||
|
|
||||||
|
### Generic collection / roles commands
|
||||||
```shell
|
```shell
|
||||||
mkdir -p collections/ansible_collections
|
mkdir -p collections/ansible_collections
|
||||||
cd collections/ansible_collections
|
cd collections/ansible_collections
|
||||||
ansible-galaxy collection init nullified.infrastructure
|
task venv -- ansible-galaxy collection init nullified.infrastructure
|
||||||
cd nullified/infrastructure/roles
|
cd nullified/infrastructure/roles
|
||||||
ansible-galaxy collection init tooling
|
task venv -- ansible-galaxy collection init tooling
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -59,8 +89,8 @@ ansible-galaxy collection init tooling
|
||||||
***handlers***
|
***handlers***
|
||||||
invoked by a task through `notify`, executed only if caller triggered a state change; runs at the end of the play in the order
|
invoked by a task through `notify`, executed only if caller triggered a state change; runs at the end of the play in the order
|
||||||
they are declared;
|
they are declared;
|
||||||
-> force handlers to run:
|
|
||||||
```yaml
|
```yaml
|
||||||
|
# -> force handlers to run:
|
||||||
- name: some task
|
- name: some task
|
||||||
meta: flush_handlers
|
meta: flush_handlers
|
||||||
```
|
```
|
||||||
|
@ -112,18 +142,8 @@ tasks:
|
||||||
|
|
||||||
### Notes / Todo
|
### Notes / Todo
|
||||||
***dir layout***
|
***dir layout***
|
||||||
- collections: ansible root dir for all modules, playbooks and collections
|
- collections: ansible root dir for all collections to reside in;
|
||||||
- configuration: <DEPRECATED> ansible root dir for inventory
|
- images: docker images, mostly used for ansible-test / molecule;
|
||||||
- images: docker images, mostly used for ansible-test / molecule
|
- inventory: all inventory related files are stored here;
|
||||||
- scripts: scripts used by go-task
|
- playbooks: top level playbooks, describe the way the infrastructure is laid out;
|
||||||
|
- scripts: various scripts and helpers;
|
||||||
### Setup
|
|
||||||
```shell
|
|
||||||
cp configuration/group_vars/vault.yml.dist configuration/group_vars/vault.yml
|
|
||||||
# encrypt vault
|
|
||||||
ansible-vault encrypt configuration/group_vars/vault.yml
|
|
||||||
# decrypt vault
|
|
||||||
ansible-vault decrypt configuration/group_vars/vault.yml
|
|
||||||
# run ansible command with vault-encrypted data
|
|
||||||
ansible-playbook --ask-vault-password -i inventories/test playbooks/test.yml
|
|
||||||
```
|
|
||||||
|
|
7
TODO
Normal file
7
TODO
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
- /etc/lvm/lvm.conf -> issue_discards = 1
|
||||||
|
- deploy hashicorp/vault to store encrypted files:
|
||||||
|
- user SSH keys
|
||||||
|
- user passwords
|
||||||
|
- secure files
|
||||||
|
- setup fstab with sshfs, noatime
|
||||||
|
- add smartmontools & conf
|
|
@ -37,7 +37,7 @@ tasks:
|
||||||
preconditions:
|
preconditions:
|
||||||
- test -d tests
|
- test -d tests
|
||||||
cmds:
|
cmds:
|
||||||
- '{{.PYTHON_WRAPPER}} ansible-test sanity --docker default'
|
- '{{.PYTHON_WRAPPER}} ansible-test sanity --venv'
|
||||||
|
|
||||||
test:collections:
|
test:collections:
|
||||||
desc: run molecule tests for all roles and collections.
|
desc: run molecule tests for all roles and collections.
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
- hosts: main_desktop
|
||||||
|
tasks:
|
||||||
|
- name: include common role
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: nullified.infrastructure.common
|
||||||
|
- name: include workstation role
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: nullified.infrastructure.workstation
|
||||||
|
- name: include development role
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: nullified.infrastructure.development
|
||||||
|
- name: include security role
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: nullified.infrastructure.security
|
||||||
|
- name: include gaming role
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: nullified.infrastructure.gaming
|
|
@ -17,43 +17,41 @@ description: vaguely similar to a package manager, but for GitHub artifacts.
|
||||||
version_added: "2.15.0"
|
version_added: "2.15.0"
|
||||||
|
|
||||||
options:
|
options:
|
||||||
artifacts:
|
asset_name:
|
||||||
description: a list of artifacts to retrieve
|
description: filename of the asset to retrieve, used only for release type; supports templating
|
||||||
type: list
|
type: str
|
||||||
|
required: false
|
||||||
|
default: ""
|
||||||
|
asset_type:
|
||||||
|
description: whether the asset is a release or just a tagged asset
|
||||||
|
type: str
|
||||||
required: true
|
required: true
|
||||||
elements: dict
|
choices:
|
||||||
suboptions:
|
- release
|
||||||
asset_name:
|
- tag
|
||||||
description: filename of the asset to retrieve, used only for release type; supports templating
|
cmds:
|
||||||
type: str
|
description: commands to execute in order to install the downloaded asset; supports templating
|
||||||
required: false
|
type: list
|
||||||
default: ""
|
elements: str
|
||||||
asset_type:
|
required: false
|
||||||
description: whether the asset is a release or just a tagged asset
|
default: []
|
||||||
type: str
|
creates:
|
||||||
required: true
|
description: if provided and target file / directory exists, this step will **not** be run
|
||||||
choices:
|
type: str
|
||||||
- release
|
required: false
|
||||||
- tag
|
|
||||||
cmds:
|
|
||||||
description: commands to execute in order to install the downloaded asset; supports templating
|
|
||||||
type: list
|
|
||||||
elements: str
|
|
||||||
required: false
|
|
||||||
default: []
|
|
||||||
repository:
|
|
||||||
description: repository to query, formatted like "<owner>/<repo>"
|
|
||||||
required: true
|
|
||||||
type: str
|
|
||||||
version:
|
|
||||||
description: version of the asset to fetch; defaults to `latest`
|
|
||||||
required: false
|
|
||||||
type: str
|
|
||||||
default: latest
|
|
||||||
github_token:
|
github_token:
|
||||||
description: a GitHub app token if you have one; limits impact of rate-limiting errors
|
description: a GitHub app token if you have one; limits impact of rate-limiting errors
|
||||||
type: str
|
type: str
|
||||||
required: false
|
required: false
|
||||||
|
repository:
|
||||||
|
description: repository to query, formatted like "<owner>/<repo>"
|
||||||
|
required: true
|
||||||
|
type: str
|
||||||
|
version:
|
||||||
|
description: version of the asset to fetch; defaults to `latest`
|
||||||
|
required: false
|
||||||
|
type: str
|
||||||
|
default: latest
|
||||||
|
|
||||||
notes:
|
notes:
|
||||||
- "Strings that allow the use of templating variables support the following:"
|
- "Strings that allow the use of templating variables support the following:"
|
||||||
|
@ -72,23 +70,18 @@ author:
|
||||||
|
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
- name: Install dependencies from GitHub
|
- name: Install dependencies from GitHub
|
||||||
become: yes
|
become: true
|
||||||
tags:
|
tags:
|
||||||
- molecule-idempotence-notest
|
- molecule-idempotence-notest
|
||||||
github_artifact:
|
nullified.infrastructure.github_artifact:
|
||||||
artifacts:
|
asset_type: tag
|
||||||
- asset_type: tag
|
repository: smxi/inxi
|
||||||
repository: smxi/inxi
|
cmds:
|
||||||
cmds:
|
- tar -zxf {asset_dirname}/{asset_filename}
|
||||||
- tar -zxf {asset_dirname}/{asset_filename}
|
- install --group=root --mode=755 --owner=root smxi-inxi-*/inxi /usr/bin
|
||||||
- install --group=root --mode=755 --owner=root smxi-inxi-*/inxi /usr/bin
|
- install --group=root --mode=644 --owner=root smxi-inxi-*/inxi.1 /usr/share/man/man1
|
||||||
- install --group=root --mode=644 --owner=root smxi-inxi-*/inxi.1 /usr/share/man/man1
|
- apt-get install libdata-dump-perl
|
||||||
- apt-get install libdata-dump-perl
|
creates: /usr/bin/inxi
|
||||||
- asset_name: dive_{version}_linux_amd64.deb
|
|
||||||
asset_type: release
|
|
||||||
repository: wagoodman/dive
|
|
||||||
cmds:
|
|
||||||
- dpkg -i {asset_dirname}/{asset_filename}
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
RETURN = r'''
|
RETURN = r'''
|
||||||
|
@ -122,7 +115,7 @@ try:
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from difflib import SequenceMatcher
|
from difflib import SequenceMatcher
|
||||||
from json import loads
|
from json import loads
|
||||||
from os import environ, sep
|
from os import environ, sep, path
|
||||||
from platform import system, machine
|
from platform import system, machine
|
||||||
from typing import Any
|
from typing import Any
|
||||||
LIB_IMPORTED = True
|
LIB_IMPORTED = True
|
||||||
|
@ -260,7 +253,7 @@ def get_tagged_asset(artifact: dict[str, Any]) -> tuple[dict[str, str], dict[str
|
||||||
}, info
|
}, info
|
||||||
|
|
||||||
|
|
||||||
def fetch_metadata(artifact: dict[str, str]) -> dict[str, str] | None:
|
def fetch_metadata(artifact: dict[str, str | list[str]]) -> dict[str, str] | None:
|
||||||
""" retrieve metadata from the specified repository """
|
""" retrieve metadata from the specified repository """
|
||||||
if artifact["asset_type"] == "tag":
|
if artifact["asset_type"] == "tag":
|
||||||
metadata, info = get_tagged_asset(artifact)
|
metadata, info = get_tagged_asset(artifact)
|
||||||
|
@ -278,37 +271,34 @@ def main():
|
||||||
global ANSIBLE_MODULE
|
global ANSIBLE_MODULE
|
||||||
|
|
||||||
module_args: dict[str, dict[str, Any]] = {
|
module_args: dict[str, dict[str, Any]] = {
|
||||||
"artifacts": {
|
"asset_name": {
|
||||||
"type": "list",
|
"type": "str",
|
||||||
"elements": "dict",
|
"required": False,
|
||||||
|
"default": ""
|
||||||
|
},
|
||||||
|
"asset_type": {
|
||||||
|
"type": "str",
|
||||||
"required": True,
|
"required": True,
|
||||||
"options": {
|
"choices": ["release", "tag"],
|
||||||
"asset_name": {
|
},
|
||||||
"type": "str",
|
"cmds": {
|
||||||
"required": False,
|
"type": "list",
|
||||||
"default": ""
|
"elements": "str",
|
||||||
},
|
"required": False,
|
||||||
"asset_type": {
|
"default": []
|
||||||
"type": "str",
|
},
|
||||||
"required": True,
|
"creates": {
|
||||||
"choices": ["release", "tag"],
|
"type": "str",
|
||||||
},
|
"required": False
|
||||||
"cmds": {
|
},
|
||||||
"type": "list",
|
"repository": {
|
||||||
"elements": "str",
|
"type": "str",
|
||||||
"required": False,
|
"required": True
|
||||||
"default": []
|
},
|
||||||
},
|
"version": {
|
||||||
"repository": {
|
"type": "str",
|
||||||
"type": "str",
|
"required": False,
|
||||||
"required": True
|
"default": "latest"
|
||||||
},
|
|
||||||
"version": {
|
|
||||||
"type": "str",
|
|
||||||
"required": False,
|
|
||||||
"default": "latest"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"github_token": {
|
"github_token": {
|
||||||
"type": "str",
|
"type": "str",
|
||||||
|
@ -317,9 +307,13 @@ def main():
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
result: dict[str, Any] = {
|
result: dict[str, Any] = {
|
||||||
"artifacts": [],
|
|
||||||
"changed": False,
|
"changed": False,
|
||||||
"msg": ""
|
"commands": [],
|
||||||
|
"failed": False,
|
||||||
|
"filepath": "",
|
||||||
|
"msg": "",
|
||||||
|
"state": "",
|
||||||
|
"version": ""
|
||||||
}
|
}
|
||||||
|
|
||||||
ANSIBLE_MODULE = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
|
ANSIBLE_MODULE = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
|
||||||
|
@ -328,6 +322,11 @@ def main():
|
||||||
if ANSIBLE_MODULE.params["github_token"]:
|
if ANSIBLE_MODULE.params["github_token"]:
|
||||||
DEFAULT_HEADERS["Authorization"] = "Bearer {}".format(ANSIBLE_MODULE.params["github_token"])
|
DEFAULT_HEADERS["Authorization"] = "Bearer {}".format(ANSIBLE_MODULE.params["github_token"])
|
||||||
|
|
||||||
|
creates_file: str | None = ANSIBLE_MODULE.params.get("creates", None)
|
||||||
|
if creates_file and path.exists(creates_file):
|
||||||
|
result["state"] = "ignored"
|
||||||
|
ANSIBLE_MODULE.exit_json(**result)
|
||||||
|
|
||||||
if not LIB_IMPORTED:
|
if not LIB_IMPORTED:
|
||||||
ANSIBLE_MODULE.fail_json(msg=missing_required_lib(IMPORT_LIB_NAME), exception=IMPORT_LIB_ERROR) # pylint: disable=used-before-assignment
|
ANSIBLE_MODULE.fail_json(msg=missing_required_lib(IMPORT_LIB_NAME), exception=IMPORT_LIB_ERROR) # pylint: disable=used-before-assignment
|
||||||
|
|
||||||
|
@ -335,66 +334,58 @@ def main():
|
||||||
TEMPLATE_ASSET_NAME_VARS.update({key.lower(): value for key, value in freedesktop_os_release().items()})
|
TEMPLATE_ASSET_NAME_VARS.update({key.lower(): value for key, value in freedesktop_os_release().items()})
|
||||||
TEMPLATE_ASSET_NAME_VARS["system"] = system().lower()
|
TEMPLATE_ASSET_NAME_VARS["system"] = system().lower()
|
||||||
TEMPLATE_ASSET_NAME_VARS["machine"] = machine().lower()
|
TEMPLATE_ASSET_NAME_VARS["machine"] = machine().lower()
|
||||||
for artifact in ANSIBLE_MODULE.params["artifacts"]:
|
|
||||||
# fetch artifact metadata
|
|
||||||
artifact_result: dict[str, Any] = {
|
|
||||||
"asset_data": fetch_metadata(artifact),
|
|
||||||
"repository": artifact.get("repository"),
|
|
||||||
"version": artifact.get("version"),
|
|
||||||
"cmds": []
|
|
||||||
}
|
|
||||||
result["rate_limit_remaining"] = artifact_result["asset_data"].get("rate_limit_remaining", "unknown")
|
|
||||||
result["rate_limit_max"] = artifact_result["asset_data"].get("rate_limit_max", "unknown")
|
|
||||||
|
|
||||||
if "error" in artifact_result["asset_data"]:
|
artifact: dict[str, str | list[str]] = {}
|
||||||
result["artifacts"].append(artifact_result)
|
for param_name in ["asset_name", "asset_type", "cmds", "repository", "version"]:
|
||||||
result["msg"] = artifact_result["asset_data"].get("error")
|
artifact[param_name] = ANSIBLE_MODULE.params[param_name]
|
||||||
result["failed"] = True
|
|
||||||
ANSIBLE_MODULE.fail_json(**result)
|
|
||||||
|
|
||||||
# download artifact
|
asset_data: dict[str, str] = fetch_metadata(artifact)
|
||||||
if ANSIBLE_MODULE.check_mode:
|
result["rate_limit_remaining"] = asset_data.get("rate_limit_remaining", "unknown")
|
||||||
artifact_result["download_dir"] = "unknown"
|
result["rate_limit_max"] = asset_data.get("rate_limit_max", "unknown")
|
||||||
else:
|
result["version"] = asset_data.get("version", artifact.get("version"))
|
||||||
artifact_result["download_dir"] = fetch_file(ANSIBLE_MODULE, artifact_result["asset_data"].get("download_url", "unknown"), decompress=False)
|
|
||||||
TEMPLATE_ASSET_NAME_VARS["asset_name"] = artifact_result["asset_data"].get("asset_name", "unknown")
|
|
||||||
TEMPLATE_ASSET_NAME_VARS["asset_version"] = artifact_result["asset_data"].get("version", "unknown")
|
|
||||||
parts = artifact_result["download_dir"].rsplit(sep, 1)
|
|
||||||
TEMPLATE_ASSET_NAME_VARS["asset_dirname"] = parts[0] if len(parts) > 1 else ""
|
|
||||||
TEMPLATE_ASSET_NAME_VARS["asset_filename"] = parts[1] if len(parts) > 1 else parts[0]
|
|
||||||
|
|
||||||
# install artifact
|
if "error" in asset_data:
|
||||||
artifact_commands = [line.format(**TEMPLATE_ASSET_NAME_VARS) for line in artifact["cmds"]]
|
result["state"] = "fetch failed"
|
||||||
if ANSIBLE_MODULE.check_mode:
|
result["msg"] = asset_data.get("error", "unknown error encountered")
|
||||||
artifact_result["stdout"] = artifact_result["stderr"] = ""
|
result["failed"] = True
|
||||||
artifact_result["ret_code"] = None
|
ANSIBLE_MODULE.fail_json(**result)
|
||||||
artifact_result["cmds"] = artifact_commands
|
|
||||||
artifact_result["state"] = "should be installed" if len(artifact_commands) else "should be downloaded"
|
|
||||||
else:
|
|
||||||
for command_line in artifact_commands:
|
|
||||||
cmd_rc, cmd_out, cmd_err = ANSIBLE_MODULE.run_command(command_line, use_unsafe_shell=True, cwd=ANSIBLE_MODULE.tmpdir)
|
|
||||||
result["changed"] = True
|
|
||||||
artifact_result["cmds"].append({
|
|
||||||
"command": command_line,
|
|
||||||
"stdout": cmd_out,
|
|
||||||
"stderr": cmd_err,
|
|
||||||
"ret_code": cmd_rc
|
|
||||||
})
|
|
||||||
|
|
||||||
if cmd_rc:
|
# download artifact
|
||||||
artifact_result["state"] = "installation failed"
|
if ANSIBLE_MODULE.check_mode:
|
||||||
result["failed"] = True
|
result["filepath"] = "unknown"
|
||||||
result["artifacts"].append(artifact_result)
|
else:
|
||||||
ANSIBLE_MODULE.fail_json(**result)
|
result["filepath"] = fetch_file(ANSIBLE_MODULE, asset_data.get("download_url", "unknown"), decompress=False)
|
||||||
|
TEMPLATE_ASSET_NAME_VARS["asset_name"] = asset_data.get("asset_name", "unknown")
|
||||||
|
TEMPLATE_ASSET_NAME_VARS["asset_version"] = asset_data.get("version", "unknown")
|
||||||
|
parts = result["filepath"].rsplit(sep, 1)
|
||||||
|
TEMPLATE_ASSET_NAME_VARS["asset_dirname"] = parts[0] if len(parts) > 1 else ""
|
||||||
|
TEMPLATE_ASSET_NAME_VARS["asset_filename"] = parts[1] if len(parts) > 1 else parts[0]
|
||||||
|
|
||||||
try:
|
# install artifact
|
||||||
del artifact_result["command"], artifact_result["stdout"], artifact_result["stderr"], artifact_result["ret_code"]
|
artifact_commands = [line.format(**TEMPLATE_ASSET_NAME_VARS) for line in artifact["cmds"]]
|
||||||
except: # pylint: disable=bare-except # noqa: 722
|
if ANSIBLE_MODULE.check_mode:
|
||||||
pass
|
result["commands"] = artifact_commands
|
||||||
artifact_result["state"] = "installed" if len(artifact_commands) else "downloaded"
|
result["state"] = "should be installed" if len(artifact_commands) else "should be downloaded"
|
||||||
|
else:
|
||||||
|
for command_line in artifact_commands:
|
||||||
|
cmd_rc, cmd_out, cmd_err = ANSIBLE_MODULE.run_command(command_line, use_unsafe_shell=True, cwd=ANSIBLE_MODULE.tmpdir)
|
||||||
|
result["changed"] = True
|
||||||
|
result["commands"].append({
|
||||||
|
"command": command_line,
|
||||||
|
"stdout": cmd_out,
|
||||||
|
"stderr": cmd_err,
|
||||||
|
"ret_code": cmd_rc
|
||||||
|
})
|
||||||
|
|
||||||
result["artifacts"].append(artifact_result)
|
if cmd_rc:
|
||||||
result["msg"] = "OK"
|
result["state"] = "installation failed"
|
||||||
|
result["msg"] = cmd_err
|
||||||
|
result["failed"] = True
|
||||||
|
ANSIBLE_MODULE.fail_json(**result)
|
||||||
|
|
||||||
|
result["state"] = "installed" if len(artifact_commands) else "downloaded"
|
||||||
|
|
||||||
|
result["msg"] = "Successful"
|
||||||
ANSIBLE_MODULE.exit_json(**result)
|
ANSIBLE_MODULE.exit_json(**result)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,42 +1,16 @@
|
||||||
{
|
{
|
||||||
"ANSIBLE_MODULE_ARGS": {
|
"ANSIBLE_MODULE_ARGS": {
|
||||||
"github_token": "",
|
"github_token": "",
|
||||||
"artifacts": [
|
"asset_type": "tag",
|
||||||
{
|
"repository": "smxi/inxi",
|
||||||
"asset_type": "tag",
|
"version": "3.3.29-1",
|
||||||
"repository": "smxi/inxi",
|
"cmds": [
|
||||||
"version": "3.3.29-1",
|
"echo \"asset_name: {asset_name}\nasset_dirname: {asset_dirname}\"",
|
||||||
"cmds": [
|
"echo \"asset_filename: {asset_filename}\nasset_version: {asset_version}\"",
|
||||||
"echo asset_name: {asset_name}",
|
"echo \"system: {system}\nmachine: {machine}\nversion: {version}\"",
|
||||||
"echo asset_dirname: {asset_dirname}",
|
"ls -lahv {asset_dirname}",
|
||||||
"echo asset_filename: {asset_filename}",
|
"test -f {asset_dirname}/{asset_filename}"
|
||||||
"echo asset_version: {asset_version}",
|
],
|
||||||
"echo system: {system}",
|
"creates": "/usr/local/bin/inxi2"
|
||||||
"echo machine: {machine}",
|
|
||||||
"echo version: {version}"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"asset_type": "tag",
|
|
||||||
"repository": "smxi/inxi",
|
|
||||||
"cmds": [
|
|
||||||
"tar -zxf {asset_dirname}/{asset_filename}",
|
|
||||||
"install --group=root --mode=755 --owner=root smxi-inxi-*/inxi /usr/bin",
|
|
||||||
"install --group=root --mode=644 --owner=root smxi-inxi-*/inxi.1 /usr/share/man/man1",
|
|
||||||
"apt-get install libdata-dump-perl"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"asset_name": "dive_{version}_linux_amd64.deb",
|
|
||||||
"asset_type": "release",
|
|
||||||
"repository": "wagoodman/dive"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"asset_name": "dive_{version}_linux_amd64.deb",
|
|
||||||
"asset_type": "release",
|
|
||||||
"repository": "wagoodman/dive",
|
|
||||||
"version": "v0.10.0"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
collections/ansible_collections/nullified/infrastructure/roles/common/assets/fonts/JetBrainsMonoNerdFontMono-Bold.ttf
(Stored with Git LFS)
Normal file
BIN
collections/ansible_collections/nullified/infrastructure/roles/common/assets/fonts/JetBrainsMonoNerdFontMono-Bold.ttf
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
collections/ansible_collections/nullified/infrastructure/roles/common/assets/fonts/JetBrainsMonoNerdFontMono-BoldItalic.ttf
(Stored with Git LFS)
Normal file
BIN
collections/ansible_collections/nullified/infrastructure/roles/common/assets/fonts/JetBrainsMonoNerdFontMono-BoldItalic.ttf
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
collections/ansible_collections/nullified/infrastructure/roles/common/assets/fonts/JetBrainsMonoNerdFontMono-Italic.ttf
(Stored with Git LFS)
Normal file
BIN
collections/ansible_collections/nullified/infrastructure/roles/common/assets/fonts/JetBrainsMonoNerdFontMono-Italic.ttf
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
collections/ansible_collections/nullified/infrastructure/roles/common/assets/fonts/JetBrainsMonoNerdFontMono-Regular.ttf
(Stored with Git LFS)
Normal file
BIN
collections/ansible_collections/nullified/infrastructure/roles/common/assets/fonts/JetBrainsMonoNerdFontMono-Regular.ttf
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
collections/ansible_collections/nullified/infrastructure/roles/common/assets/fonts/Meslo LG S NF Mono Bold Italic.ttf
(Stored with Git LFS)
Normal file
BIN
collections/ansible_collections/nullified/infrastructure/roles/common/assets/fonts/Meslo LG S NF Mono Bold Italic.ttf
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
collections/ansible_collections/nullified/infrastructure/roles/common/assets/fonts/Meslo LG S NF Mono Bold.ttf
(Stored with Git LFS)
Normal file
BIN
collections/ansible_collections/nullified/infrastructure/roles/common/assets/fonts/Meslo LG S NF Mono Bold.ttf
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
collections/ansible_collections/nullified/infrastructure/roles/common/assets/fonts/Meslo LG S NF Mono Italic.ttf
(Stored with Git LFS)
Normal file
BIN
collections/ansible_collections/nullified/infrastructure/roles/common/assets/fonts/Meslo LG S NF Mono Italic.ttf
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
collections/ansible_collections/nullified/infrastructure/roles/common/assets/fonts/Meslo LG S NF Mono Regular.ttf
(Stored with Git LFS)
Normal file
BIN
collections/ansible_collections/nullified/infrastructure/roles/common/assets/fonts/Meslo LG S NF Mono Regular.ttf
(Stored with Git LFS)
Normal file
Binary file not shown.
|
@ -1,2 +1,10 @@
|
||||||
---
|
---
|
||||||
custom_github_token: ""
|
custom_github_token: ""
|
||||||
|
common_user_account: "{{ custom_base_user_account | lower }}"
|
||||||
|
common_gitconfig_enable: false
|
||||||
|
common_gitconfig_username: ""
|
||||||
|
common_gitconfig_email: ""
|
||||||
|
common_gitconfig_force_sign: false
|
||||||
|
common_gitconfig_signingkey: ""
|
||||||
|
common_apt_packages: []
|
||||||
|
common_install_fonts: false
|
||||||
|
|
|
@ -1 +1,5 @@
|
||||||
---
|
---
|
||||||
|
- name: '[system] reload sysctl configuration'
|
||||||
|
become: true
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: sysctl --system
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
---
|
||||||
|
- name: '[home] get user account information'
|
||||||
|
ansible.builtin.getent:
|
||||||
|
database: passwd
|
||||||
|
key: "{{ common_user_account }}"
|
||||||
|
split: ":"
|
||||||
|
changed_when: false
|
||||||
|
when: getent_passwd is undefined or common_user_account not in getent_passwd
|
||||||
|
|
||||||
|
- name: '[home] create common directories'
|
||||||
|
become: true
|
||||||
|
become_user: "{{ common_user_account }}"
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ getent_passwd[common_user_account][4] }}/{{ item }}"
|
||||||
|
state: directory
|
||||||
|
mode: '0750'
|
||||||
|
loop:
|
||||||
|
- .local/bin
|
||||||
|
- .local/share/fonts
|
||||||
|
- .config
|
||||||
|
- .ssh
|
||||||
|
|
||||||
|
- name: '[home] setup home files'
|
||||||
|
become: true
|
||||||
|
become_user: "{{ common_user_account }}"
|
||||||
|
block:
|
||||||
|
- name: '[home] git configuration'
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: ../templates/home/.gitconfig.j2
|
||||||
|
dest: "{{ getent_passwd[common_user_account][4] }}/.gitconfig"
|
||||||
|
mode: '0640'
|
||||||
|
when: common_gitconfig_enable | bool
|
||||||
|
|
||||||
|
- name: '[home] basic files'
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "../templates/home/{{ item.name }}"
|
||||||
|
dest: "{{ getent_passwd[common_user_account][4] }}/{{ item.name }}"
|
||||||
|
mode: "{{ item.mode | default('0640') }}"
|
||||||
|
loop:
|
||||||
|
- { name: ".lessfilter", mode: '0750' }
|
||||||
|
- { name: ".pythonrc" }
|
|
@ -1,47 +1,68 @@
|
||||||
---
|
---
|
||||||
- name: '[APT] install dependencies and tools'
|
- name: '[apt] install dependencies and tools'
|
||||||
become: yes
|
become: true
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
update_cache: yes
|
update_cache: true
|
||||||
force_apt_get: true
|
force_apt_get: true
|
||||||
cache_valid_time: 3600
|
cache_valid_time: 3600
|
||||||
pkg:
|
pkg:
|
||||||
|
- apt-transport-https
|
||||||
- bzip2
|
- bzip2
|
||||||
|
- catimg
|
||||||
- cron
|
- cron
|
||||||
|
- dateutils
|
||||||
- emacs-nox
|
- emacs-nox
|
||||||
|
- firmware-misc-nonfree
|
||||||
|
- firmware-linux-nonfree
|
||||||
|
- fwupd
|
||||||
|
- gir1.2-fwupd-2.0 # fwupd
|
||||||
- git
|
- git
|
||||||
|
- iotop
|
||||||
|
- ioping
|
||||||
- jq
|
- jq
|
||||||
- less
|
- less
|
||||||
- libdata-dump-perl # inxi
|
- libdata-dump-perl # inxi
|
||||||
- libxml-dumper-perl # inxi
|
- libxml-dumper-perl # inxi
|
||||||
|
- lm-sensors
|
||||||
- ncdu
|
- ncdu
|
||||||
- openssh-server
|
- nvme-cli
|
||||||
- procps
|
- procps
|
||||||
|
- python3-pygments
|
||||||
- rsync
|
- rsync
|
||||||
- zsh
|
- smartmontools
|
||||||
|
- tree
|
||||||
|
- xz-utils
|
||||||
|
- yq
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: '[GitHub] install tools'
|
- name: '[GitHub] install tools'
|
||||||
become: yes
|
become: true
|
||||||
tags:
|
|
||||||
- molecule-idempotence-notest
|
|
||||||
nullified.infrastructure.github_artifact:
|
nullified.infrastructure.github_artifact:
|
||||||
github_token: '{{ custom_github_token }}'
|
asset_name: "{{ item.asset_name | default('') }}"
|
||||||
artifacts:
|
asset_type: "{{ item.asset_type }}"
|
||||||
|
cmds: "{{ item.cmds | default([]) }}"
|
||||||
|
creates: "{{ item.creates | default('') }}"
|
||||||
|
github_token: "{{ custom_github_token }}"
|
||||||
|
repository: "{{ item.repository }}"
|
||||||
|
version: "{{ item.version | default('') }}"
|
||||||
|
loop:
|
||||||
- repository: smxi/inxi
|
- repository: smxi/inxi
|
||||||
asset_type: tag
|
asset_type: tag
|
||||||
cmds:
|
cmds:
|
||||||
- tar -zxf {asset_dirname}/{asset_filename}
|
- tar -zxf {asset_dirname}/{asset_filename}
|
||||||
- install --group=root --mode=755 --owner=root smxi-inxi-*/inxi /usr/local/bin
|
- install --group=root --mode=755 --owner=root smxi-inxi-*/inxi /usr/local/bin
|
||||||
- install --group=root --mode=644 --owner=root smxi-inxi-*/inxi.1 /usr/share/man/man1
|
- install --group=root --mode=644 --owner=root smxi-inxi-*/inxi.1 /usr/share/man/man1
|
||||||
|
creates: /usr/local/bin
|
||||||
- repository: sharkdp/bat
|
- repository: sharkdp/bat
|
||||||
asset_name: bat_{version}_amd64.deb
|
asset_name: bat_{version}_amd64.deb
|
||||||
asset_type: release
|
asset_type: release
|
||||||
|
creates: /usr/bin/bat
|
||||||
cmds:
|
cmds:
|
||||||
- dpkg -i {asset_dirname}/{asset_filename}
|
- dpkg -i {asset_dirname}/{asset_filename}
|
||||||
- repository: aristocratos/btop
|
- repository: aristocratos/btop
|
||||||
asset_name: btop-x86_64-linux-musl.tbz
|
asset_name: btop-x86_64-linux-musl.tbz
|
||||||
asset_type: release
|
asset_type: release
|
||||||
|
creates: /usr/bin/btop
|
||||||
cmds:
|
cmds:
|
||||||
- tar -xjf {asset_dirname}/{asset_filename}
|
- tar -xjf {asset_dirname}/{asset_filename}
|
||||||
- install --group=root --mode=755 --owner=root btop/bin/btop /usr/bin
|
- install --group=root --mode=755 --owner=root btop/bin/btop /usr/bin
|
||||||
|
@ -50,11 +71,36 @@
|
||||||
- repository: eza-community/eza
|
- repository: eza-community/eza
|
||||||
asset_name: eza_x86_64-unknown-linux-gnu.tar.gz
|
asset_name: eza_x86_64-unknown-linux-gnu.tar.gz
|
||||||
asset_type: release
|
asset_type: release
|
||||||
|
creates: /usr/bin/eza
|
||||||
cmds:
|
cmds:
|
||||||
- tar -zxf {asset_dirname}/{asset_filename}
|
- tar -zxf {asset_dirname}/{asset_filename}
|
||||||
- install --group=root --mode=755 --owner=root eza /usr/bin
|
- install --group=root --mode=755 --owner=root eza /usr/bin
|
||||||
- repository: muesli/duf
|
- repository: muesli/duf
|
||||||
asset_name: duf_{version}_linux_amd64.deb
|
asset_name: duf_{version}_linux_amd64.deb
|
||||||
asset_type: release
|
asset_type: release
|
||||||
|
creates: /usr/bin/duf
|
||||||
cmds:
|
cmds:
|
||||||
- dpkg -i {asset_dirname}/{asset_filename}
|
- dpkg -i {asset_dirname}/{asset_filename}
|
||||||
|
|
||||||
|
- name: '[system] add sysctl tweaks'
|
||||||
|
become: true
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: ../templates/system/sysctld.local.conf.j2
|
||||||
|
dest: /etc/sysctl.d/local.conf
|
||||||
|
mode: '0644'
|
||||||
|
when: custom_sysctl is defined
|
||||||
|
notify:
|
||||||
|
- 'common : [system] reload sysctl configuration'
|
||||||
|
|
||||||
|
- name: '[apt] install custom packages'
|
||||||
|
become: true
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: true
|
||||||
|
force_apt_get: true
|
||||||
|
cache_valid_time: 3600
|
||||||
|
pkg:
|
||||||
|
"{{ common_apt_packages }}"
|
||||||
|
|
||||||
|
- include_tasks: home_setup.yml
|
||||||
|
|
||||||
|
- include_tasks: shell_customization.yml
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
---
|
||||||
|
- name: '[home] get user account information'
|
||||||
|
ansible.builtin.getent:
|
||||||
|
database: passwd
|
||||||
|
key: "{{ common_user_account }}"
|
||||||
|
split: ":"
|
||||||
|
changed_when: false
|
||||||
|
when: getent_passwd is undefined or common_user_account not in getent_passwd
|
||||||
|
|
||||||
|
- name: '[shell] install ZSH and dependencies'
|
||||||
|
become: true
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: true
|
||||||
|
force_apt_get: true
|
||||||
|
cache_valid_time: 3600
|
||||||
|
pkg:
|
||||||
|
- git
|
||||||
|
- zsh
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: '[shell] install custom fonts'
|
||||||
|
become: true
|
||||||
|
become_user: "{{ common_user_account }}"
|
||||||
|
block:
|
||||||
|
- name: '[fonts] add fonts tooling'
|
||||||
|
become_user: root
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: true
|
||||||
|
force_apt_get: true
|
||||||
|
cache_valid_time: 3600
|
||||||
|
pkg:
|
||||||
|
- fontconfig
|
||||||
|
|
||||||
|
- name: '[fonts] adding fonts'
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: ../assets/fonts/
|
||||||
|
dest: "{{ getent_passwd[common_user_account][4] }}/.local/share/fonts"
|
||||||
|
mode: '0640'
|
||||||
|
|
||||||
|
- name: '[fonts] refresh fonts cache'
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: fc-cache
|
||||||
|
changed_when: false
|
||||||
|
when: common_install_fonts | bool
|
||||||
|
|
||||||
|
- name: '[shell] install Oh-My-ZSH'
|
||||||
|
become: true
|
||||||
|
become_user: "{{ common_user_account }}"
|
||||||
|
block:
|
||||||
|
- name: '[omz] get install script'
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh
|
||||||
|
dest: /tmp/zsh-install.sh
|
||||||
|
mode: '0750'
|
||||||
|
|
||||||
|
- name: '[omz] install OMZ'
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: sh /tmp/zsh-install.sh --unattended
|
||||||
|
creates: "{{ getent_passwd[common_user_account][4] }}/.oh-my-zsh"
|
||||||
|
|
||||||
|
- name: '[shell] install powerlevel10k customization for OMZ'
|
||||||
|
become: true
|
||||||
|
become_user: "{{ common_user_account }}"
|
||||||
|
ansible.builtin.git:
|
||||||
|
repo: https://github.com/romkatv/powerlevel10k.git
|
||||||
|
dest: "{{ getent_passwd[common_user_account][4] }}/.oh-my-zsh/custom/themes/powerlevel10k"
|
||||||
|
depth: 1
|
||||||
|
|
||||||
|
- name: '[home] copy zsh files'
|
||||||
|
become: true
|
||||||
|
become_user: "{{ common_user_account }}"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "../templates/home/{{ item }}"
|
||||||
|
dest: "{{ getent_passwd[common_user_account][4] }}/{{ item }}"
|
||||||
|
mode: '0640'
|
||||||
|
loop:
|
||||||
|
- .p10k.zsh
|
||||||
|
- .zsh_aliases
|
||||||
|
- .zsh_completions
|
||||||
|
- .zsh_exports
|
||||||
|
- .zsh_functions
|
||||||
|
- .zshrc
|
||||||
|
|
||||||
|
- name: '[shell] update user shell to ZSH'
|
||||||
|
become: true
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ common_user_account }}"
|
||||||
|
shell: "/usr/bin/zsh"
|
||||||
|
state: present
|
|
@ -0,0 +1,107 @@
|
||||||
|
[user]
|
||||||
|
name = {{ common_gitconfig_username }}
|
||||||
|
email = {{ common_gitconfig_email }}
|
||||||
|
{% if common_gitconfig_force_sign and common_gitconfig_signingkey %}
|
||||||
|
signingkey = {{ common_gitconfig_signingkey }}
|
||||||
|
{% endif %}
|
||||||
|
[commit]
|
||||||
|
{% if common_gitconfig_force_sign %}
|
||||||
|
gpgsign = true
|
||||||
|
{% else %}
|
||||||
|
gpgsign = false
|
||||||
|
{% endif %}
|
||||||
|
[tag]
|
||||||
|
{% if common_gitconfig_force_sign %}
|
||||||
|
gpgsign = true
|
||||||
|
{% else %}
|
||||||
|
gpgsign = false
|
||||||
|
{% endif -%}
|
||||||
|
{% raw %}
|
||||||
|
[alias]
|
||||||
|
br = "branch"
|
||||||
|
ci = "commit"
|
||||||
|
cmp = "!f() { git log --graph --color --boundary --oneline HEAD...origin/$1; }; f"
|
||||||
|
co = "checkout"
|
||||||
|
cp = "cherry-pick"
|
||||||
|
cpo = "cherry-pick --strategy=recursive -Xours --allow-empty"
|
||||||
|
cpt = "cherry-pick --strategy=recursive -Xtheirs --allow-empty"
|
||||||
|
dm = "log --graph --color --boundary --oneline HEAD...origin/master"
|
||||||
|
dup = "!git log --graph --color --boundary --oneline HEAD...origin/$(git rev-parse --abbrev-ref HEAD)"
|
||||||
|
psuo = "!git push --set-upstream origin $(git rev-parse --abbrev-ref HEAD)"
|
||||||
|
rf = "!git reflog --date=iso"
|
||||||
|
ru = "remote update"
|
||||||
|
rup = "!f() { git remote update && git pull --rebase; }; f"
|
||||||
|
pr = "pull --rebase"
|
||||||
|
st = "status"
|
||||||
|
subup = "!git submodule foreach git remote update"
|
||||||
|
undo = "!f() { git reset --soft HEAD~${1:-1}; }; f"
|
||||||
|
|
||||||
|
lg = lg1
|
||||||
|
lg1 = lg1-specific --all
|
||||||
|
lg2 = lg2-specific --all
|
||||||
|
lg3 = lg3-specific --all
|
||||||
|
lg1-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(auto)%d%C(reset)'
|
||||||
|
lg2-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(auto)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'
|
||||||
|
lg3-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset) %C(bold cyan)(committed: %cD)%C(reset) %C(auto)%d%C(reset)%n'' %C(white)%s%C(reset)%n'' %C(dim white)- %an <%ae> %C(reset) %C(dim white)(committer: %cn <%ce>)%C(reset)'
|
||||||
|
[core]
|
||||||
|
editor = emacs
|
||||||
|
autocrlf = input
|
||||||
|
pager = delta
|
||||||
|
[color]
|
||||||
|
status = auto
|
||||||
|
branch = auto
|
||||||
|
interactive = auto
|
||||||
|
diff = auto
|
||||||
|
ui = true
|
||||||
|
pager = true
|
||||||
|
[delta]
|
||||||
|
navigate = true
|
||||||
|
line-numbers = true
|
||||||
|
[push]
|
||||||
|
default = simple
|
||||||
|
[merge]
|
||||||
|
conflictstyle = diff3
|
||||||
|
[pull]
|
||||||
|
rebase = true
|
||||||
|
[diff]
|
||||||
|
colorMoved = default
|
||||||
|
[diff "pdf"]
|
||||||
|
textconv = pdfinfo
|
||||||
|
[diff "pdfdiff"]
|
||||||
|
command = diffpdf
|
||||||
|
[init]
|
||||||
|
defaultBranch = main
|
||||||
|
[interactive]
|
||||||
|
diffFilter = delta --color-only
|
||||||
|
[submodule]
|
||||||
|
recurse = true
|
||||||
|
[advice]
|
||||||
|
addEmbeddedRepo = false
|
||||||
|
addEmptyPathspec = false
|
||||||
|
addIgnoredFile = false
|
||||||
|
amWorkDir = false
|
||||||
|
checkoutAmbiguousRemoteBranchName = false
|
||||||
|
commitBeforeMerge = false
|
||||||
|
detachedHead = false
|
||||||
|
fetchShowForcedUpdates = false
|
||||||
|
ignoredHook = false
|
||||||
|
implicitIdentity = false
|
||||||
|
nestedTag = false
|
||||||
|
pushAlreadyExists = true
|
||||||
|
pushFetchFirst = true
|
||||||
|
pushNeedsForce = true
|
||||||
|
pushNonFFCurrent = true
|
||||||
|
pushNonFFMatching = true
|
||||||
|
pushRefNeedsUpdate = true
|
||||||
|
pushUnqualifiedRefname = true
|
||||||
|
pushUpdateRejected = true
|
||||||
|
resetQuiet = false
|
||||||
|
resolveConflict = true
|
||||||
|
rmHints = false
|
||||||
|
sequencerInUse = false
|
||||||
|
statusAheadBehind = false
|
||||||
|
statusHints = false
|
||||||
|
statusUoption = false
|
||||||
|
submoduleAlternateErrorStrategyDie = false
|
||||||
|
waitingForEditor = false
|
||||||
|
{% endraw %}
|
|
@ -0,0 +1,68 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Best effort auto-pygmentization with transparent decompression
|
||||||
|
# (c) Reuben Thomas 2012
|
||||||
|
# This program is in the public domain.
|
||||||
|
|
||||||
|
# Strategy: first see if pygmentize can find a lexer; if not, ask file; if that finds nothing, fail
|
||||||
|
# Set the environment variable PYGMENTIZE_OPTS to configure pygments.
|
||||||
|
|
||||||
|
# This program can be used as a .lessfilter for the less pager to auto-color less's output
|
||||||
|
|
||||||
|
if [ `pygmentize -N $1` != "text" ]; then
|
||||||
|
pygmentize $PYGMENTIZE_OPTS "$1"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
file_common_opts="--brief --dereference --uncompress"
|
||||||
|
|
||||||
|
unset lexer
|
||||||
|
case `file --mime-type $file_common_opts "$1"` in
|
||||||
|
application/xml|image/svg+xml) lexer=xml;;
|
||||||
|
text/html) lexer=html;;
|
||||||
|
text/troff) lexer=nroff;;
|
||||||
|
text/x-asm) lexer=nasm;;
|
||||||
|
text/x-awk) lexer=awk;;
|
||||||
|
text/x-c) lexer=c;;
|
||||||
|
text/x-c++) lexer=cpp;;
|
||||||
|
text/x-diff) lexer=diff;;
|
||||||
|
text/x-fortran) lexer=fortran;;
|
||||||
|
text/x-gawk) lexer=gawk;;
|
||||||
|
text/x-java) lexer=java;;
|
||||||
|
text/x-lisp) lexer=common-lisp;;
|
||||||
|
text/x-lua) lexer=lua;;
|
||||||
|
text/x-makefile) lexer=make;;
|
||||||
|
text/x-msdos-batch) lexer=bat;;
|
||||||
|
text/x-nawk) lexer=nawk;;
|
||||||
|
text/x-pascal) lexer=pascal;;
|
||||||
|
text/x-perl) lexer=perl;;
|
||||||
|
text/x-php) lexer=php;;
|
||||||
|
text/x-po) lexer=po;;
|
||||||
|
text/x-python) lexer=python;;
|
||||||
|
text/x-ruby) lexer=ruby;;
|
||||||
|
text/x-shellscript) lexer=sh;;
|
||||||
|
text/x-tcl) lexer=tcl;;
|
||||||
|
text/x-tex|text/x-texinfo) lexer=latex;; # FIXME: texinfo really needs its own lexer
|
||||||
|
|
||||||
|
# Types that file outputs which pygmentize didn't support as of file 5.11, pygments 1.5
|
||||||
|
# text/calendar
|
||||||
|
# text/PGP
|
||||||
|
# text/rtf
|
||||||
|
# text/texmacs
|
||||||
|
# text/x-bcpl
|
||||||
|
# text/x-info
|
||||||
|
# text/x-m4
|
||||||
|
# text/x-vcard
|
||||||
|
# text/x-xmcd
|
||||||
|
esac
|
||||||
|
|
||||||
|
encoding=`file --mime-encoding $file_common_opts "$1"`
|
||||||
|
|
||||||
|
if [ -n "$lexer" ]; then
|
||||||
|
# FIXME: Specify input encoding rather than output encoding https://bitbucket.org/birkenfeld/pygments-main/issue/800
|
||||||
|
# FIXME: Encoding argument ignored on stdin https://bitbucket.org/birkenfeld/pygments-main/issue/799
|
||||||
|
#zcat "$1" | pygmentize -O encoding=$encoding,outencoding=UTF-8 $PYGMENTIZE_OPTS -l $lexer
|
||||||
|
pygmentize -O encoding=$encoding,outencoding=UTF-8 $PYGMENTIZE_OPTS -l $lexer $1
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 1
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,7 @@
|
||||||
|
try:
|
||||||
|
import readline
|
||||||
|
except ImportError:
|
||||||
|
print("Module readline not available.")
|
||||||
|
else:
|
||||||
|
import rlcompleter
|
||||||
|
readline.parse_and_bind("tab: complete")
|
|
@ -0,0 +1,34 @@
|
||||||
|
# Utilities
|
||||||
|
alias dig=ydig
|
||||||
|
alias e="emacs"
|
||||||
|
alias grep="egrep --color"
|
||||||
|
alias cpr="rsync -rlptgoDAXhP --info=all0,progress2"
|
||||||
|
alias rcp="cpr"
|
||||||
|
alias ll="eza -lahv --color"
|
||||||
|
alias l="eza -l -g --icons --all --all"
|
||||||
|
alias ls="eza"
|
||||||
|
alias xclip="xclip -sel clipboard"
|
||||||
|
alias git='GIT_COMMITTER_DATE="$(date +%Y-%m-%d) 00:00:00+0000" GIT_AUTHOR_DATE="$(date +%Y-%m-%d) 00:00:00+0000" git'
|
||||||
|
alias cat=bat
|
||||||
|
alias less=bat
|
||||||
|
|
||||||
|
# Dev
|
||||||
|
alias dcl="docker container ls -a --format='{{ .ID }}\t{{ .Names }}\t{{ index (split .Status \" \") 0 }}' | sort -k3r -k2 | column -t -N ID,Name,State"
|
||||||
|
alias composer80="composerX 8.0"
|
||||||
|
alias composer81="composerX 8.1"
|
||||||
|
alias composer82="composerX 8.2"
|
||||||
|
alias phpqa="phpqa82"
|
||||||
|
alias phpqa81='docker run --init -it --rm -v "$(pwd):/project" -v "$(pwd)/tmp-phpqa:/tmp" -w /project jakzal/phpqa:php8.1-alpine'
|
||||||
|
alias phpqa82='docker run --init -it --rm -v "$(pwd):/project" -v "$(pwd)/tmp-phpqa:/tmp" -w /project jakzal/phpqa:php8.2-alpine'
|
||||||
|
|
||||||
|
# DevOps / Admin
|
||||||
|
alias ssl_scan="docker run -ti --rm drwetter/testssl.sh"
|
||||||
|
alias tf="tofu"
|
||||||
|
alias terraform="tofu"
|
||||||
|
alias ks="kubeshell"
|
||||||
|
|
||||||
|
# Personal
|
||||||
|
alias awesome_test="Xephyr -screen 1440x1080 :5 & sleep 1 ; DISPLAY=:5 awesome"
|
||||||
|
alias clean_pa='pkill -U ${USER} pulseaudio; systemctl --user stop pulseaudio.socket && systemctl --user start pulseaudio.socket'
|
||||||
|
alias ssh_jump="ssh -qTNn"
|
||||||
|
alias x11_paste='sleep 2; xdotool type "$(xclip -o -selection clipboard)"'
|
|
@ -0,0 +1,21 @@
|
||||||
|
# https://github.com/zsh-users/zsh-completions
|
||||||
|
fpath+=${ZSH_CUSTOM:-${ZSH:-~/.oh-my-zsh}/custom}/plugins/zsh-completions/src
|
||||||
|
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
if command -v ansible &> /dev/null; then
|
||||||
|
source <(register-python-argcomplete ansible)
|
||||||
|
source <(register-python-argcomplete ansible-config)
|
||||||
|
source <(register-python-argcomplete ansible-console)
|
||||||
|
source <(register-python-argcomplete ansible-doc)
|
||||||
|
source <(register-python-argcomplete ansible-galaxy)
|
||||||
|
source <(register-python-argcomplete ansible-inventory)
|
||||||
|
source <(register-python-argcomplete ansible-playbook)
|
||||||
|
source <(register-python-argcomplete ansible-pull)
|
||||||
|
source <(register-python-argcomplete ansible-vault)
|
||||||
|
fi
|
||||||
|
|
||||||
|
autoload -U compinit && compinit
|
||||||
|
|
||||||
|
command -v boundary &> /dev/null && complete -o nospace -C /usr/bin/boundary boundary || true
|
||||||
|
command -v molecule &> /dev/null && source <(_MOLECULE_COMPLETE=zsh_source molecule) || true
|
||||||
|
command -v helm &> /dev/null && source <(helm completion zsh) || true
|
|
@ -0,0 +1,29 @@
|
||||||
|
# Versions
|
||||||
|
export RUBY_VERSION="3.1"
|
||||||
|
|
||||||
|
# Settings
|
||||||
|
export DEFAULT_USER=$(id -un)
|
||||||
|
export EDITOR=emacs
|
||||||
|
export TERM=xterm-256color
|
||||||
|
export LESS='-R'
|
||||||
|
export LESSOPEN='|~/.lessfilter %s'
|
||||||
|
export DOTNET_CLI_TELEMETRY_OPTOUT=1
|
||||||
|
export SSH_KEY_PATH="${HOME}/.ssh/id_ed25519"
|
||||||
|
export PAGER=less
|
||||||
|
export GPG_TTY="${TTY}"
|
||||||
|
|
||||||
|
# Dev
|
||||||
|
[ -d "$HOME/.nvm" ] && export NVM_DIR="$HOME/.nvm"
|
||||||
|
[ -d "$HOME/.nvm" ] && export NVM_SYMLINK_CURRENT=true
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
[ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh" # This loads nvm
|
||||||
|
[ -d "${HOME}/.local/share/gems/ruby/${RUBY_VERSION}" ] && export GEM_DIR="${HOME}/.local/share/gems/ruby/${RUBY_VERSION}"
|
||||||
|
[ -d "${HOME}/.cargo/env" ] && source "${HOME}/.cargo/env"
|
||||||
|
|
||||||
|
# Path
|
||||||
|
export PATH="${PATH}:${HOME}/.local/bin"
|
||||||
|
[ -d "${HOME}/.nvm/current/bin" ] && export PATH="${PATH}:${HOME}/.nvm/current/bin"
|
||||||
|
[ -d "${GEM_DIR}/bin" ] && export PATH="${PATH}:${GEM_DIR}/bin"
|
||||||
|
[ -d "/usr/local/go/bin" ] && export PATH="${PATH}:/usr/local/go/bin"
|
||||||
|
[ -d "$HOME/.cargo/bin" ] && export PATH="${PATH}:$HOME/.cargo/bin"
|
||||||
|
[ -d "$HOME/.local/share/JetBrains/Toolbox/scripts" ] && export PATH="${PATH}:$HOME/.local/share/JetBrains/Toolbox/scripts"
|
|
@ -0,0 +1,21 @@
|
||||||
|
function ydig() {
|
||||||
|
dig +yaml "${@}" | yq '.[].message.response_message_data|{"answer": .ANSWER_SECTION, status}'
|
||||||
|
}
|
||||||
|
|
||||||
|
function kubeshell() {
|
||||||
|
if [ $# -lt 3 ]; then
|
||||||
|
print "Invalid parameters: kubeshell NAMESPACE CONTAINER POD "
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local kubeBinary
|
||||||
|
local namespace="${1}"
|
||||||
|
shift
|
||||||
|
local container="${1}"
|
||||||
|
shift
|
||||||
|
local pod="${1}"
|
||||||
|
shift
|
||||||
|
|
||||||
|
kubeBinary=$(command -v kubectl)
|
||||||
|
"${kubeBinary}" exec -i -t -n "${namespace}" "${pod}" -c "${container}" "${@}" -- sh -c "clear; (zsh || bash || ash || sh)"
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
|
||||||
|
# Initialization code that may require console input (password prompts, [y/n]
|
||||||
|
# confirmations, etc.) must go above this block; everything else may go below.
|
||||||
|
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
|
||||||
|
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Path to your oh-my-zsh installation.
|
||||||
|
export ZSH="${HOME}/.oh-my-zsh"
|
||||||
|
export TERM="xterm-256color"
|
||||||
|
|
||||||
|
ZSH_THEME="powerlevel10k/powerlevel10k"
|
||||||
|
CASE_SENSITIVE="true"
|
||||||
|
|
||||||
|
# Uncomment the following line to use hyphen-insensitive completion.
|
||||||
|
# Case-sensitive completion must be off. _ and - will be interchangeable.
|
||||||
|
# HYPHEN_INSENSITIVE="true"
|
||||||
|
|
||||||
|
# Uncomment the following line to disable bi-weekly auto-update checks.
|
||||||
|
# DISABLE_AUTO_UPDATE="true"
|
||||||
|
|
||||||
|
# Uncomment the following line to automatically update without prompting.
|
||||||
|
# DISABLE_UPDATE_PROMPT="true"
|
||||||
|
|
||||||
|
# Uncomment the following line to change how often to auto-update (in days).
|
||||||
|
# export UPDATE_ZSH_DAYS=13
|
||||||
|
|
||||||
|
# Uncomment the following line if pasting URLs and other text is messed up.
|
||||||
|
# DISABLE_MAGIC_FUNCTIONS=true
|
||||||
|
|
||||||
|
# Uncomment the following line to disable colors in ls.
|
||||||
|
# DISABLE_LS_COLORS="true"
|
||||||
|
|
||||||
|
# Uncomment the following line to disable auto-setting terminal title.
|
||||||
|
# DISABLE_AUTO_TITLE="true"
|
||||||
|
|
||||||
|
# Uncomment the following line to enable command auto-correction.
|
||||||
|
# ENABLE_CORRECTION="true"
|
||||||
|
|
||||||
|
# Uncomment the following line to display red dots whilst waiting for completion.
|
||||||
|
# COMPLETION_WAITING_DOTS="true"
|
||||||
|
|
||||||
|
HIST_STAMPS="yyyy.mm.dd"
|
||||||
|
|
||||||
|
plugins=(autopep8 aws branch colored-man-pages colorize composer docker docker-compose git kubectl kube-ps1 npm nvm pass pep8 pip redis-cli rsync rust terraform)
|
||||||
|
|
||||||
|
source $ZSH/oh-my-zsh.sh
|
||||||
|
|
||||||
|
[ -f ~/.zsh_exports ] && source ~/.zsh_exports
|
||||||
|
[ -f ~/.p10k.zsh ] && source ~/.p10k.zsh
|
||||||
|
[ -f ~/.zsh_functions ] && source ~/.zsh_functions
|
||||||
|
[ -f ~/.zsh_aliases ] && source ~/.zsh_aliases
|
||||||
|
[ -f ~/.env ] && source ~/.env
|
||||||
|
[ -f ~/.zsh_completions ] && source ~/.zsh_completions
|
|
@ -0,0 +1,3 @@
|
||||||
|
{% for item in custom_sysctl.keys() -%}
|
||||||
|
{{ item }} = {{ custom_sysctl[item] }}
|
||||||
|
{% endfor %}
|
|
@ -1,2 +1,4 @@
|
||||||
---
|
---
|
||||||
custom_github_token: ""
|
custom_github_token: ""
|
||||||
|
development_docker_remap_user: "{{ custom_base_user_account }}"
|
||||||
|
development_docker_remap_group: "{{ custom_base_user_account }}"
|
|
@ -1,2 +1,7 @@
|
||||||
---
|
---
|
||||||
# handlers file for development
|
- name: '[docker] restart service'
|
||||||
|
become: true
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: docker
|
||||||
|
enabled: true
|
||||||
|
state: restarted
|
||||||
|
|
|
@ -1,140 +1,230 @@
|
||||||
---
|
---
|
||||||
- name: '[APT] install dependencies and tools'
|
- name: '[setup] gather facts if not already done'
|
||||||
|
setup:
|
||||||
|
gather_subset:
|
||||||
|
- distribution
|
||||||
|
- distribution_release
|
||||||
|
|
||||||
|
- name: '[home] get user account information'
|
||||||
|
ansible.builtin.getent:
|
||||||
|
database: passwd
|
||||||
|
key: "{{ custom_base_user_account }}"
|
||||||
|
split: ":"
|
||||||
|
changed_when: false
|
||||||
|
when: getent_passwd is undefined or custom_base_user_account not in getent_passwd
|
||||||
|
|
||||||
|
- name: '[apt] install dependencies and tools'
|
||||||
become: true
|
become: true
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
update_cache: true
|
update_cache: true
|
||||||
force_apt_get: true
|
force_apt_get: true
|
||||||
cache_valid_time: 3600
|
cache_valid_time: 3600
|
||||||
pkg:
|
pkg:
|
||||||
|
- apt-transport-https # docker-ce
|
||||||
- autoconf
|
- autoconf
|
||||||
|
- automake
|
||||||
- bc
|
- bc
|
||||||
|
- build-essential
|
||||||
- ca-certificates # docker-ce
|
- ca-certificates # docker-ce
|
||||||
- curl
|
- curl
|
||||||
- g++
|
- g++
|
||||||
- gcc
|
- gcc
|
||||||
- git
|
- git
|
||||||
- gnupg # docker-ce
|
- git-lfs
|
||||||
|
- gnupg2 # docker-ce
|
||||||
- jq
|
- jq
|
||||||
- libasound2 # draw.io
|
- libasound2 # draw.io
|
||||||
- libatspi2.0-0 # draw.io
|
- libatspi2.0-0 # draw.io
|
||||||
|
- libcairo2
|
||||||
|
- libcairo2-dev
|
||||||
|
- libcurl4-openssl-dev
|
||||||
|
- libffi-dev
|
||||||
- libgtk-3-0 # draw.io
|
- libgtk-3-0 # draw.io
|
||||||
- libnotify4 # draw.io
|
- libnotify4 # draw.io
|
||||||
- libnss3 # draw.io
|
- libnss3 # draw.io
|
||||||
- libsecret-1-0 # draw.io
|
- libsecret-1-0 # draw.io
|
||||||
|
- libssl-dev
|
||||||
|
- libtool
|
||||||
- libxss1 # draw.io
|
- libxss1 # draw.io
|
||||||
- libxtst6 # draw.io
|
- libxtst6 # draw.io
|
||||||
- make
|
- make
|
||||||
|
- mariadb-client
|
||||||
|
- pipx
|
||||||
|
- postgresql-client
|
||||||
|
- python3-dev
|
||||||
|
- python3-pip
|
||||||
|
- python3-virtualenv
|
||||||
- shellcheck
|
- shellcheck
|
||||||
|
- sqlite3
|
||||||
- valgrind
|
- valgrind
|
||||||
- xdg-utils # draw.io
|
- xdg-utils # draw.io
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: '[GitHub] install tools'
|
- name: '[github] install tools'
|
||||||
become: true
|
become: true
|
||||||
tags:
|
|
||||||
- molecule-idempotence-notest
|
|
||||||
nullified.infrastructure.github_artifact:
|
nullified.infrastructure.github_artifact:
|
||||||
github_token: '{{ custom_github_token }}'
|
github_token: '{{ custom_github_token }}'
|
||||||
artifacts:
|
asset_name: "{{ item.asset_name | default('') }}"
|
||||||
- asset_name: dive_{version}_linux_amd64.deb
|
asset_type: "{{ item.asset_type }}"
|
||||||
asset_type: release
|
cmds: "{{ item.cmds | default([]) }}"
|
||||||
repository: wagoodman/dive
|
creates: "{{ item.creates | default('') }}"
|
||||||
cmds:
|
repository: "{{ item.repository }}"
|
||||||
- dpkg -i {asset_dirname}/{asset_filename}
|
version: "{{ item.version | default('') }}"
|
||||||
- asset_name: kubeconform-linux-amd64.tar.gz
|
loop:
|
||||||
asset_type: release
|
- asset_name: kind-linux-amd64
|
||||||
repository: yannh/kubeconform
|
asset_type: release
|
||||||
cmds:
|
repository: kubernetes-sigs/kind
|
||||||
- tar -zxf {asset_dirname}/{asset_filename}
|
creates: /usr/local/bin/kind
|
||||||
- install --group=root --mode=755 --owner=root kubeconform /usr/local/bin
|
cmds:
|
||||||
- asset_name: git-delta_{version}_amd64.deb
|
- install --group=root --owner=root --mode=755 {asset_dirname}/{asset_filename} /usr/local/bin/kind
|
||||||
asset_type: release
|
- rm {asset_dirname}/{asset_filename}
|
||||||
repository: dandavison/delta
|
- asset_name: dive_{version}_linux_amd64.deb
|
||||||
cmds:
|
asset_type: release
|
||||||
- dpkg -i {asset_dirname}/{asset_filename}
|
repository: wagoodman/dive
|
||||||
- asset_name: docker-compose-linux-x86_64
|
creates: /usr/bin/dive
|
||||||
asset_type: release
|
cmds:
|
||||||
repository: docker/compose
|
- dpkg -i {asset_dirname}/{asset_filename}
|
||||||
cmds:
|
- asset_name: kubeconform-linux-amd64.tar.gz
|
||||||
- install --group=root --mode=755 --owner=root {asset_dirname}/{asset_filename} /usr/local/bin/docker-compose
|
asset_type: release
|
||||||
- test -d /usr/local/lib/docker/cli-plugins && (rm /usr/local/lib/docker/cli-plugins/docker-compose; ln -s /usr/local/bin/docker-compose /usr/local/lib/docker/cli-plugins) || true
|
repository: yannh/kubeconform
|
||||||
- test -d /usr/local/libexec/docker/cli-plugins && (rm /usr/local/libexec/docker/cli-plugins/docker-compose; ln -s /usr/local/bin/docker-compose /usr/local/libexec/docker/cli-plugins) || true
|
creates: /usr/local/bin/kubeconform
|
||||||
- test -d /usr/lib/docker/cli-plugins && (rm /usr/lib/docker/cli-plugins/docker-compose; ln -s /usr/local/bin/docker-compose /usr/lib/docker/cli-plugins) || true
|
cmds:
|
||||||
- test -d /usr/libexec/docker/cli-plugins && (rm /usr/libexec/docker/cli-plugins/docker-compose; ln -s /usr/local/bin/docker-compose /usr/libexec/docker/cli-plugins) || true
|
- tar -zxf {asset_dirname}/{asset_filename}
|
||||||
- asset_name: buildx-{version}.linux-amd64
|
- install --group=root --mode=755 --owner=root kubeconform /usr/local/bin
|
||||||
asset_type: release
|
- asset_name: git-delta_{version}_amd64.deb
|
||||||
repository: docker/buildx
|
asset_type: release
|
||||||
cmds:
|
repository: dandavison/delta
|
||||||
- install --group=root --mode=755 --owner=root {asset_dirname}/{asset_filename} /usr/local/bin/docker-buildx
|
creates: /usr/bin/delta
|
||||||
- test -d /usr/local/lib/docker/cli-plugins && (rm /usr/local/lib/docker/cli-plugins/docker-compose; ln -s /usr/local/bin/docker-compose /usr/local/lib/docker/cli-plugins) || true
|
cmds:
|
||||||
- test -d /usr/local/libexec/docker/cli-plugins && (rm /usr/local/libexec/docker/cli-plugins/docker-compose; ln -s /usr/local/bin/docker-compose /usr/local/libexec/docker/cli-plugins) || true
|
- dpkg -i {asset_dirname}/{asset_filename}
|
||||||
- test -d /usr/lib/docker/cli-plugins && (rm /usr/lib/docker/cli-plugins/docker-compose; ln -s /usr/local/bin/docker-compose /usr/lib/docker/cli-plugins) || true
|
- asset_name: docker-compose-linux-x86_64
|
||||||
- test -d /usr/libexec/docker/cli-plugins && (rm /usr/libexec/docker/cli-plugins/docker-compose; ln -s /usr/local/bin/docker-compose /usr/libexec/docker/cli-plugins) || true
|
asset_type: release
|
||||||
- asset_name: drawio-amd64-{version}.deb
|
repository: docker/compose
|
||||||
asset_type: release
|
creates: /usr/local/bin/docker-compose
|
||||||
repository: jgraph/drawio-desktop
|
cmds:
|
||||||
cmds:
|
- install --group=root --mode=755 --owner=root {asset_dirname}/{asset_filename} /usr/local/bin/docker-compose
|
||||||
- dpkg -i {asset_dirname}/{asset_filename}
|
- test -d /usr/local/lib/docker/cli-plugins && (rm /usr/local/lib/docker/cli-plugins/docker-compose; ln -s /usr/local/bin/docker-compose /usr/local/lib/docker/cli-plugins) || true
|
||||||
- asset_name: OpenLens-{version}.amd64.deb
|
- test -d /usr/local/libexec/docker/cli-plugins && (rm /usr/local/libexec/docker/cli-plugins/docker-compose; ln -s /usr/local/bin/docker-compose /usr/local/libexec/docker/cli-plugins) || true
|
||||||
asset_type: release
|
- test -d /usr/lib/docker/cli-plugins && (rm /usr/lib/docker/cli-plugins/docker-compose; ln -s /usr/local/bin/docker-compose /usr/lib/docker/cli-plugins) || true
|
||||||
repository: MuhammedKalkan/OpenLens
|
- test -d /usr/libexec/docker/cli-plugins && (rm /usr/libexec/docker/cli-plugins/docker-compose; ln -s /usr/local/bin/docker-compose /usr/libexec/docker/cli-plugins) || true
|
||||||
cmds:
|
- asset_name: buildx-{version}.linux-amd64
|
||||||
- dpkg -i {asset_dirname}/{asset_filename}
|
asset_type: release
|
||||||
- asset_name: stern_{version}_linux_amd64.tar.gz
|
repository: docker/buildx
|
||||||
asset_type: release
|
creates: /usr/local/bin/docker-buildx
|
||||||
repository: stern/stern
|
cmds:
|
||||||
cmds:
|
- install --group=root --mode=755 --owner=root {asset_dirname}/{asset_filename} /usr/local/bin/docker-buildx
|
||||||
- tar -zxf {asset_dirname}/{asset_filename}
|
- test -d /usr/local/lib/docker/cli-plugins && (rm /usr/local/lib/docker/cli-plugins/docker-compose; ln -s /usr/local/bin/docker-compose /usr/local/lib/docker/cli-plugins) || true
|
||||||
- install --group=root --mode=755 --owner=root stern /usr/local/bin
|
- test -d /usr/local/libexec/docker/cli-plugins && (rm /usr/local/libexec/docker/cli-plugins/docker-compose; ln -s /usr/local/bin/docker-compose /usr/local/libexec/docker/cli-plugins) || true
|
||||||
- asset_name: tofu_{version}_amd64.deb
|
- test -d /usr/lib/docker/cli-plugins && (rm /usr/lib/docker/cli-plugins/docker-compose; ln -s /usr/local/bin/docker-compose /usr/lib/docker/cli-plugins) || true
|
||||||
asset_type: release
|
- test -d /usr/libexec/docker/cli-plugins && (rm /usr/libexec/docker/cli-plugins/docker-compose; ln -s /usr/local/bin/docker-compose /usr/libexec/docker/cli-plugins) || true
|
||||||
repository: opentofu/opentofu
|
- asset_name: drawio-amd64-{version}.deb
|
||||||
cmds:
|
asset_type: release
|
||||||
- dpkg -i {asset_dirname}/{asset_filename}
|
repository: jgraph/drawio-desktop
|
||||||
|
creates: /usr/bin/drawio
|
||||||
|
cmds:
|
||||||
|
- dpkg -i {asset_dirname}/{asset_filename}
|
||||||
|
- asset_name: OpenLens-{version}.amd64.deb
|
||||||
|
asset_type: release
|
||||||
|
repository: MuhammedKalkan/OpenLens
|
||||||
|
creates: /usr/bin/open-lens
|
||||||
|
cmds:
|
||||||
|
- dpkg -i {asset_dirname}/{asset_filename}
|
||||||
|
- asset_name: stern_{version}_linux_amd64.tar.gz
|
||||||
|
asset_type: release
|
||||||
|
repository: stern/stern
|
||||||
|
creates: /usr/local/bin/stern
|
||||||
|
cmds:
|
||||||
|
- tar -zxf {asset_dirname}/{asset_filename}
|
||||||
|
- install --group=root --mode=755 --owner=root stern /usr/local/bin
|
||||||
|
- asset_name: tofu_{version}_amd64.deb
|
||||||
|
asset_type: release
|
||||||
|
repository: opentofu/opentofu
|
||||||
|
creates: /usr/bin/tofu
|
||||||
|
cmds:
|
||||||
|
- dpkg -i {asset_dirname}/{asset_filename}
|
||||||
|
|
||||||
- name: '[Custom] install latest kubectl'
|
- name: '[custom] install latest kubectl'
|
||||||
become: yes
|
become: true
|
||||||
tags:
|
block:
|
||||||
- molecule-idempotence-notest
|
- name: '[kubectl] find latest version available'
|
||||||
ansible.builtin.shell: |
|
ansible.builtin.command:
|
||||||
kubeVersion=$(curl -sSL -f https://storage.googleapis.com/kubernetes-release/release/stable.txt 2> /dev/null)
|
cmd: curl -L -s https://dl.k8s.io/release/stable.txt
|
||||||
kubeVersion=${kubeVersion:-v1.28.2}
|
register: latest_kube_version
|
||||||
curl --silent --compressed -L -XGET https://storage.googleapis.com/kubernetes-release/release/${kubeVersion}/bin/linux/amd64/kubectl -o kubectl
|
changed_when: false
|
||||||
install --group=root --mode=755 --owner=root kubectl /usr/local/bin && rm kubectl
|
|
||||||
|
|
||||||
- name: '[Custom] install latest Helm'
|
- name: '[kubectl] fetch binary'
|
||||||
become: yes
|
ansible.builtin.get_url:
|
||||||
tags:
|
url: "https://dl.k8s.io/release/{{ latest_kube_version.stdout }}/bin/linux/amd64/kubectl"
|
||||||
- molecule-idempotence-notest
|
dest: /usr/local/bin/kubectl
|
||||||
ansible.builtin.shell: |
|
owner: root
|
||||||
helmVersion=$(curl -sSL https://api.github.com/repos/helm/helm/releases/latest | jq -r '.tag_name')
|
group: root
|
||||||
helmVersion=${helmVersion:-v3.13.0}
|
mode: '0755'
|
||||||
curl --silent --compressed -L -XGET https://get.helm.sh/helm-${helmVersion}-linux-amd64.tar.gz -o helm.tar.gz
|
|
||||||
tar -zxf helm.tar.gz
|
- name: '[custom] install latest Helm'
|
||||||
install --group=root --mode=755 --owner=root linux-amd64/helm /usr/local/bin && rm -rf linux-amd64 helm.tar.gz
|
become: true
|
||||||
|
block:
|
||||||
|
- name: '[helm] find latest version available'
|
||||||
|
ansible.builtin.shell: |-
|
||||||
|
curl -sSL https://api.github.com/repos/helm/helm/releases/latest | jq -r '.tag_name'
|
||||||
|
register: latest_helm_version
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: '[helm] find if binary is already installed'
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /usr/local/bin/helm
|
||||||
|
register: helm_stat
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: '[helm] setup temp directory'
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /tmp/helm-unarchive
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0700'
|
||||||
|
when: helm_stat.state is match("absent")
|
||||||
|
|
||||||
|
- name: '[helm] fetch archive'
|
||||||
|
ansible.builtin.unarchive:
|
||||||
|
remote_src: true
|
||||||
|
src: "https://get.helm.sh/helm-{{ latest_helm_version.stdout }}-linux-amd64.tar.gz"
|
||||||
|
dest: /tmp/helm-unarchive
|
||||||
|
when: helm_stat.state is match("absent")
|
||||||
|
|
||||||
|
- name: '[helm] install binary'
|
||||||
|
ansible.builtin.copy:
|
||||||
|
remote_src: true
|
||||||
|
src: /tmp/helm-unarchive/linux-amd64/helm
|
||||||
|
dest: /usr/local/bin/helm
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0755'
|
||||||
|
when: helm_stat.state is match("absent")
|
||||||
|
|
||||||
|
- name: '[helm] cleanup'
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /tmp/helm-unarchive
|
||||||
|
state: absent
|
||||||
|
when: helm_stat.state is match("absent")
|
||||||
|
|
||||||
- name: '[custom] install Docker CE repository'
|
- name: '[custom] install Docker CE repository'
|
||||||
|
become: true
|
||||||
block:
|
block:
|
||||||
- name: '[apt key] retrieve GPG key'
|
- name: '[apt key] add docker key'
|
||||||
tags:
|
ansible.builtin.get_url:
|
||||||
- molecule-idempotence-notest
|
url: "https://download.docker.com/linux/{{ ansible_distribution | lower }}/gpg"
|
||||||
ansible.builtin.shell: |-
|
dest: /etc/apt/trusted.gpg.d/docker.asc
|
||||||
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
mode: '0644'
|
||||||
chmod a+r /etc/apt/keyrings/docker.gpg
|
|
||||||
|
|
||||||
- name: '[apt key] add source'
|
- name: '[apt key] add source'
|
||||||
ansible.builtin.apt_repository:
|
ansible.builtin.apt_repository:
|
||||||
repo: "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian {{ ansible_distribution_release }} stable"
|
repo: "deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/docker.asc] https://download.docker.com/linux/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} stable"
|
||||||
state: present
|
state: present
|
||||||
|
filename: docker
|
||||||
- name: '[Apt Key] refresh repository'
|
|
||||||
ansible.builtin.apt:
|
|
||||||
update_cache: true
|
update_cache: true
|
||||||
force_apt_get: true
|
|
||||||
cache_valid_time: 0
|
|
||||||
|
|
||||||
- name: '[Apt] install Docker CE'
|
- name: '[apt] install Docker CE'
|
||||||
become: yes
|
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
update_cache: true
|
update_cache: true
|
||||||
force_apt_get: true
|
force_apt_get: true
|
||||||
|
@ -144,3 +234,96 @@
|
||||||
- docker-ce-cli
|
- docker-ce-cli
|
||||||
- containerd.io
|
- containerd.io
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
|
- name: '[docker] update daemon configuration'
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: ../templates/docker-ce/daemon.json.j2
|
||||||
|
dest: /etc/docker/daemon.json
|
||||||
|
mode: '0644'
|
||||||
|
notify:
|
||||||
|
- 'development : [docker] restart service'
|
||||||
|
|
||||||
|
- name: '[docker] add default user to docker group'
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ development_docker_remap_user }}"
|
||||||
|
append: true
|
||||||
|
groups: docker
|
||||||
|
state: present
|
||||||
|
notify:
|
||||||
|
- 'development : [docker] restart service'
|
||||||
|
|
||||||
|
- name: '[python] install tools'
|
||||||
|
become: true
|
||||||
|
become_user: "{{ custom_base_user_account }}"
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "pipx install {{ item.cmd }}"
|
||||||
|
creates: "{{ getent_passwd[custom_base_user_account][4] }}/.local/bin/{{ item.creates }}"
|
||||||
|
loop:
|
||||||
|
- { "cmd": "black", "creates": "black" }
|
||||||
|
- { "cmd": "flake8", "creates": "flake8" }
|
||||||
|
|
||||||
|
- name: '[python] install pipx packages dependencies'
|
||||||
|
become: true
|
||||||
|
become_user: "{{ custom_base_user_account }}"
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "pipx inject {{ item.venv }} {{ item.extension }}"
|
||||||
|
creates:
|
||||||
|
"{{ getent_passwd[custom_base_user_account][4] }}/.local/pipx/venvs/{{ item.venv }}/lib/python3.11/site-packages/{{ item.creates }}"
|
||||||
|
loop:
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-annotations-complexity"
|
||||||
|
creates: "flake8_annotations_complexity"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-bandit"
|
||||||
|
creates: "flake8_bandit.py"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-breakpoint"
|
||||||
|
creates: "flake8_breakpoint"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-bugbear"
|
||||||
|
creates: "bugbear.py"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-builtins"
|
||||||
|
creates: "flake8_builtins.py"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-comprehensions"
|
||||||
|
creates: "flake8_comprehensions"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-docstrings"
|
||||||
|
creates: "flake8_docstrings.py"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-eradicate"
|
||||||
|
creates: "flake8_eradicate.py"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-expression-complexity"
|
||||||
|
creates: "flake8_expression_complexity"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-if-expr"
|
||||||
|
creates: "flake8_if_expr"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-isort"
|
||||||
|
creates: "flake8_isort.py"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-logging-format"
|
||||||
|
creates: "logging_format"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-print"
|
||||||
|
creates: "flake8_print.py"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-pytest"
|
||||||
|
creates: "flake8_pytest.py"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-pytest-style"
|
||||||
|
creates: "flake8_pytest_style"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-requirements"
|
||||||
|
creates: "flake8_requirements"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-return"
|
||||||
|
creates: "flake8_return"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "flake8-rst-docstrings"
|
||||||
|
creates: "flake8_rst_docstrings.py"
|
||||||
|
- venv: "flake8"
|
||||||
|
extension: "pep8-naming"
|
||||||
|
creates: "pep8ext_naming.py"
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"userns-remap": "{{ development_docker_remap_user }}:{{ development_docker_remap_group }}",
|
||||||
|
"cgroup-parent": "{{ development_docker_systemd_slice }}"
|
||||||
|
}
|
|
@ -1,2 +1,2 @@
|
||||||
---
|
---
|
||||||
# vars file for development
|
development_docker_systemd_slice: docker.slice
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
custom_github_token: ""
|
|
@ -0,0 +1 @@
|
||||||
|
---
|
|
@ -0,0 +1,21 @@
|
||||||
|
---
|
||||||
|
galaxy_info:
|
||||||
|
author: Florian L.
|
||||||
|
namespace: nullified
|
||||||
|
description: Install games and gaming related software
|
||||||
|
# issue_tracker_url: http://example.com/issue/tracker
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: 2.15
|
||||||
|
|
||||||
|
# https://galaxy.ansible.com/api/v1/platforms/
|
||||||
|
platforms:
|
||||||
|
- name: Debian
|
||||||
|
versions:
|
||||||
|
- bookworm
|
||||||
|
|
||||||
|
galaxy_tags:
|
||||||
|
- github
|
||||||
|
- steam
|
||||||
|
- games
|
||||||
|
|
||||||
|
dependencies: []
|
|
@ -0,0 +1,56 @@
|
||||||
|
---
|
||||||
|
- name: '[games] install Steam'
|
||||||
|
become: true
|
||||||
|
block:
|
||||||
|
- name: '[system] get existing architectures'
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: dpkg --print-foreign-architectures
|
||||||
|
register: dpkg_archs
|
||||||
|
changed_when: false
|
||||||
|
when: dpkg_archs is not defined
|
||||||
|
|
||||||
|
- name: '[steam] enable i386 architecture'
|
||||||
|
command:
|
||||||
|
cmd: dpkg --add-architecture i386
|
||||||
|
when: dpkg_archs.stdout is not regex("(^|\b)i386($|\b)", multiline = true)
|
||||||
|
|
||||||
|
- name: '[apt key] add Steam GPG key'
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: "https://repo.steampowered.com/steam/archive/stable/steam.gpg"
|
||||||
|
dest: /usr/share/keyrings/steam.gpg
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: '[apt key] add source'
|
||||||
|
apt_repository:
|
||||||
|
repo: "{{ item }} [arch=amd64,i386 signed-by=/usr/share/keyrings/steam.gpg] https://repo.steampowered.com/steam/ stable steam"
|
||||||
|
state: present
|
||||||
|
filename: steam
|
||||||
|
update_cache: true
|
||||||
|
loop:
|
||||||
|
- deb
|
||||||
|
- deb-src
|
||||||
|
|
||||||
|
- name: '[steam] install dependencies'
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: true
|
||||||
|
force_apt_get: true
|
||||||
|
cache_valid_time: 3600
|
||||||
|
pkg:
|
||||||
|
- libgl1-mesa-dri:amd64
|
||||||
|
- libgl1-mesa-dri:i386
|
||||||
|
- libgl1-mesa-glx:amd64
|
||||||
|
- libgl1-mesa-glx:i386
|
||||||
|
- steam-launcher
|
||||||
|
|
||||||
|
- name: '[games] install Heroic Games Launcher'
|
||||||
|
become: true
|
||||||
|
block:
|
||||||
|
- name: '[hgl] fetch assets from github'
|
||||||
|
nullified.infrastructure.github_artifact:
|
||||||
|
github_token: '{{ custom_github_token }}'
|
||||||
|
asset_name: heroic_{version}_amd64.deb
|
||||||
|
asset_type: release
|
||||||
|
repository: Heroic-Games-Launcher/HeroicGamesLauncher
|
||||||
|
creates: /usr/bin/heroic
|
||||||
|
cmds:
|
||||||
|
- dpkg -i {asset_dirname}/{asset_filename}
|
|
@ -0,0 +1,2 @@
|
||||||
|
localhost
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
---
|
|
@ -1,27 +1,32 @@
|
||||||
---
|
---
|
||||||
- name: '[ssh] restart service'
|
- name: '[ssh] restart service'
|
||||||
|
become: true
|
||||||
ansible.builtin.systemd_service:
|
ansible.builtin.systemd_service:
|
||||||
name: sshd.service
|
name: sshd.service
|
||||||
enabled: true
|
enabled: true
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
||||||
- name: '[clamav] daemon reload'
|
- name: '[clamav] daemon reload'
|
||||||
|
become: true
|
||||||
ansible.builtin.systemd_service:
|
ansible.builtin.systemd_service:
|
||||||
daemon_reload: true
|
daemon_reload: true
|
||||||
|
|
||||||
- name: '[freshclam] restart service'
|
- name: '[freshclam] restart service'
|
||||||
|
become: true
|
||||||
ansible.builtin.systemd_service:
|
ansible.builtin.systemd_service:
|
||||||
name: sshd.service
|
name: sshd.service
|
||||||
enabled: true
|
enabled: true
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
||||||
- name: '[clamd] wait for signatures'
|
- name: '[clamd] wait for signatures'
|
||||||
|
become: true
|
||||||
ansible.builtin.wait_for:
|
ansible.builtin.wait_for:
|
||||||
path: /var/lib/clamav/bytecode.cvd
|
path: /var/lib/clamav/bytecode.cvd
|
||||||
timeout: 600
|
timeout: 600
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: '[clamd] restart service'
|
- name: '[clamd] restart service'
|
||||||
|
become: true
|
||||||
ansible.builtin.systemd_service:
|
ansible.builtin.systemd_service:
|
||||||
name: sshd.service
|
name: sshd.service
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
|
@ -1,29 +1,36 @@
|
||||||
---
|
---
|
||||||
- name: '[setup] gather facts is not already done'
|
- name: '[setup] gather facts if not already done'
|
||||||
setup:
|
setup:
|
||||||
gather_subset:
|
gather_subset:
|
||||||
- distribution
|
- distribution
|
||||||
|
|
||||||
- name: '[ssh] hardening sshd'
|
- name: '[ssh] hardening sshd'
|
||||||
become: yes
|
become: true
|
||||||
block:
|
block:
|
||||||
- name: '[ssh] setup sshd_config'
|
- name: '[ssh] setup sshd_config'
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: ../templates/openssh-server/sshd_config.j2
|
src: ../templates/openssh-server/sshd_config.j2
|
||||||
dest: /etc/ssh/sshd_config
|
dest: /etc/ssh/sshd_config
|
||||||
mode: 644
|
mode: '0644'
|
||||||
notify:
|
|
||||||
- '[ssh] restart service'
|
|
||||||
- name: '[ssh] setup sshd_config.d'
|
- name: '[ssh] setup sshd_config.d'
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: ../templates/openssh-server/sshd_config.d/encryption.conf.j2
|
src: ../templates/openssh-server/sshd_config.d/encryption.conf.j2
|
||||||
dest: /etc/ssh/sshd_config.d/encryption.conf
|
dest: /etc/ssh/sshd_config.d/encryption.conf
|
||||||
mode: 644
|
mode: '0644'
|
||||||
notify:
|
- name: '[ssh] remove low security keys'
|
||||||
- 'security : [ssh] restart service'
|
ansible.builtin.file:
|
||||||
|
path: "/etc/ssh/{{ item }}"
|
||||||
|
state: absent
|
||||||
|
loop:
|
||||||
|
- ssh_host_ecdsa_key
|
||||||
|
- ssh_host_ecdsa_key.pub
|
||||||
|
- ssh_host_rsa_key
|
||||||
|
- ssh_host_rsa_key.pub
|
||||||
|
notify:
|
||||||
|
- 'security : [ssh] restart service'
|
||||||
|
|
||||||
- name: '[utils] install security and audit tools'
|
- name: '[utils] install security and audit tools'
|
||||||
become: yes
|
become: true
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
update_cache: true
|
update_cache: true
|
||||||
force_apt_get: true
|
force_apt_get: true
|
||||||
|
@ -35,7 +42,7 @@
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: '[system] configure rkhunter'
|
- name: '[system] configure rkhunter'
|
||||||
become: yes
|
become: true
|
||||||
block:
|
block:
|
||||||
- name: '[rkhunter] create include dir'
|
- name: '[rkhunter] create include dir'
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
|
@ -57,7 +64,7 @@
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: '[system] clamav'
|
- name: '[system] clamav'
|
||||||
become: yes
|
become: true
|
||||||
block:
|
block:
|
||||||
- name: '[clamav] retrieve and install clamav package'
|
- name: '[clamav] retrieve and install clamav package'
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
|
@ -80,35 +87,16 @@
|
||||||
system: true
|
system: true
|
||||||
state: present
|
state: present
|
||||||
- name: '[clamav] setup directories'
|
- name: '[clamav] setup directories'
|
||||||
block:
|
ansible.builtin.file:
|
||||||
- name: '[clamav] ensure /etc/clamav dir exists'
|
path: "{{ item }}"
|
||||||
ansible.builtin.file:
|
state: directory
|
||||||
path: /etc/clamav
|
owner: clamav
|
||||||
state: directory
|
group: clamav
|
||||||
owner: clamav
|
mode: '0750'
|
||||||
group: clamav
|
loop:
|
||||||
mode: '0750'
|
- /etc/clamav
|
||||||
- name: '[clamav] ensure /var/lib/clamav dir exists'
|
- /var/lib/clamav/quarantine
|
||||||
ansible.builtin.file:
|
- /var/log/clamav
|
||||||
path: /var/lib/clamav
|
|
||||||
state: directory
|
|
||||||
owner: clamav
|
|
||||||
group: clamav
|
|
||||||
mode: '0750'
|
|
||||||
- name: '[clamav] ensure /var/lib/clamav/quarantine dir exists'
|
|
||||||
ansible.builtin.file:
|
|
||||||
path: /var/lib/clamav/quarantine
|
|
||||||
state: directory
|
|
||||||
owner: clamav
|
|
||||||
group: clamav
|
|
||||||
mode: '0750'
|
|
||||||
- name: '[clamav] ensure /var/log/clamav dir exists'
|
|
||||||
ansible.builtin.file:
|
|
||||||
path: /var/log/clamav
|
|
||||||
state: directory
|
|
||||||
owner: clamav
|
|
||||||
group: clamav
|
|
||||||
mode: '0750'
|
|
||||||
- name: '[clamav] copy clamd.conf'
|
- name: '[clamav] copy clamd.conf'
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: '../templates/clamav/clamd.conf.j2'
|
src: '../templates/clamav/clamd.conf.j2'
|
||||||
|
@ -123,20 +111,16 @@
|
||||||
owner: clamav
|
owner: clamav
|
||||||
group: clamav
|
group: clamav
|
||||||
mode: '0640'
|
mode: '0640'
|
||||||
- name: '[clamav] setup freshclam service'
|
- name: '[clamav] copy freshclam service file'
|
||||||
block:
|
ansible.builtin.template:
|
||||||
- name: '[clamav] copy freshclam service file'
|
src: '../templates/clamav/clamav-freshclam.service.j2'
|
||||||
ansible.builtin.template:
|
dest: /usr/lib/systemd/system/clamav-freshclam.service
|
||||||
src: '../templates/clamav/clamav-freshclam.service.j2'
|
mode: '0644'
|
||||||
dest: /usr/lib/systemd/system/clamav-freshclam.service
|
- name: '[clamav] copy clamd service file'
|
||||||
mode: '0644'
|
ansible.builtin.template:
|
||||||
- name: '[clamav] setup clamd service'
|
src: '../templates/clamav/clamav-clamd.service.j2'
|
||||||
block:
|
dest: /usr/lib/systemd/system/clamav-clamd.service
|
||||||
- name: '[clamav] copy clamd service file'
|
mode: '0644'
|
||||||
ansible.builtin.template:
|
|
||||||
src: '../templates/clamav/clamav-clamd.service.j2'
|
|
||||||
dest: /usr/lib/systemd/system/clamav-clamd.service
|
|
||||||
mode: '0644'
|
|
||||||
- name: '[clamav] setup cron job'
|
- name: '[clamav] setup cron job'
|
||||||
ansible.builtin.cron:
|
ansible.builtin.cron:
|
||||||
name: clamav full system scan
|
name: clamav full system scan
|
||||||
|
@ -152,7 +136,7 @@
|
||||||
- 'security : [clamd] restart service'
|
- 'security : [clamd] restart service'
|
||||||
|
|
||||||
- name: '[system] hardening system'
|
- name: '[system] hardening system'
|
||||||
become: yes
|
become: true
|
||||||
block:
|
block:
|
||||||
- name: '[system] login.defs'
|
- name: '[system] login.defs'
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
---
|
---
|
||||||
custom_base_user_account: "root"
|
workstation_user_account: "{{ custom_base_user_account }}"
|
||||||
|
custom_github_token: ""
|
||||||
|
custom_sysctl: {}
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
---
|
---
|
||||||
# handlers file for development
|
|
||||||
|
|
|
@ -1,25 +1,181 @@
|
||||||
---
|
---
|
||||||
- name: '[APT] install dependencies and tools'
|
- name: '[home] get user account information'
|
||||||
become: yes
|
ansible.builtin.getent:
|
||||||
|
database: passwd
|
||||||
|
key: "{{ workstation_user_account }}"
|
||||||
|
split: ":"
|
||||||
|
changed_when: false
|
||||||
|
when: getent_passwd is undefined or workstation_user_account not in getent_passwd
|
||||||
|
|
||||||
|
- name: '[apt] install dependencies and tools'
|
||||||
|
become: true
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
update_cache: true
|
update_cache: true
|
||||||
force_apt_get: true
|
force_apt_get: true
|
||||||
cache_valid_time: 3600
|
cache_valid_time: 3600
|
||||||
pkg:
|
pkg:
|
||||||
- curl
|
- curl
|
||||||
|
- dbus-x11 # terminator
|
||||||
|
- diffpdf
|
||||||
|
- feh
|
||||||
|
- ffmpeg
|
||||||
- flatpak
|
- flatpak
|
||||||
- gnupg
|
- gettext # terminator
|
||||||
|
- gir1.2-keybinder-3.0 # terminator
|
||||||
|
- gir1.2-vte-2.91 # terminator
|
||||||
|
- gnupg2
|
||||||
|
- gvfs-backends
|
||||||
|
- intltool # terminator
|
||||||
|
- mpc
|
||||||
|
- mpd
|
||||||
|
- ncmpcpp
|
||||||
|
- numlockx
|
||||||
|
- openssh-server
|
||||||
|
- pass
|
||||||
|
- poppler-utils
|
||||||
- pwgen
|
- pwgen
|
||||||
|
- python3-configobj # terminator
|
||||||
|
- python3-gi # terminator
|
||||||
|
- python3-gi-cairo # terminator
|
||||||
|
- python3-pip
|
||||||
|
- python3-psutil # terminator
|
||||||
|
- ruby
|
||||||
|
- scrot
|
||||||
|
- smbclient
|
||||||
|
- socat
|
||||||
|
- sshfs
|
||||||
|
- suckless-tools
|
||||||
- sudo
|
- sudo
|
||||||
|
- unclutter-xfixes
|
||||||
|
- vlc
|
||||||
|
- wireshark
|
||||||
|
- xdotool
|
||||||
|
- xsel
|
||||||
|
- xserver-xephyr
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: '[Setup] setup Flatpak'
|
- name: '[setup] add user to sudo group'
|
||||||
become: yes
|
become: true
|
||||||
become_user: "{{ custom_base_user_account }}"
|
ansible.builtin.user:
|
||||||
become_method: su
|
name: "{{ workstation_user_account }}"
|
||||||
tags:
|
groups:
|
||||||
- molecule-idempotence-notest
|
- sudo
|
||||||
ansible.builtin.shell: |
|
append: true
|
||||||
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
|
||||||
flatpak install --noninteractive flathub com.discordapp.Discord
|
- name: '[setup] setup Flatpak'
|
||||||
flatpak install --noninteractive flathub md.obsidian.Obsidian
|
become: true
|
||||||
|
become_user: "{{ workstation_user_account }}"
|
||||||
|
block:
|
||||||
|
- name: '[flatpak] add flatpak repos'
|
||||||
|
command:
|
||||||
|
cmd: flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||||
|
changed_when: false
|
||||||
|
- name: '[flatpak] install flatpak apps'
|
||||||
|
command:
|
||||||
|
cmd: "flatpak install --noninteractive {{ item.repo }} {{ item.app }}"
|
||||||
|
creates: "{{ getent_passwd[workstation_user_account][4] }}/.var/app/{{ item.app }}"
|
||||||
|
loop:
|
||||||
|
- repo: flathub
|
||||||
|
app: com.discordapp.Discord
|
||||||
|
- repo: flathub
|
||||||
|
app: md.obsidian.Obsidian
|
||||||
|
|
||||||
|
- name: '[github] install tools'
|
||||||
|
become: true
|
||||||
|
nullified.infrastructure.github_artifact:
|
||||||
|
github_token: '{{ custom_github_token }}'
|
||||||
|
asset_name: "{{ item.asset_name | default('') }}"
|
||||||
|
asset_type: "{{ item.asset_type }}"
|
||||||
|
cmds: "{{ item.cmds | default([]) }}"
|
||||||
|
creates: "{{ item.creates | default('') }}"
|
||||||
|
repository: "{{ item.repository }}"
|
||||||
|
version: "{{ item.version | default('') }}"
|
||||||
|
loop:
|
||||||
|
- asset_name: terminator-{version}.tar.gz
|
||||||
|
asset_type: release
|
||||||
|
repository: gnome-terminator/terminator
|
||||||
|
creates: /usr/local/bin/terminator
|
||||||
|
cmds:
|
||||||
|
- tar -zxf {asset_dirname}/{asset_filename}
|
||||||
|
- cd $(find . -maxdepth 1 -name terminator\* -type d); python3 setup.py build; python3 setup.py install --single-version-externally-managed --record=install-files.txt
|
||||||
|
- rm -rf {asset_dirname}/{asset_filename}
|
||||||
|
|
||||||
|
- name: '[ruby] install tools'
|
||||||
|
become: true
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: "gem install {{ item.app }}"
|
||||||
|
creates: "{{ item.creates }}"
|
||||||
|
loop:
|
||||||
|
- app: mdless
|
||||||
|
creates: /usr/local/bin/mdless
|
||||||
|
|
||||||
|
- name: '[system] setup various directories'
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item.path }}"
|
||||||
|
mode: "{{ item.mode | default('0750') }}"
|
||||||
|
owner: "{{ item.owner | default(workstation_user_account) }}"
|
||||||
|
group: "{{ item.group | default(workstation_user_account) }}"
|
||||||
|
state: directory
|
||||||
|
loop:
|
||||||
|
- { path: '/opt/git/foss' }
|
||||||
|
- { path: '/opt/git/perso' }
|
||||||
|
- { path: '/opt/git/work' }
|
||||||
|
- { path: '/srv/storage' }
|
||||||
|
|
||||||
|
- name: '[emacs] fetch emacs configuration files'
|
||||||
|
become: true
|
||||||
|
become_user: "{{ workstation_user_account }}"
|
||||||
|
ansible.builtin.git:
|
||||||
|
repo: "ssh://git@gitlab.0x2a.ninja:4222/naeikindus/emacsd.git"
|
||||||
|
dest: "{{ getent_passwd[workstation_user_account][4] }}/.emacs.d"
|
||||||
|
force: false
|
||||||
|
|
||||||
|
- name: '[config] set tools configuration'
|
||||||
|
become: true
|
||||||
|
become_user: "{{ workstation_user_account }}"
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ item.src }}"
|
||||||
|
dest: "{{ item.dest }}"
|
||||||
|
mode: "{{ item.mode | default('0640') }}"
|
||||||
|
loop:
|
||||||
|
- { src: "../templates/.config/terminator", dest: "{{ getent_passwd[workstation_user_account][4] }}/.config" }
|
||||||
|
- { src: "../templates/.config/vlc", dest: "{{ getent_passwd[workstation_user_account][4] }}/.config" }
|
||||||
|
|
||||||
|
- name: '[yubico] install authenticator'
|
||||||
|
become: true
|
||||||
|
block:
|
||||||
|
- name: '[yubico] fetch latest authenticator source'
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: https://developers.yubico.com/yubioath-flutter/Releases/yubico-authenticator-latest-linux.tar.gz
|
||||||
|
dest: /tmp/yubico-authenticator-latest-linux.tar.gz
|
||||||
|
mode: '0640'
|
||||||
|
|
||||||
|
- name: '[yubico] prepare target directory'
|
||||||
|
file:
|
||||||
|
path: /opt/yubico-authenticator
|
||||||
|
owner: "{{ workstation_user_account }}"
|
||||||
|
group: "{{ workstation_user_account }}"
|
||||||
|
mode: '0750'
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: '[yubico] extract data'
|
||||||
|
ansible.builtin.unarchive:
|
||||||
|
src: /tmp/yubico-authenticator-latest-linux.tar.gz
|
||||||
|
remote_src: true
|
||||||
|
dest: /opt/yubico-authenticator
|
||||||
|
owner: "{{ workstation_user_account }}"
|
||||||
|
group: "{{ workstation_user_account }}"
|
||||||
|
creates: /opt/yubico-authenticator/authenticator
|
||||||
|
|
||||||
|
- name: '[yubico] create shell wrapper'
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: ../templates/bin_wrapper.sh.j2
|
||||||
|
dest: "{{ getent_passwd[workstation_user_account][4] }}/.local/bin/authenticator"
|
||||||
|
mode: '0750'
|
||||||
|
owner: "{{ workstation_user_account }}"
|
||||||
|
group: "{{ workstation_user_account }}"
|
||||||
|
vars:
|
||||||
|
application: "/opt/yubico-authenticator/authenticator"
|
||||||
|
|
||||||
|
- include_tasks: window_manager.yml
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
---
|
||||||
|
- name: '[home] get user account information'
|
||||||
|
ansible.builtin.getent:
|
||||||
|
database: passwd
|
||||||
|
key: "{{ workstation_user_account }}"
|
||||||
|
split: ":"
|
||||||
|
changed_when: false
|
||||||
|
when: getent_passwd is undefined or workstation_user_account not in getent_passwd
|
||||||
|
|
||||||
|
- name: '[awesomewm] install dependencies'
|
||||||
|
become: true
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: true
|
||||||
|
force_apt_get: true
|
||||||
|
cache_valid_time: 3600
|
||||||
|
pkg:
|
||||||
|
- asciidoctor
|
||||||
|
- build-essential
|
||||||
|
- cmake
|
||||||
|
- gir1.2-freedesktop
|
||||||
|
- gir1.2-gdkpixbuf-2.0
|
||||||
|
- gir1.2-glib-2.0
|
||||||
|
- gir1.2-gtk-3.0
|
||||||
|
- gir1.2-pango-1.0
|
||||||
|
- imagemagick
|
||||||
|
- libcairo-gobject2
|
||||||
|
- libcairo2-dev
|
||||||
|
- libdbus-1-dev
|
||||||
|
- libgdk-pixbuf-2.0-dev
|
||||||
|
- libgirepository1.0-dev
|
||||||
|
- libglib2.0-dev
|
||||||
|
- liblua5.4-dev
|
||||||
|
- liblua5.4-dev
|
||||||
|
- librsvg2-dev
|
||||||
|
- libstartup-notification0-dev
|
||||||
|
- libx11-dev
|
||||||
|
- libx11-xcb-dev
|
||||||
|
- libxcb-cursor-dev
|
||||||
|
- libxcb-icccm4-dev
|
||||||
|
- libxcb-keysyms1-dev
|
||||||
|
- libxcb-randr0-dev
|
||||||
|
- libxcb-shape0-dev
|
||||||
|
- libxcb-util0-dev
|
||||||
|
- libxcb-xfixes0-dev
|
||||||
|
- libxcb-xinerama0-dev
|
||||||
|
- libxcb-xkb-dev
|
||||||
|
- libxcb-xrm-dev
|
||||||
|
- libxcb-xtest0-dev
|
||||||
|
- libxcb1-dev
|
||||||
|
- libxdg-basedir-dev
|
||||||
|
- libxkbcommon-x11-dev
|
||||||
|
- libxkbcommon-dev
|
||||||
|
- lua5.4
|
||||||
|
- luajit2
|
||||||
|
- menu
|
||||||
|
- picom
|
||||||
|
- x11-xserver-utils
|
||||||
|
- xutils-dev
|
||||||
|
|
||||||
|
- name: '[lua-lgi] install lua-lgi'
|
||||||
|
block:
|
||||||
|
- name: '[lua-lgi] fetch source'
|
||||||
|
become: true
|
||||||
|
become_user: "{{ workstation_user_account }}"
|
||||||
|
ansible.builtin.git:
|
||||||
|
repo: https://github.com/lgi-devs/lgi.git
|
||||||
|
dest: /opt/git/foss/lua-lgi
|
||||||
|
force: false
|
||||||
|
register: repo_clone
|
||||||
|
failed_when:
|
||||||
|
- repo_clone.failed
|
||||||
|
- not 'Local modifications exist in the destination' in repo_clone.msg
|
||||||
|
|
||||||
|
- name: '[lua-lgi] switch from LUA 5.1 to LUA 5.4'
|
||||||
|
ansible.builtin.replace:
|
||||||
|
path: /opt/git/foss/lua-lgi/lgi/Makefile
|
||||||
|
regexp: '5\.1'
|
||||||
|
replace: '5.4'
|
||||||
|
|
||||||
|
- name: '[lua-lgi] building project'
|
||||||
|
ansible.builtin.command:
|
||||||
|
chdir: /opt/git/foss/lua-lgi
|
||||||
|
cmd: LUA_CFLAGS="-I/usr/include/lua5.4" make all
|
||||||
|
creates: /opt/git/foss/lua-lgi/lgi/corelgilua51.so
|
||||||
|
|
||||||
|
- name: '[lua-lgi] compile and install'
|
||||||
|
become: true
|
||||||
|
ansible.builtin.command:
|
||||||
|
chdir: /opt/git/foss/lua-lgi
|
||||||
|
cmd: make install
|
||||||
|
creates: /usr/local/lib/lua/5.4/lgi/corelgilua51.so
|
||||||
|
|
||||||
|
- name: '[awesomewm] install window manager'
|
||||||
|
block:
|
||||||
|
- name: '[awesomewm] fetch source'
|
||||||
|
become: true
|
||||||
|
become_user: "{{ workstation_user_account }}"
|
||||||
|
ansible.builtin.git:
|
||||||
|
repo: https://github.com/awesomeWM/awesome.git
|
||||||
|
dest: /opt/git/foss/awesomeWM
|
||||||
|
force: false
|
||||||
|
register: repo_clone
|
||||||
|
failed_when:
|
||||||
|
- repo_clone.failed
|
||||||
|
- not 'Local modifications exist in the destination' in repo_clone.msg
|
||||||
|
|
||||||
|
- name: '[awesomewm] building project'
|
||||||
|
become: true
|
||||||
|
become_user: "{{ workstation_user_account }}"
|
||||||
|
ansible.builtin.command:
|
||||||
|
chdir: /opt/git/foss/awesomeWM
|
||||||
|
cmd: 'CMAKE_ARGS="-DWITH_DBUS=ON -DLUA_LIBRARY=/usr/lib/x86_64-linux-gnu/liblua5.4.so.0 -DLUA_INCLUDE_DIR=/usr/include/lua5.4" make'
|
||||||
|
creates: /opt/git/foss/awesomeWM/build
|
||||||
|
|
||||||
|
- name: '[awesomewm] building project'
|
||||||
|
become: true
|
||||||
|
ansible.builtin.command:
|
||||||
|
chdir: /opt/git/foss/awesomeWM
|
||||||
|
cmd: make install
|
||||||
|
creates: /usr/local/bin/awesome
|
||||||
|
|
||||||
|
- name: '[awesomewm] setup configuration'
|
||||||
|
become: true
|
||||||
|
become_user: "{{ workstation_user_account }}"
|
||||||
|
block:
|
||||||
|
- name: '[awesomewm] fetch copycats base'
|
||||||
|
ansible.builtin.git:
|
||||||
|
repo: https://github.com/lcpz/awesome-copycats.git
|
||||||
|
dest: "{{ getent_passwd[workstation_user_account][4] }}/.config/awesome"
|
||||||
|
depth: 1
|
||||||
|
recursive: true
|
||||||
|
force: false
|
||||||
|
- name: '[awesomewm] copy customization'
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: ../templates/.config/awesome/
|
||||||
|
dest: "{{ getent_passwd[workstation_user_account][4] }}/.config/awesome"
|
||||||
|
mode: '0640'
|
||||||
|
|
||||||
|
- name: '[home] copy X related configuration'
|
||||||
|
become: true
|
||||||
|
block:
|
||||||
|
- name: '[x11] xorg.conf'
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: ../templates/system/xorg.conf
|
||||||
|
dest: /etc/X11/xorg.conf
|
||||||
|
mode: '0640'
|
||||||
|
- name: '[x11] user .xsession'
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: ../templates/.xsession
|
||||||
|
dest: "{{ getent_passwd[workstation_user_account][4] }}/.xsession"
|
BIN
collections/ansible_collections/nullified/infrastructure/roles/workstation/templates/.config/awesome/background.png
(Stored with Git LFS)
Normal file
BIN
collections/ansible_collections/nullified/infrastructure/roles/workstation/templates/.config/awesome/background.png
(Stored with Git LFS)
Normal file
Binary file not shown.
|
@ -0,0 +1,138 @@
|
||||||
|
-------------------------------------------------
|
||||||
|
-- Battery Widget for Awesome Window Manager
|
||||||
|
-- Shows the battery status using the ACPI tool
|
||||||
|
-- More details could be found here:
|
||||||
|
-- https://github.com/streetturtle/awesome-wm-widgets/tree/master/battery-widget
|
||||||
|
|
||||||
|
-- @author Pavel Makhov
|
||||||
|
-- @copyright 2017 Pavel Makhov
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
local awful = require("awful")
|
||||||
|
local naughty = require("naughty")
|
||||||
|
local watch = require("awful.widget.watch")
|
||||||
|
local wibox = require("wibox")
|
||||||
|
|
||||||
|
-- acpi sample outputs
|
||||||
|
-- Battery 0: Discharging, 75%, 01:51:38 remaining
|
||||||
|
-- Battery 0: Charging, 53%, 00:57:43 until charged
|
||||||
|
|
||||||
|
local PATH_TO_ICONS = "/usr/share/icons/Arc/status/symbolic/"
|
||||||
|
local HOME = os.getenv("HOME")
|
||||||
|
|
||||||
|
local battery_widget = wibox.widget {
|
||||||
|
{
|
||||||
|
id = "icon",
|
||||||
|
widget = wibox.widget.imagebox,
|
||||||
|
resize = true
|
||||||
|
},
|
||||||
|
layout = wibox.container.margin(_, 0, 0, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Popup with battery info
|
||||||
|
-- One way of creating a pop-up notification - naughty.notify
|
||||||
|
local notification
|
||||||
|
local function show_battery_status()
|
||||||
|
awful.spawn.easy_async([[bash -c 'acpi']],
|
||||||
|
function(stdout, _, _, _)
|
||||||
|
naughty.destroy(notification)
|
||||||
|
notification = naughty.notify{
|
||||||
|
text = stdout,
|
||||||
|
title = "Battery status",
|
||||||
|
timeout = 5, hover_timeout = 0.5,
|
||||||
|
width = 200,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Alternative to naughty.notify - tooltip. You can compare both and choose the preferred one
|
||||||
|
--battery_popup = awful.tooltip({objects = {battery_widget}})
|
||||||
|
|
||||||
|
-- To use colors from beautiful theme put
|
||||||
|
-- following lines in rc.lua before require("battery"):
|
||||||
|
-- beautiful.tooltip_fg = beautiful.fg_normal
|
||||||
|
-- beautiful.tooltip_bg = beautiful.bg_normal
|
||||||
|
|
||||||
|
local function show_battery_warning()
|
||||||
|
naughty.notify{
|
||||||
|
-- icon = HOME .. "/.config/awesome/nichosi.png",
|
||||||
|
-- icon_size=100,
|
||||||
|
text = "Huston, we have a problem",
|
||||||
|
title = "Battery is dying",
|
||||||
|
timeout = 5, hover_timeout = 0.5,
|
||||||
|
position = "bottom_right",
|
||||||
|
bg = "#F06060",
|
||||||
|
fg = "#EEE9EF",
|
||||||
|
width = 300,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local last_battery_check = os.time()
|
||||||
|
|
||||||
|
watch("acpi -i", 10,
|
||||||
|
function(widget, stdout, stderr, exitreason, exitcode)
|
||||||
|
local batteryType
|
||||||
|
|
||||||
|
local battery_info = {}
|
||||||
|
local capacities = {}
|
||||||
|
for s in stdout:gmatch("[^\r\n]+") do
|
||||||
|
local status, charge_str, time = string.match(s, '.+: (%a+), (%d?%d?%d)%%,?.*')
|
||||||
|
if string.match(s, 'rate information') then
|
||||||
|
-- ignore such line
|
||||||
|
elseif status ~= nil then
|
||||||
|
table.insert(battery_info, {status = status, charge = tonumber(charge_str)})
|
||||||
|
else
|
||||||
|
local cap_str = string.match(s, '.+:.+last full capacity (%d+)')
|
||||||
|
table.insert(capacities, tonumber(cap_str))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local capacity = 0
|
||||||
|
for i, cap in ipairs(capacities) do
|
||||||
|
capacity = capacity + cap
|
||||||
|
end
|
||||||
|
|
||||||
|
local charge = 0
|
||||||
|
local status
|
||||||
|
for i, batt in ipairs(battery_info) do
|
||||||
|
if batt.charge >= charge then
|
||||||
|
status = batt.status -- use most charged battery status
|
||||||
|
-- this is arbitrary, and maybe another metric should be used
|
||||||
|
end
|
||||||
|
|
||||||
|
charge = charge + batt.charge * capacities[i]
|
||||||
|
end
|
||||||
|
charge = charge / capacity
|
||||||
|
|
||||||
|
if (charge >= 0 and charge < 15) then
|
||||||
|
batteryType = "battery-empty%s-symbolic"
|
||||||
|
if status ~= 'Charging' and os.difftime(os.time(), last_battery_check) > 300 then
|
||||||
|
-- if 5 minutes have elapsed since the last warning
|
||||||
|
last_battery_check = time()
|
||||||
|
|
||||||
|
show_battery_warning()
|
||||||
|
end
|
||||||
|
elseif (charge >= 15 and charge < 40) then batteryType = "battery-caution%s-symbolic"
|
||||||
|
elseif (charge >= 40 and charge < 60) then batteryType = "battery-low%s-symbolic"
|
||||||
|
elseif (charge >= 60 and charge < 80) then batteryType = "battery-good%s-symbolic"
|
||||||
|
elseif (charge >= 80 and charge <= 100) then batteryType = "battery-full%s-symbolic"
|
||||||
|
end
|
||||||
|
|
||||||
|
if status == 'Charging' then
|
||||||
|
batteryType = string.format(batteryType, '-charging')
|
||||||
|
else
|
||||||
|
batteryType = string.format(batteryType, '')
|
||||||
|
end
|
||||||
|
|
||||||
|
widget.icon:set_image(PATH_TO_ICONS .. batteryType .. ".svg")
|
||||||
|
|
||||||
|
-- Update popup text
|
||||||
|
-- battery_popup.text = string.gsub(stdout, "\n$", "")
|
||||||
|
end,
|
||||||
|
battery_widget)
|
||||||
|
|
||||||
|
battery_widget:connect_signal("mouse::enter", function() show_battery_status() end)
|
||||||
|
battery_widget:connect_signal("mouse::leave", function() naughty.destroy(notification) end)
|
||||||
|
|
||||||
|
return battery_widget
|
|
@ -0,0 +1,759 @@
|
||||||
|
--[[
|
||||||
|
|
||||||
|
Awesome WM configuration template
|
||||||
|
github.com/lcpz
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
-- {{{ Required libraries
|
||||||
|
local awesome, client, mouse, screen, tag = awesome, client, mouse, screen, tag
|
||||||
|
local ipairs, string, os, table, tostring, tonumber, type = ipairs, string, os, table, tostring, tonumber, type
|
||||||
|
|
||||||
|
local gears = require("gears")
|
||||||
|
local awful = require("awful")
|
||||||
|
require("awful.autofocus")
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local beautiful = require("beautiful")
|
||||||
|
local naughty = require("naughty")
|
||||||
|
local lain = require("lain")
|
||||||
|
local menubar = require("menubar")
|
||||||
|
local freedesktop = require("freedesktop")
|
||||||
|
local hotkeys_popup = require("awful.hotkeys_popup").widget
|
||||||
|
require("awful.hotkeys_popup.keys")
|
||||||
|
local my_table = awful.util.table or gears.table -- 4.{0,1} compatibility
|
||||||
|
local dpi = require("beautiful.xresources").apply_dpi
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
-- {{{ Error handling
|
||||||
|
-- Check if awesome encountered an error during startup and fell back to
|
||||||
|
-- another config (This code will only ever execute for the fallback config)
|
||||||
|
if awesome.startup_errors then
|
||||||
|
naughty.notify({ preset = naughty.config.presets.critical,
|
||||||
|
title = "Oops, there were errors during startup!",
|
||||||
|
text = awesome.startup_errors })
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Handle runtime errors after startup
|
||||||
|
do
|
||||||
|
local in_error = false
|
||||||
|
awesome.connect_signal("debug::error", function (err)
|
||||||
|
if in_error then return end
|
||||||
|
in_error = true
|
||||||
|
|
||||||
|
naughty.notify({ preset = naughty.config.presets.critical,
|
||||||
|
title = "Oops, an error happened!",
|
||||||
|
text = tostring(err) })
|
||||||
|
in_error = false
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
-- {{{ Autostart windowless processes
|
||||||
|
|
||||||
|
-- This function will run once every time Awesome is started
|
||||||
|
local function run_once(cmd_arr)
|
||||||
|
for _, cmd in ipairs(cmd_arr) do
|
||||||
|
awful.spawn.with_shell(string.format("pgrep -u $USER -fx '%s' > /dev/null || (%s)", cmd, cmd))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
run_once({ "unclutter -root", os.getenv("HOME") .. "/bin/autorun.sh" }) -- entries must be separated by commas
|
||||||
|
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
-- {{{ Variable definitions
|
||||||
|
|
||||||
|
local themes = {
|
||||||
|
"blackburn", -- 1
|
||||||
|
"copland", -- 2
|
||||||
|
"dremora", -- 3
|
||||||
|
"holo", -- 4
|
||||||
|
"multicolor", -- 5
|
||||||
|
"powerarrow", -- 6
|
||||||
|
"powerarrow-dark", -- 7
|
||||||
|
"rainbow", -- 8
|
||||||
|
"steamburn", -- 9
|
||||||
|
"vertex", -- 10
|
||||||
|
}
|
||||||
|
|
||||||
|
local chosen_theme = themes[6]
|
||||||
|
local modkey = "Mod4"
|
||||||
|
local altkey = "Mod1"
|
||||||
|
local terminal = "terminator"
|
||||||
|
local vi_focus = false -- vi-like client focus - https://github.com/lcpz/awesome-copycats/issues/275
|
||||||
|
local cycle_prev = true -- cycle trough all previous client or just the first -- https://github.com/lcpz/awesome-copycats/issues/274
|
||||||
|
local editor = os.getenv("EDITOR") or "emacs"
|
||||||
|
local gui_editor = os.getenv("GUI_EDITOR") or "gvim"
|
||||||
|
local browser = os.getenv("BROWSER") or "firefox"
|
||||||
|
local scrshooter = os.getenv("SCREENSHOOTER") or "xfce4-screenshooter"
|
||||||
|
local scrlocker = "slock"
|
||||||
|
|
||||||
|
awful.util.terminal = terminal
|
||||||
|
awful.util.tagnames = { "Web", "Dev", "Admin", "Media" }
|
||||||
|
awful.layout.layouts = {
|
||||||
|
awful.layout.suit.tile,
|
||||||
|
awful.layout.suit.fair,
|
||||||
|
lain.layout.centerwork
|
||||||
|
--awful.layout.suit.floating,
|
||||||
|
--awful.layout.suit.tile.left,
|
||||||
|
--awful.layout.suit.tile.bottom,
|
||||||
|
--awful.layout.suit.tile.top,
|
||||||
|
--awful.layout.suit.fair,
|
||||||
|
--awful.layout.suit.fair.horizontal,
|
||||||
|
--awful.layout.suit.spiral,
|
||||||
|
--awful.layout.suit.spiral.dwindle,
|
||||||
|
--awful.layout.suit.max,
|
||||||
|
--awful.layout.suit.max.fullscreen,
|
||||||
|
--awful.layout.suit.magnifier,
|
||||||
|
--awful.layout.suit.corner.nw,
|
||||||
|
--awful.layout.suit.corner.ne,
|
||||||
|
--awful.layout.suit.corner.sw,
|
||||||
|
--awful.layout.suit.corner.se,
|
||||||
|
--lain.layout.cascade,
|
||||||
|
--lain.layout.cascade.tile,
|
||||||
|
--lain.layout.centerwork,
|
||||||
|
--lain.layout.centerwork.horizontal,
|
||||||
|
--lain.layout.termfair,
|
||||||
|
--lain.layout.termfair.center,
|
||||||
|
}
|
||||||
|
|
||||||
|
awful.util.taglist_buttons = my_table.join(
|
||||||
|
awful.button({ }, 1, function(t) t:view_only() end),
|
||||||
|
awful.button({ modkey }, 1, function(t)
|
||||||
|
if client.focus then
|
||||||
|
client.focus:move_to_tag(t)
|
||||||
|
end
|
||||||
|
end),
|
||||||
|
awful.button({ }, 3, awful.tag.viewtoggle),
|
||||||
|
awful.button({ modkey }, 3, function(t)
|
||||||
|
if client.focus then
|
||||||
|
client.focus:toggle_tag(t)
|
||||||
|
end
|
||||||
|
end),
|
||||||
|
awful.button({ }, 4, function(t) awful.tag.viewnext(t.screen) end),
|
||||||
|
awful.button({ }, 5, function(t) awful.tag.viewprev(t.screen) end)
|
||||||
|
)
|
||||||
|
|
||||||
|
awful.util.tasklist_buttons = my_table.join(
|
||||||
|
awful.button({ }, 1, function (c)
|
||||||
|
if c == client.focus then
|
||||||
|
c.minimized = true
|
||||||
|
else
|
||||||
|
--c:emit_signal("request::activate", "tasklist", {raise = true})<Paste>
|
||||||
|
|
||||||
|
-- Without this, the following
|
||||||
|
-- :isvisible() makes no sense
|
||||||
|
c.minimized = false
|
||||||
|
if not c:isvisible() and c.first_tag then
|
||||||
|
c.first_tag:view_only()
|
||||||
|
end
|
||||||
|
-- This will also un-minimize
|
||||||
|
-- the client, if needed
|
||||||
|
client.focus = c
|
||||||
|
c:raise()
|
||||||
|
end
|
||||||
|
end),
|
||||||
|
awful.button({ }, 2, function (c) c:kill() end),
|
||||||
|
awful.button({ }, 3, function ()
|
||||||
|
local instance = nil
|
||||||
|
|
||||||
|
return function ()
|
||||||
|
if instance and instance.wibox.visible then
|
||||||
|
instance:hide()
|
||||||
|
instance = nil
|
||||||
|
else
|
||||||
|
instance = awful.menu.clients({theme = {width = dpi(250)}})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end),
|
||||||
|
awful.button({ }, 4, function () awful.client.focus.byidx(1) end),
|
||||||
|
awful.button({ }, 5, function () awful.client.focus.byidx(-1) end)
|
||||||
|
)
|
||||||
|
|
||||||
|
lain.layout.termfair.nmaster = 3
|
||||||
|
lain.layout.termfair.ncol = 1
|
||||||
|
lain.layout.termfair.center.nmaster = 3
|
||||||
|
lain.layout.termfair.center.ncol = 1
|
||||||
|
lain.layout.cascade.tile.offset_x = dpi(2)
|
||||||
|
lain.layout.cascade.tile.offset_y = dpi(32)
|
||||||
|
lain.layout.cascade.tile.extra_padding = dpi(5)
|
||||||
|
lain.layout.cascade.tile.nmaster = 5
|
||||||
|
lain.layout.cascade.tile.ncol = 2
|
||||||
|
|
||||||
|
beautiful.init(string.format("%s/.config/awesome/themes/%s/theme-personal.lua", os.getenv("HOME"), chosen_theme))
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
-- {{{ Menu
|
||||||
|
local myawesomemenu = {
|
||||||
|
{ "hotkeys", function() return false, hotkeys_popup.show_help end },
|
||||||
|
{ "manual", terminal .. " -e man awesome" },
|
||||||
|
{ "edit config", string.format("%s -e %s %s", terminal, editor, awesome.conffile) },
|
||||||
|
{ "restart", awesome.restart },
|
||||||
|
{ "quit", function() awesome.quit() end }
|
||||||
|
}
|
||||||
|
awful.util.mymainmenu = freedesktop.menu.build({
|
||||||
|
icon_size = beautiful.menu_height or dpi(16),
|
||||||
|
before = {
|
||||||
|
{ "Awesome", myawesomemenu, beautiful.awesome_icon },
|
||||||
|
-- other triads can be put here
|
||||||
|
},
|
||||||
|
after = {
|
||||||
|
{ "Open terminal", terminal },
|
||||||
|
-- other triads can be put here
|
||||||
|
}
|
||||||
|
})
|
||||||
|
-- hide menu when mouse leaves it
|
||||||
|
--awful.util.mymainmenu.wibox:connect_signal("mouse::leave", function() awful.util.mymainmenu:hide() end)
|
||||||
|
|
||||||
|
menubar.utils.terminal = terminal -- Set the Menubar terminal for applications that require it
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
-- {{{ Screen
|
||||||
|
-- Re-set wallpaper when a screen's geometry changes (e.g. different resolution)
|
||||||
|
screen.connect_signal("property::geometry", function(s)
|
||||||
|
-- Wallpaper
|
||||||
|
if beautiful.wallpaper then
|
||||||
|
local wallpaper = beautiful.wallpaper
|
||||||
|
-- If wallpaper is a function, call it with the screen
|
||||||
|
if type(wallpaper) == "function" then
|
||||||
|
wallpaper = wallpaper(s)
|
||||||
|
end
|
||||||
|
gears.wallpaper.maximized(wallpaper, s, true)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- No borders when rearranging only 1 non-floating or maximized client
|
||||||
|
screen.connect_signal("arrange", function (s)
|
||||||
|
local only_one = #s.tiled_clients == 1
|
||||||
|
for _, c in pairs(s.clients) do
|
||||||
|
if only_one and not c.floating or c.maximized then
|
||||||
|
c.border_width = 0
|
||||||
|
else
|
||||||
|
c.border_width = beautiful.border_width
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
-- Create a wibox for each screen and add it
|
||||||
|
awful.screen.connect_for_each_screen(function(s) beautiful.at_screen_connect(s) end)
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
-- {{{ Mouse bindings
|
||||||
|
root.buttons(my_table.join(
|
||||||
|
awful.button({ }, 3, function () awful.util.mymainmenu:toggle() end),
|
||||||
|
awful.button({ }, 4, awful.tag.viewnext),
|
||||||
|
awful.button({ }, 5, awful.tag.viewprev)
|
||||||
|
))
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
-- {{{ Key bindings
|
||||||
|
globalkeys = my_table.join(
|
||||||
|
-- X screen locker
|
||||||
|
awful.key({ altkey, "Control" }, "l", function () awful.spawn(scrlocker) end,
|
||||||
|
{description = "lock screen", group = "hotkeys"}),
|
||||||
|
|
||||||
|
-- Hotkeys
|
||||||
|
awful.key({ modkey, }, "s", hotkeys_popup.show_help,
|
||||||
|
{description = "show help", group="awesome"}),
|
||||||
|
-- Tag browsing
|
||||||
|
awful.key({ modkey, }, "Left", awful.tag.viewprev,
|
||||||
|
{description = "view previous", group = "tag"}),
|
||||||
|
awful.key({ modkey, }, "Right", awful.tag.viewnext,
|
||||||
|
{description = "view next", group = "tag"}),
|
||||||
|
awful.key({ modkey, }, "Escape", awful.tag.history.restore,
|
||||||
|
{description = "go back", group = "tag"}),
|
||||||
|
|
||||||
|
-- Non-empty tag browsing
|
||||||
|
awful.key({ altkey }, "Left", function () lain.util.tag_view_nonempty(-1) end,
|
||||||
|
{description = "view previous nonempty", group = "tag"}),
|
||||||
|
awful.key({ altkey }, "Right", function () lain.util.tag_view_nonempty(1) end,
|
||||||
|
{description = "view previous nonempty", group = "tag"}),
|
||||||
|
|
||||||
|
-- Default client focus
|
||||||
|
awful.key({ altkey, }, "j",
|
||||||
|
function ()
|
||||||
|
awful.client.focus.byidx( 1)
|
||||||
|
end,
|
||||||
|
{description = "focus next by index", group = "client"}
|
||||||
|
),
|
||||||
|
awful.key({ altkey, }, "k",
|
||||||
|
function ()
|
||||||
|
awful.client.focus.byidx(-1)
|
||||||
|
end,
|
||||||
|
{description = "focus previous by index", group = "client"}
|
||||||
|
),
|
||||||
|
|
||||||
|
-- By direction client focus
|
||||||
|
awful.key({ modkey }, "j",
|
||||||
|
function()
|
||||||
|
awful.client.focus.global_bydirection("down")
|
||||||
|
if client.focus then client.focus:raise() end
|
||||||
|
end,
|
||||||
|
{description = "focus down", group = "client"}),
|
||||||
|
awful.key({ modkey }, "k",
|
||||||
|
function()
|
||||||
|
awful.client.focus.global_bydirection("up")
|
||||||
|
if client.focus then client.focus:raise() end
|
||||||
|
end,
|
||||||
|
{description = "focus up", group = "client"}),
|
||||||
|
awful.key({ modkey }, "h",
|
||||||
|
function()
|
||||||
|
awful.client.focus.global_bydirection("left")
|
||||||
|
if client.focus then client.focus:raise() end
|
||||||
|
end,
|
||||||
|
{description = "focus left", group = "client"}),
|
||||||
|
awful.key({ modkey }, "l",
|
||||||
|
function()
|
||||||
|
awful.client.focus.global_bydirection("right")
|
||||||
|
if client.focus then client.focus:raise() end
|
||||||
|
end,
|
||||||
|
{description = "focus right", group = "client"}),
|
||||||
|
awful.key({ modkey, }, "w", function () awful.util.mymainmenu:show() end,
|
||||||
|
{description = "show main menu", group = "awesome"}),
|
||||||
|
|
||||||
|
-- Layout manipulation
|
||||||
|
awful.key({ modkey, "Shift" }, "j", function () awful.client.swap.byidx( 1) end,
|
||||||
|
{description = "swap with next client by index", group = "client"}),
|
||||||
|
awful.key({ modkey, "Shift" }, "k", function () awful.client.swap.byidx( -1) end,
|
||||||
|
{description = "swap with previous client by index", group = "client"}),
|
||||||
|
awful.key({ modkey, "Control" }, "j", function () awful.screen.focus_relative( 1) end,
|
||||||
|
{description = "focus the next screen", group = "screen"}),
|
||||||
|
awful.key({ modkey, "Control" }, "k", function () awful.screen.focus_relative(-1) end,
|
||||||
|
{description = "focus the previous screen", group = "screen"}),
|
||||||
|
awful.key({ modkey, }, "u", awful.client.urgent.jumpto,
|
||||||
|
{description = "jump to urgent client", group = "client"}),
|
||||||
|
awful.key({ modkey, }, "Tab",
|
||||||
|
function ()
|
||||||
|
if cycle_prev then
|
||||||
|
awful.client.focus.history.previous()
|
||||||
|
else
|
||||||
|
awful.client.focus.byidx(-1)
|
||||||
|
end
|
||||||
|
if client.focus then
|
||||||
|
client.focus:raise()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
{description = "cycle with previous/go back", group = "client"}),
|
||||||
|
awful.key({ modkey, "Shift" }, "Tab",
|
||||||
|
function ()
|
||||||
|
if cycle_prev then
|
||||||
|
awful.client.focus.byidx(1)
|
||||||
|
if client.focus then
|
||||||
|
client.focus:raise()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
{description = "go forth", group = "client"}),
|
||||||
|
|
||||||
|
-- Show/Hide Wibox
|
||||||
|
awful.key({ modkey }, "b", function ()
|
||||||
|
for s in screen do
|
||||||
|
s.mywibox.visible = not s.mywibox.visible
|
||||||
|
if s.mybottomwibox then
|
||||||
|
s.mybottomwibox.visible = not s.mybottomwibox.visible
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
{description = "toggle wibox", group = "awesome"}),
|
||||||
|
|
||||||
|
-- On the fly useless gaps change
|
||||||
|
awful.key({ altkey, "Control" }, "+", function () lain.util.useless_gaps_resize(1) end,
|
||||||
|
{description = "increment useless gaps", group = "tag"}),
|
||||||
|
awful.key({ altkey, "Control" }, "-", function () lain.util.useless_gaps_resize(-1) end,
|
||||||
|
{description = "decrement useless gaps", group = "tag"}),
|
||||||
|
|
||||||
|
-- Dynamic tagging
|
||||||
|
awful.key({ modkey, "Shift" }, "n", function () lain.util.add_tag() end,
|
||||||
|
{description = "add new tag", group = "tag"}),
|
||||||
|
awful.key({ modkey, "Shift" }, "r", function () lain.util.rename_tag() end,
|
||||||
|
{description = "rename tag", group = "tag"}),
|
||||||
|
awful.key({ modkey, "Shift" }, "Left", function () lain.util.move_tag(-1) end,
|
||||||
|
{description = "move tag to the left", group = "tag"}),
|
||||||
|
awful.key({ modkey, "Shift" }, "Right", function () lain.util.move_tag(1) end,
|
||||||
|
{description = "move tag to the right", group = "tag"}),
|
||||||
|
awful.key({ modkey, "Shift" }, "d", function () lain.util.delete_tag() end,
|
||||||
|
{description = "delete tag", group = "tag"}),
|
||||||
|
|
||||||
|
-- Standard program
|
||||||
|
awful.key({ modkey, }, "Return", function () awful.spawn(terminal) end,
|
||||||
|
{description = "open a terminal", group = "launcher"}),
|
||||||
|
awful.key({ modkey, "Control" }, "r", awesome.restart,
|
||||||
|
{description = "reload awesome", group = "awesome"}),
|
||||||
|
awful.key({ modkey, "Shift" }, "q", awesome.quit,
|
||||||
|
{description = "quit awesome", group = "awesome"}),
|
||||||
|
|
||||||
|
awful.key({ altkey, "Shift" }, "l", function () awful.tag.incmwfact( 0.05) end,
|
||||||
|
{description = "increase master width factor", group = "layout"}),
|
||||||
|
awful.key({ altkey, "Shift" }, "h", function () awful.tag.incmwfact(-0.05) end,
|
||||||
|
{description = "decrease master width factor", group = "layout"}),
|
||||||
|
awful.key({ modkey, "Shift" }, "h", function () awful.tag.incnmaster( 1, nil, true) end,
|
||||||
|
{description = "increase the number of master clients", group = "layout"}),
|
||||||
|
awful.key({ modkey, "Shift" }, "l", function () awful.tag.incnmaster(-1, nil, true) end,
|
||||||
|
{description = "decrease the number of master clients", group = "layout"}),
|
||||||
|
awful.key({ modkey, "Control" }, "h", function () awful.tag.incncol( 1, nil, true) end,
|
||||||
|
{description = "increase the number of columns", group = "layout"}),
|
||||||
|
awful.key({ modkey, "Control" }, "l", function () awful.tag.incncol(-1, nil, true) end,
|
||||||
|
{description = "decrease the number of columns", group = "layout"}),
|
||||||
|
awful.key({ modkey, }, "space", function () awful.layout.inc( 1) end,
|
||||||
|
{description = "select next", group = "layout"}),
|
||||||
|
awful.key({ modkey, "Shift" }, "space", function () awful.layout.inc(-1) end,
|
||||||
|
{description = "select previous", group = "layout"}),
|
||||||
|
|
||||||
|
awful.key({ modkey, "Control" }, "n",
|
||||||
|
function ()
|
||||||
|
local c = awful.client.restore()
|
||||||
|
-- Focus restored client
|
||||||
|
if c then
|
||||||
|
client.focus = c
|
||||||
|
c:raise()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
{description = "restore minimized", group = "client"}),
|
||||||
|
|
||||||
|
-- Dropdown application
|
||||||
|
awful.key({ modkey, }, "z", function () awful.screen.focused().quake:toggle() end,
|
||||||
|
{description = "dropdown application", group = "launcher"}),
|
||||||
|
|
||||||
|
-- Widgets popups
|
||||||
|
awful.key({ altkey, }, "c", function () if beautiful.cal then beautiful.cal.show(7) end end,
|
||||||
|
{description = "show calendar", group = "widgets"}),
|
||||||
|
awful.key({ altkey, }, "h", function () if beautiful.fs then beautiful.fs.show(7) end end,
|
||||||
|
{description = "show filesystem", group = "widgets"}),
|
||||||
|
awful.key({ altkey, }, "w", function () if beautiful.weather then beautiful.weather.show(7) end end,
|
||||||
|
{description = "show weather", group = "widgets"}),
|
||||||
|
|
||||||
|
-- Brightness
|
||||||
|
awful.key({ }, "XF86MonBrightnessUp", function () awful.spawn("xbacklight -inc 10") end,
|
||||||
|
{description = "+10%", group = "hotkeys"}),
|
||||||
|
awful.key({ }, "XF86MonBrightnessDown", function () awful.spawn("xbacklight -dec 10") end,
|
||||||
|
{description = "-10%", group = "hotkeys"}),
|
||||||
|
|
||||||
|
-- ALSA volume control
|
||||||
|
awful.key({ altkey }, "Up",
|
||||||
|
function ()
|
||||||
|
awful.spawn(string.format("amixer -q set %s 1%%+", beautiful.volume.channel))
|
||||||
|
beautiful.volume.update()
|
||||||
|
end,
|
||||||
|
{description = "volume up", group = "hotkeys"}),
|
||||||
|
awful.key({ altkey }, "Down",
|
||||||
|
function ()
|
||||||
|
awful.spawn(string.format("amixer -q set %s 1%%-", beautiful.volume.channel))
|
||||||
|
beautiful.volume.update()
|
||||||
|
end,
|
||||||
|
{description = "volume down", group = "hotkeys"}),
|
||||||
|
awful.key({ altkey }, "m",
|
||||||
|
function ()
|
||||||
|
awful.spawn(string.format("amixer -q set %s toggle", beautiful.volume.togglechannel or beautiful.volume.channel))
|
||||||
|
beautiful.volume.update()
|
||||||
|
end,
|
||||||
|
{description = "toggle mute", group = "hotkeys"}),
|
||||||
|
awful.key({ altkey, "Control" }, "m",
|
||||||
|
function ()
|
||||||
|
awful.spawn(string.format("amixer -q set %s 100%%", beautiful.volume.channel))
|
||||||
|
beautiful.volume.update()
|
||||||
|
end,
|
||||||
|
{description = "volume 100%", group = "hotkeys"}),
|
||||||
|
awful.key({ altkey, "Control" }, "0",
|
||||||
|
function ()
|
||||||
|
awful.spawn(string.format("amixer -q set %s 0%%", beautiful.volume.channel))
|
||||||
|
beautiful.volume.update()
|
||||||
|
end,
|
||||||
|
{description = "volume 0%", group = "hotkeys"}),
|
||||||
|
|
||||||
|
-- MPD control
|
||||||
|
awful.key({ altkey, "Control" }, "Up",
|
||||||
|
function ()
|
||||||
|
awful.spawn("mpc toggle")
|
||||||
|
beautiful.mpd.update()
|
||||||
|
end,
|
||||||
|
{description = "mpc toggle", group = "widgets"}),
|
||||||
|
awful.key({ altkey, "Control" }, "Down",
|
||||||
|
function ()
|
||||||
|
awful.spawn("mpc stop")
|
||||||
|
beautiful.mpd.update()
|
||||||
|
end,
|
||||||
|
{description = "mpc stop", group = "widgets"}),
|
||||||
|
awful.key({ altkey, "Control" }, "Left",
|
||||||
|
function ()
|
||||||
|
awful.spawn("mpc prev")
|
||||||
|
beautiful.mpd.update()
|
||||||
|
end,
|
||||||
|
{description = "mpc prev", group = "widgets"}),
|
||||||
|
awful.key({ altkey, "Control" }, "Right",
|
||||||
|
function ()
|
||||||
|
awful.spawn("mpc next")
|
||||||
|
beautiful.mpd.update()
|
||||||
|
end,
|
||||||
|
{description = "mpc next", group = "widgets"}),
|
||||||
|
awful.key({ altkey }, "0",
|
||||||
|
function ()
|
||||||
|
local common = { text = "MPD widget ", position = "top_middle", timeout = 2 }
|
||||||
|
if beautiful.mpd.timer.started then
|
||||||
|
beautiful.mpd.timer:stop()
|
||||||
|
common.text = common.text .. lain.util.markup.bold("OFF")
|
||||||
|
else
|
||||||
|
beautiful.mpd.timer:start()
|
||||||
|
common.text = common.text .. lain.util.markup.bold("ON")
|
||||||
|
end
|
||||||
|
naughty.notify(common)
|
||||||
|
end,
|
||||||
|
{description = "mpc on/off", group = "widgets"}),
|
||||||
|
|
||||||
|
-- Copy primary to clipboard (terminals to gtk)
|
||||||
|
awful.key({ modkey }, "c", function () awful.spawn.with_shell("xsel | xsel -i -b") end,
|
||||||
|
{description = "copy terminal to gtk", group = "hotkeys"}),
|
||||||
|
-- Copy clipboard to primary (gtk to terminals)
|
||||||
|
awful.key({ modkey }, "v", function () awful.spawn.with_shell("xsel -b | xsel") end,
|
||||||
|
{description = "copy gtk to terminal", group = "hotkeys"}),
|
||||||
|
|
||||||
|
-- User programs
|
||||||
|
awful.key({ modkey }, "q", function () awful.spawn(browser) end,
|
||||||
|
{description = "run browser", group = "launcher"}),
|
||||||
|
awful.key({ modkey }, "a", function () awful.spawn(gui_editor) end,
|
||||||
|
{description = "run gui editor", group = "launcher"}),
|
||||||
|
awful.key({ }, "Print", function () awful.spawn(scrshooter) end,
|
||||||
|
{description = "run screenshot program", group = "hotkeys"}),
|
||||||
|
-- Menubar
|
||||||
|
awful.key({ modkey }, "p", function() menubar.show() end,
|
||||||
|
{description = "show the menubar", group = "launcher"}),
|
||||||
|
-- Prompt
|
||||||
|
awful.key({ modkey }, "r", function () awful.screen.focused().mypromptbox:run() end,
|
||||||
|
{description = "run prompt", group = "launcher"}),
|
||||||
|
|
||||||
|
awful.key({ modkey }, "x",
|
||||||
|
function ()
|
||||||
|
awful.prompt.run {
|
||||||
|
prompt = "Run Lua code: ",
|
||||||
|
textbox = awful.screen.focused().mypromptbox.widget,
|
||||||
|
exe_callback = awful.util.eval,
|
||||||
|
history_path = awful.util.get_cache_dir() .. "/history_eval"
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
{description = "lua execute prompt", group = "awesome"})
|
||||||
|
--
|
||||||
|
)
|
||||||
|
|
||||||
|
clientkeys = my_table.join(
|
||||||
|
awful.key({ altkey, "Shift" }, "m", lain.util.magnify_client,
|
||||||
|
{description = "magnify client", group = "client"}),
|
||||||
|
awful.key({ modkey, }, "f",
|
||||||
|
function (c)
|
||||||
|
c.fullscreen = not c.fullscreen
|
||||||
|
c:raise()
|
||||||
|
end,
|
||||||
|
{description = "toggle fullscreen", group = "client"}),
|
||||||
|
awful.key({ modkey, "Shift" }, "c", function (c) c:kill() end,
|
||||||
|
{description = "close", group = "client"}),
|
||||||
|
awful.key({ modkey, "Control" }, "space", awful.client.floating.toggle ,
|
||||||
|
{description = "toggle floating", group = "client"}),
|
||||||
|
awful.key({ modkey, "Control" }, "Return", function (c) c:swap(awful.client.getmaster()) end,
|
||||||
|
{description = "move to master", group = "client"}),
|
||||||
|
awful.key({ modkey, }, "o", function (c) c:move_to_screen() end,
|
||||||
|
{description = "move to screen", group = "client"}),
|
||||||
|
awful.key({ modkey, }, "t", function (c) c.ontop = not c.ontop end,
|
||||||
|
{description = "toggle keep on top", group = "client"}),
|
||||||
|
awful.key({ modkey, }, "n",
|
||||||
|
function (c)
|
||||||
|
-- The client currently has the input focus, so it cannot be
|
||||||
|
-- minimized, since minimized clients can't have the focus.
|
||||||
|
c.minimized = true
|
||||||
|
end ,
|
||||||
|
{description = "minimize", group = "client"}),
|
||||||
|
awful.key({ modkey, }, "m",
|
||||||
|
function (c)
|
||||||
|
c.maximized = not c.maximized
|
||||||
|
c:raise()
|
||||||
|
end ,
|
||||||
|
{description = "maximize", group = "client"})
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Bind all key numbers to tags.
|
||||||
|
-- Be careful: we use keycodes to make it works on any keyboard layout.
|
||||||
|
-- This should map on the top row of your keyboard, usually 1 to 9.
|
||||||
|
for i = 1, 9 do
|
||||||
|
-- Hack to only show tags 1 and 9 in the shortcut window (mod+s)
|
||||||
|
local descr_view, descr_toggle, descr_move, descr_toggle_focus
|
||||||
|
if i == 1 or i == 9 then
|
||||||
|
descr_view = {description = "view tag #", group = "tag"}
|
||||||
|
descr_toggle = {description = "toggle tag #", group = "tag"}
|
||||||
|
descr_move = {description = "move focused client to tag #", group = "tag"}
|
||||||
|
descr_toggle_focus = {description = "toggle focused client on tag #", group = "tag"}
|
||||||
|
end
|
||||||
|
globalkeys = my_table.join(globalkeys,
|
||||||
|
-- View tag only.
|
||||||
|
awful.key({ modkey }, "#" .. i + 9,
|
||||||
|
function ()
|
||||||
|
local screen = awful.screen.focused()
|
||||||
|
local tag = screen.tags[i]
|
||||||
|
if tag then
|
||||||
|
tag:view_only()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
descr_view),
|
||||||
|
-- Toggle tag display.
|
||||||
|
awful.key({ modkey, "Control" }, "#" .. i + 9,
|
||||||
|
function ()
|
||||||
|
local screen = awful.screen.focused()
|
||||||
|
local tag = screen.tags[i]
|
||||||
|
if tag then
|
||||||
|
awful.tag.viewtoggle(tag)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
descr_toggle),
|
||||||
|
-- Move client to tag.
|
||||||
|
awful.key({ modkey, "Shift" }, "#" .. i + 9,
|
||||||
|
function ()
|
||||||
|
if client.focus then
|
||||||
|
local tag = client.focus.screen.tags[i]
|
||||||
|
if tag then
|
||||||
|
client.focus:move_to_tag(tag)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
descr_move),
|
||||||
|
-- Toggle tag on focused client.
|
||||||
|
awful.key({ modkey, "Control", "Shift" }, "#" .. i + 9,
|
||||||
|
function ()
|
||||||
|
if client.focus then
|
||||||
|
local tag = client.focus.screen.tags[i]
|
||||||
|
if tag then
|
||||||
|
client.focus:toggle_tag(tag)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
descr_toggle_focus)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
clientbuttons = gears.table.join(
|
||||||
|
awful.button({ }, 1, function (c)
|
||||||
|
c:emit_signal("request::activate", "mouse_click", {raise = true})
|
||||||
|
end),
|
||||||
|
awful.button({ modkey }, 1, function (c)
|
||||||
|
c:emit_signal("request::activate", "mouse_click", {raise = true})
|
||||||
|
awful.mouse.client.move(c)
|
||||||
|
end),
|
||||||
|
awful.button({ modkey }, 3, function (c)
|
||||||
|
c:emit_signal("request::activate", "mouse_click", {raise = true})
|
||||||
|
awful.mouse.client.resize(c)
|
||||||
|
end)
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Set keys
|
||||||
|
root.keys(globalkeys)
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
-- {{{ Rules
|
||||||
|
-- Rules to apply to new clients (through the "manage" signal).
|
||||||
|
awful.rules.rules = {
|
||||||
|
-- All clients will match this rule.
|
||||||
|
{ rule = { },
|
||||||
|
properties = { border_width = beautiful.border_width,
|
||||||
|
border_color = beautiful.border_normal,
|
||||||
|
focus = awful.client.focus.filter,
|
||||||
|
raise = true,
|
||||||
|
keys = clientkeys,
|
||||||
|
buttons = clientbuttons,
|
||||||
|
screen = awful.screen.preferred,
|
||||||
|
placement = awful.placement.no_overlap+awful.placement.no_offscreen,
|
||||||
|
size_hints_honor = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
-- Titlebars
|
||||||
|
{ rule_any = { type = { "dialog", "normal" } },
|
||||||
|
properties = { titlebars_enabled = true } },
|
||||||
|
|
||||||
|
-- Set Firefox to always map on the first tag on screen 1.
|
||||||
|
{ rule = { class = "Firefox" },
|
||||||
|
properties = { screen = 1, tag = awful.util.tagnames[1] } },
|
||||||
|
|
||||||
|
{ rule = { class = "Gimp", role = "gimp-image-window" },
|
||||||
|
properties = { maximized = true } },
|
||||||
|
}
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
-- {{{ Signals
|
||||||
|
-- Signal function to execute when a new client appears.
|
||||||
|
client.connect_signal("manage", function (c)
|
||||||
|
-- Set the windows at the slave,
|
||||||
|
-- i.e. put it at the end of others instead of setting it master.
|
||||||
|
-- if not awesome.startup then awful.client.setslave(c) end
|
||||||
|
|
||||||
|
if awesome.startup and
|
||||||
|
not c.size_hints.user_position
|
||||||
|
and not c.size_hints.program_position then
|
||||||
|
-- Prevent clients from being unreachable after screen count changes.
|
||||||
|
awful.placement.no_offscreen(c)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Add a titlebar if titlebars_enabled is set to true in the rules.
|
||||||
|
client.connect_signal("request::titlebars", function(c)
|
||||||
|
-- Custom
|
||||||
|
if beautiful.titlebar_fun then
|
||||||
|
beautiful.titlebar_fun(c)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Default
|
||||||
|
-- buttons for the titlebar
|
||||||
|
local buttons = my_table.join(
|
||||||
|
awful.button({ }, 1, function()
|
||||||
|
c:emit_signal("request::activate", "titlebar", {raise = true})
|
||||||
|
awful.mouse.client.move(c)
|
||||||
|
end),
|
||||||
|
awful.button({ }, 2, function() c:kill() end),
|
||||||
|
awful.button({ }, 3, function()
|
||||||
|
c:emit_signal("request::activate", "titlebar", {raise = true})
|
||||||
|
awful.mouse.client.resize(c)
|
||||||
|
end)
|
||||||
|
)
|
||||||
|
|
||||||
|
awful.titlebar(c, {size = dpi(16)}) : setup {
|
||||||
|
{ -- Left
|
||||||
|
awful.titlebar.widget.iconwidget(c),
|
||||||
|
buttons = buttons,
|
||||||
|
layout = wibox.layout.fixed.horizontal
|
||||||
|
},
|
||||||
|
{ -- Middle
|
||||||
|
{ -- Title
|
||||||
|
align = "center",
|
||||||
|
widget = awful.titlebar.widget.titlewidget(c)
|
||||||
|
},
|
||||||
|
buttons = buttons,
|
||||||
|
layout = wibox.layout.flex.horizontal
|
||||||
|
},
|
||||||
|
{ -- Right
|
||||||
|
awful.titlebar.widget.floatingbutton (c),
|
||||||
|
awful.titlebar.widget.maximizedbutton(c),
|
||||||
|
awful.titlebar.widget.stickybutton (c),
|
||||||
|
awful.titlebar.widget.ontopbutton (c),
|
||||||
|
awful.titlebar.widget.closebutton (c),
|
||||||
|
layout = wibox.layout.fixed.horizontal()
|
||||||
|
},
|
||||||
|
layout = wibox.layout.align.horizontal
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Enable sloppy focus, so that focus follows mouse.
|
||||||
|
client.connect_signal("mouse::enter", function(c)
|
||||||
|
c:emit_signal("request::activate", "mouse_enter", {raise = vi_focus})
|
||||||
|
end)
|
||||||
|
|
||||||
|
client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end)
|
||||||
|
client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end)
|
||||||
|
|
||||||
|
-- possible workaround for tag preservation when switching back to default screen:
|
||||||
|
-- https://github.com/lcpz/awesome-copycats/issues/251
|
||||||
|
-- }}}
|
||||||
|
|
||||||
|
-- Test to work around fullscreen game issues
|
||||||
|
client.connect_signal("property::fullscreen", function(c)
|
||||||
|
if c.fullscreen then
|
||||||
|
gears.timer.delayed_call(function()
|
||||||
|
if c.valid then
|
||||||
|
c:geometry(c.screen.geometry)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end)
|
|
@ -0,0 +1,386 @@
|
||||||
|
--[[
|
||||||
|
|
||||||
|
Powerarrow Awesome WM theme
|
||||||
|
github.com/lcpz
|
||||||
|
|
||||||
|
--]]
|
||||||
|
|
||||||
|
local gears = require("gears")
|
||||||
|
local lain = require("lain")
|
||||||
|
local awful = require("awful")
|
||||||
|
local wibox = require("wibox")
|
||||||
|
local dpi = require("beautiful.xresources").apply_dpi
|
||||||
|
|
||||||
|
local math, string, os = math, string, os
|
||||||
|
local my_table = awful.util.table or gears.table -- 4.{0,1} compatibility
|
||||||
|
|
||||||
|
local output_sink_index = 1
|
||||||
|
|
||||||
|
local theme = {}
|
||||||
|
theme.dir = os.getenv("HOME") .. "/.config/awesome/themes/powerarrow"
|
||||||
|
theme.wallpaper = os.getenv("HOME") .. "/.config/awesome/background.png"
|
||||||
|
theme.font = "Roboto Slab 9"
|
||||||
|
theme.fg_normal = "#FEFEFE"
|
||||||
|
theme.fg_focus = "#32D6FF"
|
||||||
|
theme.fg_urgent = "#C83F11"
|
||||||
|
theme.bg_normal = "#222222"
|
||||||
|
theme.bg_focus = "#1E2320"
|
||||||
|
theme.bg_urgent = "#3F3F3F"
|
||||||
|
theme.taglist_fg_focus = "#00CCFF"
|
||||||
|
theme.tasklist_bg_focus = "#222222"
|
||||||
|
theme.tasklist_fg_focus = "#00CCFF"
|
||||||
|
theme.border_width = dpi(2)
|
||||||
|
theme.border_normal = "#3F3F3F"
|
||||||
|
theme.border_focus = "#6F6F6F"
|
||||||
|
theme.border_marked = "#CC9393"
|
||||||
|
theme.titlebar_bg_focus = "#3F3F3F"
|
||||||
|
theme.titlebar_bg_normal = "#3F3F3F"
|
||||||
|
theme.titlebar_bg_focus = theme.bg_focus
|
||||||
|
theme.titlebar_bg_normal = theme.bg_normal
|
||||||
|
theme.titlebar_fg_focus = theme.fg_focus
|
||||||
|
theme.menu_height = dpi(16)
|
||||||
|
theme.menu_width = dpi(140)
|
||||||
|
theme.menu_submenu_icon = theme.dir .. "/icons/submenu.png"
|
||||||
|
theme.awesome_icon = theme.dir .. "/icons/awesome.png"
|
||||||
|
theme.taglist_squares_sel = theme.dir .. "/icons/square_sel.png"
|
||||||
|
theme.taglist_squares_unsel = theme.dir .. "/icons/square_unsel.png"
|
||||||
|
theme.layout_tile = theme.dir .. "/icons/tile.png"
|
||||||
|
theme.layout_tileleft = theme.dir .. "/icons/tileleft.png"
|
||||||
|
theme.layout_tilebottom = theme.dir .. "/icons/tilebottom.png"
|
||||||
|
theme.layout_tiletop = theme.dir .. "/icons/tiletop.png"
|
||||||
|
theme.layout_fairv = theme.dir .. "/icons/fairv.png"
|
||||||
|
theme.layout_fairh = theme.dir .. "/icons/fairh.png"
|
||||||
|
theme.layout_spiral = theme.dir .. "/icons/spiral.png"
|
||||||
|
theme.layout_dwindle = theme.dir .. "/icons/dwindle.png"
|
||||||
|
theme.layout_max = theme.dir .. "/icons/max.png"
|
||||||
|
theme.layout_fullscreen = theme.dir .. "/icons/fullscreen.png"
|
||||||
|
theme.layout_magnifier = theme.dir .. "/icons/magnifier.png"
|
||||||
|
theme.layout_floating = theme.dir .. "/icons/floating.png"
|
||||||
|
theme.widget_ac = theme.dir .. "/icons/ac.png"
|
||||||
|
theme.widget_battery = theme.dir .. "/icons/battery.png"
|
||||||
|
theme.widget_battery_low = theme.dir .. "/icons/battery_low.png"
|
||||||
|
theme.widget_battery_empty = theme.dir .. "/icons/battery_empty.png"
|
||||||
|
theme.widget_brightness = theme.dir .. "/icons/brightness.png"
|
||||||
|
theme.widget_mem = theme.dir .. "/icons/mem.png"
|
||||||
|
theme.widget_cpu = theme.dir .. "/icons/cpu.png"
|
||||||
|
theme.widget_temp = theme.dir .. "/icons/temp.png"
|
||||||
|
theme.widget_net = theme.dir .. "/icons/net.png"
|
||||||
|
theme.widget_hdd = theme.dir .. "/icons/hdd.png"
|
||||||
|
theme.widget_music = theme.dir .. "/icons/note.png"
|
||||||
|
theme.widget_music_on = theme.dir .. "/icons/note_on.png"
|
||||||
|
theme.widget_music_pause = theme.dir .. "/icons/pause.png"
|
||||||
|
theme.widget_music_stop = theme.dir .. "/icons/stop.png"
|
||||||
|
-- Borrow volume icons from powerarrow-dark
|
||||||
|
theme.widget_vol = theme.dir .. "/../powerarrow-dark/icons/vol.png"
|
||||||
|
theme.widget_vol_low = theme.dir .. "/../powerarrow-dark/icons/vol_low.png"
|
||||||
|
theme.widget_vol_no = theme.dir .. "/../powerarrow-dark/icons/vol_no.png"
|
||||||
|
theme.widget_vol_mute = theme.dir .. "/../powerarrow-dark/icons/vol_mute.png"
|
||||||
|
--
|
||||||
|
theme.widget_mail = theme.dir .. "/icons/mail.png"
|
||||||
|
theme.widget_mail_on = theme.dir .. "/icons/mail_on.png"
|
||||||
|
theme.widget_task = theme.dir .. "/icons/task.png"
|
||||||
|
theme.widget_scissors = theme.dir .. "/icons/scissors.png"
|
||||||
|
theme.tasklist_plain_task_name = true
|
||||||
|
theme.tasklist_disable_icon = true
|
||||||
|
theme.useless_gap = 0
|
||||||
|
theme.titlebar_close_button_focus = theme.dir .. "/icons/titlebar/close_focus.png"
|
||||||
|
theme.titlebar_close_button_normal = theme.dir .. "/icons/titlebar/close_normal.png"
|
||||||
|
theme.titlebar_ontop_button_focus_active = theme.dir .. "/icons/titlebar/ontop_focus_active.png"
|
||||||
|
theme.titlebar_ontop_button_normal_active = theme.dir .. "/icons/titlebar/ontop_normal_active.png"
|
||||||
|
theme.titlebar_ontop_button_focus_inactive = theme.dir .. "/icons/titlebar/ontop_focus_inactive.png"
|
||||||
|
theme.titlebar_ontop_button_normal_inactive = theme.dir .. "/icons/titlebar/ontop_normal_inactive.png"
|
||||||
|
theme.titlebar_sticky_button_focus_active = theme.dir .. "/icons/titlebar/sticky_focus_active.png"
|
||||||
|
theme.titlebar_sticky_button_normal_active = theme.dir .. "/icons/titlebar/sticky_normal_active.png"
|
||||||
|
theme.titlebar_sticky_button_focus_inactive = theme.dir .. "/icons/titlebar/sticky_focus_inactive.png"
|
||||||
|
theme.titlebar_sticky_button_normal_inactive = theme.dir .. "/icons/titlebar/sticky_normal_inactive.png"
|
||||||
|
theme.titlebar_floating_button_focus_active = theme.dir .. "/icons/titlebar/floating_focus_active.png"
|
||||||
|
theme.titlebar_floating_button_normal_active = theme.dir .. "/icons/titlebar/floating_normal_active.png"
|
||||||
|
theme.titlebar_floating_button_focus_inactive = theme.dir .. "/icons/titlebar/floating_focus_inactive.png"
|
||||||
|
theme.titlebar_floating_button_normal_inactive = theme.dir .. "/icons/titlebar/floating_normal_inactive.png"
|
||||||
|
theme.titlebar_maximized_button_focus_active = theme.dir .. "/icons/titlebar/maximized_focus_active.png"
|
||||||
|
theme.titlebar_maximized_button_normal_active = theme.dir .. "/icons/titlebar/maximized_normal_active.png"
|
||||||
|
theme.titlebar_maximized_button_focus_inactive = theme.dir .. "/icons/titlebar/maximized_focus_inactive.png"
|
||||||
|
theme.titlebar_maximized_button_normal_inactive = theme.dir .. "/icons/titlebar/maximized_normal_inactive.png"
|
||||||
|
|
||||||
|
local markup = lain.util.markup
|
||||||
|
local separators = lain.util.separators
|
||||||
|
|
||||||
|
-- Conventional clock
|
||||||
|
local convclock = wibox.widget.textclock()
|
||||||
|
|
||||||
|
-- Calendar
|
||||||
|
theme.cal = lain.widget.cal({
|
||||||
|
--cal = "cal --color=always",
|
||||||
|
--attach_to = { binclock.widget },
|
||||||
|
attach_to = { convclock },
|
||||||
|
notification_preset = {
|
||||||
|
-- font = "Terminus 10",
|
||||||
|
font = "Roboto Slab 10",
|
||||||
|
fg = theme.fg_normal,
|
||||||
|
bg = theme.bg_normal
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Taskwarrior
|
||||||
|
local task = wibox.widget.imagebox(theme.widget_task)
|
||||||
|
lain.widget.contrib.task.attach(task, {
|
||||||
|
-- do not colorize output
|
||||||
|
show_cmd = "task | sed -r 's/\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g'"
|
||||||
|
})
|
||||||
|
task:buttons(my_table.join(awful.button({}, 1, lain.widget.contrib.task.prompt)))
|
||||||
|
|
||||||
|
-- Scissors (xsel copy and paste)
|
||||||
|
local scissors = wibox.widget.imagebox(theme.widget_scissors)
|
||||||
|
scissors:buttons(my_table.join(awful.button({}, 1, function() awful.spawn.with_shell("xsel | xsel -i -b") end)))
|
||||||
|
|
||||||
|
-- PulseAudio volume
|
||||||
|
local volicon = wibox.widget.imagebox(theme.widget_vol)
|
||||||
|
theme.volume = lain.widget.pulse({
|
||||||
|
settings = function()
|
||||||
|
if volume_now == nil or volume_now.muted == "yes" then
|
||||||
|
volicon:set_image(theme.widget_vol_mute)
|
||||||
|
elseif volume_now.left == "N/A" then
|
||||||
|
volicon:set_image(theme.widget_vol_no)
|
||||||
|
elseif tonumber(volume_now.left) == 0 then
|
||||||
|
volicon:set_image(theme.widget_vol_no)
|
||||||
|
elseif tonumber(volume_now.left) <= 50 then
|
||||||
|
volicon:set_image(theme.widget_vol_low)
|
||||||
|
else
|
||||||
|
volicon:set_image(theme.widget_vol)
|
||||||
|
end
|
||||||
|
|
||||||
|
widget:set_markup(markup.font(theme.font, " " .. volume_now.left .. "% "))
|
||||||
|
end
|
||||||
|
})
|
||||||
|
theme.volume.widget:buttons(awful.util.table.join(
|
||||||
|
awful.button({}, 4, function ()
|
||||||
|
awful.spawn("pactl set-sink-volume " .. output_sink_index .. " +3%")
|
||||||
|
theme.volume.update()
|
||||||
|
end),
|
||||||
|
awful.button({}, 5, function ()
|
||||||
|
awful.spawn("pactl set-sink-volume " .. output_sink_index .. " -3%")
|
||||||
|
theme.volume.update()
|
||||||
|
end)
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
-- MPD
|
||||||
|
local musicplr = awful.util.terminal .. " --title Music -g 130x34-320+16 -e ncmpcpp"
|
||||||
|
local mpdicon = wibox.widget.imagebox(theme.widget_music)
|
||||||
|
mpdicon:buttons(my_table.join(
|
||||||
|
awful.button({ modkey }, 1, function () awful.spawn.with_shell(musicplr) end),
|
||||||
|
awful.button({ }, 1, function ()
|
||||||
|
os.execute("mpc prev")
|
||||||
|
theme.mpd.update()
|
||||||
|
end),
|
||||||
|
awful.button({ }, 2, function ()
|
||||||
|
os.execute("mpc toggle")
|
||||||
|
theme.mpd.update()
|
||||||
|
end),
|
||||||
|
awful.button({ }, 3, function ()
|
||||||
|
os.execute("mpc next")
|
||||||
|
theme.mpd.update()
|
||||||
|
end)))
|
||||||
|
theme.mpd = lain.widget.mpd({
|
||||||
|
settings = function()
|
||||||
|
if mpd_now.state == "play" then
|
||||||
|
artist = " " .. mpd_now.artist .. " "
|
||||||
|
title = mpd_now.title .. " "
|
||||||
|
mpdicon:set_image(theme.widget_music_on)
|
||||||
|
widget:set_markup(markup.font(theme.font, markup("#FF8466", artist) .. " " .. title))
|
||||||
|
elseif mpd_now.state == "pause" then
|
||||||
|
widget:set_markup(markup.font(theme.font, " mpd paused "))
|
||||||
|
mpdicon:set_image(theme.widget_music_pause)
|
||||||
|
else
|
||||||
|
widget:set_text("")
|
||||||
|
mpdicon:set_image(theme.widget_music)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
-- MEM
|
||||||
|
local memicon = wibox.widget.imagebox(theme.widget_mem)
|
||||||
|
local mem = lain.widget.mem({
|
||||||
|
settings = function()
|
||||||
|
widget:set_markup(markup.font(theme.font, " " .. mem_now.used .. "MB "))
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
-- CPU
|
||||||
|
local cpuicon = wibox.widget.imagebox(theme.widget_cpu)
|
||||||
|
local cpu = lain.widget.cpu({
|
||||||
|
settings = function()
|
||||||
|
widget:set_markup(markup.font(theme.font, " " .. cpu_now.usage .. "% "))
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Coretemp (lain, average)
|
||||||
|
local temp = lain.widget.temp({
|
||||||
|
settings = function()
|
||||||
|
widget:set_markup(markup.font(theme.font, " " .. coretemp_now .. "°C "))
|
||||||
|
end
|
||||||
|
})
|
||||||
|
--
|
||||||
|
local tempicon = wibox.widget.imagebox(theme.widget_temp)
|
||||||
|
|
||||||
|
-- / fs
|
||||||
|
local fsicon = wibox.widget.imagebox(theme.widget_hdd)
|
||||||
|
-- commented because it needs Gio/Glib >= 2.54
|
||||||
|
theme.fs = lain.widget.fs({
|
||||||
|
-- notification_preset = { fg = theme.fg_normal, bg = theme.bg_normal, font = "Terminus 10" },
|
||||||
|
notification_preset = { fg = theme.fg_normal, bg = theme.bg_normal, font = "Roboto Slab 10" },
|
||||||
|
settings = function()
|
||||||
|
local fsp = string.format(" %3.2f %s ", fs_now["/"].free, fs_now["/"].units)
|
||||||
|
widget:set_markup(markup.font(theme.font, fsp))
|
||||||
|
end
|
||||||
|
})
|
||||||
|
--
|
||||||
|
|
||||||
|
-- Battery
|
||||||
|
local baticon = wibox.widget.imagebox(theme.widget_battery)
|
||||||
|
local bat = lain.widget.bat({
|
||||||
|
settings = function()
|
||||||
|
if bat_now.status and bat_now.status ~= "N/A" then
|
||||||
|
if bat_now.ac_status == 1 then
|
||||||
|
widget:set_markup(markup.font(theme.font, " AC "))
|
||||||
|
baticon:set_image(theme.widget_ac)
|
||||||
|
return
|
||||||
|
elseif not bat_now.perc and tonumber(bat_now.perc) <= 5 then
|
||||||
|
baticon:set_image(theme.widget_battery_empty)
|
||||||
|
elseif not bat_now.perc and tonumber(bat_now.perc) <= 15 then
|
||||||
|
baticon:set_image(theme.widget_battery_low)
|
||||||
|
else
|
||||||
|
baticon:set_image(theme.widget_battery)
|
||||||
|
end
|
||||||
|
widget:set_markup(markup.font(theme.font, " " .. bat_now.perc .. "% "))
|
||||||
|
else
|
||||||
|
widget:set_markup()
|
||||||
|
baticon:set_image(theme.widget_ac)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Net
|
||||||
|
local neticon = wibox.widget.imagebox(theme.widget_net)
|
||||||
|
local net = lain.widget.net({
|
||||||
|
settings = function()
|
||||||
|
widget:set_markup(markup.fontfg(theme.font, "#FEFEFE", " " .. net_now.received .. " ↓↑ " .. net_now.sent .. " "))
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Brigtness
|
||||||
|
local brighticon = wibox.widget.imagebox(theme.widget_brightness)
|
||||||
|
-- If you use xbacklight, comment the line with "light -G" and uncomment the line bellow
|
||||||
|
-- local brightwidget = awful.widget.watch('xbacklight -get', 0.1,
|
||||||
|
local brightwidget = awful.widget.watch('light -G', 0.1,
|
||||||
|
function(widget, stdout, stderr, exitreason, exitcode)
|
||||||
|
local brightness_level = tonumber(string.format("%.0f", stdout))
|
||||||
|
widget:set_markup(markup.font(theme.font, " " .. brightness_level .. "%"))
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Separators
|
||||||
|
local arrow = separators.arrow_left
|
||||||
|
|
||||||
|
function theme.powerline_rl(cr, width, height)
|
||||||
|
local arrow_depth, offset = height/2, 0
|
||||||
|
|
||||||
|
-- Avoid going out of the (potential) clip area
|
||||||
|
if arrow_depth < 0 then
|
||||||
|
width = width + 2*arrow_depth
|
||||||
|
offset = -arrow_depth
|
||||||
|
end
|
||||||
|
|
||||||
|
cr:move_to(offset + arrow_depth , 0 )
|
||||||
|
cr:line_to(offset + width , 0 )
|
||||||
|
cr:line_to(offset + width - arrow_depth , height/2 )
|
||||||
|
cr:line_to(offset + width , height )
|
||||||
|
cr:line_to(offset + arrow_depth , height )
|
||||||
|
cr:line_to(offset , height/2 )
|
||||||
|
|
||||||
|
cr:close_path()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function pl(widget, bgcolor, padding)
|
||||||
|
return wibox.container.background(wibox.container.margin(widget, dpi(16), dpi(16)), bgcolor, theme.powerline_rl)
|
||||||
|
end
|
||||||
|
|
||||||
|
function theme.at_screen_connect(s)
|
||||||
|
-- Quake application
|
||||||
|
s.quake = lain.util.quake({ app = awful.util.terminal })
|
||||||
|
|
||||||
|
-- If wallpaper is a function, call it with the screen
|
||||||
|
local wallpaper = theme.wallpaper
|
||||||
|
if type(wallpaper) == "function" then
|
||||||
|
wallpaper = wallpaper(s)
|
||||||
|
end
|
||||||
|
gears.wallpaper.maximized(wallpaper, s, true)
|
||||||
|
|
||||||
|
-- Tags
|
||||||
|
awful.tag(awful.util.tagnames, s, awful.layout.layouts)
|
||||||
|
|
||||||
|
-- Create a promptbox for each screen
|
||||||
|
s.mypromptbox = awful.widget.prompt()
|
||||||
|
-- Create an imagebox widget which will contains an icon indicating which layout we're using.
|
||||||
|
-- We need one layoutbox per screen.
|
||||||
|
s.mylayoutbox = awful.widget.layoutbox(s)
|
||||||
|
s.mylayoutbox:buttons(my_table.join(
|
||||||
|
awful.button({}, 1, function () awful.layout.inc( 1) end),
|
||||||
|
awful.button({}, 2, function () awful.layout.set( awful.layout.layouts[1] ) end),
|
||||||
|
awful.button({}, 3, function () awful.layout.inc(-1) end),
|
||||||
|
awful.button({}, 4, function () awful.layout.inc( 1) end),
|
||||||
|
awful.button({}, 5, function () awful.layout.inc(-1) end)))
|
||||||
|
-- Create a taglist widget
|
||||||
|
s.mytaglist = awful.widget.taglist(s, awful.widget.taglist.filter.all, awful.util.taglist_buttons)
|
||||||
|
|
||||||
|
-- Create a tasklist widget
|
||||||
|
s.mytasklist = awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, awful.util.tasklist_buttons)
|
||||||
|
|
||||||
|
-- Create the wibox
|
||||||
|
s.mywibox = awful.wibar({ position = "top", screen = s, height = dpi(16), bg = theme.bg_normal, fg = theme.fg_normal })
|
||||||
|
|
||||||
|
-- Add widgets to the wibox
|
||||||
|
s.mywibox:setup {
|
||||||
|
layout = wibox.layout.align.horizontal,
|
||||||
|
{ -- Left widgets
|
||||||
|
layout = wibox.layout.fixed.horizontal,
|
||||||
|
--spr,
|
||||||
|
s.mytaglist,
|
||||||
|
s.mypromptbox,
|
||||||
|
spr,
|
||||||
|
},
|
||||||
|
s.mytasklist, -- Middle widget
|
||||||
|
{ -- Right widgets
|
||||||
|
layout = wibox.layout.fixed.horizontal,
|
||||||
|
wibox.widget.systray(),
|
||||||
|
wibox.container.margin(scissors, dpi(4), dpi(8)),
|
||||||
|
arrow(theme.bg_normal, theme.bg_normal),
|
||||||
|
wibox.container.background(wibox.container.margin(wibox.widget { volicon, theme.volume.widget, layout = wibox.layout.align.horizontal }, dpi(4), dpi(7)), theme.bg_focus),
|
||||||
|
arrow(theme.bg_normal, "#343434"),
|
||||||
|
wibox.container.background(wibox.container.margin(wibox.widget { mailicon, theme.mail and theme.mail.widget, layout = wibox.layout.align.horizontal }, dpi(4), dpi(7)), "#343434"),
|
||||||
|
arrow("#343434", theme.bg_normal),
|
||||||
|
wibox.container.background(wibox.container.margin(wibox.widget { mpdicon, theme.mpd.widget, layout = wibox.layout.align.horizontal }, dpi(3), dpi(6)), theme.bg_focus),
|
||||||
|
arrow(theme.bg_normal, "#343434"),
|
||||||
|
wibox.container.background(wibox.container.margin(task, dpi(3), dpi(7)), "#343434"),
|
||||||
|
arrow("#343434", "#777E76"),
|
||||||
|
wibox.container.background(wibox.container.margin(wibox.widget { memicon, mem.widget, layout = wibox.layout.align.horizontal }, dpi(2), dpi(3)), "#777E76"),
|
||||||
|
arrow("#777E76", "#4B696D"),
|
||||||
|
wibox.container.background(wibox.container.margin(wibox.widget { cpuicon, cpu.widget, layout = wibox.layout.align.horizontal }, dpi(3), dpi(4)), "#4B696D"),
|
||||||
|
arrow("#4B696D", "#4B3B51"),
|
||||||
|
wibox.container.background(wibox.container.margin(wibox.widget { tempicon, temp.widget, layout = wibox.layout.align.horizontal }, dpi(4), dpi(4)), "#4B3B51"),
|
||||||
|
arrow("#4B3B51", "#CB755B"),
|
||||||
|
wibox.container.background(wibox.container.margin(wibox.widget { fsicon, theme.fs and theme.fs.widget, layout = wibox.layout.align.horizontal }, dpi(3), dpi(3)), "#CB755B"),
|
||||||
|
arrow("#CB755B", "#8DAA9A"),
|
||||||
|
wibox.container.background(wibox.container.margin(wibox.widget { baticon, bat.widget, layout = wibox.layout.align.horizontal }, dpi(3), dpi(3)), "#8DAA9A"),
|
||||||
|
arrow("#8DAA9A", "#C0C0A2"),
|
||||||
|
wibox.container.background(wibox.container.margin(wibox.widget { nil, neticon, net.widget, layout = wibox.layout.align.horizontal }, dpi(3), dpi(3)), "#C0C0A2"),
|
||||||
|
arrow("#C0C0A2", "#777E76"),
|
||||||
|
--wibox.container.background(wibox.container.margin(binclock.widget, dpi(4), dpi(8)), "#777E76"),
|
||||||
|
wibox.container.background(wibox.container.margin(convclock, dpi(4), dpi(8)), "#777E76"),
|
||||||
|
arrow("#777E76", "alpha"),
|
||||||
|
--
|
||||||
|
s.mylayoutbox,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return theme
|
|
@ -0,0 +1,21 @@
|
||||||
|
[global_config]
|
||||||
|
enabled_plugins = SaveLastSessionLayout, LaunchpadBugURLHandler, LaunchpadCodeURLHandler, APTURLHandler
|
||||||
|
[keybindings]
|
||||||
|
[profiles]
|
||||||
|
[[default]]
|
||||||
|
background_darkness = 0.8
|
||||||
|
background_type = transparent
|
||||||
|
font = JetBrainsMono Nerd Font Mono 10
|
||||||
|
scrollback_lines = 15000
|
||||||
|
palette = "#282828:#cc241d:#98971a:#d79921:#458588:#b16286:#689d6a:#a89984:#928374:#fb4934:#b8bb26:#fabd2f:#83a598:#d3869b:#8ec07c:#ebdbb2"
|
||||||
|
use_system_font = False
|
||||||
|
copy_on_selection = True
|
||||||
|
[layouts]
|
||||||
|
[[default]]
|
||||||
|
[[[window0]]]
|
||||||
|
type = Window
|
||||||
|
parent = ""
|
||||||
|
[[[child1]]]
|
||||||
|
type = Terminal
|
||||||
|
parent = window0
|
||||||
|
[plugins]
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,3 @@
|
||||||
|
setxkbmap -layout us -variant alt-intl
|
||||||
|
picom --daemon
|
||||||
|
exec awesome
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/usr/bin/env zsh
|
||||||
|
|
||||||
|
APP_BIN="{{ application }}"
|
||||||
|
|
||||||
|
if [ ! -x "${APP_BIN}" ]; then
|
||||||
|
printf "%s: target not found" "${APP_BIN}" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "${APP_BIN}" "$@"
|
|
@ -0,0 +1,105 @@
|
||||||
|
#############################################
|
||||||
|
# FILES #
|
||||||
|
#############################################
|
||||||
|
Section "Files"
|
||||||
|
ModulePath "/usr/lib/xorg/modules"
|
||||||
|
FontPath "/usr/share/fonts/X11/misc"
|
||||||
|
FontPath "/usr/share/fonts/X11/100dpi/:unscaled"
|
||||||
|
FontPath "/usr/share/fonts/X11/75dpi/:unscaled"
|
||||||
|
FontPath "/usr/share/fonts/X11/Type1"
|
||||||
|
FontPath "/usr/share/fonts/X11/100dpi"
|
||||||
|
FontPath "/usr/share/fonts/X11/75dpi"
|
||||||
|
FontPath "built-ins"
|
||||||
|
EndSection
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
# MODULES #
|
||||||
|
#############################################
|
||||||
|
Section "Module"
|
||||||
|
Load "glx"
|
||||||
|
EndSection
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
# INPUTDEVICES #
|
||||||
|
#############################################
|
||||||
|
Section "InputDevice"
|
||||||
|
Identifier "Mouse0"
|
||||||
|
Driver "mouse"
|
||||||
|
Option "Protocol" "auto"
|
||||||
|
Option "Device" "/dev/input/mice"
|
||||||
|
Option "ZAxisMapping" "4 5 6 7"
|
||||||
|
Option "CorePointer"
|
||||||
|
EndSection
|
||||||
|
|
||||||
|
Section "InputDevice"
|
||||||
|
Identifier "Keyboard0"
|
||||||
|
Driver "keyboard"
|
||||||
|
Option "CoreKeyboard"
|
||||||
|
Option "XkbRules" "xorg"
|
||||||
|
EndSection
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
# DEVICES #
|
||||||
|
#############################################
|
||||||
|
Section "Device"
|
||||||
|
Identifier "Card0"
|
||||||
|
Driver "amdgpu"
|
||||||
|
Option "Monitor-HDMI-A-0" "VG248"
|
||||||
|
Option "HDMI-A-0" "VG248"
|
||||||
|
Option "Monitor-DisplayPort-2" "LG UWQHD"
|
||||||
|
Option "DisplayPort-2" "LG UWQHD"
|
||||||
|
Option "Monitor-DisplayPort-0" "LG ULTRAWIDE"
|
||||||
|
Option "DisplayPort-0" "LG ULTRAWIDE"
|
||||||
|
EndSection
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
# SERVER LAYOUT #
|
||||||
|
#############################################
|
||||||
|
Section "ServerLayout"
|
||||||
|
Identifier "Layout0"
|
||||||
|
Screen 0 "Screen0" 0 0
|
||||||
|
InputDevice "Keyboard0" "CoreKeyboard"
|
||||||
|
InputDevice "Mouse0" "CorePointer"
|
||||||
|
Option "Xinerama" "0"
|
||||||
|
EndSection
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
# SCREENS #
|
||||||
|
#############################################
|
||||||
|
Section "Screen"
|
||||||
|
Identifier "Screen0"
|
||||||
|
Device "Card0"
|
||||||
|
EndSection
|
||||||
|
|
||||||
|
#############################################
|
||||||
|
# MONITORS #
|
||||||
|
#############################################
|
||||||
|
Section "Monitor"
|
||||||
|
Identifier "VG248"
|
||||||
|
ModelName "VG248"
|
||||||
|
VendorName "ACI"
|
||||||
|
Option "DPMS" "on"
|
||||||
|
Option "PreferredMode" "1920x1080"
|
||||||
|
Option "LeftOf" "DisplayPort-2"
|
||||||
|
Option "Position" "0 520"
|
||||||
|
EndSection
|
||||||
|
|
||||||
|
Section "Monitor"
|
||||||
|
Identifier "LG UWQHD"
|
||||||
|
ModelName "LG UWQHD"
|
||||||
|
VendorName "GSM"
|
||||||
|
Option "LeftOf" "DisplayPort-0"
|
||||||
|
Option "DPMS" "on"
|
||||||
|
Option "PreferredMode" "3840x1600"
|
||||||
|
Option "Primary" "true"
|
||||||
|
Option "Position" "1920 0"
|
||||||
|
EndSection
|
||||||
|
|
||||||
|
Section "Monitor"
|
||||||
|
Identifier "LG ULTRAWIDE"
|
||||||
|
ModelName "LG ULTRAWIDE"
|
||||||
|
VendorName "GSM"
|
||||||
|
Option "DPMS" "on"
|
||||||
|
Option "PreferredMode" "3440x1440"
|
||||||
|
Option "Position" "5760 160"
|
||||||
|
EndSection
|
3
inventory/host_vars/lithium/vars.yml
Normal file
3
inventory/host_vars/lithium/vars.yml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
ansible_become_password: "{{ vault_root_pass }}"
|
||||||
|
ansible_host: "{{ vault_ansible_host }}"
|
||||||
|
ansible_user: "{{ vault_ssh_user }}"
|
19
inventory/host_vars/localhost/vars.yml
Normal file
19
inventory/host_vars/localhost/vars.yml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
ansible_become_password: "{{ vault_root_pass }}"
|
||||||
|
ansible_host: "{{ vault_ansible_host }}"
|
||||||
|
ansible_connection: local
|
||||||
|
|
||||||
|
custom_sysctl:
|
||||||
|
'fs.inotify.max_user_watches': 1048576
|
||||||
|
'vm.swappiness': 1
|
||||||
|
|
||||||
|
common_apt_packages:
|
||||||
|
- pcscd
|
||||||
|
- pinentry-curses
|
||||||
|
- radeontop
|
||||||
|
|
||||||
|
common_gitconfig_enable: true
|
||||||
|
common_gitconfig_username: "{{ vault_common_gitconfig_username }}"
|
||||||
|
common_gitconfig_email: "{{ vault_common_gitconfig_email }}"
|
||||||
|
common_gitconfig_force_sign: true
|
||||||
|
common_gitconfig_signingkey: "{{ vault_common_gitconfig_signingkey }}"
|
||||||
|
common_install_fonts: true
|
19
inventory/host_vars/unobtainium/vars.yml
Normal file
19
inventory/host_vars/unobtainium/vars.yml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
ansible_become_password: "{{ vault_root_pass }}"
|
||||||
|
ansible_host: "{{ vault_ansible_host }}"
|
||||||
|
ansible_connection: local
|
||||||
|
|
||||||
|
custom_sysctl:
|
||||||
|
'fs.inotify.max_user_watches': 1048576
|
||||||
|
'vm.swappiness': 1
|
||||||
|
|
||||||
|
common_apt_packages:
|
||||||
|
- pcscd
|
||||||
|
- pinentry-curses
|
||||||
|
- radeontop
|
||||||
|
|
||||||
|
common_gitconfig_enable: true
|
||||||
|
common_gitconfig_username: "{{ vault_common_gitconfig_username }}"
|
||||||
|
common_gitconfig_email: "{{ vault_common_gitconfig_email }}"
|
||||||
|
common_gitconfig_force_sign: true
|
||||||
|
common_gitconfig_signingkey: "{{ vault_common_gitconfig_signingkey }}"
|
||||||
|
common_install_fonts: true
|
|
@ -1,2 +1,14 @@
|
||||||
all:
|
all:
|
||||||
hosts:
|
hosts:
|
||||||
|
|
||||||
|
external:
|
||||||
|
hosts:
|
||||||
|
|
||||||
|
main_desktop:
|
||||||
|
hosts:
|
||||||
|
|
||||||
|
internal:
|
||||||
|
hosts:
|
||||||
|
|
||||||
|
server:
|
||||||
|
hosts:
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
vault_custom_base_user_account:
|
vault_custom_base_user_account: ""
|
||||||
vault_custom_github_token:
|
vault_custom_github_token: ""
|
||||||
|
vault_custom_dockerhub_password: ""
|
||||||
|
|
|
@ -1 +1,9 @@
|
||||||
---
|
---
|
||||||
|
- name: setup internal infrastructure
|
||||||
|
hosts: internal
|
||||||
|
gather_facts: false
|
||||||
|
vars_files: ../inventory/vault.yml
|
||||||
|
tasks:
|
||||||
|
- include_vars: ../inventory/vault.yml
|
||||||
|
|
||||||
|
- ansible.builtin.import_playbook: nullified.infrastructure.main_desktop
|
||||||
|
|
|
@ -12,7 +12,7 @@ USAGE
|
||||||
\$> ./$(basename "$0") [option [option...]] [file_path]
|
\$> ./$(basename "$0") [option [option...]] [file_path]
|
||||||
|
|
||||||
ARGUMENTS
|
ARGUMENTS
|
||||||
file_path file path where the file will be saved; defaults to '\$HOME/.ansible.cfg';
|
file_path file path where the file will be saved;
|
||||||
if neither this argument nor the environment variable \$ANSIBLE_CFG_PATH is provided, the
|
if neither this argument nor the environment variable \$ANSIBLE_CFG_PATH is provided, the
|
||||||
content will be printed on stdout.
|
content will be printed on stdout.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue