diff --git a/.gitignore b/.gitignore index 285ea1e..f617a5e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,24 @@ .vagrant +Berksfile.lock *~ *# .#* \#*# .*.sw[a-z] *.un~ -/cookbooks -*.DS_Store +*.iso +*.pem # Bundler bin/* .bundle/* + .kitchen/ .kitchen.local.yml -Berksfile.lock -Gemfile.lock -coverage/ +# OS +.DS_Store +Icon? +nohup.out +ehthumbs.db +Thumbs.db diff --git a/.kitchen.ec2.yml b/.kitchen.ec2.yml index a3c76c4..462981f 100644 --- a/.kitchen.ec2.yml +++ b/.kitchen.ec2.yml @@ -6,39 +6,53 @@ driver: availability_zone: <%= ENV['AWS_AVAILABILITY_ZONE'] %> require_chef_omnibus: true subnet_id: <%= ENV['AWS_SUBNET'] %> - instance_type: <%= ENV['INSTANCE_SIZE'] %> associate_public_ip: false interface: private - user_data: <%= ENV['USER_DATA_PATH'] %> tags: OWNER: <%= ENV['AWS_OWNER_TAG'] %> Name: <%= ENV['AWS_NAME_TAG'] %> + ENVIRONMENT: <%= ENV['AWS_ENVIRONMENT_TAG'] %> + provisioner: name: chef_zero + log_level: <%= ENV['CHEF_LOG_LEVEL'] || 'auto' %> transport: - username: cloud-user ssh_key: ~/.ssh/<%= ENV['AWS_SSH_KEY'] %>.pem platforms: - - name: centos-6.7-python-integration-tests + - name: gci-centos7 driver: - image_id: <%= ENV['AWS_AMI_ID'] %> + image_id: <%= ENV['AWS_GCI_CENTOS7_AMI_ID'] %> + instance_type: <%= ENV['LINUX_INSTANCE_SIZE'] %> + user_data: <%= ENV['LINUX_USER_DATA_PATH'] %> + transport: + username: <%= ENV['AWS_CENTOS7_USERNAME'] %> suites: - name: default run_list: - - recipe[yum-gd] - recipe[python] + - recipe[virtualenv-test] + attributes: + python: + setuptools_version: 18.0.1 + virtualenv_version: 13.1.0 +- name: chef14-default + provisioner: + require_chef_omnibus: 14.0.202 + run_list: + - recipe[python] + - recipe[virtualenv-test] attributes: python: setuptools_version: 18.0.1 virtualenv_version: 13.1.0 - name: package run_list: - - recipe[yum-gd] - recipe[python] + - recipe[virtualenv-test] attributes: python: install_method: "package" @@ -46,8 +60,8 @@ suites: virtualenv_version: 13.1.0 - name: custom-package run_list: - - recipe[yum-gd] - recipe[python] + - recipe[virtualenv-test] attributes: python: install_method: "custom-package" @@ -55,8 +69,8 @@ suites: virtualenv_version: 13.1.0 - name: source run_list: - - recipe[yum-gd] - recipe[python] + - recipe[virtualenv-test] attributes: python: install_method: "source" diff --git a/.kitchen.gce.yml b/.kitchen.gce.yml new file mode 100644 index 0000000..72d270a --- /dev/null +++ b/.kitchen.gce.yml @@ -0,0 +1,79 @@ +--- +driver: + name: gce + preemptible: true + project: <%= ENV['GCE_PROJECT'] %> + zone: <%= ENV['GCE_ZONE'] %> + subnet_project: <%= ENV['GCE_SUBNET_PROJECT'] %> + subnet: <%= ENV['GCE_SUBNET'] %> + service_account_name: <%= ENV['GCE_SERVICE_ACCOUNT_NAME'] %> + service_account_scopes: <%= ENV['GCE_SERVICE_ACCOUNT_SCOPES'] %> + use_private_ip: true + image_project: <%= ENV['GCE_IMAGE_PROJECT'] %> + require_chef_omnibus: true + refresh_rate: 2 + wait_time: 120 + tags: [office-ssh, tools-ssh, private] + metadata: + ssh-keys: <%= ENV['GCE_SSH_KEY_META'] %> + +provisioner: + name: chef_zero + log_level: <%= ENV['CHEF_LOG_LEVEL'] || 'auto' %> + +transport: + username: <%= ENV['GCE_USER'] %> + ssh_key: <%= ENV['GCE_SSH_KEY'] %> + +platforms: + - name: gci-centos7 + driver: + image_name: <%= ENV['GCE_GCI_CENTOS7_IMAGE'] %> + machine_type: <%= ENV['GCE_MACHINE_TYPE'] %> + +suites: +- name: default + run_list: + - recipe[python] + - recipe[virtualenv-test] + attributes: + python: + setuptools_version: 18.0.1 + virtualenv_version: 13.1.0 +- name: chef14-default + provisioner: + require_chef_omnibus: 14.0.202 + run_list: + - recipe[python] + - recipe[virtualenv-test] + attributes: + python: + setuptools_version: 18.0.1 + virtualenv_version: 13.1.0 +- name: package + run_list: + - recipe[python] + - recipe[virtualenv-test] + attributes: + python: + install_method: "package" + setuptools_version: 18.0.1 + virtualenv_version: 13.1.0 +- name: custom-package + run_list: + - recipe[python] + - recipe[virtualenv-test] + attributes: + python: + install_method: "custom-package" + setuptools_version: 18.0.1 + virtualenv_version: 13.1.0 +- name: source + run_list: + - recipe[python] + - recipe[virtualenv-test] + attributes: + python: + install_method: "source" + setuptools_version: 18.0.1 + virtualenv_version: 13.1.0 diff --git a/.kitchen.yml b/.kitchen.yml index c0c5b33..0f5fd34 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -1,32 +1,38 @@ --- driver: name: vagrant - customize: - memory: 2048 + pre_create_command: "cd {{vagrant_root}}/ && vagrant box update" provisioner: name: chef_zero - chef_zero_port: 9010 + log_level: <%= ENV['CHEF_LOG_LEVEL'] || 'auto' %> platforms: -- name: gdp-centos-6.7 - driver: - box: centos-67 - box_url: https://deploy.gmti.gbahn.net/Images/CentOS6/vagrant/centos67-cloud-1.0.0.box + - name: gannett/gci-centos7 suites: - name: default run_list: - - recipe[yum-gd] - recipe[python] + - recipe[virtualenv-test] + attributes: + python: + setuptools_version: 18.0.1 + virtualenv_version: 13.1.0 +- name: chef14-default + provisioner: + require_chef_omnibus: 14.0.202 + run_list: + - recipe[python] + - recipe[virtualenv-test] attributes: python: setuptools_version: 18.0.1 virtualenv_version: 13.1.0 - name: package run_list: - - recipe[yum-gd] - recipe[python] + - recipe[virtualenv-test] attributes: python: install_method: "package" @@ -34,8 +40,8 @@ suites: virtualenv_version: 13.1.0 - name: custom-package run_list: - - recipe[yum-gd] - recipe[python] + - recipe[virtualenv-test] attributes: python: install_method: "custom-package" @@ -43,8 +49,8 @@ suites: virtualenv_version: 13.1.0 - name: source run_list: - - recipe[yum-gd] - recipe[python] + - recipe[virtualenv-test] attributes: python: install_method: "source" diff --git a/.rubocop.yml b/.rubocop.yml index 286c90d..858a8ff 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -3,15 +3,14 @@ AllCops: Exclude: + - 'test/**/*' - 'spec/**/*' # ignore spec tests for now - 'vendor/**/*' # ignore non-local files - - 'test/**/**/**/*' # ignore serverspec tests - - 'providers/pip.rb' #ignore pip provider for now, requires refactor - Guardfile # We like longer lines Metrics/LineLength: - Max: 132 + Max: 160 # TODO: add encoding headers Style/Encoding: @@ -34,7 +33,7 @@ Style/SignalException: Enabled: false # We enjoy parameters lining up for visual comprehension -Style/SingleSpaceBeforeFirstArg: +Layout/SpaceBeforeFirstArg: Enabled: false # Only enforce a wordlist for 5 or longer lists. diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c40abd3..0000000 --- a/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -language: ruby -rvm: - - 1.9.3 - - 2.0.0 -bundler_args: --deployment --binstubs -before_script: - - ./bin/berks install -script: - - ./bin/foodcritic -f any . - - ./bin/rake diff --git a/Berksfile b/Berksfile index 26269c9..6344662 100644 --- a/Berksfile +++ b/Berksfile @@ -1,3 +1,7 @@ source 'https://gdp-chef-supermarket.gannettdigital.com' +group :integration do + cookbook 'virtualenv-test', path: 'test/fixtures/virtualenv-test' +end + metadata diff --git a/CHANGELOG.md b/CHANGELOG.md index 82333b4..fe54ec1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,36 @@ python Cookbook CHANGELOG ========================= This file is used to list changes made in each version of the python cookbook. +v2.0.6 +------ +- Joseph Kregloh - Added variable virtualenv install options (PENG-22741) + +v2.0.5 +------ +- Joseph Kregloh - Added variable for Wheel and set a default. Wheel was updated + to not work with older versions of Python and get-pip.py just gets latest. (PENG-22741) + +v2.0.4 +------ +- Joseph Kregloh - Removing yum-gd. (PENG-14254) + +v2.0.3 +------ +- Joseph Kregloh - Fix for Python setuptools version (PENG-14437) + +v2.0.2 +------ +- Brian Lieberman - remove unused & deprecated mixin for chef-14 support (PENG-1975) + +v2.0.1 +------ +- Dane Thorsen - Updated to work with chef 13 ResourceResolver (PENG-1428) +- Dane Thorsen - Add Google Cloud testing (PENG-1428) + +v2.0.0 +------ +- Franklin Hanson - updated cookbook for chef client 13 and deprecate OS that we no longer support on platform (PAAS-10840) + v1.6.0 ------ - Jason Neves - updated cookbook to be able to pin pip version installed, @@ -48,13 +78,13 @@ v1.4.10 v1.4.6 ------ -- **[#61](https://github.com/poise/python/pull/61)** – Python packages specified for Fedora platform. -- **[#62](https://github.com/poise/python/pull/62)** – Use tgz archive instead of tbz2 as new releases no longer offer tb2 -- **[#72](https://github.com/poise/python/pull/72)** – Set $HOME in virtualenv provider -- **[#74](https://github.com/poise/python/pull/74)** – Allow setting of virtualenv version -- **[#78](https://github.com/poise/python/pull/78)** – AFix the pip version_check_cmd to use the virtualenv pip when applicable -- **[#79](https://github.com/poise/python/pull/79)** – Add ability in pip lwrp to send custom env vars -- **[#80](https://github.com/poise/python/pull/80)** – Update to yum3 yum-epel cookbook +- **[#61](https://github.com/poise/python/pull/61)** ? Python packages specified for Fedora platform. +- **[#62](https://github.com/poise/python/pull/62)** ? Use tgz archive instead of tbz2 as new releases no longer offer tb2 +- **[#72](https://github.com/poise/python/pull/72)** ? Set $HOME in virtualenv provider +- **[#74](https://github.com/poise/python/pull/74)** ? Allow setting of virtualenv version +- **[#78](https://github.com/poise/python/pull/78)** ? AFix the pip version_check_cmd to use the virtualenv pip when applicable +- **[#79](https://github.com/poise/python/pull/79)** ? Add ability in pip lwrp to send custom env vars +- **[#80](https://github.com/poise/python/pull/80)** ? Update to yum3 yum-epel cookbook - Remove ez_setup.py usage and upgrade get-pip.py to 1.5.2. v1.4.4 diff --git a/Gemfile b/Gemfile deleted file mode 100644 index fda89b6..0000000 --- a/Gemfile +++ /dev/null @@ -1,26 +0,0 @@ -# -*- encoding: utf-8 -*- -source 'https://rubygems.org' - -gem 'berkshelf' -gem 'coveralls', require: false -gem 'rubocop' -gem 'webmock' - -group :test do - gem 'rubocop-checkstyle_formatter', require: false - gem 'chefspec', '~> 4.2' - gem 'foodcritic', '~> 4.0.0' - gem 'rake', '>= 10.2' -end - -group :integration do - gem 'guard', '>= 2.6' - gem 'guard-foodcritic', '~> 1.0.3' - gem 'guard-kitchen' - gem 'guard-rspec' - gem 'guard-rubocop', '>= 1.1' - gem 'kitchen-vagrant' - gem 'kitchen-ec2' - gem 'test-kitchen', '~> 1.2.0' - gem 'travis-lint' -end diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..ebbc2f3 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,91 @@ + +node('chef13') { + dest = '' + env.COOKBOOK_REPO = 'GannettDigital/chef-python' + env.COOKBOOK_NAME = 'python' + // If you need to change the instance size for your testing + // update it in your kitchen.ec2.yml file + try { + stage 'Github checkout' + deleteDir() + checkout scm + v = version() + sh "echo -n `git rev-parse HEAD` > .git/commit-id" + env.BRANCH_COMMIT = readFile('.git/commit-id') + echo "Testing ${env.COOKBOOK_NAME} ${v}\nBRANCH: ${env.BRANCH_NAME}\nCOMMIT: ${env.BRANCH_COMMIT}" + if (env.BRANCH_NAME != 'master') { + dest = 'test' + stage 'check PR script' + // run our basic pr version check tests + sh 'bash ${JENKINS_HOME}/dev-ops/ci/check_pr_versions.sh' + } else { + dest = 'chef-server' + } + stage 'GD foodcritic' + // Run our foodcritic tests + sh 'foodcritic -f "any" -t "~FC071" -t "~FC078" -t "~FC104" -t "~FC005" -X "spec/**/*" -X "test/**/*" -I $FC_RULES_LOCATION .' + stage 'EC2 integration tests' + // this is the "chef exec bundle exec rake ec2 job" + sh 'chef exec rake ci' + if (env.BRANCH_NAME == 'master') { + stage 'supermarket upload' + build job: 'supermarket_upload_sub', parameters: [string(name: 'COOKBOOK_BRANCH', value: "${env.BRANCH_COMMIT}"), + string(name: 'COOKBOOK_REPO', value: "${env.COOKBOOK_REPO}"), + string(name: 'COOKBOOK_NAME', value: "${env.COOKBOOK_NAME}")] + try { + stage 'chef server upload' + build job: 'chef_upload_sub', parameters: [string(name: 'COOKBOOK_BRANCH', value: "${env.BRANCH_COMMIT}"), + string(name: 'COOKBOOK_REPO', value: "${env.COOKBOOK_REPO}"), + string(name: 'COOKBOOK_NAME', value: "${env.COOKBOOK_NAME}")] + currentBuild.result = "SUCCESS" + } + catch (err) { + stage 'supermarket rollback' + build job: 'supermarket_rollback_sub', parameters: [string(name: 'COOKBOOK_BRANCH', value: "${env.BRANCH_COMMIT}"), + string(name: 'COOKBOOK_REPO', value: "${env.COOKBOOK_REPO}"), + string(name: 'COOKBOOK_NAME', value: "${env.COOKBOOK_NAME}")] + currentBuild.result = "FAILURE" + } + } + stage 'notify or tag' + // we could notify slack directly with a plugin + echo 'call pipeline-alerting' + if (env.BRANCH_NAME != 'master') { + // if you got here and you're not master then you're golden + currentBuild.result = "SUCCESS" + } + build job: 'pipeline-alerting', parameters: [string(name: 'TRIGGERING_JOB_NAME', value: "${env.COOKBOOK_NAME}"), + string(name: 'TRIGGERING_BUILD_NUMBER', value: "${env.BUILD_NUMBER}"), + string(name: 'TRIGGERING_ENVIRONMENT', value: 'tools'), + string(name: 'TRIGGERING_BUILD_URL', value: "${env.BUILD_URL}"), + string(name: 'TRIGGERING_GIT_URL', value: "https://github.com/${env.COOKBOOK_REPO}/"), + string(name: 'TRIGGERING_GIT_COMMIT', value: "${env.BRANCH_COMMIT}"), + string(name: 'APP_NAME', value: "${env.COOKBOOK_NAME}"), + string(name: 'EVENT_TYPE', value: 'deploy'), + string(name: 'TEST_TYPE', value: 'none'), + string(name: 'PUBLISH_DESTINATION', value: "${dest}"), + string(name: 'TEAM', value: 'paas-delivery'), + string(name: 'BUILD_STATUS', value: "${currentBuild.result}")] + } + catch (err) { + // if anything broke early on before the master logic + currentBuild.result = "FAILURE" + stage 'notify or tag' + build job: 'pipeline-alerting', parameters: [string(name: 'TRIGGERING_JOB_NAME', value: "${env.COOKBOOK_NAME}"), + string(name: 'TRIGGERING_BUILD_NUMBER', value: "${env.BUILD_NUMBER}"), + string(name: 'TRIGGERING_ENVIRONMENT', value: 'tools'), + string(name: 'TRIGGERING_BUILD_URL', value: "${env.BUILD_URL}"), + string(name: 'TRIGGERING_GIT_URL', value: "https://github.com/${env.COOKBOOK_REPO}/"), + string(name: 'TRIGGERING_GIT_COMMIT', value: "${env.BRANCH_COMMIT}"), + string(name: 'APP_NAME', value: "${env.COOKBOOK_NAME}"), + string(name: 'EVENT_TYPE', value: 'deploy'), + string(name: 'TEST_TYPE', value: 'none'), + string(name: 'PUBLISH_DESTINATION', value: "${dest}"), + string(name: 'TEAM', value: 'paas-delivery'), + string(name: 'BUILD_STATUS', value: "${currentBuild.result}")] + } +} +def version() { + def matcher = readFile('metadata.rb') =~ /version\s+['"](\d+\.\d+\.\d+)['"]/ + matcher ? matcher[0][1] : null +} diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 11069ed..0000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/NOTICE.txt b/NOTICE.txt deleted file mode 100644 index 7f4a2b9..0000000 --- a/NOTICE.txt +++ /dev/null @@ -1,2 +0,0 @@ -The script located at files/default/ez_setup.py is licensed under the -Zope Public License, found at the root of this cookbook at ZPL.txt. diff --git a/README.md b/README.md index c2513ff..fba76c8 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,7 @@ Installs and configures Python. Also includes LWRPs for managing python package Requirements ------------ ### Platforms -- Debian, Ubuntu -- CentOS, Red Hat, Fedora +- CentOS ### Cookbooks - build-essential diff --git a/Rakefile b/Rakefile index 05d2f3d..e89e896 100644 --- a/Rakefile +++ b/Rakefile @@ -1,4 +1,5 @@ require 'rspec/core/rake_task' +require 'cookstyle' require 'rubocop/rake_task' require 'foodcritic' require 'kitchen/cli' @@ -12,7 +13,7 @@ namespace :style do FoodCritic::Rake::LintTask.new(:chef) do |t| t.options = { fail_tags: ['any'], - tags: ['~FC005'] + tags: ['~FC071', '~FC078', '~FC104'], } end end @@ -41,10 +42,15 @@ namespace :integration do ENV['KITCHEN_YAML'] = './.kitchen.ec2.yml' Kitchen::CLI.new([], destroy: 'always').test end + task :gce do + ENV['KITCHEN_YAML'] = './.kitchen.gce.yml' + Kitchen::CLI.new([], concurrency: 5, destroy: 'always').test + end end # Default task default: ['style', 'spec', 'integration:vagrant'] +task ci: ['style', 'spec', 'integration:ec2', 'integration:gce'] task ec2: ['style', 'spec', 'integration:ec2'] task ec2_singlethread: ['style', 'spec', 'integration:ec2_singlethread'] task test: ['style', 'spec'] diff --git a/TESTING.md b/TESTING.md deleted file mode 100644 index e29ff7c..0000000 --- a/TESTING.md +++ /dev/null @@ -1,25 +0,0 @@ -This cookbook includes support for running tests via Test Kitchen (1.0). This has some requirements. - -1. You must be using the Git repository, rather than the downloaded cookbook from the Chef Community Site. -2. You must have Vagrant 1.1 installed. -3. You must have a "sane" Ruby 1.9.3 environment. - -Once the above requirements are met, install the additional requirements: - -Install the berkshelf plugin for vagrant, and berkshelf to your local Ruby environment. - - vagrant plugin install vagrant-berkshelf - gem install berkshelf - -Install Test Kitchen 1.0 (unreleased yet, use the alpha / prerelease version). - - gem install test-kitchen --pre - -Install the Vagrant driver for Test Kitchen. - - gem install kitchen-vagrant - -Once the above are installed, you should be able to run Test Kitchen: - - kitchen list - kitchen test diff --git a/ZPL.txt b/ZPL.txt deleted file mode 100644 index 44e0648..0000000 --- a/ZPL.txt +++ /dev/null @@ -1,59 +0,0 @@ -Zope Public License (ZPL) Version 2.0 ------------------------------------------------ - -This software is Copyright (c) Zope Corporation (tm) and -Contributors. All rights reserved. - -This license has been certified as open source. It has also -been designated as GPL compatible by the Free Software -Foundation (FSF). - -Redistribution and use in source and binary forms, with or -without modification, are permitted provided that the -following conditions are met: - -1. Redistributions in source code must retain the above - copyright notice, this list of conditions, and the following - disclaimer. - -2. Redistributions in binary form must reproduce the above - copyright notice, this list of conditions, and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - -3. The name Zope Corporation (tm) must not be used to - endorse or promote products derived from this software - without prior written permission from Zope Corporation. - -4. The right to distribute this software or to use it for - any purpose does not give you the right to use Servicemarks - (sm) or Trademarks (tm) of Zope Corporation. Use of them is - covered in a separate agreement (see - http://www.zope.com/Marks). - -5. If any files are modified, you must cause the modified - files to carry prominent notices stating that you changed - the files and the date of any change. - -Disclaimer - - THIS SOFTWARE IS PROVIDED BY ZOPE CORPORATION ``AS IS'' - AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT - NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - NO EVENT SHALL ZOPE CORPORATION OR ITS CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. - - -This software consists of contributions made by Zope -Corporation and many individuals on behalf of Zope -Corporation. Specific attributions are listed in the -accompanying credits file. diff --git a/attributes/default.rb b/attributes/default.rb index b492683..f4f9b33 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -20,51 +20,22 @@ default['python']['install_method'] = 'custom-package' -if node['python']['install_method'] == 'package' - default['python']['prefix_dir'] = case platform - when 'smartos' - '/opt/local' - else - '/usr' - end -else - default['python']['prefix_dir'] = '/usr/local' -end - +default['python']['prefix_dir'] = if node['python']['install_method'] == 'package' + '/usr' + else + '/usr/local' + end default['python']['binary'] = "#{node['python']['prefix_dir']}/bin/python" if node['python']['install_method'] == 'custom-package' - default['python']['custom_package_name'] = case platform - when 'amazon' - 'python27alt' - else - 'python27' - end + default['python']['custom_package_name'] = 'python27' end case node['python']['install_method'] when 'custom-package' - case platform - when 'amazon' - default['python']['version'] = '2.7.9-1.amzn1.gd' - when 'centos', 'redhat' - default['python']['version'] = if node['platform_version'].to_f >= 7 - '2.7.9-1.el7.centos.gd' - else - '2.7.9-1.el6.gd' - end - end + default['python']['version'] = '2.7.9-1.el7.centos.gd' when 'package' - case platform - when 'centos', 'redhat' - default['python']['version'] = if node['platform_version'].to_f >= 7 - '2.7.5-18.el7_1.1' - else - '2.6.6-64.el6' - end - else - default['python']['version'] = '2.6.6-64.el6' - end + default['python']['version'] = '2.7.5-80.el7_6' when 'source' default['python']['version'] = '2.7.9' end @@ -72,11 +43,14 @@ default['python']['custom_binary'] = "#{node['python']['prefix_dir']}/bin/python2.7" default['python']['url'] = 'http://www.python.org/ftp/python' default['python']['checksum'] = 'c8bba33e66ac3201dabdc556f0ea7cfe6ac11946ec32d357c4c6f9b018c12c5b' -default['python']['configure_options'] = %W(--prefix=#{python['prefix_dir']}) +default['python']['configure_options'] = %W(--prefix=#{node['python']['prefix_dir']}) default['python']['make_options'] = %w(install) default['python']['pip_location'] = "#{node['python']['prefix_dir']}/bin/pip" default['python']['virtualenv_location'] = "#{node['python']['prefix_dir']}/bin/virtualenv" default['python']['setuptools_version'] = nil # defaults to latest default['python']['virtualenv_version'] = nil +default['python']['virtualenv_options'] = nil default['python']['pip']['version'] = '7.1.2' +default['python']['wheel']['version'] = '0.37.1' +default['python']['setuptools_version'] = '44.0.0' diff --git a/chefignore b/chefignore index a6de142..b31977b 100644 --- a/chefignore +++ b/chefignore @@ -51,8 +51,12 @@ spec/* spec/fixtures/* test/* features/* +examples/* Guardfile Procfile +.kitchen* +.rubocop.yml +Jenkinsfile # SCM # ####### @@ -76,8 +80,9 @@ tmp # Cookbooks # ############# -CONTRIBUTING +CONTRIBUTING* CHANGELOG* +TESTING* # Strainer # ############ diff --git a/metadata.rb b/metadata.rb index 93d31c8..29d07f9 100644 --- a/metadata.rb +++ b/metadata.rb @@ -1,23 +1,21 @@ -name 'python' -maintainer 'Noah Kantrowitz' -maintainer_email 'noah@coderanger.net' -license 'Apache 2.0' -description 'Installs Python, pip and virtualenv. \ - Includes LWRPs for managing Python packages with `pip` and `virtualenv` isolated Python environments.' -version '1.6.0' +name 'python' +maintainer 'PAAS' +maintainer_email 'paas-integration@gannett.com' +license ' Copyright (c) 2017 Gannett Co., Inc, All Rights Reserved.' +description 'Installs Python, pip and virtualenv. \ + Includes LWRPs for managing Python packages with `pip` and `virtualenv` isolated Python environments.' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) -depends 'build-essential' -depends 'yum-epel' -depends 'yum-gd' -depends 'apt' +version '2.0.6' -recipe 'python', 'Installs python, pip, and virtualenv' -recipe 'python::package', 'Installs python using packages.' -recipe 'python::custom-package', 'Installs python using an alternative package.' -recipe 'python::source', 'Installs python from source.' -recipe 'python::pip', 'Installs pip from source.' -recipe 'python::virtualenv', 'Installs virtualenv using the python_pip resource.' +chef_version '>= 12.11.18' -%w( debian ubuntu centos redhat fedora freebsd smartos ).each do |os| +depends 'build-essential' +depends 'yum-epel' + +source_url 'https://github.com/GannettDigital/chef-python' +issues_url 'https://github.com/GannettDigital/chef-python/issues' + +%w(centos).each do |os| supports os end diff --git a/providers/pip.rb b/providers/pip.rb index 5f38dbc..d573fda 100644 --- a/providers/pip.rb +++ b/providers/pip.rb @@ -20,20 +20,21 @@ use_inline_resources require 'chef/mixin/shell_out' -require 'chef/mixin/language' include Chef::Mixin::ShellOut def whyrun_supported? true end +use_inline_resources + # the logic in all action methods mirror that of # the Chef::Provider::Package which will make # refactoring into core chef easy action :install do # If we specified a version, and it's not the current version, move to the specified version - if !new_resource.version.nil? && new_resource.version != current_resource.version + if !new_resource.version.nil? && new_resource.version != current_resource.version install_version = new_resource.version # If it's not installed at all, install it elsif current_resource.version.nil? @@ -44,8 +45,7 @@ def whyrun_supported? description = "install package #{new_resource} version #{install_version}" converge_by(description) do Chef::Log.info("Installing #{new_resource} version #{install_version}") - status = install_package(install_version) - new_resource.updated_by_last_action(true) if status + install_package(install_version) end end end @@ -56,8 +56,7 @@ def whyrun_supported? description = "upgrade #{current_resource} version from #{current_resource.version} to #{candidate_version}" converge_by(description) do Chef::Log.info("Upgrading #{new_resource} version from #{orig_version} to #{candidate_version}") - status = upgrade_package(candidate_version) - new_resource.updated_by_last_action(true) if status + upgrade_package(candidate_version) end end end @@ -68,7 +67,6 @@ def whyrun_supported? converge_by(description) do Chef::Log.info("Removing #{new_resource}") remove_package(new_resource.version) - new_resource.updated_by_last_action(true) end end end @@ -90,7 +88,7 @@ def removing_package? # so refactoring into core Chef should be easy def load_current_resource - @current_resource = Chef::Resource::PythonPip.new(new_resource.name) + @current_resource = Chef::ResourceResolver.resolve(:python_pip).new(new_resource.name) @current_resource.package_name(new_resource.package_name) @current_resource.version(nil) @@ -104,7 +102,7 @@ def load_current_resource def current_installed_version @current_installed_version ||= begin out = nil - package_name = new_resource.package_name.gsub('_', '-') + package_name = new_resource.package_name.tr('_', '-') pattern = Regexp.new("^#{Regexp.escape(package_name)} \\(([^)]+)\\)$", true) shell_out("#{which_pip(new_resource)} list").stdout.lines.find do |line| out = pattern.match(line) @@ -125,12 +123,12 @@ def candidate_version def install_package(version) # if a version isn't specified (latest), is a source archive (ex. http://my.package.repo/SomePackage-1.0.4.zip), # or from a VCS (ex. git+https://git.repo/some_pkg.git) then do not append a version as this will break the source link - if version == 'latest' || new_resource.package_name.downcase.start_with?('http:', 'https:') \ - || ['git', 'hg', 'svn'].include?(new_resource.package_name.downcase.split('+')[0]) - version = '' - else - version = "==#{version}" - end + version = if version == 'latest' || new_resource.package_name.downcase.start_with?('http:', 'https:') \ + || ['git', 'hg', 'svn'].include?(new_resource.package_name.downcase.split('+')[0]) + '' + else + "==#{version}" + end pip_cmd('install', version) end diff --git a/providers/virtualenv.rb b/providers/virtualenv.rb index 167c1cc..fc0c18d 100644 --- a/providers/virtualenv.rb +++ b/providers/virtualenv.rb @@ -20,13 +20,14 @@ use_inline_resources require 'chef/mixin/shell_out' -require 'chef/mixin/language' include Chef::Mixin::ShellOut def whyrun_supported? true end +use_inline_resources + action :create do unless exists? directory new_resource.path do @@ -40,7 +41,6 @@ def whyrun_supported? group new_resource.group if new_resource.group environment('HOME' => ::Dir.home(new_resource.owner)) if new_resource.owner end - new_resource.updated_by_last_action(true) end end @@ -55,7 +55,7 @@ def whyrun_supported? end def load_current_resource - @current_resource = Chef::Resource::PythonVirtualenv.new(new_resource.name) + @current_resource = Chef::ResourceResolver.resolve(:python_virtualenv).new(new_resource.name) @current_resource.path(new_resource.path) if exists? diff --git a/recipes/custom-package.rb b/recipes/custom-package.rb index 9f3a921..fdeb360 100644 --- a/recipes/custom-package.rb +++ b/recipes/custom-package.rb @@ -21,17 +21,7 @@ # This recipe assumes that you have a custom package repository with # Python built and named as "python27" -include_recipe 'yum-gd' - -python_pkgs = value_for_platform_family( - 'debian' => [node['python']['custom_package_name'], "#{node['python']['custom_package_name']}-dev"], - 'rhel' => [node['python']['custom_package_name'], "#{node['python']['custom_package_name']}-devel"], - 'centos' => [node['python']['custom_package_name'], "#{node['python']['custom_package_name']}-devel"], - 'fedora' => [node['python']['custom_package_name'], "#{node['python']['custom_package_name']}-devel"], - 'freebsd' => [node['python']['custom_package_name']], - 'smartos' => [node['python']['custom_package_name']], - 'default' => [node['python']['custom_package_name'], "#{node['python']['custom_package_name']}-dev"] -) +python_pkgs = [node['python']['custom_package_name'], "#{node['python']['custom_package_name']}-devel"] python_pkgs.each do |pkg| package pkg do diff --git a/recipes/package.rb b/recipes/package.rb index 1a8a4d3..5529e74 100644 --- a/recipes/package.rb +++ b/recipes/package.rb @@ -17,27 +17,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # - -major_version = node['platform_version'].split('.').first.to_i - -# COOK-1016 Handle RHEL/CentOS namings of python packages, by installing EPEL -# repo & package -if platform_family?('rhel') && major_version < 6 - include_recipe 'yum-epel' - python_pkgs = ['python26', 'python26-devel'] - node.default['python']['binary'] = '/usr/bin/python26' - -else - python_pkgs = value_for_platform_family( - 'debian' => ['python', 'python-dev'], - 'rhel' => ['python', 'python-devel'], - 'centos' => ['python', 'python-devel'], - 'fedora' => ['python', 'python-devel'], - 'freebsd' => ['python'], - 'smartos' => ['python27'], - 'default' => ['python', 'python-dev'] - ) -end +python_pkgs = ['python', 'python-devel'] python_pkgs.each do |pkg| package pkg do diff --git a/recipes/pip.rb b/recipes/pip.rb index b2d0067..8e9ea8f 100644 --- a/recipes/pip.rb +++ b/recipes/pip.rb @@ -43,11 +43,11 @@ cwd Chef::Config[:file_cache_path] if node['python']['install_method'] == 'custom-package' command <<-EOF - #{node['python']['custom_binary']} get-pip.py pip==#{node['python']['pip']['version']} + #{node['python']['custom_binary']} get-pip.py --no-setuptools wheel==#{node['python']['wheel']['version']} pip==#{node['python']['pip']['version']} EOF else command <<-EOF - #{node['python']['binary']} get-pip.py pip==#{node['python']['pip']['version']} + #{node['python']['binary']} get-pip.py --no-setuptools wheel==#{node['python']['wheel']['version']} pip==#{node['python']['pip']['version']} EOF end not_if { ::File.exist?(pip_binary) } diff --git a/recipes/source.rb b/recipes/source.rb index 21d0439..c88b603 100644 --- a/recipes/source.rb +++ b/recipes/source.rb @@ -31,7 +31,7 @@ 'db4-devel', 'sqlite-devel', 'ncurses-devel', - 'readline-devel' + 'readline-devel', ], 'default' => ['libssl-dev', 'libbz2-dev', @@ -43,7 +43,7 @@ 'libncurses5-dev', 'libreadline-dev', 'libsasl2-dev', - 'libgdbm-dev' + 'libgdbm-dev', ] ) # diff --git a/recipes/virtualenv.rb b/recipes/virtualenv.rb index 65fabb9..11b9a58 100644 --- a/recipes/virtualenv.rb +++ b/recipes/virtualenv.rb @@ -23,4 +23,5 @@ python_pip 'virtualenv' do action :upgrade version node['python']['virtualenv_version'] + options node['python']['virtualenv_options'] end diff --git a/resources/pip.rb b/resources/pip.rb index 1475b3a..4db1032 100644 --- a/resources/pip.rb +++ b/resources/pip.rb @@ -19,13 +19,7 @@ # actions :install, :upgrade, :remove, :purge -default_action :install if defined?(default_action) # Chef > 10.8 - -# Default action for Chef <= 10.8 -def initialize(*args) - super - @action = :install -end +default_action :install if defined?(default_action) attribute :package_name, :kind_of => String, :name_attribute => true attribute :version, :default => nil diff --git a/resources/virtualenv.rb b/resources/virtualenv.rb index e9f7327..9af1eae 100644 --- a/resources/virtualenv.rb +++ b/resources/virtualenv.rb @@ -19,13 +19,7 @@ # actions :create, :delete -default_action :create if defined?(default_action) # Chef > 10.8 - -# Default action for Chef <= 10.8 -def initialize(*args) - super - @action = :create -end +default_action :create if defined?(default_action) attribute :path, :kind_of => String, :name_attribute => true attribute :interpreter, :kind_of => String diff --git a/spec/custom_package_spec.rb b/spec/custom_package_spec.rb deleted file mode 100644 index f55ac03..0000000 --- a/spec/custom_package_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -# encoding: utf-8 -require 'chefspec' -require 'spec_helper' -require 'fauxhai' - -describe 'python::custom-package' do - let(:chef_run) { ChefSpec::SoloRunner.new } - - before do - chef_run.node.set['python']['install_method'] = 'custom-package' - end - - it 'includes yum-gd' do - chef_run.converge(described_recipe) - expect(chef_run).to include_recipe('yum-gd') - end - - it 'installs python27' do - chef_run.converge(described_recipe) - expect(chef_run).to install_package('python27') - end - - it 'installs python-devel' do - chef_run.converge(described_recipe) - expect(chef_run).to install_package('python27-devel') - end - - it 'installs python27alt' do - chef_run.node.set['platform'] = 'amazon' - chef_run.converge(described_recipe) - expect(chef_run).to install_package('python27') - end - - it 'installs pythonalt-devel' do - chef_run.node.set['platform'] = 'amazon' - chef_run.converge(described_recipe) - expect(chef_run).to install_package('python27-devel') - end -end diff --git a/spec/default_spec.rb b/spec/default_spec.rb deleted file mode 100644 index 2789d37..0000000 --- a/spec/default_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -# encoding: utf-8 -require 'chefspec' -require 'spec_helper' -require 'fauxhai' - -describe 'python::default' do - let :chef_run do - ChefSpec::SoloRunner.new(file_cache_path: '/var/chef/cache').converge(described_recipe) - end - - before do - stub_command("/usr/bin/python -c 'import setuptools'").and_return(true) - end - - it 'includes python::custom-package by default' do - chef_run.converge(described_recipe) - expect(chef_run).to include_recipe('python::custom-package') - end - - it 'includes python::pip' do - chef_run.converge(described_recipe) - expect(chef_run).to include_recipe('python::pip') - end - - it 'includes python::virtualenv' do - chef_run.converge(described_recipe) - expect(chef_run).to include_recipe('python::virtualenv') - end -end diff --git a/spec/package_spec.rb b/spec/package_spec.rb deleted file mode 100644 index 904eef2..0000000 --- a/spec/package_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -# encoding: utf-8 -require 'chefspec' -require 'spec_helper' -require 'fauxhai' - -describe 'python::package' do - let :chef_run do - ChefSpec::SoloRunner.converge(described_recipe) - end - - before do - stub_command("/usr/bin/python -c 'import setuptools'").and_return(true) - end - - it 'installs python' do - chef_run.converge(described_recipe) - expect(chef_run).to install_package('python') - end - - it 'installs python-devel' do - chef_run.converge(described_recipe) - expect(chef_run).to install_package('python-devel') - end - -end diff --git a/spec/pip_spec.rb b/spec/pip_spec.rb deleted file mode 100644 index a62e8b6..0000000 --- a/spec/pip_spec.rb +++ /dev/null @@ -1,36 +0,0 @@ -# encoding: utf-8 -require 'chefspec' -require 'spec_helper' -require 'fauxhai' - -describe 'python::pip' do - let :chef_run do - ChefSpec::SoloRunner.new(file_cache_path: '/var/chef/cache').converge(described_recipe) - end - - before do - stub_command("/usr/bin/python -c 'import setuptools'").and_return(true) - stub_command("/usr/bin/python get-pip-py").and_return(true) - stub_command("/usr/local/bin/python2.7 get-pip-py").and_return(true) - end - - it 'creates get-pip.py in the Chef file_cache_path with mode 644' do - chef_run.converge(described_recipe) - expect(chef_run).to create_cookbook_file(File.join(Chef::Config[:file_cache_path], 'get-pip.py')).with( - :mode => '0644' - ) - end - - it 'executes get-pip.py to install pip' do - chef_run.converge(described_recipe) - node_python_attributes = chef_run.node['python'] - expect(chef_run).to run_execute("install-pip") - # expect(chef_run).to run_execute("#{node_python_attributes['binary']} get-pip.py") - end - - it 'installs setuptools' do - chef_run.converge(described_recipe) - expect(chef_run).to upgrade_python_pip('setuptools') - end - -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 5596b68..21c8e0e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,10 +1,6 @@ -require 'coveralls' require 'chefspec' require 'chefspec/berkshelf' require 'support/matchers' -require 'webmock/rspec' - -WebMock.allow_net_connect! RSpec.configure do |config| # run all specs when using a filter, but no spec match diff --git a/spec/unit/recipes/custom_package_spec.rb b/spec/unit/recipes/custom_package_spec.rb new file mode 100644 index 0000000..b3b08ed --- /dev/null +++ b/spec/unit/recipes/custom_package_spec.rb @@ -0,0 +1,22 @@ +# encoding: utf-8 +require 'chefspec' +require 'spec_helper' +require 'fauxhai' + +describe 'python::custom-package' do + context 'When all attributes are default, on CentOS 7.4' do + let(:chef_run) do + ChefSpec::SoloRunner.new(platform: 'centos', version: '7.4.1708') do |node| + node.set['python']['install_method'] = 'custom-package' + end.converge(described_recipe) + end + + it 'installs python27' do + expect(chef_run).to install_package('python27') + end + + it 'installs python-devel' do + expect(chef_run).to install_package('python27-devel') + end + end +end diff --git a/spec/unit/recipes/default_spec.rb b/spec/unit/recipes/default_spec.rb new file mode 100644 index 0000000..156708f --- /dev/null +++ b/spec/unit/recipes/default_spec.rb @@ -0,0 +1,26 @@ +# encoding: utf-8 +require 'chefspec' +require 'spec_helper' +require 'fauxhai' + +describe 'python::default' do + context 'When all attributes are default, on CentOS 7.4' do + let(:chef_run) do + ChefSpec::SoloRunner.new(platform: 'centos', version: '7.4.1708') do |node| + stub_command("/usr/bin/python -c 'import setuptools'").and_return(true) + end.converge(described_recipe) + end + + it 'includes python::custom-package by default' do + expect(chef_run).to include_recipe('python::custom-package') + end + + it 'includes python::pip' do + expect(chef_run).to include_recipe('python::pip') + end + + it 'includes python::virtualenv' do + expect(chef_run).to include_recipe('python::virtualenv') + end + end +end diff --git a/spec/unit/recipes/package_spec.rb b/spec/unit/recipes/package_spec.rb new file mode 100644 index 0000000..90dfe82 --- /dev/null +++ b/spec/unit/recipes/package_spec.rb @@ -0,0 +1,22 @@ +# encoding: utf-8 +require 'chefspec' +require 'spec_helper' +require 'fauxhai' + +describe 'python::package' do + context 'When all attributes are default, on CentOS 7.4' do + let(:chef_run) do + ChefSpec::SoloRunner.new(platform: 'centos', version: '7.4.1708') do |node| + stub_command("/usr/bin/python -c 'import setuptools'").and_return(true) + end.converge(described_recipe) + end + + it 'installs python' do + expect(chef_run).to install_package('python') + end + + it 'installs python-devel' do + expect(chef_run).to install_package('python-devel') + end + end +end diff --git a/spec/unit/recipes/pip_spec.rb b/spec/unit/recipes/pip_spec.rb new file mode 100644 index 0000000..e5de095 --- /dev/null +++ b/spec/unit/recipes/pip_spec.rb @@ -0,0 +1,35 @@ +# encoding: utf-8 +require 'chefspec' +require 'spec_helper' +require 'fauxhai' + +describe 'python::pip' do + context 'When all attributes are default, on CentOS 7.4' do + let(:chef_run) do + ChefSpec::SoloRunner.new(platform: 'centos', version: '7.4.1708') do |node| + stub_command("/usr/bin/python -c 'import setuptools'").and_return(true) + stub_command("/usr/bin/python get-pip-py").and_return(true) + stub_command("/usr/local/bin/python2.7 get-pip-py").and_return(true) + Chef::Config[:file_cache_path] = '/var/chef/cache' + end.converge(described_recipe) + end + + it 'creates get-pip.py in the Chef file_cache_path with mode 644' do + expect(chef_run).to create_cookbook_file(File.join(Chef::Config[:file_cache_path], 'get-pip.py')).with( + :mode => '0644' + ) + end + + it 'executes get-pip.py to install pip' do + expect(chef_run).to run_execute("install-pip") + end + + it 'installs setuptools' do + expect(chef_run).to upgrade_python_pip('setuptools') + end + end +end + + + + diff --git a/spec/unit/recipes/virtualenv_spec.rb b/spec/unit/recipes/virtualenv_spec.rb new file mode 100644 index 0000000..5d2336a --- /dev/null +++ b/spec/unit/recipes/virtualenv_spec.rb @@ -0,0 +1,24 @@ +# encoding: utf-8 +require 'chefspec' +require 'spec_helper' +require 'fauxhai' + +describe 'python::virtualenv' do + context 'When all attributes are default, on CentOS 7.4' do + let(:chef_run) do + ChefSpec::SoloRunner.new(platform: 'centos', version: '7.4.1708') do |node| + stub_command("/usr/bin/python -c 'import setuptools'").and_return(true) + stub_command("/usr/bin/python get-pip-py").and_return(true) + stub_command("/usr/local/bin/python2.7 get-pip-py").and_return(true) + end.converge(described_recipe) + end + + it 'includes python::pip' do + expect(chef_run).to include_recipe('python::pip') + end + + it 'installs virtualenv' do + expect(chef_run).to upgrade_python_pip('virtualenv') + end + end +end diff --git a/spec/virtualenv_spec.rb b/spec/virtualenv_spec.rb deleted file mode 100644 index 8fa692e..0000000 --- a/spec/virtualenv_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -# encoding: utf-8 -require 'chefspec' -require 'spec_helper' -require 'fauxhai' - -describe 'python::virtualenv' do - let :chef_run do - ChefSpec::SoloRunner.new(file_cache_path: '/var/chef/cache').converge(described_recipe) - end - - before do - stub_command("/usr/bin/python -c 'import setuptools'").and_return(true) - stub_command("/usr/bin/python get-pip-py").and_return(true) - stub_command("/usr/local/bin/python2.7 get-pip-py").and_return(true) - end - - it 'includes python::pip' do - chef_run.converge(described_recipe) - expect(chef_run).to include_recipe('python::pip') - end - - it 'installs virtualenv' do - chef_run.converge(described_recipe) - expect(chef_run).to upgrade_python_pip('virtualenv') - end - -end diff --git a/test/fixtures/virtualenv-test/metadata.rb b/test/fixtures/virtualenv-test/metadata.rb new file mode 100644 index 0000000..29bbfc5 --- /dev/null +++ b/test/fixtures/virtualenv-test/metadata.rb @@ -0,0 +1,2 @@ +name 'virtualenv-test' +version '0.1.0' diff --git a/test/fixtures/virtualenv-test/recipes/default.rb b/test/fixtures/virtualenv-test/recipes/default.rb new file mode 100644 index 0000000..759c057 --- /dev/null +++ b/test/fixtures/virtualenv-test/recipes/default.rb @@ -0,0 +1,3 @@ +python_virtualenv 'testenv' do + path '/tmp/testenv' +end diff --git a/test/integration/chef13-default/serverspec/Gemfile b/test/integration/chef13-default/serverspec/Gemfile new file mode 100644 index 0000000..00b80ee --- /dev/null +++ b/test/integration/chef13-default/serverspec/Gemfile @@ -0,0 +1,2 @@ +source 'https://rubygems.org' +gem 'serverspec', '= 2.41.3' diff --git a/test/integration/chef13-default/serverspec/custom-package_spec.rb b/test/integration/chef13-default/serverspec/custom-package_spec.rb new file mode 100644 index 0000000..3d103ea --- /dev/null +++ b/test/integration/chef13-default/serverspec/custom-package_spec.rb @@ -0,0 +1,14 @@ +require_relative 'spec_helper' + +describe file('/etc/yum.repos.d/gdcustom.repo') do + it { should be_file } +end + +#Should install dependant packages +describe package('python27') do + it { should be_installed } +end + +describe package('python27-devel') do + it { should be_installed } +end diff --git a/test/integration/chef13-default/serverspec/pip_spec.rb b/test/integration/chef13-default/serverspec/pip_spec.rb new file mode 100644 index 0000000..93d706d --- /dev/null +++ b/test/integration/chef13-default/serverspec/pip_spec.rb @@ -0,0 +1,16 @@ +require_relative 'spec_helper' + +describe file('/usr/local/bin/pip') do + it { should be_file } + it { should be_executable } +end + +describe command('/usr/local/bin/pip show setuptools') do + its(:stdout) { should contain('Name: setuptools') } + its(:stdout) { should contain('Version: 18.0.1') } +end + +describe command('/usr/local/bin/pip show pip') do + its(:stdout) { should contain('Name: pip') } + its(:stdout) { should contain('Version: 7.1.2') } +end diff --git a/test/integration/chef13-default/serverspec/spec_helper.rb b/test/integration/chef13-default/serverspec/spec_helper.rb new file mode 100644 index 0000000..393d781 --- /dev/null +++ b/test/integration/chef13-default/serverspec/spec_helper.rb @@ -0,0 +1,5 @@ +require 'serverspec' + +set :backend, :exec + +set :path, '/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:$PATH' diff --git a/test/integration/chef13-default/serverspec/virtualenv_spec.rb b/test/integration/chef13-default/serverspec/virtualenv_spec.rb new file mode 100644 index 0000000..fd5cd35 --- /dev/null +++ b/test/integration/chef13-default/serverspec/virtualenv_spec.rb @@ -0,0 +1,15 @@ +require_relative 'spec_helper' + +describe command('/usr/local/bin/pip show virtualenv') do + its(:stdout) { should contain('Name: virtualenv') } + its(:stdout) { should contain('Version: 13.1.0') } +end + +describe file('/tmp/testenv') do + it { should be_directory } +end + +describe file('/tmp/testenv/bin/activate') do + it { should be_file } + its(:content) { should match(/PYTHONHOME/) } +end diff --git a/test/integration/custom-package/serverspec/Gemfile b/test/integration/custom-package/serverspec/Gemfile new file mode 100644 index 0000000..00b80ee --- /dev/null +++ b/test/integration/custom-package/serverspec/Gemfile @@ -0,0 +1,2 @@ +source 'https://rubygems.org' +gem 'serverspec', '= 2.41.3' diff --git a/test/integration/default/serverspec/Gemfile b/test/integration/default/serverspec/Gemfile new file mode 100644 index 0000000..00b80ee --- /dev/null +++ b/test/integration/default/serverspec/Gemfile @@ -0,0 +1,2 @@ +source 'https://rubygems.org' +gem 'serverspec', '= 2.41.3' diff --git a/test/integration/default/serverspec/custom-package_spec.rb b/test/integration/default/serverspec/custom-package_spec.rb index 086c21d..3d103ea 100644 --- a/test/integration/default/serverspec/custom-package_spec.rb +++ b/test/integration/default/serverspec/custom-package_spec.rb @@ -1,26 +1,9 @@ require_relative 'spec_helper' -#Should include yum-gd recipe -describe file('/etc/yum.repos.d/datadog.repo') do - it { should be_file } -end - describe file('/etc/yum.repos.d/gdcustom.repo') do it { should be_file } end -describe file('/etc/yum.repos.d/opsmatic.repo') do - it { should be_file } -end - -describe file('/etc/yum.repos.d/s3tools.repo') do - it { should be_file } -end - -describe file('/etc/yum.repos.d/scalr.repo') do - it { should be_file } -end - #Should install dependant packages describe package('python27') do it { should be_installed } @@ -28,4 +11,4 @@ describe package('python27-devel') do it { should be_installed } -end \ No newline at end of file +end diff --git a/test/integration/default/serverspec/virtualenv_spec.rb b/test/integration/default/serverspec/virtualenv_spec.rb index 94138a9..fd5cd35 100644 --- a/test/integration/default/serverspec/virtualenv_spec.rb +++ b/test/integration/default/serverspec/virtualenv_spec.rb @@ -3,4 +3,13 @@ describe command('/usr/local/bin/pip show virtualenv') do its(:stdout) { should contain('Name: virtualenv') } its(:stdout) { should contain('Version: 13.1.0') } -end \ No newline at end of file +end + +describe file('/tmp/testenv') do + it { should be_directory } +end + +describe file('/tmp/testenv/bin/activate') do + it { should be_file } + its(:content) { should match(/PYTHONHOME/) } +end diff --git a/test/integration/helpers/serverspec/Gemfile b/test/integration/helpers/serverspec/Gemfile new file mode 100644 index 0000000..00b80ee --- /dev/null +++ b/test/integration/helpers/serverspec/Gemfile @@ -0,0 +1,2 @@ +source 'https://rubygems.org' +gem 'serverspec', '= 2.41.3' diff --git a/test/integration/helpers/serverspec/helpers.rb b/test/integration/helpers/serverspec/helpers.rb new file mode 100644 index 0000000..9a8762b --- /dev/null +++ b/test/integration/helpers/serverspec/helpers.rb @@ -0,0 +1,28 @@ +# helpers +def redhat? + os[:family] == 'redhat' +end + +def windows? + os[:family] == 'windows' +end + +def release?(test_version) + os[:release] == test_version +end + +def debian? + %w(debian).include?(os[:family]) +end + +def ubuntu? + %w(ubuntu).include?(os[:family]) +end + +def firewalld? + redhat? && os[:release].to_f >= 7.0 +end + +def iptables? + redhat? && os[:release].to_f < 7.0 +end diff --git a/test/integration/helpers/serverspec/spec_helper.rb b/test/integration/helpers/serverspec/spec_helper.rb new file mode 100644 index 0000000..ce128c2 --- /dev/null +++ b/test/integration/helpers/serverspec/spec_helper.rb @@ -0,0 +1,16 @@ +require 'serverspec' +require 'helpers' +require 'pathname' +require 'json' + +if ENV['OS'] == 'Windows_NT' + set :backend, :cmd + # On Windows, set the target host's OS explicitly + set :os, :family => 'windows' + $node = ::JSON.parse(File.read('c:\windows\temp\serverspec\node.json')) +else + set :backend, :exec + $node = ::JSON.parse(File.read('/tmp/serverspec/node.json')) +end + +set :path, '/sbin:/usr/local/sbin:/usr/sbin:$PATH' unless os[:family] == 'windows' diff --git a/test/integration/package/serverspec/Gemfile b/test/integration/package/serverspec/Gemfile new file mode 100644 index 0000000..00b80ee --- /dev/null +++ b/test/integration/package/serverspec/Gemfile @@ -0,0 +1,2 @@ +source 'https://rubygems.org' +gem 'serverspec', '= 2.41.3' diff --git a/test/integration/package/serverspec/pip_spec.rb b/test/integration/package/serverspec/pip_spec.rb index ba21cc2..e14a55e 100644 --- a/test/integration/package/serverspec/pip_spec.rb +++ b/test/integration/package/serverspec/pip_spec.rb @@ -1,12 +1,6 @@ require_relative 'spec_helper' -if ['rhel', 'fedora', 'redhat'].include?(os[:family]) - pip_binary = '/usr/bin/pip' -elsif os[:family] == 'smartos' - pip_binary = '/opt/local/bin/pip' -else - pip_binary = '/usr/local/bin/pip' -end +pip_binary = '/usr/bin/pip' describe file("#{pip_binary}") do it { should be_file } @@ -15,7 +9,6 @@ describe command("#{pip_binary} show setuptools") do its(:stdout) { should contain('Name: setuptools') } - its(:stdout) { should contain('Version: 18.0.1') } end describe command("#{pip_binary} show pip") do diff --git a/test/integration/package/serverspec/virtualenv_spec.rb b/test/integration/package/serverspec/virtualenv_spec.rb index bc7a027..c9f8292 100644 --- a/test/integration/package/serverspec/virtualenv_spec.rb +++ b/test/integration/package/serverspec/virtualenv_spec.rb @@ -1,14 +1,7 @@ require_relative 'spec_helper' -if ['rhel', 'fedora', 'redhat'].include?(os[:family]) - pip_binary = '/usr/bin/pip' -elsif os[:family] == 'smartos' - pip_binary = '/opt/local/bin/pip' -else - pip_binary = '/usr/local/bin/pip' -end +pip_binary = '/usr/bin/pip' describe command("#{pip_binary} show virtualenv") do its(:stdout) { should contain('Name: virtualenv') } - its(:stdout) { should contain('Version: 13.1.0') } end \ No newline at end of file diff --git a/test/integration/source/serverspec/Gemfile b/test/integration/source/serverspec/Gemfile new file mode 100644 index 0000000..00b80ee --- /dev/null +++ b/test/integration/source/serverspec/Gemfile @@ -0,0 +1,2 @@ +source 'https://rubygems.org' +gem 'serverspec', '= 2.41.3' diff --git a/test/integration/source/serverspec/source_spec.rb b/test/integration/source/serverspec/source_spec.rb index de192a8..8711bef 100644 --- a/test/integration/source/serverspec/source_spec.rb +++ b/test/integration/source/serverspec/source_spec.rb @@ -17,10 +17,6 @@ it { should be_installed } end - describe package('db4-devel') do - it { should be_installed } - end - describe package('sqlite-devel') do it { should be_installed } end