The dependencies.json file allows for more granularity than metadata.rb, specifying the remote repository and optionally the branch and revision to use. It should be placed in the root directory for each cookbook you create, but can be empty:
{}
The dependencies.json file allows for more granularity than metadata.rb, specifying the remote repository and optionally the branch and revision to use. It should be placed in the root directory for each cookbook you create, but can be empty:
{}
| { | |
| "cookbooks": { | |
| "build-essential": { | |
| "url": "git://github.com/opscode-cookbooks/build-essential.git" | |
| � "branch": "master", | |
| "revision": "2991fc6e5448e5b2378eb6882e9c1ce557d828f0" | |
| }, | |
| "cron": { | |
| "url": "git://github.com/opscode-cookbooks/cron.git" | |
| }, | |
| "hp_server": { | |
| "url": "git://github.meetmecorp.com/chef/hp_server.git" | |
| }, | |
| "ohai": { | |
| "url": "git://github.com/opscode-cookbooks/ohai.git" | |
| }, | |
| "python": { | |
| "url": "git://github.com/opscode-cookbooks/python.git" | |
| }, | |
| "resolver": { | |
| "url": "git://github.com/opscode-cookbooks/resolver.git" | |
| }, | |
| "sudo": { | |
| "url": "git://github.com/opscode-cookbooks/sudo.git" | |
| }, | |
| "supervisor": { | |
| "url": "git://github.com/opscode-cookbooks/supervisor.git" | |
| }, | |
| "yum": { | |
| "url": "git://github.com/opscode-cookbooks/yum.git" | |
| } | |
| } | |
| } |
| # Goes in /var/lib/jenkins/.chef/ | |
| log_level :info | |
| log_location STDOUT | |
| syntax_check_cache_path "#{ENV['HOME']}/.chef/syntax_check_cache" | |
| chef_server_url "#{ENV['KNIFE_CHEF_SERVER']}" | |
| client_key "#{ENV['KNIFE_CLIENT_KEY']}" | |
| node_name "#{ENV['KNIFE_NODE_NAME']}" | |
| validation_client_name "#{ENV['KNIFE_VALIDATION_CLIENT_NAME']}" | |
| validation_key "#{ENV['KNIFE_VALIDATION_CLIENT_KEY']}" | |
| cookbook_path "#{ENV['KNIFE_COOKBOOK_PATH']}" |
| # This is the first build step for a cookbook repo update which is | |
| # triggered by a GitHub callback to Jenkins on commit | |
| # Reset the workspace, we don't want the git checkout of $JOB_NAME | |
| cd $WORKSPACE/.. | |
| rm -rf workspace | |
| mkdir workspace | |
| cd workspace | |
| # Pull down repo | |
| git clone git@github.com:YOUR/chef-repo.git | |
| cd repo | |
| # Add or update the cookbook | |
| if [ ! -d "cookbooks/${JOB_NAME}" ]; then | |
| git submodule add $GIT_URL cookbooks/$JOB_NAME | |
| git submodule init cookbooks/$JOB_NAME | |
| git commit -m "Adding cookbook ${JOB_NAME}" .gitmodules cookbooks/$JOB_NAME | |
| else | |
| git submodule update --init cookbooks/$JOB_NAME | |
| cd cookbooks/$JOB_NAME | |
| git pull -f -u origin master | |
| cd ../.. | |
| git commit -m "Updating cookbook ${JOB_NAME} to ${GIT_COMMIT}" .gitmodules cookbooks/$JOB_NAME | |
| fi |
| # This is the only build step for updates to the data bag, role and | |
| # environment repositories which are triggered by a GitHub callback | |
| # to Jenkins on commit | |
| # Reset the workspace, we don't want the git checkout of $JOB_NAME | |
| cd $WORKSPACE/.. | |
| rm -rf workspace | |
| mkdir workspace | |
| cd workspace | |
| # Pull down repo | |
| git clone git@github.com:YOUR/chef-repo.git | |
| cd repo | |
| # Update the $JOB_NAME | |
| git submodule update --init $JOB_NAME | |
| cd $JOB_NAME | |
| git pull -f -u origin master | |
| cd .. | |
| git commit -m "Updating ${JOB_NAME} to ${GIT_COMMIT}" .gitmodules $JOB_NAME | |
| # Push the change | |
| git push origin master |
| # This script processes the dependencies.json file in a cookbook and either adds | |
| # or updates the submodule information in the master repo, this is run in a job | |
| # per cookbook "Execute Python" build step *after* the cookbook-update.sh build | |
| # step | |
| import json | |
| import os | |
| import subprocess | |
| import sys | |
| base_path = os.environ['WORKSPACE'] + '/' + 'repo' | |
| cookbook = os.environ['JOB_NAME'] | |
| cookbook_path = '%s/cookbooks/%s' % (base_path, cookbook) | |
| dependencies = '%s/dependencies.json' % cookbook_path | |
| def execute(command): | |
| p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
| stdout, stderr = p.communicate() | |
| if p.returncode: | |
| print 'Command failure [%s] returned %s' % (' '.join(command), | |
| p.returncode) | |
| print stderr | |
| sys.exit(p.returncode) | |
| return stdout | |
| os.chdir(base_path) | |
| if os.path.exists(dependencies): | |
| with open(dependencies, 'r') as handle: | |
| data = json.load(handle) | |
| cookbooks = data.get('cookbooks', dict()) | |
| for name in cookbooks: | |
| print 'Processing dependency cookbook %s' % name | |
| dependency_path = '%s/cookbooks/%s' % (base_path, name) | |
| if not os.path.exists(dependency_path): | |
| print 'Adding dependency cookbook %s' % name | |
| execute(['git', 'submodule', 'add', cookbooks[name]['url'], 'cookbooks/%s' % name]) | |
| print 'Committing addition of dependency cookbook %s' % name | |
| execute(['git', 'commit', '-m', 'Adding dependency cookbook %s' % name, | |
| '.gitmodules', 'cookbooks/%s' % name]) | |
| print 'Updating dependency cookbook %s' % name | |
| execute(['git', 'submodule', 'update', '--init', 'cookbooks/%s' % name]) | |
| os.chdir(dependency_path) | |
| if cookbooks[name].get('branch'): | |
| execute(['git', 'checkout', '-b', cookbooks[name].get('branch', 'master')]) | |
| execute(['git', 'pull', '-f', '-u', 'origin', cookbooks[name].get('branch', 'master')]) | |
| os.chdir(base_path) | |
| if 'revision' in cookbooks[name]: | |
| # Change to that revision | |
| os.chdir(dependency_path) | |
| execute(['git', 'reset', '--hard', cookbooks[name]['revision']]) | |
| # Commit the specific revision for that cookbook | |
| os.chdir(base_path) | |
| stdout = execute(['git', 'status', '--porcelain']) | |
| if stdout: | |
| print 'Committing updates to dependency cookbook "%s"' % name | |
| revision = cookbooks[name].get('revision', 'HEAD') | |
| execute(['git', 'commit', '-m', 'Updating dependency cookbook %s to %s' % (name, revision), | |
| '.gitmodules', 'cookbooks/%s' % name]) | |
| else: | |
| print 'No changes to commit for dependency cookbook %s' % name |
| # Used for the job that is notified when the master chef repository is updated when | |
| # a cookbook, role, environment or data bag repository updates chef-repo. When | |
| # cookbook-dependency.py, cookbook-update.sh or other-buid.sh are run, they will | |
| # update chef-repo and push the changes, causing GitHub to trigger Jenkins to run | |
| # the job with this shell script as its build step. | |
| # Update the submodules to the proper revisions | |
| git submodule update --init --recursive | |
| # Knife configuration | |
| export KNIFE_CHEF_SERVER="YOUR_CHEF_SERVER" | |
| export KNIFE_CLIENT_KEY="$HOME/.chef/client.pem" | |
| export KNIFE_NODE_NAME="jenkins" | |
| export KNIFE_VALIDATION_CLIENT_NAME="chef-validator" | |
| export KNIFE_VALIDATION_CLIENT_KEY="$HOME/.chef/validation.pem" | |
| export KNIFE_COOKBOOK_PATH=$WORKSPACE/cookbooks | |
| OBJECT=`git log --pretty=oneline -n 1 | perl -n -e '/^(\w{40})\s+(Adding|Updating)\s(cookbook|dependency\scookbook|environments|data_bags|roles)/ && {print "$3"}'` | |
| if [ "$OBJECT" == "cookbook" ] || [ "$OBJECT" == "dependency cookbook" ]; then | |
| # Extract the cookbook to upload | |
| COOKBOOK=`git log --pretty=oneline -n 1 | perl -n -e '/^\w{40}\s+((Adding|Updating)\sdependency\scookbook\s([\w-]+)\sto.*$|(Adding|Updating)\scookbook\s([\w-_]+)\sto.*$)/m && {print "$3$5\n"}'` | |
| # Upload the cookbook | |
| knife cookbook upload $COOKBOOK | |
| elif [ "$OBJECT" == "data_bags" ]; then | |
| cd $WORKSPACE/data_bags | |
| FILES=`git log --pretty=oneline --name-only -n 1 | perl -n -e '/^([\w\-\_]+\/[\w\-\_]+\.json)$/m && {print "$1\n"}'` | |
| cd $WORKSPACE | |
| for data_bag in $FILES | |
| do | |
| knife data bag from file ${data_bag/\// } | |
| done | |
| elif [ "$OBJECT" == "environments" ]; then | |
| cd $WORKSPACE/environments | |
| FILES=`git log --pretty=oneline --name-only -n 1 | perl -n -e '/^([\w\-_]+\.json)$/m && {print "$1\n"}'` | |
| cd $WORKSPACE | |
| for environment in $FILES | |
| do | |
| knife environment from file $environment | |
| done | |
| elif [ "$OBJECT" == "roles" ]; then | |
| cd $WORKSPACE/roles | |
| FILES=`git log --pretty=oneline --name-only -n 1 | perl -n -e '/^([\w\-_]+\.json)$/m && {print "$1\n"}'` | |
| cd $WORKSPACE | |
| for role in FILES | |
| do | |
| knife role from file $f | |
| done | |
| fi |