NixOS / nixops

NixOps is a tool for deploying to NixOS machines in a network or cloud.
https://nixos.org/nixops
GNU Lesser General Public License v3.0
1.86k stars 365 forks source link

eval-machine-info.nix: ported to modules #1508

Open pasqui23 opened 2 years ago

pasqui23 commented 2 years ago

Fixes https://github.com/NixOS/nixops/issues/1486 Done:

roberth commented 2 years ago

Heads up about the resources; just a merged a PR that touches that.

pasqui23 commented 2 years ago

what pr @roberth ?

roberth commented 2 years ago

https://github.com/NixOS/nixops/pull/1506

pasqui23 commented 2 years ago

So do I have to rebase on master?

pasqui23 commented 2 years ago

Ok I did rebase on master

pasqui23 commented 2 years ago

Ok I've tried and failed to build a network, it goes in infinite recursion while evaluating scrubOptionValues in info.machines

pasqui23 commented 2 years ago

It still goes in infinite recursion, I need to know what nixops expects exactly from this file and what can be safely removed.

roberth commented 2 years ago

it goes in infinite recursion

Maybe the attrsOfs need to be lazyAttrsOfs. attrsOf can only return its attrset by inspecting the children for mkIf false values and filtering out those attributes. That makes it more strict than lazyAttrsOf, which will return the spine of the attribute set (attr names + thunks) without inspecting those thunks.

roberth commented 2 years ago

I need to know what nixops expects exactly

I don't expect this to be documented anywhere.

pasqui23 commented 2 years ago

I need to know what nixops expects exactly

I don't expect this to be documented anywhere.

I don't need to be fully documented,only to tell me what the nixops cli and plugins take from the eval-machine-info.nix file right now. If, after merging this, you go and change that I would not care abut it.

pasqui23 commented 2 years ago

it goes in infinite recursion

Maybe the attrsOfs need to be lazyAttrsOfs. attrsOf can only return its attrset by inspecting the children for mkIf false values and filtering out those attributes. That makes it more strict than lazyAttrsOf, which will return the spine of the attribute set (attr names + thunks) without inspecting those thunks.

Tried with lazyAttrsOf but it still gives me the same problems.

pasqui23 commented 2 years ago

Ok it was an error on my part, I forgot network.nodesExtraArgs = { inherit inputs; }; in my config. 🤦🤦🤦🤦

pasqui23 commented 2 years ago

Ok now the error I get is

; nixops list
error: The option `resources' is used but not defined.

Which I don't know where even to begin

roberth commented 2 years ago
; nixops list
error: The option `resources' is used but not defined.

Just add a default = { }; to the resources option.

It's some silly ux :/

pasqui23 commented 2 years ago

Ok latest error is definetly on the python side

; nixops list                       
def-matcher: command not found
Traceback (most recent call last):
  File "/nix/store/nbrhfv3wcdsiish3y3k64jgs9826k2xc-python3.8-nixops-2.0.0/bin/.nixops-wrapped", line 9, in <module>
    sys.exit(main())
  File "/nix/store/nbrhfv3wcdsiish3y3k64jgs9826k2xc-python3.8-nixops-2.0.0/lib/python3.8/site-packages/nixops/__main__.py", line 56, in main
    args.op(args)
  File "/nix/store/nbrhfv3wcdsiish3y3k64jgs9826k2xc-python3.8-nixops-2.0.0/lib/python3.8/site-packages/nixops/script_defs.py", line 200, in op_list_deployments
    depl.evaluate()
  File "/nix/store/nbrhfv3wcdsiish3y3k64jgs9826k2xc-python3.8-nixops-2.0.0/lib/python3.8/site-packages/nixops/deployment.py", line 431, in evaluate
    self.evaluate_network()
  File "/nix/store/nbrhfv3wcdsiish3y3k64jgs9826k2xc-python3.8-nixops-2.0.0/lib/python3.8/site-packages/nixops/deployment.py", line 423, in evaluate_network
    self.description = config.get("description", self.default_description)
  File "/nix/store/nbrhfv3wcdsiish3y3k64jgs9826k2xc-python3.8-nixops-2.0.0/lib/python3.8/site-packages/nixops/util.py", line 493, in set
    self._set_attr(name, x)
  File "/nix/store/nbrhfv3wcdsiish3y3k64jgs9826k2xc-python3.8-nixops-2.0.0/lib/python3.8/site-packages/nixops/deployment.py", line 250, in _set_attr
    self._set_attrs({name: value})
  File "/nix/store/nbrhfv3wcdsiish3y3k64jgs9826k2xc-python3.8-nixops-2.0.0/lib/python3.8/site-packages/nixops/deployment.py", line 243, in _set_attrs
    c.execute(
sqlite3.OperationalError: attempt to write a readonly database
roberth commented 2 years ago

sqlite3.OperationalError: attempt to write a readonly database

This is a known issue. https://github.com/NixOS/nixops/issues/1490

At this time, nixops deploy is more suitable for testing, as this command does request write access to the db.

pasqui23 commented 2 years ago
; nixops deploy                  
def-matcher: command not found
flatwoody> generating new SSH key pair... done
Password: 
flatwoody> setting state version to 22.05
flatwoody> waiting for SSH...
building all machine configurations...
trace: warning: Please use the actual nodes.* option instead of assigning machines to the config's top level
error: 'flatwoody' at /tmp/nixops-tmpnvee6p43/physical.nix:2:15 called without required argument 'pkgs'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/types.nix:199:25:

          198|                 file = def.file;
          199|                 value = def.value arg;
             |                         ^
          200|               }) defs);

       … while evaluating the attribute 'value'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/types.nix:199:17:

          198|                 file = def.file;
          199|                 value = def.value arg;
             |                 ^
          200|               }) defs);

       … while evaluating 'getType'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/types.nix:171:21:

          170|         let
          171|           getType = value:
             |                     ^
          172|             if isAttrs value && isCoercibleToString value

       … from call site

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/types.nix:179:16:

          178|           commonType = foldl' (type: def:
          179|             if getType def.value == type
             |                ^
          180|             then type

       … while evaluating anonymous lambda

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/types.nix:178:38:

          177|           # don't have the same type
          178|           commonType = foldl' (type: def:
             |                                      ^
          179|             if getType def.value == type

       … from call site

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/types.nix:178:24:

          177|           # don't have the same type
          178|           commonType = foldl' (type: def:
             |                        ^
          179|             if getType def.value == type

       … while evaluating 'merge'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/types.nix:169:20:

          168|       check = value: true;
          169|       merge = loc: defs:
             |                    ^
          170|         let

       … from call site

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/types.nix:195:38:

          194|             stringCoercibleSet = mergeOneOption;
          195|             lambda = loc: defs: arg: anything.merge
             |                                      ^
          196|               (loc ++ [ "<function body>" ])

       … while evaluating 'lambda'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/types.nix:195:33:

          194|             stringCoercibleSet = mergeOneOption;
          195|             lambda = loc: defs: arg: anything.merge
             |                                 ^
          196|               (loc ++ [ "<function body>" ])

       … from call site

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/types.nix:530:46:

          529|         coerce = unify: value: if isFunction value
          530|           then setFunctionArgs (args: unify (value args)) (functionArgs value)
             |                                              ^
          531|           else unify (if shorthandOnlyDefinesConfig then { config = value; } else value);

       … while evaluating 'unifyModuleSyntax'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:343:34:

          342|      of ‘options’, ‘config’ and ‘imports’ attributes. */
          343|   unifyModuleSyntax = file: key: m:
             |                                  ^
          344|     let

       … from call site

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/types.nix:530:39:

          529|         coerce = unify: value: if isFunction value
          530|           then setFunctionArgs (args: unify (value args)) (functionArgs value)
             |                                       ^
          531|           else unify (if shorthandOnlyDefinesConfig then { config = value; } else value);

       … while evaluating anonymous lambda

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/types.nix:530:33:

          529|         coerce = unify: value: if isFunction value
          530|           then setFunctionArgs (args: unify (value args)) (functionArgs value)
             |                                 ^
          531|           else unify (if shorthandOnlyDefinesConfig then { config = value; } else value);

       … from call site

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:397:8:

          396|       # works.
          397|     in f (args // extraArgs)
             |        ^
          398|   else

       … while evaluating 'applyIfFunction'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:373:29:

          372|
          373|   applyIfFunction = key: f: args@{ config, options, lib, ... }: if isFunction f then
             |                             ^
          374|     let

       … from call site

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:272:55:

          271|         if isFunction m || isAttrs m then
          272|           unifyModuleSyntax fallbackFile fallbackKey (applyIfFunction fallbackKey m args)
             |                                                       ^
          273|         else if isList m then

       … while evaluating 'unifyModuleSyntax'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:343:34:

          342|      of ‘options’, ‘config’ and ‘imports’ attributes. */
          343|   unifyModuleSyntax = file: key: m:
             |                                  ^
          344|     let

       … from call site

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:272:11:

          271|         if isFunction m || isAttrs m then
          272|           unifyModuleSyntax fallbackFile fallbackKey (applyIfFunction fallbackKey m args)
             |           ^
          273|         else if isList m then

       … while evaluating 'loadModule'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:270:53:

          269|       # Like unifyModuleSyntax, but also imports paths and calls functions if necessary
          270|       loadModule = args: fallbackFile: fallbackKey: m:
             |                                                     ^
          271|         if isFunction m || isAttrs m then

       … from call site

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:311:22:

          310|           let
          311|             module = loadModule args parentFile "${parentKey}:anon-${toString n}" x;
             |                      ^
          312|             collectedImports = collectStructuredModules module._file module.key module.imports args;

       … while evaluating anonymous lambda

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:328:31:

          327|           disabledKeys = map moduleKey disabled;
          328|           keyFilter = filter (attrs: ! elem attrs.key disabledKeys);
             |                               ^
          329|         in map (attrs: attrs.module) (builtins.genericClosure {

       … from call site

       … while evaluating 'filterModules'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:324:36:

          323|       # modules recursively. It returns the final list of unique-by-key modules
          324|       filterModules = modulesPath: { disabled, modules }:
             |                                    ^
          325|         let

       … from call site

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:335:7:

          334|     in modulesPath: initialModules: args:
          335|       filterModules modulesPath (collectStructuredModules unknownModule "" initialModules args);
             |       ^
          336|

       … while evaluating anonymous lambda

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:334:37:

          333|
          334|     in modulesPath: initialModules: args:
             |                                     ^
          335|       filterModules modulesPath (collectStructuredModules unknownModule "" initialModules args);

       … from call site

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:180:25:

          179|       merged =
          180|         let collected = collectModules
             |                         ^
          181|           (specialArgs.modulesPath or "")

       … while evaluating 'reverseList'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/lists.nix:393:17:

          392|   */
          393|   reverseList = xs:
             |                 ^
          394|     let l = length xs; in genList (n: elemAt xs (l - n - 1)) l;

       … from call site

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:184:33:

          183|           ({ inherit lib options config specialArgs; } // specialArgs);
          184|         in mergeModules prefix (reverseList collected);
             |                                 ^
          185|

       … while evaluating 'byName'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:449:25:

          448|       */
          449|       byName = attr: f: modules:
             |                         ^
          450|         zipAttrsWith (n: concatLists)

       … from call site

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:466:21:

          465|       # an attrset 'name' => list of submodules that declare ‘name’.
          466|       declsByName = byName "options" (module: option:
             |                     ^
          467|           [{ inherit (module) _file; options = option; }]

       … while evaluating the attribute 'matchedOptions'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:510:14:

          509|     in {
          510|       inherit matchedOptions;
             |              ^
          511|

       … while evaluating 'mapAttrsRecursiveCond'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/attrsets.nix:296:36:

          295|   */
          296|   mapAttrsRecursiveCond = cond: f: set:
             |                                    ^
          297|     let

       … from call site

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:192:28:

          191|           # For definitions that have an associated option
          192|           declaredConfig = mapAttrsRecursiveCond (v: ! isOption v) (_: v: v.value) options;
             |                            ^
          193|

       … while evaluating the attribute 'config'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:257:9:

          256|         options = checked options;
          257|         config = checked (removeAttrs config [ "_module" ]);
             |         ^
          258|         _module = checked (config._module);

       … while evaluating 'merge'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/types.nix:569:22:

          568|         check = x: isAttrs x || isFunction x || path.check x;
          569|         merge = loc: defs:
             |                      ^
          570|           (base.extendModules {

       … from call site

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:649:59:

          648|       if isDefined then
          649|         if all (def: type.check def.value) defsFinal then type.merge loc defsFinal
             |                                                           ^
          650|         else let allInvalid = filter (def: ! type.check def.value) defsFinal;

       … while evaluating the attribute 'value'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/modules.nix:660:27:

          659|     optionalValue =
          660|       if isDefined then { value = mergedValue; }
             |                           ^
          661|       else {};

       … while evaluating anonymous lambda

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/lib/types.nix:413:22:

          412|       merge = loc: defs:
          413|         mapAttrs (n: v: v.value) (filterAttrs (n: v: v ? value) (zipAttrsWith (name: defs:
             |                      ^
          414|             (mergeDefinitions (loc ++ [name]) elemType defs).optionalValue

       … from call site

       … while evaluating the attribute 'config.system.build.toplevel'

       at /nix/store/kxlj5h6jss1szi1rs0lkccggr18g0lza-python3.8-nixops-2.0.0/lib/python3.8/site-packages/nix/eval-machine-info.nix:161:32:

          160|   #TODO: take options and auter modules outputs for each node
          161|   nodes = lib.mapAttrs (n: v: {config = v;}) net.config.nodes;
             |                                ^
          162|

       … while evaluating anonymous lambda

       at /nix/store/kxlj5h6jss1szi1rs0lkccggr18g0lza-python3.8-nixops-2.0.0/lib/python3.8/site-packages/nix/eval-machine-info.nix:309:54:

          308|         mkdir -p $out
          309|         ${toString (lib.attrValues (lib.mapAttrs (n: v: ''
             |                                                      ^
          310|           ln -s ${v.config.system.build.toplevel} $out/${n}

       … from call site

       … while evaluating the attribute 'buildCommand' of the derivation 'nixops-machines'

       at /nix/store/531v6sf2db04x3xqphfkh7zg2dgw135k-source/pkgs/stdenv/generic/make-derivation.nix:205:7:

          204|     // (lib.optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) {
          205|       name =
             |       ^
          206|         let
error: evaluation of the deployment specification failed
pasqui23 commented 2 years ago

Where it would ask for a pkgs param?

roberth commented 2 years ago

The error seems to originate from the "physical" expression that's generated by nixops. You can see that expression with nixops show-physical.

pasqui23 commented 2 years ago
; nixops show-physical
def-matcher: command not found
Traceback (most recent call last):
  File "/nix/store/3y06h6hsw56r0bszn9pl7cdpz91qjbh1-python3.8-nixops-2.0.0/bin/.nixops-wrapped", line 9, in <module>
    sys.exit(main())
  File "/nix/store/3y06h6hsw56r0bszn9pl7cdpz91qjbh1-python3.8-nixops-2.0.0/lib/python3.8/site-packages/nixops/__main__.py", line 56, in main
    args.op(args)
  File "/nix/store/3y06h6hsw56r0bszn9pl7cdpz91qjbh1-python3.8-nixops-2.0.0/lib/python3.8/site-packages/nixops/script_defs.py", line 813, in op_show_physical
    depl.evaluate()
  File "/nix/store/3y06h6hsw56r0bszn9pl7cdpz91qjbh1-python3.8-nixops-2.0.0/lib/python3.8/site-packages/nixops/deployment.py", line 431, in evaluate
    self.evaluate_network()
  File "/nix/store/3y06h6hsw56r0bszn9pl7cdpz91qjbh1-python3.8-nixops-2.0.0/lib/python3.8/site-packages/nixops/deployment.py", line 423, in evaluate_network
    self.description = config.get("description", self.default_description)
  File "/nix/store/3y06h6hsw56r0bszn9pl7cdpz91qjbh1-python3.8-nixops-2.0.0/lib/python3.8/site-packages/nixops/util.py", line 493, in set
    self._set_attr(name, x)
  File "/nix/store/3y06h6hsw56r0bszn9pl7cdpz91qjbh1-python3.8-nixops-2.0.0/lib/python3.8/site-packages/nixops/deployment.py", line 250, in _set_attr
    self._set_attrs({name: value})
  File "/nix/store/3y06h6hsw56r0bszn9pl7cdpz91qjbh1-python3.8-nixops-2.0.0/lib/python3.8/site-packages/nixops/deployment.py", line 243, in _set_attrs
    c.execute(
sqlite3.OperationalError: attempt to write a readonly database
pasqui23 commented 2 years ago

https://github.com/NixOS/nixops/issues/1490 strikes again☹

roberth commented 2 years ago

1490 strikes againfrowning_face

https://github.com/NixOS/nixops/pull/1511 should work around it.

pasqui23 commented 2 years ago
; nixops show-physical
def-matcher: command not found
{
  flatwoody = { config, lib, pkgs, ... }: {
    config = {
      boot.kernelModules = [];
      networking = { extraHosts = "\n"; firewall.trustedInterfaces = []; };
      system.stateVersion = ( lib.mkDefault "22.05" );
    };
    imports = [
      {
        config.users.extraUsers.root.openssh.authorizedKeys.keys = [
          "ssh-ed25519 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX NixOps client key for flatwoody"
        ];
      }
    ];
  };
}
pasqui23 commented 2 years ago

The worst thing is that pkgs is not even used …

roberth commented 2 years ago

It seems that the "physical" expression is using the legacy format compatibility which isn't working correctly.

trace: warning: Please use the actual nodes.* option instead of assigning machines to the config's top level
pasqui23 commented 2 years ago

It seems that the "physical" expression is using the legacy format compatibility which isn't working correctly.

trace: warning: Please use the actual nodes.* option instead of assigning machines to the config's top level

No, I just have written the warning incorrectly

roberth commented 2 years ago

It seems that the "physical" expression is using the legacy format compatibility which isn't working correctly.

trace: warning: Please use the actual nodes.* option instead of assigning machines to the config's top level

No, I just have written the warning incorrectly

To pick out the legacy nodes from the freeformtype more easily, you can postcompose a function that puts the all the freeform stuff in a separate attribute.

Here's what that looks like (crux: freeformItems), although it shouldn't use // { merge = ... }. https://github.com/NixOS/nixpkgs/pull/163597/files#diff-619679c9f04a185497c93f14a481d1fe65cc75298f422169128a902ba907ffa2

It'd be better to use a copy of postTransform (https://github.com/NixOS/nixpkgs/pull/163601) instead of // { merge = ... }.

pasqui23 commented 2 years ago

Using your proposed deferredModule instead of anything in freeformType will give me:

; nixops create -n net.nix
def-matcher: command not found

WARNING: NixOps 1.0 -> 2.0 conversion step required

NixOps 2.0 added support for multiple storage backends.

Upgrade steps:
1. Open /home/me/src/my-nixos-conf
2. Add:
    network.storage.legacy = {
      databasefile = "~/.nixops/deployments.nixops";
    };
3. Rerun

See https://nixops.readthedocs.io/en/latest/manual/migrating.html#state-location for more guidance.

I suspect other storage backends would have similar problems as they would not be written with modules in mind.

pasqui23 commented 2 years ago

Even after making defaults.type = deferredModules it still does the same error.

pasqui23 commented 2 years ago

Where is the code evaluating physical.nix?

roberth commented 2 years ago

Where is the code evaluating physical.nix?

Roughly here it seems https://github.com/NixOS/nixops/blob/9b3ac919d87db872854fb528064821b959ac38c1/nixops/deployment.py#L639-L660

roberth commented 2 years ago

I suspect other storage backends would have similar problems as they would not be written with modules in mind.

Probably the network attr is treated as a legacy node instead of options?

pasqui23 commented 2 years ago

Probably the network attr is treated as a legacy node instead of options?

What do you mean? nodes = removeAttrs config (builtins.attrNames options); was written specifically to remove network and other from the legacy nodes.

pasqui23 commented 2 years ago

However the network.storage.legacy,as it is not defined by our config, it fall through to freeformType and gets merged as [{storage.legacy=...;}]. Again without actual options to configure the storage options it still would not be merged without the anything type.

pasqui23 commented 2 years ago

Where is the code evaluating physical.nix?

Roughly here it seems

https://github.com/NixOS/nixops/blob/9b3ac919d87db872854fb528064821b959ac38c1/nixops/deployment.py#L639-L660

That is the part that seems to generate the file. I mean what part in the nixops deploy command that runs nix-instantiate with the generated physical.nix?

roberth commented 2 years ago

nix-instantiate

That'd be nixops/evaluation.py

roberth commented 2 years ago

However the network.storage.legacy,as it is not defined by our config, it fall through to freeformType and gets merged as [{storage.legacy=...;}]. Again without actual options to configure the storage options it still would not be merged without the anything type.

I don't think I fully understand this problem as it relates to the code. Did you intend to rename this option?

Perhaps you could define only storage as an empty submodule with an anything freeformType?

Sorry if I can only throw ideas at you now. I'll have a more thorough look later.

pasqui23 commented 2 years ago

Perhaps you could define only storage as an empty submodule with an anything freeformType?

Tried that but I get:

; nixops create -n net.nix
error: The option `network.storage' is used but not defined.
pasqui23 commented 2 years ago

And yes adding default ={} did not solve it.

pasqui23 commented 2 years ago

Ok I've only tested it as the world's worst replacement for nixos-rebuild but it works!

pasqui23 commented 2 years ago

@roberth is there anything I have to do change about this pr?

pasqui23 commented 2 years ago

Also when I try to deploy my test it always ask me for password even if deployment.provisionSSHKey is defaulted to true. Is that related to https://github.com/NixOS/nixops/issues/1429 ?

roberth commented 2 years ago

Hi @pasqui23,

I've tried your PR and made some followup changes in #1515 (and accidentally pushed here; reverted that)

Also when I try to deploy my test it always ask me for password even if deployment.provisionSSHKey is defaulted to true. Is that related to #1429 ?

I don't know. Did you try without this PR? It's possible that recent changes to ssh flags handling haven't been fixed completely yet. #1464 (ssh keys for remote state) caused #1493 and subsequently #1509.

roberth commented 2 years ago

is there anything I have to do change about this pr?

I will test it some more and see if can find anything else. Perhaps you could review my additions in #1515?

pasqui23 commented 2 years ago

I don't know. Did you try without this PR?

I can't, my config relies on networking.nodesExtraArgs

pasqui23 commented 2 years ago

@roberth I've added a simplified way to define resources with defineResources.

pasqui23 commented 2 years ago

ok updated to only single import. @roberth What do you think about defineResource?

pasqui23 commented 2 years ago

@roberth also why don't we contribute both on this branch instead of duplicating the work?

roberth commented 2 years ago

ok updated to only single import. @roberth What do you think about defineResource?

That looks really useful. Defining one was a little cumbersome. DRY-ing this also puts the nixops core in charge of precisely how resources are defined, which might prove useful one day.

@roberth also why don't we contribute both on this branch instead of duplicating the work?

:+1:

pasqui23 commented 2 years ago

@roberth what is about that mypy-ratchet failing test?