Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Referencing a non-existing stack variable error is hard to understand #1846

Closed
matti opened this issue Feb 12, 2017 · 4 comments · Fixed by #1884
Closed

Referencing a non-existing stack variable error is hard to understand #1846

matti opened this issue Feb 12, 2017 · 4 comments · Fixed by #1884
Labels

Comments

@matti
Copy link
Contributor

matti commented Feb 12, 2017

 [error] undefined method `match' for nil:NilClass
Did you mean?  catch
@kke kke added the cli label Feb 13, 2017
@kke
Copy link
Contributor

kke commented Feb 13, 2017

What kind of yml does this come from? It should say "Undeclared variable 'foo' ...." if you're trying to use an unknown one.

@matti
Copy link
Contributor Author

matti commented Feb 14, 2017

see affinitylol in this stack:

stack: matti/pgweb
version: 0.0.1
description: sosedoff/pg-web

variables:
  affinity:
    type: string
    default: label!=no-pgweb
    from:
      prompt:
  lb_service:
    type: string
    from:
      service_link:
        prompt: Pick a loadbalancer
        image: kontena/lb
  lb_domain:
    type: string
    default: pgweb.example.net
    from:
      prompt:

services:
  web:
    image: sosedoff/pgweb:latest
    deploy:
      wait_for_port: 8081
      interval: 1d
    health_check:
      protocol: http
      port: 8081
      interval: 60
      uri: /
      initial_delay: 60
      timeout: 2
    affinity:
      - {{ affinitylol }}
    environment:
      - KONTENA_LB_INTERNAL_PORT=8081
      - KONTENA_LB_VIRTUAL_HOSTS={{ lb_domain }}
      - KONTENA_LB_CUSTOM_SETTINGS=redirect scheme https if !{ ssl_fc }
    links:
      - {{ lb_service }}

@SpComb
Copy link
Contributor

SpComb commented Feb 22, 2017

It looks like the stackfile interpolation results in nil values for invalid liquid {{ ... }} variables:

stack: test/variables
variables:
  asdf:
    type: string
    default: asdf
services:
  test:
    image: redis
    affinity:
      - {{ asdflol }}

Results in the following Kontena::Cli::Stacks::YAML::Reader.fully_interpolated_yaml:

{"stack"=>"test/variables", "variables"=>{"asdf"=>{"type"=>"string", "default"=>"asdf"}}, "services"=>{"test"=>{"image"=>"redis", "affinity"=>[nil]}}}

The nil then explodes as if the YAML had affinity: - null:

NoMethodError: undefined method `match' for nil:NilClass
Did you mean?  catch
  /home/kontena/kontena/kontena/cli/lib/kontena/cli/stacks/yaml/custom_validators/affinities_validator.rb:13:in `block in validate'
  /home/kontena/kontena/kontena/cli/lib/kontena/cli/stacks/yaml/custom_validators/affinities_validator.rb:13:in `each'
  /home/kontena/kontena/kontena/cli/lib/kontena/cli/stacks/yaml/custom_validators/affinities_validator.rb:13:in `find_all'
  /home/kontena/kontena/kontena/cli/lib/kontena/cli/stacks/yaml/custom_validators/affinities_validator.rb:13:in `validate'
  /home/kontena/kontena/kontena/cli/vendor/bundle/ruby/2.3.0/gems/hash_validator-0.7.0/lib/hash_validator/validators/optional_validator.rb:14:in `validate'
  /home/kontena/kontena/kontena/cli/vendor/bundle/ruby/2.3.0/gems/hash_validator-0.7.0/lib/hash_validator/validators/hash_validator.rb:21:in `block in validate'
  /home/kontena/kontena/kontena/cli/vendor/bundle/ruby/2.3.0/gems/hash_validator-0.7.0/lib/hash_validator/validators/hash_validator.rb:20:in `each'
  /home/kontena/kontena/kontena/cli/vendor/bundle/ruby/2.3.0/gems/hash_validator-0.7.0/lib/hash_validator/validators/hash_validator.rb:20:in `validate'
  /home/kontena/kontena/kontena/cli/vendor/bundle/ruby/2.3.0/gems/hash_validator-0.7.0/lib/hash_validator/base.rb:28:in `validate'
  /home/kontena/kontena/kontena/cli/vendor/bundle/ruby/2.3.0/gems/hash_validator-0.7.0/lib/hash_validator/base.rb:10:in `initialize'
  /home/kontena/kontena/kontena/cli/vendor/bundle/ruby/2.3.0/gems/hash_validator-0.7.0/lib/hash_validator/base.rb:19:in `new'
  /home/kontena/kontena/kontena/cli/vendor/bundle/ruby/2.3.0/gems/hash_validator-0.7.0/lib/hash_validator/base.rb:19:in `validate'
  /home/kontena/kontena/kontena/cli/vendor/bundle/ruby/2.3.0/gems/hash_validator-0.7.0/lib/hash_validator.rb:3:in `validate'
  /home/kontena/kontena/kontena/cli/lib/kontena/cli/stacks/yaml/validations.rb:70:in `validate_options'
  /home/kontena/kontena/kontena/cli/lib/kontena/cli/stacks/yaml/validator_v3.rb:36:in `block in validate'
  /home/kontena/kontena/kontena/cli/lib/kontena/cli/stacks/yaml/validator_v3.rb:31:in `each'
  /home/kontena/kontena/kontena/cli/lib/kontena/cli/stacks/yaml/validator_v3.rb:31:in `validate'
  /home/kontena/kontena/kontena/cli/lib/kontena/cli/stacks/yaml/reader.rb:168:in `validate'
  /home/kontena/kontena/kontena/cli/lib/kontena/cli/stacks/yaml/reader.rb:125:in `execute'
  /home/kontena/kontena/kontena/cli/lib/kontena/cli/stacks/common.rb:64:in `stack_from_yaml'
  /home/kontena/kontena/kontena/cli/lib/kontena/cli/stacks/install_command.rb:23:in `execute'
  /home/kontena/kontena/kontena/cli/lib/kontena/command.rb:191:in `run'
  /home/kontena/kontena/kontena/cli/vendor/bundle/ruby/2.3.0/gems/clamp-1.1.2/lib/clamp/subcommand/execution.rb:11:in `execute'
  /home/kontena/kontena/kontena/cli/lib/kontena/command.rb:191:in `run'
  /home/kontena/kontena/kontena/cli/vendor/bundle/ruby/2.3.0/gems/clamp-1.1.2/lib/clamp/subcommand/execution.rb:11:in `execute'
  /home/kontena/kontena/kontena/cli/lib/kontena/command.rb:191:in `run'
  /home/kontena/kontena/kontena/cli/vendor/bundle/ruby/2.3.0/gems/clamp-1.1.2/lib/clamp/command.rb:132:in `run'
  bin/kontena:16:in `<top (required)>'

@SpComb
Copy link
Contributor

SpComb commented Feb 22, 2017

The Kontena::Cli::Stacks::YAML::Reader calls Liquid::Template.render(..., strict_variables: true), but it does not check the resulting template.errors. In this case, that would contain

[#<Liquid::UndefinedVariable: Liquid error: undefined variable asdflol>]

The reader should probably just use Liquid::Template.render! instead, although the resulting error is missing any file:line context :(

 [error] Liquid error: undefined variable asdflol

SpComb added a commit that referenced this issue Mar 1, 2017
The current CLI stacks YAML reader uses `Liquid::Template.render(..., strict_variables: true)`. This means that that any references to undefined variables will omit the tag from the output and push an error message into `template.errors`. The CLI ignores those errors, which cascades into other difficult to debug issues when parts are missing from the resulting YAML:

* #1846
* #1890

A Liquid bug also means that optional `required: false` stack variables also behave as undefined variables: Shopify/liquid#749

This PR fixes the CLI stack YAML reader to:

* Workaround Liquid bugs to treat optional  `required: false` stack variables as falsey values for Liquid conditional blocks

* Fail `kontena stack ...` fast with a  `Liquid error: undefined variable ... ` message if the YAML contains invalid variable references.

    These errors would be nicer if they also contained the source YAML `file:line`, but that is missing from the `Liquid::UndefinedVariable` error...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants