From edca29969251c35337e21795859e850344baa6da Mon Sep 17 00:00:00 2001 From: rjaros87 Date: Mon, 28 Nov 2016 10:59:35 +0100 Subject: [PATCH] Add xip support --- .gitignore | 2 + .kitchen.yml | 46 +++++++++ Berksfile | 2 + README.md | 17 ++++ metadata.rb | 2 + recipes/default.rb | 97 +++++++++++++++++-- test/fixtures/cookbooks/xcode_test/README.md | 1 + .../fixtures/cookbooks/xcode_test/metadata.rb | 10 ++ .../cookbooks/xcode_test/recipes/default.rb | 1 + .../shared_examples/default_test.rb | 23 +++++ .../helpers/serverspec/spec_helper.rb | 5 + .../serverspec/default_spec.rb | 5 + .../serverspec/default_spec.rb | 5 + 13 files changed, 208 insertions(+), 8 deletions(-) create mode 100644 .kitchen.yml create mode 100644 test/fixtures/cookbooks/xcode_test/README.md create mode 100644 test/fixtures/cookbooks/xcode_test/metadata.rb create mode 100644 test/fixtures/cookbooks/xcode_test/recipes/default.rb create mode 100644 test/integration/helpers/serverspec/shared_examples/default_test.rb create mode 100644 test/integration/helpers/serverspec/spec_helper.rb create mode 100644 test/integration/xcode_dmg_installer/serverspec/default_spec.rb create mode 100644 test/integration/xcode_xip_archive/serverspec/default_spec.rb diff --git a/.gitignore b/.gitignore index ec2a890..c3508e9 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ bin/* .kitchen/ .kitchen.local.yml + +.idea diff --git a/.kitchen.yml b/.kitchen.yml new file mode 100644 index 0000000..a1736f3 --- /dev/null +++ b/.kitchen.yml @@ -0,0 +1,46 @@ +--- +driver: + name: vagrant + +provisioner: + name: chef_zero + require_chef_omnibus: latest + +platforms: + - name: mac_osx_elcapitan + os_type: mac_os_x + driver: + provision: true + network: + - ["private_network", {ip: "192.168.33.33"}] + gui: false + box: jhcook/osx-elcapitan-10.11 + +suites: + - name: xcode_dmg_installer + run_list: + - recipe[xcode_test::default] + attributes: + xcode: + url: "http://192.168.33.1/Xcode_7.3.1.dmg" + checksum: "bb0dedf613e86ecb46ced945913fa5069ab716a0ade1035e239d70dee0b2de1b" + last_gm_license: "EA1327" + version: "7.3.1" + cli: + url: "http://192.168.33.1/Command_Line_Tools_OS_X_10.11_for_Xcode_7.3.1.dmg" + checksum: "0c80753d207fa2254bcc1c880d4d8907071241f3f2e092c7caa87e340245835a" + package_name: "Command Line Tools (OS X 10.11)" + + - name: xcode_xip_archive + run_list: + - recipe[xcode_test::default] + attributes: + xcode: + url: "http://192.168.33.1/Xcode_8.1.xip" + checksum: "30378e76f7d1adcf3573fc990bd7b46e0939b466b83338ba8f4290444462e5da" + last_gm_license: "8B62" + version: "8.1" + cli: + url: "http://192.168.33.1/Command_Line_Tools_macOS_10.12_for_Xcode_8.1.dmg" + checksum: "d1697a3f76a1241f32793dee24166415dd64bfbac07dbbf84b02b0b59bf713c5" + package_name: "Command Line Tools (macOS 10.12)" diff --git a/Berksfile b/Berksfile index 34fea21..f86199f 100644 --- a/Berksfile +++ b/Berksfile @@ -1,3 +1,5 @@ source 'https://supermarket.chef.io' metadata + +cookbook 'xcode_test', path: 'test/fixtures/cookbooks/xcode_test', group: 'test' diff --git a/README.md b/README.md index 53456c1..04f781c 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,23 @@ Just include `xcode` in your node's `run_list` and set the attributes above. } ``` +Test +---- +Prerequisites: +- HTTP server which provides `Xcode` installers. +If the host machine has installed python, just run in the directory where `Xcode` installers are: +``` +python -m SimpleHTTPServer 80 +``` +- Vagrant 1.8.6 +- VirtualBox 5.1.10 + ExtensionPack +- ChefDK latest + +This cookbook use the test-kitchen tool for developing infrastructure code. To verify cookbook execute command in terminal +``` +kitchen test +``` + Bugs ---- diff --git a/metadata.rb b/metadata.rb index 515acea..83c3b0f 100644 --- a/metadata.rb +++ b/metadata.rb @@ -6,4 +6,6 @@ long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) version '1.3.1' supports 'mac_os_x' + depends 'dmg' +depends 'homebrew' diff --git a/recipes/default.rb b/recipes/default.rb index 3a05274..2b6f16e 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -17,10 +17,93 @@ # limitations under the License. # -dmg_package "Xcode" do - source node['xcode']['url'] - checksum node['xcode']['checksum'] - action :install +file_basename = ::File.basename(node['xcode']['url']) +installer_path = "#{Chef::Config[:file_cache_path]}/#{file_basename}" +installer_extension = ::File.extname installer_path + +if ::Dir.exist? '/Applications/Xcode.app' + Chef::Log.info('Xcode already installed.') +else + remote_file "Download #{file_basename}" do + backup false + path installer_path + source node['xcode']['url'] + checksum node['xcode']['checksum'] + not_if { ::File.exist? installer_path } + end + + case installer_extension + when '.dmg' + dmg_package 'Xcode' do + file installer_path + action :install + end + when '.xip' + include_recipe 'homebrew' + package 'xz' + + remote_file 'Download PBZX v2 unpacker' do + backup false + path "#{Chef::Config[:file_cache_path]}/parse_pbzx2.py" + source 'https://gist.githubusercontent.com/pudquick/ff412bcb29c9c1fa4b8d/raw/24b25538ea8df8d0634a2a6189aa581ccc6a5b4b/parse_pbzx2.py' + not_if { ::File.exist? "#{Chef::Config[:file_cache_path]}/Content" } + end + + execute 'Verify the signature and certificate chain that signed the archive' do + command "pkgutil --check-signature #{installer_path}" + cwd Chef::Config[:file_cache_path] + end + + execute 'Extract the PBZX stream from the archive' do + command "xar -xf #{file_basename} Content -C ./" + cwd Chef::Config[:file_cache_path] + end + + execute 'Unpack PBZX archive' do + command 'python parse_pbzx2.py Content' + cwd Chef::Config[:file_cache_path] + end + + file "#{Chef::Config[:file_cache_path]}/Content" do + backup false + action :delete + only_if { ::File.exist? "#{Chef::Config[:file_cache_path]}/Content" } + end + + execute 'Decompress the archive' do + command 'xz -d Content.part00.cpio.xz' + cwd Chef::Config[:file_cache_path] + end + + execute 'Unpack the CPIO archive' do + command 'cpio --quiet -idm < ./Content.part00.cpio' + cwd Chef::Config[:file_cache_path] + end + + file "#{Chef::Config[:file_cache_path]}/Content.part00.cpio" do + backup false + action :delete + only_if { ::File.exist? "#{Chef::Config[:file_cache_path]}/Content.part00.cpio" } + end + + execute 'Move the resulting Xcode app bundle into /Applications' do + command 'mv Xcode.app /Applications/Xcode.app' + cwd Chef::Config[:file_cache_path] + end + + file installer_path do + backup false + action :delete + only_if { ::Dir.exist? installer_path } + end + else + Chef::Log.error("Not supported file extension: '#{installer_extension}'.") + end +end + +execute 'Switch Xcode' do + command 'xcode-select --switch /Applications/Xcode.app/Contents/Developer' + not_if { system('xcodebuild -version > /dev/null 2>&1') } end dmg_package node['xcode']['cli']['package_name'] do @@ -32,10 +115,8 @@ action :install end -template "/Library/Preferences/com.apple.dt.Xcode.plist" do - source "com.apple.dt.Xcode.plist.erb" - owner "root" - group "wheel" +template '/Library/Preferences/com.apple.dt.Xcode.plist' do + source 'com.apple.dt.Xcode.plist.erb' mode 00644 variables({ :last_gm_license => node['xcode']['last_gm_license'], diff --git a/test/fixtures/cookbooks/xcode_test/README.md b/test/fixtures/cookbooks/xcode_test/README.md new file mode 100644 index 0000000..ae91f05 --- /dev/null +++ b/test/fixtures/cookbooks/xcode_test/README.md @@ -0,0 +1 @@ +This is a test cookbook for use by chefspec and test-kitchen diff --git a/test/fixtures/cookbooks/xcode_test/metadata.rb b/test/fixtures/cookbooks/xcode_test/metadata.rb new file mode 100644 index 0000000..11b3b14 --- /dev/null +++ b/test/fixtures/cookbooks/xcode_test/metadata.rb @@ -0,0 +1,10 @@ +name 'xcode_test' +maintainer 'Urbandecoder Labs' +maintainer_email 'jdunn@aquezada.com' +license 'Apache 2.0' +description 'Installs Apple XCode and command-line tools' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version '0.1.0' + +depends 'xcode' + diff --git a/test/fixtures/cookbooks/xcode_test/recipes/default.rb b/test/fixtures/cookbooks/xcode_test/recipes/default.rb new file mode 100644 index 0000000..60913a6 --- /dev/null +++ b/test/fixtures/cookbooks/xcode_test/recipes/default.rb @@ -0,0 +1 @@ +include_recipe 'xcode' diff --git a/test/integration/helpers/serverspec/shared_examples/default_test.rb b/test/integration/helpers/serverspec/shared_examples/default_test.rb new file mode 100644 index 0000000..43c0e82 --- /dev/null +++ b/test/integration/helpers/serverspec/shared_examples/default_test.rb @@ -0,0 +1,23 @@ +shared_examples 'simple installation of xcode with CLI' do + describe 'Check Xcode CLI' do + describe command('xcode-select -p') do + its(:exit_status) { should eq 0 } + end + + describe command('gcc -v') do + its(:exit_status) { should eq 0 } + end + + describe command('make -v') do + its(:exit_status) { should eq 0 } + end + end + + describe 'Check xcodebuild' do + describe command('xcodebuild -version') do + its(:exit_status) { should eq 0 } + its(:stdout) { should contain('Xcode') } + its(:stdout) { should contain('Build version') } + end + end +end \ No newline at end of file diff --git a/test/integration/helpers/serverspec/spec_helper.rb b/test/integration/helpers/serverspec/spec_helper.rb new file mode 100644 index 0000000..8af94aa --- /dev/null +++ b/test/integration/helpers/serverspec/spec_helper.rb @@ -0,0 +1,5 @@ +require 'serverspec' + +set :backend, :exec + +::Dir[::File.join(::File.dirname(__FILE__), 'shared_examples/*.rb')].sort.each { |f| require f } diff --git a/test/integration/xcode_dmg_installer/serverspec/default_spec.rb b/test/integration/xcode_dmg_installer/serverspec/default_spec.rb new file mode 100644 index 0000000..a4877da --- /dev/null +++ b/test/integration/xcode_dmg_installer/serverspec/default_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe 'Xcode.dmg installer' do + it_behaves_like 'simple installation of xcode with CLI' +end diff --git a/test/integration/xcode_xip_archive/serverspec/default_spec.rb b/test/integration/xcode_xip_archive/serverspec/default_spec.rb new file mode 100644 index 0000000..bb5ecb7 --- /dev/null +++ b/test/integration/xcode_xip_archive/serverspec/default_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe 'Xcode.xip installer' do + it_behaves_like 'simple installation of xcode with CLI' +end