mirror of
https://gitlab.com/TECHNOFAB/nixible.git
synced 2025-12-12 02:00:15 +01:00
chore: initial commit
This commit is contained in:
commit
7602719790
24 changed files with 1916 additions and 0 deletions
45
lib/ansible-collections.nix
Normal file
45
lib/ansible-collections.nix
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
stdenv,
|
||||
lib,
|
||||
pkgs,
|
||||
}: ansible: collections: let
|
||||
inherit (lib) concatStringsSep mapAttrsToList;
|
||||
|
||||
mkCollection = {
|
||||
name,
|
||||
version,
|
||||
hash,
|
||||
}:
|
||||
stdenv.mkDerivation {
|
||||
pname = name;
|
||||
inherit version;
|
||||
src = pkgs.fetchurl {
|
||||
inherit hash;
|
||||
url = "https://galaxy.ansible.com/download/${name}-${version}.tar.gz";
|
||||
};
|
||||
|
||||
phases = ["installPhase"];
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
cp $src $out/collection.tar.gz
|
||||
'';
|
||||
};
|
||||
|
||||
installCollection = collection: "${ansible}/bin/ansible-galaxy collection install ${collection}/collection.tar.gz";
|
||||
installCollections = concatStringsSep "\n" (
|
||||
mapAttrsToList (
|
||||
name: coll:
|
||||
installCollection (
|
||||
mkCollection ({inherit name;} // coll)
|
||||
)
|
||||
)
|
||||
collections
|
||||
);
|
||||
in
|
||||
pkgs.runCommand "ansible-collections" {} ''
|
||||
mkdir -p $out
|
||||
export HOME=./
|
||||
export ANSIBLE_COLLECTIONS_PATH=$out
|
||||
${installCollections}
|
||||
''
|
||||
91
lib/ansible-core.nix
Normal file
91
lib/ansible-core.nix
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
{
|
||||
lib,
|
||||
buildPythonPackage,
|
||||
fetchPypi,
|
||||
installShellFiles,
|
||||
docutils,
|
||||
setuptools,
|
||||
cryptography,
|
||||
jinja2,
|
||||
junit-xml,
|
||||
lxml,
|
||||
ncclient,
|
||||
packaging,
|
||||
paramiko,
|
||||
ansible-pylibssh,
|
||||
pexpect,
|
||||
psutil,
|
||||
pycrypto,
|
||||
pyyaml,
|
||||
requests,
|
||||
resolvelib,
|
||||
scp,
|
||||
windowsSupport ? false,
|
||||
pywinrm,
|
||||
xmltodict,
|
||||
}:
|
||||
buildPythonPackage rec {
|
||||
pname = "ansible-core";
|
||||
version = "2.18.6";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchPypi {
|
||||
pname = "ansible_core";
|
||||
inherit version;
|
||||
hash = "sha256-JbsgzhUWobcweDGyY872hAQ7NyBxFGa9nUFk5f1XZVc=";
|
||||
};
|
||||
|
||||
# ansible_connection is already wrapped, so don't pass it through
|
||||
# the python interpreter again, as it would break execution of
|
||||
# connection plugins.
|
||||
postPatch = ''
|
||||
substituteInPlace lib/ansible/executor/task_executor.py \
|
||||
--replace "[python," "["
|
||||
|
||||
patchShebangs --build packaging/cli-doc/build.py
|
||||
|
||||
SETUPTOOLS_PATTERN='"setuptools[0-9 <>=.,]+"'
|
||||
PYPROJECT=$(cat pyproject.toml)
|
||||
if [[ "$PYPROJECT" =~ $SETUPTOOLS_PATTERN ]]; then
|
||||
echo "setuptools replace: ''${BASH_REMATCH[0]}"
|
||||
echo "''${PYPROJECT//''${BASH_REMATCH[0]}/'"setuptools"'}" > pyproject.toml
|
||||
else
|
||||
exit 2
|
||||
fi
|
||||
'';
|
||||
|
||||
nativeBuildInputs = [
|
||||
installShellFiles
|
||||
docutils
|
||||
];
|
||||
|
||||
build-system = [setuptools];
|
||||
|
||||
dependencies =
|
||||
[
|
||||
# from requirements.txt
|
||||
cryptography
|
||||
jinja2
|
||||
packaging
|
||||
pyyaml
|
||||
resolvelib
|
||||
# optional dependencies
|
||||
junit-xml
|
||||
lxml
|
||||
ncclient
|
||||
paramiko
|
||||
ansible-pylibssh
|
||||
pexpect
|
||||
psutil
|
||||
pycrypto
|
||||
requests
|
||||
scp
|
||||
xmltodict
|
||||
]
|
||||
++ lib.optionals windowsSupport [pywinrm];
|
||||
|
||||
pythonRelaxDeps = ["resolvelib"];
|
||||
|
||||
# internal import errors, missing dependencies
|
||||
doCheck = false;
|
||||
}
|
||||
20
lib/default.nix
Normal file
20
lib/default.nix
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
pkgs,
|
||||
lib ? pkgs.lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) evalModules;
|
||||
in rec {
|
||||
module = ./module.nix;
|
||||
|
||||
mkNixible = config:
|
||||
evalModules {
|
||||
specialArgs = {inherit pkgs;};
|
||||
modules = [
|
||||
module
|
||||
config
|
||||
];
|
||||
};
|
||||
|
||||
mkNixibleCli = config: (mkNixible config).config.cli;
|
||||
}
|
||||
6
lib/flake.nix
Normal file
6
lib/flake.nix
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
outputs = {...}: {
|
||||
lib = import ./.;
|
||||
flakeModule = ./flakeModule.nix;
|
||||
};
|
||||
}
|
||||
33
lib/flakeModule.nix
Normal file
33
lib/flakeModule.nix
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
flake-parts-lib,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkOption types;
|
||||
in {
|
||||
options.perSystem = flake-parts-lib.mkPerSystemOption (
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
nixible-lib = import ./. {inherit pkgs lib;};
|
||||
in {
|
||||
options.nixible = mkOption {
|
||||
type = types.attrsOf (types.submodule (args:
|
||||
# needed to get pkgs in there, weirdly enough
|
||||
import nixible-lib.module (args
|
||||
// {
|
||||
inherit pkgs;
|
||||
})));
|
||||
default = {};
|
||||
};
|
||||
|
||||
config.legacyPackages = lib.fold (playbook: acc: acc // playbook) {} (
|
||||
map (playbook_name: {
|
||||
"nixible:${playbook_name}" = (builtins.getAttr playbook_name config.nixible).cli;
|
||||
}) (builtins.attrNames config.nixible)
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
103
lib/module.nix
Normal file
103
lib/module.nix
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) types mkOption;
|
||||
|
||||
collectionType = types.submodule {
|
||||
options = {
|
||||
version = mkOption {
|
||||
type = types.str;
|
||||
description = "Version of collection";
|
||||
};
|
||||
hash = mkOption {
|
||||
type = types.str;
|
||||
description = "Hash of the collection tarball";
|
||||
};
|
||||
};
|
||||
};
|
||||
in {
|
||||
options = {
|
||||
ansiblePackage = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.python3Packages.callPackage ./ansible-core.nix {};
|
||||
description = "Ansible package to use (default doesn't have any collections installed for size)";
|
||||
};
|
||||
collections = mkOption {
|
||||
type = types.attrsOf collectionType;
|
||||
default = {};
|
||||
description = "Collections to fetch and install";
|
||||
};
|
||||
dependencies = mkOption {
|
||||
type = types.listOf types.package;
|
||||
default = [];
|
||||
description = "List of packages to include at runtime";
|
||||
};
|
||||
playbook = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
options = {
|
||||
name = mkOption {
|
||||
type = types.str;
|
||||
description = "Name of the play";
|
||||
};
|
||||
hosts = mkOption {
|
||||
type = types.str;
|
||||
description = "The target hosts for this play (e.g., 'all', 'webservers')";
|
||||
};
|
||||
become = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Whether to use privilege escalation (become: yes)";
|
||||
};
|
||||
tasks = mkOption {
|
||||
type = types.listOf types.attrs;
|
||||
default = [];
|
||||
description = "List of tasks to execute in this play";
|
||||
};
|
||||
};
|
||||
});
|
||||
description = "The actual playbook, defined as a Nix data structure";
|
||||
};
|
||||
|
||||
inventory = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
description = "Ansible inventory, will be converted to json and passed to ansible";
|
||||
};
|
||||
|
||||
inventoryFile = mkOption {
|
||||
internal = true;
|
||||
type = types.package;
|
||||
};
|
||||
playbookFile = mkOption {
|
||||
internal = true;
|
||||
type = types.package;
|
||||
};
|
||||
installedCollections = mkOption {
|
||||
internal = true;
|
||||
type = types.package;
|
||||
};
|
||||
cli = mkOption {
|
||||
internal = true;
|
||||
type = types.package;
|
||||
};
|
||||
};
|
||||
config = {
|
||||
inventoryFile = (pkgs.formats.json {}).generate "inventory.json" config.inventory;
|
||||
playbookFile = (pkgs.formats.yaml {}).generate "playbook.yml" config.playbook;
|
||||
installedCollections = pkgs.callPackage ./ansible-collections.nix {} config.ansiblePackage config.collections;
|
||||
cli = pkgs.writeShellApplication {
|
||||
name = "nixible";
|
||||
runtimeInputs = config.dependencies;
|
||||
text = ''
|
||||
set -euo pipefail
|
||||
export ANSIBLE_COLLECTIONS_PATH=${config.installedCollections}
|
||||
|
||||
git_repo=$(git rev-parse --show-toplevel 2>/dev/null || true)
|
||||
${config.ansiblePackage}/bin/ansible-playbook -i ${config.inventoryFile} ${config.playbookFile} -e "pwd=$(pwd)" -e "git_root=$git_repo" "$@"
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue