Issue #20997 has been updated by Andrew Parker.
Looking at that data structure, this is not the fault of the module tool. The
interpretation of the response from the forge has to completely alter. Before
the change the specification of that data structure could be stated as "a map
of module name to the module's list of releases". That specification now no
longer holds because there is now a special "module" ("_warnings") that isn't a
module. Therefore any reasonable consumer of the API will no longer work now
that "_warnings" has been introduced.
----------------------------------------
Bug #20997: `puppet module install` fails cryptically when served bad module
information
https://projects.puppetlabs.com/issues/20997#change-91977
* Author: Adrien Thebo
* Status: In Topic Branch Pending Review
* Priority: Normal
* Assignee:
* Category: module tool
* Target version:
* Affected Puppet version: 3.0.0
* Keywords:
* Branch: https://github.com/puppetlabs/puppet/pull/1684
----------------------------------------
If a Puppet module on the Forge has poorly formed metadata, querying for the
module metadata can emit an extra field which breaks the Puppet module tool.
For instance, an early version of
[adrien/pe_upgrade](http://forge.puppetlabs.com/adrien/pe_upgrade/0.1.0) had a
malformed version specifier on a module dependency, using the Ruby Gems `'>=
0'` specification instead of `'>= 0.0.0'`. When querying the module data from
the forge, the following data is returned:
<pre>
{"adrien/pe_upgrade"=>
[{"file"=>"/system/releases/a/adrien/adrien-pe_upgrade-0.4.0.tar.gz",
"version"=>"0.4.0",
"dependencies"=>
[["nanliu/staging", "0.x"], ["puppetlabs/stdlib", ">= 2.5.1"]]},
{"file"=>"/system/releases/a/adrien/adrien-pe_upgrade-0.4.2.tar.gz",
"version"=>"0.4.2",
"dependencies"=>
[["nanliu/staging", "0.x"], ["puppetlabs/stdlib", ">= 2.5.1"]]}],
"nanliu/staging"=>
[{"file"=>"/system/releases/n/nanliu/nanliu-staging-0.1.0.tar.gz",
"version"=>"0.1.0",
"dependencies"=>[]},
{"file"=>"/system/releases/n/nanliu/nanliu-staging-0.2.0.tar.gz",
"version"=>"0.2.0",
"dependencies"=>[]},
{"file"=>"/system/releases/n/nanliu/nanliu-staging-0.2.1.tar.gz",
"version"=>"0.2.1",
"dependencies"=>[]},
{"file"=>"/system/releases/n/nanliu/nanliu-staging-0.3.0.tar.gz",
"version"=>"0.3.0",
"dependencies"=>[]}],
"puppetlabs/stdlib"=>
[{"file"=>"/system/releases/p/puppetlabs/puppetlabs-stdlib-3.2.0.tar.gz",
"version"=>"3.2.0",
"dependencies"=>[]},
{"file"=>"/system/releases/p/puppetlabs/puppetlabs-stdlib-4.1.0.tar.gz",
"version"=>"4.1.0",
"dependencies"=>[]}],
"_warnings"=>
["Dependency nanliu/staging for module adrien/pe_upgrade had invalid version
range \">= 0\"",
"Dependency nanliu/staging for module adrien/pe_upgrade had invalid version
range \">= 0\""]}
</pre>
(Metadata was truncated for brevity.)
When running `puppet module install adrien/pe_upgrade` this module metadata is
fetched.
https://github.com/puppetlabs/puppet/blob/3.0.0/lib/puppet/module_tool/shared_behaviors.rb#L34
walks over this data structure, and it assumes that each entry in the hash is
a key/value pair with the key being the module name and the value being an
array of metadata for each version of that module. However the `_warnings`
field only contains strings, which breaks the assumption that the PMT is making.
The the module tool is fetching this information it tries to fetch the version
of the module
(https://github.com/puppetlabs/puppet/blob/3.0.0/lib/puppet/module_tool/shared_behaviors.rb#L39).
It assumes that the given value is a hash, tries to look up the version field,
and if that fails then it falls back to using the SemVer `MIN` value.
There are three problems here:
1. _warnings is not a module and shouldn't be treated as such when reading
metadata
1. The PMT shouldn't blindly rescue errors parsing the SemVer
1. It's `SemVer::MIN`, not `SemVer.MIN`
For a long time the Puppet Forge would silently swallow errors with module
metadata, but on May 23 it started handling that correctly and started emitting
the `_warnings` field. Any module with malformed module
### Expected behavior
<pre>
puppet module install adrien/pe_upgrade --version 0.4.2
Notice: Preparing to install into /home/adrien/.puppet/modules ...
Notice: Downloading from https://forge.puppetlabs.com ...
Notice: Installing -- do not interrupt ...
Warning: Dependency nanliu/staging for module adrien/pe_upgrade had invalid
version range ">= 0"
Warning: Dependency nanliu/staging for module adrien/pe_upgrade had invalid
version range ">= 0"
/home/adrien/.puppet/modules
└─┬ adrien-pe_upgrade (v0.4.2)
├── nanliu-staging (v0.3.0)
└── puppetlabs-stdlib (v4.1.0)
</pre>
### Actual behavior
<pre>
puppet module install adrien/pe_upgrade
Notice: Preparing to install into /home/adrien/.puppet/modules ...
Notice: Downloading from https://forge.puppetlabs.com ...
Error: undefined method `MIN' for SemVer:Class
Error: Try 'puppet help module install' for usage
</pre>
### Workaround
Installing the exact version of the faulty module works around this:
<pre>
puppet module install adrien/pe_upgrade --version 0.4.2
Notice: Preparing to install into /home/adrien/.puppet/modules ...
Notice: Downloading from https://forge.puppetlabs.com ...
Notice: Installing -- do not interrupt ...
/home/adrien/.puppet/modules
└─┬ adrien-pe_upgrade (v0.4.2)
├── nanliu-staging (v0.3.0)
└── puppetlabs-stdlib (v4.1.0)
</pre>
- - -
#### Bonus stage:
The error message being emitted from the Forge is misleading:
"Dependency nanliu/staging for module adrien/pe_upgrade had invalid version
range ">= 0"
1. adrien/pe_upgrade is the one with the invalid version range, not
nanliu/staging
1. the error message doesn't indicate which version of adrien/pe_upgrade has
the bad version.
--
You have received this notification because you have either subscribed to it,
or are involved in it.
To change your notification preferences, please click here:
http://projects.puppetlabs.com/my/account
--
You received this message because you are subscribed to the Google Groups
"Puppet Bugs" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/puppet-bugs?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.