We have two goals:
- Ensure that we have local deterministic cache of puppet modules pulled from the forge
- Force all server requests to go through artifactory where possible
We're going to use a remote repo type of generic pointing to forgeapi.puppetlabs.com. The json in this gist should provide the relevant information.
This is where things get KIND of hairy:
puppet module
makes calls to some endpoints to find a module with pagination query params
- /modules
- /users
- /releases
Because artifactory doesn't really understand the pagination stuff, what ends up happening is the cached releases
call, forces an infinite loop:
Debug: HTTP GET https://puppetforge.mydomain.com/v3/releases?module=puppetlabs-stdlib&limit=20&offset=20
over and over and over again because Artifactory is serving a cached copy of that with the same pagination data. Ideally what would happen here is that Artifactory would build the FINAL releases,modules,users from iterating through all pagination.
What this means is that for now we need to just send all of those requests to the forge directly.
However we CAN at least proxy and cache the actual tarballs of the modules cleanly so for requests to v3/files
we're going to send those directly to artifactory.
If we needed to recover those files for whatever reason, we could though doing it via puppet module install
would likely fail if forgeapi.puppetlabs.com was offline for any reason.
It's not a perfect solution but it helps a bit.
It may be possible to write a user plugin for Artifactory that handles those specific requests more cleanly to build final consolidated files with no pagination data listing everything.
What would be nicer is if Puppet made a v4 api that offered releases.gz
, modules.gz
and users.gz
to make proxying and caching the forge for this reason much easier.
$ bundle exec puppet module install --debug --module_repository=https://puppetforge.mydomain.com -i .tmp puppetlabs-stdlib
Debug: Runtime environment: puppet_version=3.7.4, ruby_version=2.1.5, run_mode=user, default_encoding=UTF-8
Notice: Preparing to install into /home/jvincent/.tmp ...
Notice: Downloading from https://puppetforge.mydomain.com ...
Debug: HTTP GET https://puppetforge.mydomain.com/v3/releases?module=puppetlabs-stdlib
Debug: Failed to load library 'pe_license' for feature 'pe_license'
Debug: HTTP GET https://puppetforge.mydomain.com/v3/releases?module=puppetlabs-stdlib&limit=20&offset=20
Debug: Failed to load library 'pe_license' for feature 'pe_license'
Debug: HTTP GET https://puppetforge.mydomain.com/v3/releases?module=puppetlabs-stdlib&limit=20&offset=40
Debug: Failed to load library 'pe_license' for feature 'pe_license'
Info: Resolving dependencies ...
Info: Preparing to install ...
Debug: HTTP GET https://puppetforge.mydomain.com/v3/files/puppetlabs-stdlib-4.13.1.tar.gz
Debug: Failed to load library 'pe_license' for feature 'pe_license'
Debug: Executing 'gzip -dc /home/jvincent/.puppet/var/puppet-module/cache/puppetlabs-stdlib20161013-9639-1ihx3s7 | tar xof -'
Debug: Executing 'find . -type d -exec chmod 755 {} +'
Debug: Executing 'find . -type f -exec chmod a-wst {} +'
Debug: Executing 'chown -R 1000:1000 .'
Notice: Installing -- do not interrupt ...
/home/jvincent/.tmp
└── puppetlabs-stdlib (v4.13.1)
Hello @lusis, I'm trying out latest Artifactory version and it seems that it works out of the box with
puppet module install
OTOH I have problems making it work with
librarian-puppet
, does your solution work with Librarian? Did you try? Thanks!