Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: NixOS/nixops
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2b63a9ae59e4
Choose a base ref
...
head repository: NixOS/nixops
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 7a68012b6651
Choose a head ref
  • 15 commits
  • 16 files changed
  • 2 contributors

Commits on Apr 2, 2020

  1. Migrate to poetry2nix

    adisbladis committed Apr 2, 2020
    Copy the full SHA
    9fab15a View commit details
  2. Deployment sorting fails with TypeError when name is None

    name is of type Optional[str] and can therefore be None.
    In the `nixops info` output we default to the deployment UUID so it
    feels reasonable to fall back sorting on UUID.
    adisbladis committed Apr 2, 2020
    Copy the full SHA
    1681be2 View commit details
  3. include nix

    grahamc authored and adisbladis committed Apr 2, 2020
    Copy the full SHA
    9f944cb View commit details
  4. Drop setup.py

    It's been replaced by pyproject.toml
    adisbladis committed Apr 2, 2020
    Copy the full SHA
    e230879 View commit details
  5. Copy the full SHA
    203f75f View commit details
  6. Copy the full SHA
    b92058d View commit details
  7. Clean up release.nix

    adisbladis committed Apr 2, 2020
    Copy the full SHA
    45d4049 View commit details
  8. Re-add manual build

    adisbladis committed Apr 2, 2020
    Copy the full SHA
    434d6a0 View commit details
  9. Copy the full SHA
    6dad7a1 View commit details
  10. mypy-ratchet: Run first ratchet run inside a nix-shell

    We need to evaluate twice, once using any previous version of mypy and
    a second time using the current version of mypy.
    
    If we don't a mypy version bump can find new type errors that makes
    the initial check fail.
    adisbladis committed Apr 2, 2020
    Copy the full SHA
    e3993d6 View commit details
  11. nix-expr.RawValue: add types

    Based on:
    
    Grepping the source code for RawValue, I see they are all strings.
    grahamc authored and adisbladis committed Apr 2, 2020
    Copy the full SHA
    2a4ff0f View commit details
  12. nix-expr.MultiLineRawValue: add types

    Based on grepping the source code for MultiLineRawValue, it apears they're all just a list of RawValue values, ie: str's
    grahamc authored and adisbladis committed Apr 2, 2020
    Copy the full SHA
    6c188f5 View commit details
  13. Copy the full SHA
    af89974 View commit details
  14. Add plugin authoring docs

    Co-Authored-By: adisbladis <adisbladis@gmail.com>
    grahamc and adisbladis committed Apr 2, 2020
    Copy the full SHA
    730a58d View commit details

Commits on Apr 7, 2020

  1. Merge pull request #1256 from adisbladis/poetry2nix-plugins

    Use Poetry & Poetry2nix for environment and plugin management
    grahamc authored Apr 7, 2020
    Copy the full SHA
    7a68012 View commit details
Showing with 701 additions and 403 deletions.
  1. +1 −1 .github/workflows/ci.yml
  2. +10 −17 ci/mypy-ratchet.sh
  3. +12 −0 ci/run-ratchet.sh
  4. +39 −0 default.nix
  5. +211 −0 doc/plugins/authoring.rst
  6. +24 −18 nixops/nix_expr.py
  7. 0 nixops/py.typed
  8. +1 −1 nixops/script_defs.py
  9. +9 −0 overrides.nix
  10. +341 −0 poetry.lock
  11. +27 −0 pyproject.toml
  12. +4 −124 release.nix
  13. +0 −32 setup.py
  14. +21 −3 shell.nix
  15. +0 −206 tests/none-backend.nix
  16. +1 −1 tests/unit/test_nix_expr.py
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ jobs:
- name: Nix
uses: cachix/install-nix-action@v8
- name: Build
run: 'nix-build --quiet release.nix -A build.x86_64-linux -I nixpkgs=channel:19.09'
run: 'nix-build --quiet release.nix -A nixops.x86_64-linux -I nixpkgs=channel:nixos-20.03'
black:
runs-on: ubuntu-latest
steps:
27 changes: 10 additions & 17 deletions ci/mypy-ratchet.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash ../shell.nix
#!/usr/bin/env bash

set -eu

cd "${0%/*}/.."

scratch=$(mktemp -d -t tmp.XXXXXXXXXX)
function finish {
rm -rf "$scratch"
}
trap finish EXIT
# trap finish EXIT

cp ci/run-ratchet.sh $scratch/

head=$(git rev-parse HEAD)
base=origin/${GITHUB_BASE_REF:-master}
@@ -17,22 +20,12 @@ git fetch origin
echo "Checking base branch at %s, then PR at %s...\n" "$base" "$head"

git checkout "$base"
mypy \
--any-exprs-report "$scratch/base" \
--linecount-report "$scratch/base" \
--lineprecision-report "$scratch/base" \
--txt-report "$scratch/base" \
nixops
nix-shell shell.nix --run "$scratch/run-ratchet.sh $scratch base"

git checkout "$head"
mypy \
--any-exprs-report "$scratch/head" \
--linecount-report "$scratch/head" \
--lineprecision-report "$scratch/head" \
--txt-report "$scratch/head" \
nixops
nix-shell shell.nix --run "$scratch/run-ratchet.sh $scratch head"

diff --ignore-all-space -u100 -r "$scratch/base/" "$scratch/head/" || true

mypy ./ci/ratchet.py
python3 ./ci/ratchet.py "$scratch"
nix-shell shell.nix --run "mypy ./ci/ratchet.py"
nix-shell shell.nix --run "python3 ./ci/ratchet.py $scratch"
12 changes: 12 additions & 0 deletions ci/run-ratchet.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -eu

scratch=$1
sub=$2

exec mypy \
--any-exprs-report "$scratch/$sub" \
--linecount-report "$scratch/$sub" \
--lineprecision-report "$scratch/$sub" \
--txt-report "$scratch/$sub" \
nixops
39 changes: 39 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{ nixpkgs ? <nixpkgs>
, pkgs ? import nixpkgs {}
}:

let

overrides = import ./overrides.nix { inherit pkgs; };

in pkgs.poetry2nix.mkPoetryApplication {
# Once the latest poetry2nix release has reached 20.03 use projectDir instead of:
# - src
# - pyproject
# - poetrylock

src = pkgs.lib.cleanSource ./.;
pyproject = ./pyproject.toml;
poetrylock = ./poetry.lock;

propagatedBuildInputs = [
pkgs.openssh
];

nativeBuildInputs = [
pkgs.docbook5_xsl
pkgs.libxslt
];

overrides = [
pkgs.poetry2nix.defaultPoetryOverrides
overrides
];

# TODO: Manual build should be included via pyproject.toml
postInstall = ''
cp ${(import ./doc/manual { revision = "1.8"; inherit nixpkgs; }).optionsDocBook} doc/manual/machine-options.xml
make -C doc/manual install docdir=$out/share/doc/nixops mandir=$out/share/man
'';

}
211 changes: 211 additions & 0 deletions doc/plugins/authoring.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
Authoring a Plugin
====

NixOps plugins extend NixOps core to support additional hosting
providers and resource types.

Some example plugins include:

- https://github.com/NixOS/nixops-aws
- https://github.com/NixOS/nixops-hetzner
- https://github.com/nix-community/nixops-vbox
- https://github.com/nix-community/nixops-libvirtd
- https://github.com/nix-community/nixops-datadog

This guide is light on the details, and intends to describe just the
supported hooks and integration process.

Packaging with Poetry and poetry2nix
====

NixOps and its plugins are packaged as standard Python applications.
Most packages will use `Poetry <https://python-poetry.org>`_ and
`poetry2nix <https://github.com/nix-community/poetry2nix>`_ for
packaging with Nix.

Note: NixOps is formatted with ``black`` and strictly typechecked with
``mypy``. Your project should follow these guidelines as well, and use
a mypy configuration at least as strict as the NixOps mypy
configuration.

First, create a ``pyproject.toml`` (see `PEP-0517
<https://www.python.org/dev/peps/pep-0517/>`_ to describe your
project. This is intsead of a ``setup.py``, and using both may cause
confusing build errors. Only use a ``pyproject.toml``::

[tool.poetry]
name = "nixops_neatcloud"
version = "1.0"
description = "NixOps plugin for NeatCloud"
authors = ["Your Name <your.name@example.com>"]
license = "MIT"
include = [ "nixops_neatcloud/nix/*.nix" ]

[tool.poetry.dependencies]
python = "^3.7"
nixops = {git = "https://github.com/NixOS/nixops.git", rev = "master"}

[tool.poetry.plugins."nixops"]
neatcloud = "nixops_neatcloud.plugin"

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"

Now create your first ``poetry.lock`` file with ``poetry lock``::

nixops_neatcloud$ nix-shell -p poetry
[nix-shell:nixops_neatcloud]$ poetry lock
Creating virtualenv nixops_neatcloud-FrXThxiS-py3.7 in ~/.cache/pypoetry/virtualenvs
Updating dependencies
Resolving dependencies... (2.1s)

Writing lock file

Exit the Nix shell, and create the supporting Nix files.

Create a ``default.nix``::

{ pkgs ? import <nixpkgs> {} }:
let
overrides = import ./overrides.nix { inherit pkgs; };
in pkgs.poetry2nix.mkPoetryApplication {
projectDir = ./.;
overrides = pkgs.poetry2nix.overrides.withDefaults overrides;
}

And a minimal ``overrides.nix``::

{ pkgs }:

self: super: {
nixops = super.nixops.overridePythonAttrs({ nativeBuildInputs ? [], ... }: {
format = "pyproject";
nativeBuildInputs = nativeBuildInputs ++ [ self.poetry ];
});
}

and finally, a ``shell.nix``::

{ pkgs ? import <nixpkgs> {} }:
let
overrides = import ./overrides.nix { inherit pkgs; };
in pkgs.mkShell {
buildInputs = [
(pkgs.poetry2nix.mkPoetryEnv {
projectDir = ./.;
overrides = pkgs.poetry2nix.overrides.withDefaults overrides;
})
pkgs.poetry
];
}

Now you can enter a Nix and Poetry shell to develop on your plugin::

nixops_neatcloud$ nix-shell
[nix-shell:nixops_neatcloud]$ poetry install
[nix-shell:nixops_neatcloud]$ poetry shell

Note: ``install`` is making a virtual environment, and does not
install anything in the traditional sense.

Create an empty file at ``nixops_neatcloud/plugin.py``, and then
you'll be able to list plugins and see your plugin:

Now you can list plugins and see your plugin is installed::

(nixops_neatcloud-FrXThxiS-py3.7)
nixops_neatcloud$ nixops list-plugins
+-------------------+
| Installed Plugins |
+-------------------+
| neatcloud |
+-------------------+

At this point, you can develop your plugin from within this shell,
running ``nixops`` and ``mypy nixops_neatcloud``./

Plug-in Loading
=====

NixOps uses `Pluggy <https://pluggy.readthedocs.io/en/latest/>`_ to
discover and load plugins. The glue which hooks things together is in
``pyproject.toml``::

[tool.poetry.plugins."nixops"]
neatcloud = "nixops_neatcloud.plugin"

NixOps implements a handful of hooks which your plugin can integrate
with. See ``nixops/plugins/hookspec.py`` for a complete list.

Developing NixOps and a plugin at the same time
====

In this case you want a mutable copy of NixOps and your plugin. Since
we are developing the plugin like any other Python program, we can
specify a relative path to NixOps's source in the pyproject.toml::

nixops = { path = "../nixops" }

Then run `poetry lock; poetry install; poetry shell` like normal.

Troubleshooting
====

If you run in to trouble, you might try deleting some things::

$ rm -rf nixops_neatcloud.egg-info pip-wheel-metadata/

Building a dependency fails
----

First, run your ``nix-shell`` or ``nix-build`` with ``--keep-going``
and then again with ``--jobs 1`` to isolate the cause. The first run
will build everything it can complete, and the second one will build
only one derivation and then fail::

nixops_neatcloud$ nix-shell -j1 --keep-going
these derivations will be built:
/nix/store/3s2a0hky73b24m4yppd7581c9w2clpnb-python3.7-nixops-1.8.0.drv
/nix/store/bv6gwayic2xxx3pd489d4gbs03kafxsd-python3-3.7.6-env.drv
building '/nix/store/3s2a0hky73b24m4yppd7581c9w2clpnb-python3.7-nixops-1.8.0.drv'...
[...]
Traceback (most recent call last):
File "nix_run_setup", line 8, in <module>
exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))
File "/nix/store/n8nviwmllwqv0fjsar8v8k8gjap1vhcw-python3-3.7.6/lib/python3.7/tokenize.py", line 447, in open
buffer = _builtin_open(filename, 'rb')
FileNotFoundError: [Errno 2] No such file or directory: 'setup.py'
builder for '/nix/store/3s2a0hky73b24m4yppd7581c9w2clpnb-python3.7-nixops-1.8.0.drv' failed with exit code 1
cannot build derivation '/nix/store/bv6gwayic2xxx3pd489d4gbs03kafxsd-python3-3.7.6-env.drv': 1 dependencies couldn't be built
error: build of '/nix/store/bv6gwayic2xxx3pd489d4gbs03kafxsd-python3-3.7.6-env.drv' failed

If a dependency is missing, add the dependency to your
``pyproject.toml``, and add an override like the Toml example for Zipp.

Zipp can't find toml
----

Add zipp to your ``overrides.nix``, providing toml explicitly::

{ pkgs }:

self: super: {
zipp = super.zipp.overridePythonAttrs({ propagatedBuildInputs ? [], ... } : {
propagatedBuildInputs = propagatedBuildInputs ++ [
self.toml
];
});
}

FileNotFoundError: [Errno 2] No such file or directory: 'setup.py'
----

This dependency needs to be built in the ``pyproject`` format, which
means it will also need poetry as a dependency. Add this to your
``overrides.nix``::

package-name = super.package-name.overridePythonAttrs({ nativeBuildInputs ? [], ... }: {
format = "pyproject";
nativeBuildInputs = nativeBuildInputs ++ [ self.poetry ];
});
Loading