Search code examples
chef-infraberkshelfberksfile

How do I configure a berks API server?


I want to implement the Berks API in my infrastructure, comprise of Jenkins, a Git server, and a Chef 12 Enterprise server. Each cookbook is in it's own repo in the Git server, per the Berkshelf way. Basically, I just want my top level Berksfile to contain ONLY role cookbooks, and then "let" Berkshelf pull the transitive dependencies from my Git server.

I've read the Berks API README for the server installation, but "where" do I install the cookbook? Do I install it on my Git server? I've read the the Chef server is Berks API ready, but I'm NOT pulling my cookbooks from there, I'm "uploading" them there.

Please help in my confusion.

Update 2

I was able to fix my SSL errors by changing the source line in my Berksfile from https to http, that is

source "http://myserver.domain.com:26200"

Update

I've configured my berks-api server's endpoints via the following config.json file in ~/.berkshelf/api-server/config.json

{
  "endpoints": [
    {
      "type": "chef_server",
       "options": {
       "url": "https://myserver.domain.com/organizations/berks-api",
       "client_name": "jenkins",
       "client_key": "/etc/berkshelf/api-server/jenkins.pem",
       "ssl_verify" : false
      }
    }
  ]
}

I then run berks-api, and see these first few lines on my terminal, so I know it's running

[2015-04-14T18:49:12.737950 #10033] INFO -- : Cache manager starting...
I, [2015-04-14T18:49:12.738207 #10033] INFO -- : Loading save from /root/.berkshelf/api-server/cerch
W, [2015-04-14T18:49:12.739368 #10033] WARN -- : Endpoints in config have changed - invalidating cache
I, [2015-04-14T18:49:12.739465 #10033] INFO -- : Cache contains 0 items
I, [2015-04-14T18:49:12.740341 #10033] INFO -- : Cache Builder starting...
I, [2015-04-14T18:49:12.846975 #10033] INFO -- : REST Gateway listening on 0.0.0.0:26200
I, [2015-04-14T18:49:12.887143 #10033] INFO -- : Processing chef_server: https://myserver.domain.com/organizations/berks-api
I, [2015-04-14T18:49:12.963418 #10033] INFO -- : Found 25 cookbooks from chef_server: https://myserver.domain.com/organizations/berks-api
I, [2015-04-14T18:49:12.964527 #10033] INFO -- : Processing metadata for 25 cookbooks with 0 remaining on chef_server: https://myserver.domain.com/organizations/berks-api

The Berksfile on one of my cookbooks has this line in it

source "https://myserver.domain.com:26200"

However, when I do a berks install on one of my Chef workstations, I get

Fetching cookbook index from https://myserver.domain.com:26200...
/opt/chef/embedded/lib/ruby/2.1.0/net/http.rb:920:in `connect': SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 read server hello A (Faraday::SSLError)
from /opt/chef/embedded/lib/ruby/2.1.0/net/http.rb:920:in `block in connect'
from /opt/chef/embedded/lib/ruby/2.1.0/timeout.rb:91:in `block in timeout'
from /opt/chef/embedded/lib/ruby/2.1.0/timeout.rb:101:in `call'
from /opt/chef/embedded/lib/ruby/2.1.0/timeout.rb:101:in `timeout'
from /opt/chef/embedded/lib/ruby/2.1.0/net/http.rb:920:in `connect'
from /opt/chef/embedded/lib/ruby/2.1.0/net/http.rb:863:in `do_start'
from /opt/chef/embedded/lib/ruby/2.1.0/net/http.rb:852:in `start'
from /opt/chef/embedded/lib/ruby/2.1.0/net/http.rb:1369:in `request'
from /opt/chef/embedded/lib/ruby/2.1.0/net/http.rb:1128:in `get'
from /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/faraday-0.9.1/lib/faraday/adapter/net_http.rb:80:in `perform_request'
from /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/faraday-0.9.1/lib/faraday/adapter/net_http.rb:40:in `block in call'
from /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/faraday-0.9.1/lib/faraday/adapter/net_http.rb:87:in `with_net_http_connection'
from /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/faraday-0.9.1/lib/faraday/adapter/net_http.rb:32:in `call'
from /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/faraday-0.9.1/lib/faraday/request/retry.rb:110:in `call'
from /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/faraday-0.9.1/lib/faraday/response.rb:8:in `call'
from /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/faraday-0.9.1/lib/faraday/response.rb:8:in `call'
from /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/faraday-0.9.1/lib/faraday/rack_builder.rb:139:in `build_response'
from /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/faraday-0.9.1/lib/faraday/connection.rb:377:in `run_request'
from /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/faraday-0.9.1/lib/faraday/connection.rb:140:in `get'
from /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/berkshelf-api-client-1.2.1/lib/berkshelf/api_client/connection.rb:62:in `universe'
from /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/berkshelf-3.2.3/lib/berkshelf/source.rb:22:in `build_universe'
from /opt/chef/embedded/lib/ruby/gems/2.1.0/gems/berkshelf-3.2.3/lib/berkshelf/installer.rb:21:in `block (2 levels) in build_universe'

Solution

  • I would suggest investigating the pipeline cookbook. It demonstrates a Jenkins solution that I think proves you don't need a Berkshelf API server.

    The cookbook creates a pretty standard Jenkins job that uses Berkshelf to download cookbooks and upload your roles, data bags and environments (from your chef repo). What makes the cookbook clever is that it will also automatically generate special cookbook jobs for your cookbooks in GIT and run useful tools like foodcritic and test kitchen against them.

    Hope it works for you.

    Update

    Berkshelf API is an indexer. If you're determined to use it then you'll need to setup an additional Chef server/organisation to hold the cookbooks and configure this in the Berkshelf API configuration. Your Jenkins build server will then load cookbook changes into this Chef server, so that it acts like a binary repository for your "released" cookbooks.

    A Berkshelf client is able to retrieve from the API server the location of each cookbook, but is still responsible for the actual download. For me this was a "gotcha". The implication for my cookbook loading process was that I needed two configuration files:

    berks install -c ~/.berkshelf/config-cookbooks.json
    berks upload 
    

    The default berkshelf configuration file points at my target chef server, but I need a second configuration file with the credentials for the chef server holding my cookbooks.

    A more complex setup (which might avoid the credential issue above) would be swapping chef server for a local instance of Chef supermarket.

    https://github.com/opscode-cookbooks/supermarket

    In conclusion, I didn't think this was what you really wanted. It's similar to the work-flow I personally use, but most would consider it far too complex.