├── .gitignore ├── .kitchen.ec2.yml ├── .kitchen.yml ├── .rubocop.yml ├── .travis.yml ├── Berksfile ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Gemfile ├── ISSUES.md ├── LICENSE ├── README.md ├── Rakefile ├── Thorfile ├── attributes └── default.rb ├── chefignore ├── libraries └── helpers.rb ├── metadata.rb ├── recipes ├── default.rb ├── install.rb ├── master.rb ├── repo.rb └── slave.rb ├── spec ├── spec_helper.rb └── unit │ └── recipes │ ├── default_spec.rb │ ├── install_spec.rb │ ├── master_spec.rb │ ├── repo_spec.rb │ └── slave_spec.rb ├── templates └── default │ ├── systemd.erb │ ├── sysvinit_debian.erb │ ├── upstart.erb │ └── wrapper.erb └── test └── integration ├── 1-0-0 └── serverspec │ └── mesos_version.rb ├── 1-0-1 └── serverspec │ └── mesos_version.rb ├── 1-1-0 └── serverspec │ └── mesos_version.rb └── helpers └── serverspec ├── mesos_install_spec.rb ├── mesos_master_spec.rb ├── mesos_slave_spec.rb └── spec_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | .vagrant 2 | Berksfile.lock 3 | *~ 4 | *# 5 | .#* 6 | \#*# 7 | .*.sw[a-z] 8 | *.un~ 9 | /cookbooks 10 | 11 | # Bundler 12 | Gemfile.lock 13 | bin/* 14 | .bundle/* 15 | 16 | .kitchen/ 17 | .kitchen.local.yml 18 | -------------------------------------------------------------------------------- /.kitchen.ec2.yml: -------------------------------------------------------------------------------- 1 | # This configuration uses the kitchen-ec2 plugin 2 | # https://github.com/test-kitchen/kitchen-ec2 3 | # 4 | # The following environmental variables are required: 5 | # - AWS_ACCESS_KEY_ID 6 | # - AWS_SECRET_ACCESS_KEY 7 | # - AWS_SSH_KEY_ID 8 | # - AWS_SUBNET_ID 9 | # - AWS_SECURITY_GROUP_ID 10 | # 11 | # Please make sure the default VPC security group 12 | # for the given subnet id allows inbound SSH. 13 | --- 14 | driver: 15 | name: ec2 16 | region: us-west-2 17 | instance_type: t2.micro # AWS Free Tier 18 | associate_public_ip: true 19 | subnet_id: <%= ENV['AWS_SUBNET_ID'] %> 20 | security_group_ids: ["<%= ENV['AWS_SECURITY_GROUP_ID'] %>"] 21 | tags: 22 | Name: 'test-kitchen mesos-cookbook <%= Time.now.strftime("%d/%m/%Y %H:%M") %>' 23 | 24 | busser: 25 | sudo: true 26 | 27 | provisioner: 28 | name: chef_zero 29 | require_chef_omnibus: 12.5.1 30 | 31 | platforms: 32 | - name: amazon-2016.09.0 33 | run_list: 34 | - recipe[yum] 35 | driver: 36 | image_id: ami-b04e92d0 37 | transport: 38 | username: ec2-user 39 | # https://cloud-images.ubuntu.com/locator/ec2/ 40 | - name: ubuntu-16.04 41 | run_list: 42 | - recipe[apt] 43 | - recipe[curl] 44 | driver: 45 | image_id: ami-a9d276c9 46 | - name: ubuntu-15.10 47 | run_list: 48 | - recipe[apt] 49 | - recipe[curl] 50 | driver: 51 | image_id: ami-1863a178 52 | - name: ubuntu-14.04 53 | run_list: 54 | - recipe[apt] 55 | - recipe[curl] 56 | driver: 57 | image_id: ami-01f05461 58 | - name: ubuntu-12.04 59 | run_list: 60 | - recipe[apt] 61 | - recipe[curl] 62 | driver: 63 | image_id: ami-adcd69cd 64 | # https://wiki.debian.org/Cloud/AmazonEC2Image 65 | - name: debian-8.6 66 | run_list: 67 | - recipe[apt] 68 | - recipe[curl] 69 | driver: 70 | image_id: ami-4e1cc32e 71 | # https://wiki.centos.org/Cloud/AWS 72 | - name: centos-7 73 | run_list: 74 | - recipe[yum] 75 | driver: 76 | image_id: ami-d2c924b2 77 | block_device_mappings: 78 | - device_name: /dev/sda1 79 | ebs: {volume_type: gp2, delete_on_termination: true} 80 | - name: centos-6 81 | run_list: 82 | - recipe[yum] 83 | driver: 84 | image_id: ami-05cf2265 85 | block_device_mappings: 86 | - device_name: /dev/sda1 87 | ebs: {volume_type: gp2, delete_on_termination: true} 88 | 89 | suites: 90 | - &default 91 | name: 1-1-0 92 | run_list: 93 | - recipe[mesos::master] 94 | - recipe[mesos::slave] 95 | attributes: 96 | mesos: 97 | slave: 98 | flags: 99 | attributes: 'attribute01:value01;attribute02:value02' 100 | - <<: *default 101 | name: 1-0-1 102 | attributes: 103 | mesos: 104 | version: 1.0.1 105 | - <<: *default 106 | name: 1-0-0 107 | attributes: 108 | mesos: 109 | version: 1.0.0 110 | -------------------------------------------------------------------------------- /.kitchen.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: vagrant 4 | customize: {cpus: 2, memory: 1024} 5 | network: [['forwarded_port', {guest: 5050, host: 5050, auto_correct: true}]] 6 | 7 | provisioner: 8 | name: chef_zero 9 | require_chef_omnibus: 12.14.60 10 | 11 | platforms: 12 | - name: ubuntu-16.04 13 | run_list: ['recipe[apt]', 'recipe[curl]'] 14 | - name: ubuntu-15.10 15 | run_list: ['recipe[apt]', 'recipe[curl]'] 16 | - name: ubuntu-14.04 17 | run_list: ['recipe[apt]', 'recipe[curl]'] 18 | - name: ubuntu-12.04 19 | run_list: ['recipe[apt]', 'recipe[curl]'] 20 | - name: debian-8.6 21 | run_list: ['recipe[apt]'] 22 | attributes: {java: {jdk_version: '7'}} 23 | - name: centos-7.2 24 | run_list: ['recipe[yum]'] 25 | - name: centos-6.8 26 | run_list: ['recipe[yum]'] 27 | # Oracle Linux 28 | # - name: box-cutter/ol68 29 | # run_list: ['recipe[yum]'] 30 | # - name: box-cutter/ol72 31 | # run_list: ['recipe[yum]'] 32 | 33 | suites: 34 | - &default 35 | name: 1-1-0 36 | run_list: 37 | - recipe[mesos::master] 38 | - recipe[mesos::slave] 39 | attributes: 40 | mesos: 41 | slave: 42 | flags: 43 | attributes: 'attribute01:value01;attribute02:value02' 44 | - <<: *default 45 | name: 1-0-1 46 | attributes: {mesos: {version: '1.0.1'}} 47 | - <<: *default 48 | name: 1-0-0 49 | attributes: {mesos: {version: '1.0.0'}} 50 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | AllCops: 3 | Exclude: 4 | - vendor/**/* 5 | - bin/**/* 6 | - .kitchen/**/* 7 | Metrics/BlockLength: 8 | Exclude: 9 | - '**/*_spec.rb' 10 | 11 | ClassLength: 12 | Enabled: false 13 | Documentation: 14 | Enabled: false 15 | Encoding: 16 | Enabled: false 17 | LineLength: 18 | Enabled: false 19 | MethodLength: 20 | Enabled: false 21 | NumericLiterals: 22 | Enabled: false 23 | ClassAndModuleChildren: 24 | Enabled: false 25 | Style/StringLiterals: 26 | Enabled: true 27 | EnforcedStyle: single_quotes 28 | Metrics/LineLength: 29 | Enabled: false 30 | Style/ExtraSpacing: 31 | Enabled: false 32 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | rvm: 3 | - 2.3.1 4 | script: 5 | - bundle exec rake travis 6 | -------------------------------------------------------------------------------- /Berksfile: -------------------------------------------------------------------------------- 1 | source 'https://supermarket.getchef.com' 2 | 3 | metadata 4 | 5 | cookbook 'curl' 6 | cookbook 'exhibitor', git: 'git@github.com:SimpleFinance/chef-exhibitor.git', branch: 'master' 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. 3 | This project adheres to [Semantic Versioning](http://semver.org/). 4 | 5 | ## [3.6.0] - 2016-12-05 6 | ### Fixed 7 | - Mesos 1.0.0 and 1.0.1 require the --work_dir flag to be specified 8 | 9 | ### Changed 10 | - Default to Mesos 1.1.0 11 | - Default Java version to 8 12 | - Unlock yum cookbook version 13 | - Platform list updated to match Mesosphere packages 14 | 15 | ## [3.5.1] - 2015-12-23 16 | ### Fixed 17 | - Fix Amazon Linux support 18 | 19 | ### Changed 20 | - Set up yum repo with `yum_repository` provider 21 | - Remove dependency on chef-sugar 22 | 23 | ## [3.5.0] - 2015-12-21 24 | ### Added 25 | - Systemd support 26 | - Dynamic configuration guard 27 | - Set default `cgroups_hierarchy` attribute 28 | 29 | ### Changed 30 | - Improved upstart script to start after network (@kamaradclimber) 31 | - Default to Mesos 0.25.0 32 | - Removed support for Mesos < 0.23.0 33 | - Refactored testing suite 34 | - Platform list updated to match Mesosphere package 35 | - Tested with Chef 12.5.1 36 | 37 | ## [3.4.0] - 2015-08-25 38 | ### Added 39 | - Added support for Apache Mesos 0.23.0. 40 | 41 | ### Changed 42 | - Removed support for Ubuntu 13.10. 43 | - Removed support for Mesos 0.20.x. 44 | - Changed all compile_time calls to at_compile_time for Chef 12.2.x compatibility with ChefSugar. 45 | 46 | ## [3.3.0] - 2015-07-05 47 | ### Added 48 | - Added support for Apache Mesos 0.22.1. 49 | - Added vagrant-wrapper in gemfile for testing. 50 | - Set ulimit for init service if defined. 51 | - Install mesosphere packages from a package mirror. 52 | 53 | ### Changed 54 | - Switched to using port 80 for Ubuntu Keyservers to get through corporate firewalls. 55 | 56 | ## [3.2.3] - 2015-03-29 57 | ### Fixed 58 | - Fixed master and slave recipes to use node override for zk endpoints. 59 | 60 | ## [3.2.2] - 2015-03-29 61 | ### Fixed 62 | - Fixed master and slave recipes to use node instead of default to set zk endpoints. 63 | 64 | ## [3.2.1] - 2015-03-29 65 | ### Fixed 66 | - Fixed zk exhibitor discovery logic to use new master and slave flags. 67 | 68 | ## [3.2.0] - 2015-03-29 69 | ### Changed 70 | - Updated default Mesos version to 0.21.1. 71 | - Added support for Mesos 0.22.0. 72 | - Removed support for Mesos 0.19.x. 73 | 74 | ## [3.1.0] - 2015-03-27 75 | ### Changed 76 | - Refactor greatly simplifies Mesos wrapper script. 77 | - Configuration now passed primarily via command line flags. 78 | - Switched to Upstart & Sysvinit for Mesos init. 79 | - Metadata uses suggests instead of recommends for the exhibitor cookbook. 80 | 81 | ### Contributors for this release: 82 | 83 | - [Robert Vežnaver](https://github.com/rveznaver) - Amazing Mesos wrapper refactor. 84 | 85 | Thank You! 86 | 87 | ## [3.0.0] - 2015-03-11 88 | ### Changed 89 | - Mesos is now installed via the Mesosphere RPM and deb package repositories. 90 | - Added validation for Mesos flags to ensure that Mesos starts with configured 91 | flags. 92 | - Added support for Mesos 0.21.1. 93 | - Added all Mesos attributes which can be configured. 94 | - Added libsvn1 depedency for newer Mesos versions. 95 | - Updated rubocop style file. 96 | 97 | ### Fixed 98 | - Fixed a bug with the ZK exhibitor discovery mechanism. 99 | - Fixed redhat family name in install recipe. 100 | 101 | ### Removed 102 | - Removed experimental docker recipe. 103 | - Removed EC2 hostname logic. 104 | - Removed support for Mesos 0.19.0. 105 | 106 | ## [2.0.0] - 2014-11-14 107 | ### Changed 108 | - Writes all attributes under `node['mesos']['common]`/`node['mesos']['master']` to respective config files 109 | - Adds support for Ubuntu 14.04 (Trusty Tahr) 110 | - Adds support for Debian 7 (Wheezy) 111 | 112 | ## [1.0.6] - 2014-02-19 113 | ### Changed 114 | - Re-added default-jre-headless as required package due to breaking issues with 115 | mesos debian package when used with a non-openjdk java like Oracle. 116 | - Added some serverspecs to verify working cookbook with oracle jdk 7. 117 | 118 | ## [1.0.5] - 2014-02-15 119 | ### Changed 120 | 121 | - Removed default-jre-headless as required package 122 | - Added slave checkpointing defaults 123 | - Added kitchen-ec2 configuration for CI 124 | 125 | ## [1.0.4] - 2014-02-07 126 | ### Changed 127 | 128 | - Add support for RHEL linux family 129 | - Updated integration tests (serverspec) 130 | 131 | ## [1.0.3] - 2014-02-03 132 | ### Changed 133 | 134 | - Fix zk_string generating logic to strip triailing comma 135 | - Add exhibitor discover zookeepers retry logic 136 | 137 | ## [1.0.2] - 2014-01-31 138 | ### Changed 139 | 140 | - Fix docker-mesos egg url 141 | 142 | ## [1.0.1] - 2014-01-13 143 | ### Changed 144 | 145 | - Update default mesos version to 0.15.0 146 | - Use attribute for mesos python bindings egg 147 | 148 | ## [1.0.0] - 2013-12-12 149 | ### Changed 150 | 151 | - Public release of cookbook 152 | - Added experimental docker-mesos recipe 153 | - Updated mesos default version to 0.14.2 154 | 155 | ## [0.1.0] - 2013-10-08 156 | ### Changed 157 | 158 | - Initial Cookbook release 159 | 160 | [3.6.0]: https://github.com/mdsol/mesos_cookbook/compare/3.5.1...3.6.0 161 | [3.5.1]: https://github.com/mdsol/mesos_cookbook/compare/3.5.0...3.5.1 162 | [3.5.0]: https://github.com/mdsol/mesos_cookbook/compare/3.4.0...3.5.0 163 | [3.4.0]: https://github.com/mdsol/mesos_cookbook/compare/3.3.0...3.4.0 164 | [3.3.0]: https://github.com/mdsol/mesos_cookbook/compare/3.2.3...3.3.0 165 | [3.2.3]: https://github.com/mdsol/mesos_cookbook/compare/3.2.2...3.2.3 166 | [3.2.2]: https://github.com/mdsol/mesos_cookbook/compare/3.2.1...3.2.2 167 | [3.2.1]: https://github.com/mdsol/mesos_cookbook/compare/3.2.0...3.2.1 168 | [3.2.0]: https://github.com/mdsol/mesos_cookbook/compare/3.1.0...3.2.0 169 | [3.1.0]: https://github.com/mdsol/mesos_cookbook/compare/3.0.0...3.1.0 170 | [3.0.0]: https://github.com/mdsol/mesos_cookbook/compare/2.0.0...3.0.0 171 | [2.0.0]: https://github.com/mdsol/mesos_cookbook/compare/1.0.6...2.0.0 172 | [1.0.6]: https://github.com/mdsol/mesos_cookbook/compare/1.0.5...1.0.6 173 | [1.0.5]: https://github.com/mdsol/mesos_cookbook/compare/1.0.4...1.0.5 174 | [1.0.4]: https://github.com/mdsol/mesos_cookbook/compare/1.0.3...1.0.4 175 | [1.0.3]: https://github.com/mdsol/mesos_cookbook/compare/1.0.2...1.0.3 176 | [1.0.2]: https://github.com/mdsol/mesos_cookbook/compare/1.0.1...1.0.2 177 | [1.0.1]: https://github.com/mdsol/mesos_cookbook/compare/1.0.0...1.0.1 178 | [1.0.0]: https://github.com/mdsol/mesos_cookbook/compare/0.1.0...1.0.0 179 | [0.1.0]: https://github.com/mdsol/mesos_cookbook/compare/0.1.0...0.1.0 180 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing to the Mesos Cookbook 2 | ==================================== 3 | The Mesos cookbook uses GitHub to triage, manage, and track issues and pull 4 | requests to the cookbook. GitHub has excellent documentation on how to 5 | [fork a repository and start contributing](https://help.github.com/articles/fork-a-repo.). 6 | 7 | All contributors are welcome to submit patches, but we ask you keep the 8 | following guidelines in mind: 9 | 10 | - [Coding Standards](#coding-standards) 11 | - [Testing](#testing) 12 | - [Prerequisites](#prerequisites) 13 | 14 | Please also keep in mind: 15 | 16 | - Be patient as not all items will be tested or reviewed immediately by the core 17 | team. 18 | - Be receptive and responsive to feedback about your additions or changes. The 19 | core team and/or other community members may make suggestions or ask questions 20 | about your change. This is part of the review process, and helps everyone to 21 | understand what is happening, why it is happening, and potentially optimizes 22 | your code. 23 | - Be understanding. 24 | 25 | If you're looking to contribute but aren't sure where to start, check out the 26 | open issues. 27 | 28 | 29 | Will Not Merge 30 | -------------- 31 | This second details Pull Requests that we will **not** merge. 32 | 33 | 1. New features without accompanying Test Kitchen tests 34 | 1. New features without accompanying usage documentation 35 | 36 | 37 | Coding Standards 38 | ---------------- 39 | The submitted code should be compatible with the standard Ruby coding guidelines. 40 | Here are some additional resources: 41 | 42 | - [Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide) 43 | - [GitHub Styleguide](https://github.com/styleguide/ruby) 44 | 45 | This cookbook is equipped with Rubocop, which will fail the build for violating 46 | these standards. 47 | 48 | 49 | Testing 50 | ------- 51 | Whether your pull request is a bug fix or introduces new classes or methods to the 52 | project, we kindly ask that you include tests for your changes. Even if it's just a 53 | small improvement, a test is necessary to ensure the bug is never re-introduced. 54 | 55 | We understand that not all users are familiar with the testing ecosystem. This cookbook 56 | is fully-tested using [Foodcritic](https://github.com/acrmp/foodcritic), 57 | [Rubocop](https://github.com/bbatsov/rubocop), and 58 | [Test Kitchen](https://github.com/test-kitchen/test-kitchen) with 59 | [Serverspec](https://github.com/serverspec/serverspec) bussers. 60 | 61 | 62 | Prerequisites 63 | ------------- 64 | Developing this cookbook requires a sane Ruby 1.9+ environment with `bundler` installed. 65 | In order to run the Test Kitchen integration suite, you must also have Vagrant and 66 | VirtualBox installed: 67 | 68 | - [Vagrant](https://vagrantup.com) 69 | - [VirtualBox](https://virtualbox.org) 70 | 71 | 72 | Process 73 | ------- 74 | 1. Clone the git repository from GitHub: 75 | 76 | $ git clone git@github.com:mdsol/mesos_cookbook.git 77 | 78 | 2. Install the dependencies using bundler: 79 | 80 | $ bundle install 81 | 82 | 3. Create a branch for your changes: 83 | 84 | $ git checkout -b my_bug_fix 85 | 86 | 4. Make any changes 87 | 5. Write tests to support those changes. 88 | 6. Run the tests: 89 | 90 | $ bundle exec rake 91 | 92 | 7. Assuming the tests pass, open a Pull Request on GitHub 93 | 94 | 95 | Do's and Don't's 96 | ---------------- 97 | - **Do** include tests for your contribution 98 | - **Do NOT** break existing behavior (unless intentional) 99 | - **Do NOT** modify the version number in the `metadata.rb` 100 | - **Do NOT** modify the CHANGELOG 101 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'berkshelf' 4 | gem 'chefspec' 5 | gem 'foodcritic' 6 | gem 'rubocop' 7 | gem 'serverspec' 8 | 9 | gem 'chef', '= 12.14.60' 10 | 11 | group :integration do 12 | gem 'kitchen-ec2' 13 | gem 'kitchen-vagrant' 14 | gem 'rake' 15 | gem 'test-kitchen' 16 | gem 'vagrant-wrapper' 17 | end 18 | -------------------------------------------------------------------------------- /ISSUES.md: -------------------------------------------------------------------------------- 1 | Mesos Cookbook Issues 2 | ============================ 3 | This file documents the steps necessary to report any issue with the mesos 4 | cookbook. Following these guidelines will help ensure your issue is resolved in a 5 | timely manner. 6 | 7 | Reporting 8 | --------- 9 | When you report an issue, please include the following information: 10 | 11 | - A high-level overview of what you are trying to accomplish 12 | - An [SSCCE](http://sscce.org/) 13 | - The command you ran 14 | - What you expected to happen 15 | - What actually happened 16 | - The exception backtrace(s), if any 17 | - What operating system and version 18 | - Everything output by running `env` 19 | - What version of the cookbook are you using? 20 | - What version of Ruby you are using (run `ruby -v`) 21 | - What version of Rubygems you are using (run `gem -v`) 22 | - What version of Chef you are using (run `knife -v`) 23 | 24 | Here's a snippet you can copy-paste into the issue and fill out: 25 | 26 | ```text 27 | (What is the issue? What are you trying to do? What happened?) 28 | 29 | - Command: `...` 30 | - OS: 31 | - Cookbook Version: 32 | - Ruby Version: 33 | - Rubygems Version: 34 | - Chef Version: 35 | - env: 36 | ```text 37 | # Paste your env here 38 | ``` 39 | - Backtrace: 40 | ```text 41 | # Paste backtrace here 42 | ``` 43 | ``` 44 | 45 | [Create a ticket](https://github.com/mdsol/mesos_cookbook/issues/new) describing your problem and include the information above. 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2015 Medidata Solutions, Inc. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Mesos Cookbook 2 | ============== 3 | [![Cookbook](http://img.shields.io/cookbook/v/mesos.svg)](https://supermarket.chef.io/cookbooks/mesos) 4 | [![Build Status](https://secure.travis-ci.org/mdsol/mesos_cookbook.png?branch=master)](http://travis-ci.org/mdsol/mesos_cookbook) 5 | [![Gitter chat](https://img.shields.io/badge/Gitter-mdsol%2Fmesos_cookbook-brightgreen.svg)](https://gitter.im/mdsol/mesos_cookbook) 6 | 7 | Application cookbook for installing the [Apache Mesos][] cluster manager. 8 | Mesos provides efficient resource isolation and sharing across distributed 9 | applications, or frameworks. This cookbook installs Mesos via packages 10 | provided by [Mesosphere][]. 11 | 12 | Requirements 13 | ------------ 14 | 15 | - Chef >= 12.14.60 16 | 17 | Platform 18 | -------- 19 | Tested on 20 | 21 | * Ubuntu 16.04 22 | * Ubuntu 15.10 23 | * Ubuntu 14.04 24 | * Ubuntu 12.04 25 | * Debian 8.6 (with Java 7) 26 | * CentOS 7.2 27 | * CentOS 6.8 28 | 29 | Supported Mesos versions 30 | ------------------------ 31 | 32 | This cookbook is tested against the following Apache Mesos versions: 33 | 34 | * 1.1.0 35 | * 1.0.1 36 | * 1.0.0 37 | 38 | We intend to support at most the three latest versions of Apache Mesos. 39 | 40 | Attributes 41 | ---------- 42 | In order to keep the README managable and in sync with the attributes, this 43 | cookbook documents attributes inline. The usage instructions and default 44 | values for attributes can be found in the individual attribute files. 45 | 46 | Configuring Mesos via attributes 47 | ----------------------------------------- 48 | This cookbook introduces a few points of validation to prevent passing Mesos 49 | invalid configuration options. The ruby block 50 | `mesos-slave-configuration-validation` and 51 | `mesos-master-configuration-validation` extract a hash of all valid Mesos 52 | configuration options from the `--help` output of the master and slave binary 53 | and check it against the provided attributes. This cookbook will fail to 54 | converge if you try to use an invalid configuration option as a command line 55 | flag attribute under `['mesos']['master']['flags']` 56 | or `['mesos']['slave']['flags']` hashes. 57 | 58 | The valid list of Mesos options may be found at: 59 | https://github.com/apache/mesos/blob/master/docs/configuration.md 60 | 61 | ## Recipes 62 | 63 | ### default 64 | The default mesos recipe will run mesos::install. 65 | 66 | ### install 67 | The install recipe installs the specified version of the mesosphere mesos 68 | RPM or Debian package and installs it. It’s also configured to stop both 69 | mesos-master and mesos-slave init files so that they don't automatically 70 | start on server restart. 71 | 72 | ### master 73 | The master recipe runs mesos::install as well as creating several 74 | mesos-master configuration files that are used at startup. This recipe also 75 | uses the zookeeper attributes and/or exhibitor attributes to configure the 76 | mesos-master using zookeeper. Lastly it sets the mesos-master init config to 77 | 'start' so that mesos-master is started on server restart. 78 | 79 | ### slave 80 | The slave recipe runs mesos::install as well as creating several 81 | mesos-slave configuration files that are used at startup. This recipe also 82 | uses the zookeeper attributes and/or exhibitor attributes to configure the 83 | mesos-slave using zookeeper. Lastly it sets the mesos-slave init config to 84 | 'start' so that mesos-slave is started on server restart. 85 | 86 | ### repo 87 | The repo recipe contains logic for setting up Mesosphere debian and RPM 88 | repositories. 89 | 90 | Dependencies 91 | ------------ 92 | 93 | The following cookbooks are dependencies: 94 | 95 | * [apt][] 96 | * [yum][] 97 | * [java][] 98 | 99 | The following cookbooks are suggested: 100 | 101 | * [exhibitor][] (used for discovering ZooKeeper ensembles via [Netflix Exhibitor][]) 102 | 103 | Usage 104 | ----- 105 | 106 | Here is a sample role for configuring a Mesos master in a ZooKeeper backed 107 | production mode. 108 | 109 | ```YAML 110 | chef_type: role 111 | default_attributes: 112 | description: 113 | env_run_lists: 114 | json_class: Chef::Role 115 | name: mesos_master 116 | override_attributes: 117 | mesos: 118 | version: 1.0.1 119 | master: 120 | flags: 121 | cluster: 'mesos-sandbox' 122 | zk: 'zk://127.0.0.1:2181/mesos' 123 | run_list: 124 | recipe[mesos::master] 125 | ``` 126 | 127 | Here is a sample role for creating a Mesos slave node with a seperate ZooKeeper 128 | ensemble dynamically discovered via Netflix Exhibitor: 129 | ```YAML 130 | chef_type: role 131 | default_attributes: 132 | description: 133 | env_run_lists: 134 | json_class: Chef::Role 135 | name: mesos_slave 136 | override_attributes: 137 | mesos: 138 | version: 1.0.1 139 | slave: 140 | flags: 141 | master: 'zk://127.0.0.1:2181/mesos' 142 | run_list: 143 | recipe[mesos::slave] 144 | ``` 145 | 146 | Development 147 | ----------- 148 | Please see the [Contributing](CONTRIBUTING.md) and [Issue Reporting](ISSUES.md) Guidelines. 149 | 150 | License and Author 151 | ------------------ 152 | * Author: [Ray Rodriguez](https://github.com/rayrod2030)(rayrod2030@gmail.com) 153 | * Author: [Robert Veznaver](https://github.com/rveznaver)(robert.veznaver@gmail.com) 154 | 155 | Copyright 2015 Medidata Solutions Worldwide 156 | 157 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 158 | this file except in compliance with the License. You may obtain a copy of the 159 | License at 160 | 161 | http://www.apache.org/licenses/LICENSE-2.0 162 | 163 | Unless required by applicable law or agreed to in writing, software distributed 164 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 165 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 166 | specific language governing permissions and limitations under the License. 167 | 168 | [Apache Mesos]: http://mesos.apache.org 169 | [Netflix Exhibitor]: https://github.com/Netflix/exhibitor 170 | [Mesosphere]: http://mesosphere.io 171 | [Medidata Solutions]: http://www.mdsol.com 172 | [exhibitor]: https://github.com/SimpleFinance/chef-exhibitor 173 | [apt]: https://github.com/opscode-cookbooks/apt 174 | [yum]: https://github.com/chef-cookbooks/yum 175 | [java]: https://github.com/agileorbit-cookbooks/java 176 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'rubocop/rake_task' 3 | require 'foodcritic' 4 | require 'kitchen' 5 | require 'rspec/core/rake_task' 6 | 7 | # Style tests. Rubocop and Foodcritic 8 | namespace :style do 9 | desc 'Run Ruby style checks' 10 | RuboCop::RakeTask.new(:ruby) 11 | 12 | desc 'Run Chef style checks' 13 | FoodCritic::Rake::LintTask.new(:chef) do |t| 14 | t.options = { 15 | fail_tags: ['any'] 16 | } 17 | end 18 | end 19 | 20 | desc 'Run all style checks' 21 | task style: ['style:chef', 'style:ruby'] 22 | 23 | # Integration tests. Kitchen.ci 24 | namespace :integration do 25 | desc 'Run Test Kitchen with Vagrant' 26 | task :vagrant do 27 | Kitchen.logger = Kitchen.default_file_logger 28 | Kitchen::Config.new.instances.each do |instance| 29 | instance.test(:always) 30 | end 31 | end 32 | end 33 | 34 | # Chefspec tests 35 | RSpec::Core::RakeTask.new(:spec) 36 | 37 | desc 'Run all tests on Travis' 38 | task travis: %w(style) 39 | 40 | task default: %w(style integration:vagrant) 41 | -------------------------------------------------------------------------------- /Thorfile: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | require 'bundler' 4 | require 'bundler/setup' 5 | require 'berkshelf/thor' 6 | 7 | begin 8 | require 'kitchen/thor_tasks' 9 | Kitchen::ThorTasks.new 10 | rescue LoadError 11 | puts '>>>>> Kitchen gem not loaded, omitting tasks' unless ENV['CI'] 12 | end 13 | -------------------------------------------------------------------------------- /attributes/default.rb: -------------------------------------------------------------------------------- 1 | # Default Java version 2 | default['java']['jdk_version'] = '8' 3 | 4 | # Use Mesosphere repo 5 | default['mesos']['repo'] = true 6 | 7 | # Mesosphere Mesos version. 8 | default['mesos']['version'] = '1.1.0' 9 | 10 | # Init system to use 11 | default['mesos']['init'] = case node['platform'] 12 | when 'debian' 13 | node['platform_version'].to_i >= 8 ? 'systemd' : 'sysvinit_debian' 14 | when 'ubuntu' 15 | node['platform_version'].to_f >= 15.04 ? 'systemd' : 'upstart' 16 | when 'redhat', 'centos', 'scientific', 'oracle' # ~FC024 17 | node['platform_version'].to_i >= 7 ? 'systemd' : 'upstart' 18 | else 'upstart' 19 | end 20 | 21 | # 22 | # Mesos MASTER configuration 23 | # 24 | 25 | # Mesos master binary location. 26 | default['mesos']['master']['bin'] = '/usr/sbin/mesos-master' 27 | 28 | # Environmental variables set before calling the mesos master process. 29 | default['mesos']['master']['env']['ULIMIT'] = '-n 16384' 30 | 31 | # Send stdout and stderr to syslog. 32 | default['mesos']['master']['syslog'] = true 33 | 34 | # Mesos master command line flags. 35 | # http://mesos.apache.org/documentation/latest/configuration/ 36 | default['mesos']['master']['flags']['port'] = 5050 37 | default['mesos']['master']['flags']['log_dir'] = '/var/log/mesos' 38 | default['mesos']['master']['flags']['logging_level'] = 'INFO' 39 | default['mesos']['master']['flags']['cluster'] = 'MyMesosCluster' 40 | default['mesos']['master']['flags']['work_dir'] = '/tmp/mesos' 41 | 42 | # 43 | # Mesos SLAVE configuration 44 | # 45 | 46 | # Mesos slave binary location. 47 | default['mesos']['slave']['bin'] = '/usr/sbin/mesos-slave' 48 | 49 | # Environmental variables set before calling the mesos-slave process. 50 | default['mesos']['slave']['env']['ULIMIT'] = '-n 16384' 51 | 52 | # Send stdout and stderr to syslog. 53 | default['mesos']['slave']['syslog'] = true 54 | 55 | # Mesos slave command line flags 56 | # http://mesos.apache.org/documentation/latest/configuration/ 57 | default['mesos']['slave']['flags']['port'] = 5051 58 | default['mesos']['slave']['flags']['log_dir'] = '/var/log/mesos' 59 | default['mesos']['slave']['flags']['logging_level'] = 'INFO' 60 | default['mesos']['slave']['flags']['work_dir'] = '/tmp/mesos' 61 | default['mesos']['slave']['flags']['isolation'] = 'posix/cpu,posix/mem' 62 | default['mesos']['slave']['flags']['master'] = 'localhost:5050' 63 | default['mesos']['slave']['flags']['strict'] = true 64 | default['mesos']['slave']['flags']['recover'] = 'reconnect' 65 | 66 | # Workaround for setting default cgroups hierarchy root 67 | default['mesos']['slave']['flags']['cgroups_hierarchy'] = if node['mesos']['init'] == 'systemd' 68 | '/sys/fs/cgroup' 69 | else 70 | '/cgroup' 71 | end 72 | 73 | # Use the following options if you are using Exhibitor to manage Zookeeper 74 | # in your environment. 75 | 76 | # Zookeeper path that Mesos will use to write to. 77 | default['mesos']['zookeeper_path'] = 'mesos' 78 | 79 | # Flag to enable Zookeeper ensemble discovery via Netflix Exhibitor. 80 | default['mesos']['zookeeper_exhibitor_discovery'] = false 81 | 82 | # Netflix Exhibitor ZooKeeper ensemble url. 83 | default['mesos']['zookeeper_exhibitor_url'] = nil 84 | -------------------------------------------------------------------------------- /chefignore: -------------------------------------------------------------------------------- 1 | # Put files/directories that should be ignored in this file when uploading 2 | # or sharing to the community site. 3 | # Lines that start with '# ' are comments. 4 | 5 | # OS generated files # 6 | ###################### 7 | .DS_Store 8 | Icon? 9 | nohup.out 10 | ehthumbs.db 11 | Thumbs.db 12 | 13 | # SASS # 14 | ######## 15 | .sass-cache 16 | 17 | # EDITORS # 18 | ########### 19 | \#* 20 | .#* 21 | *~ 22 | *.sw[a-z] 23 | *.bak 24 | REVISION 25 | TAGS* 26 | tmtags 27 | *_flymake.* 28 | *_flymake 29 | *.tmproj 30 | .project 31 | .settings 32 | mkmf.log 33 | 34 | ## COMPILED ## 35 | ############## 36 | a.out 37 | *.o 38 | *.pyc 39 | *.so 40 | *.com 41 | *.class 42 | *.dll 43 | *.exe 44 | */rdoc/ 45 | 46 | # Testing # 47 | ########### 48 | .watchr 49 | .rspec 50 | spec/* 51 | spec/fixtures/* 52 | test/* 53 | features/* 54 | Guardfile 55 | Procfile 56 | 57 | # SCM # 58 | ####### 59 | .git 60 | */.git 61 | .gitignore 62 | .gitmodules 63 | .gitconfig 64 | .gitattributes 65 | .svn 66 | */.bzr/* 67 | */.hg/* 68 | */.svn/* 69 | 70 | # Berkshelf # 71 | ############# 72 | Berksfile 73 | Berksfile.lock 74 | cookbooks/* 75 | tmp 76 | 77 | # Cookbooks # 78 | ############# 79 | CONTRIBUTING 80 | CHANGELOG* 81 | 82 | # Strainer # 83 | ############ 84 | Colanderfile 85 | Strainerfile 86 | .colander 87 | .strainer 88 | 89 | # Vagrant # 90 | ########### 91 | .vagrant 92 | Vagrantfile 93 | 94 | # Travis # 95 | ########## 96 | .travis.yml 97 | -------------------------------------------------------------------------------- /libraries/helpers.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: mesos 3 | # Library:: helpers 4 | # 5 | # Copyright (C) 2015 Medidata Solutions, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | module MesosHelper 21 | # Adds retry logic to exhibitor discovery 22 | # 23 | # @return [Hash] 24 | def self.discover_zookeepers_with_retry(url) 25 | tries ||= 5 26 | discover_zookeepers(url) 27 | rescue ExhibitorError 28 | Chef::Log.warn("Error while attempting to discover exhibitor zookeepers: Retry #{6 - tries} of 5") 29 | retry unless (tries -= 1).zero? 30 | end 31 | end 32 | # rubocop:eable Style/ClassAndModuleChildren 33 | -------------------------------------------------------------------------------- /metadata.rb: -------------------------------------------------------------------------------- 1 | name 'mesos' 2 | maintainer 'Ray Rodriguez' 3 | maintainer_email 'rayrod2030@gmail.com' 4 | license 'Apache 2.0' 5 | description 'Installs/Configures Apache Mesos' 6 | long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) 7 | version '3.6.0' 8 | source_url 'https://github.com/mdsol/mesos_cookbook' 9 | issues_url 'https://github.com/mdsol/mesos_cookbook/issues' 10 | 11 | %w(ubuntu debian centos amazon scientific oracle).each do |os| 12 | supports os 13 | end 14 | 15 | %w(java apt yum).each do |cookbook| 16 | depends cookbook 17 | end 18 | -------------------------------------------------------------------------------- /recipes/default.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: mesos 3 | # Recipe:: default 4 | # 5 | # Copyright (C) 2015 Medidata Solutions, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | # install mesos package 21 | include_recipe 'mesos::install' 22 | -------------------------------------------------------------------------------- /recipes/install.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: mesos 3 | # Recipe:: install 4 | # 5 | # Copyright (C) 2015 Medidata Solutions, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | include_recipe 'java' 21 | 22 | # 23 | # Install default repos 24 | # 25 | 26 | include_recipe 'mesos::repo' if node['mesos']['repo'] 27 | 28 | # 29 | # Install package 30 | # 31 | 32 | case node['platform_family'] 33 | when 'debian' 34 | %w(unzip default-jre-headless libcurl3 libsvn1).each do |pkg| 35 | package pkg do 36 | action :install 37 | end 38 | end 39 | 40 | package 'mesos' do 41 | action :install 42 | # --no-install-recommends to skip installing zk. unnecessary. 43 | options '--no-install-recommends' 44 | # Glob is necessary to select the deb version string 45 | version "#{node['mesos']['version']}*" 46 | end 47 | when 'rhel' 48 | %w(unzip libcurl subversion).each do |pkg| 49 | yum_package pkg do 50 | action :install 51 | end 52 | end 53 | 54 | yum_package 'mesos' do 55 | version lazy { 56 | # get the version-release string directly from the Yum provider rpmdb 57 | Chef::Provider::Package::Yum::YumCache 58 | .instance.instance_variable_get('@rpmdb').lookup('mesos') 59 | .find { |pkg| pkg.version.v == node['mesos']['version'] } 60 | .version.to_s 61 | } 62 | end 63 | end 64 | 65 | # 66 | # Support for multiple init systems 67 | # 68 | 69 | directory '/etc/mesos-chef' 70 | 71 | # Init templates 72 | template 'mesos-master-init' do 73 | case node['mesos']['init'] 74 | when 'systemd' 75 | path '/etc/systemd/system/mesos-master.service' 76 | source 'systemd.erb' 77 | when 'sysvinit_debian' 78 | mode 0o755 79 | path '/etc/init.d/mesos-master' 80 | source 'sysvinit_debian.erb' 81 | when 'upstart' 82 | path '/etc/init/mesos-master.conf' 83 | source 'upstart.erb' 84 | end 85 | variables(name: 'mesos-master', 86 | wrapper: '/etc/mesos-chef/mesos-master') 87 | end 88 | 89 | template 'mesos-slave-init' do 90 | case node['mesos']['init'] 91 | when 'systemd' 92 | path '/etc/systemd/system/mesos-slave.service' 93 | source 'systemd.erb' 94 | when 'sysvinit_debian' 95 | mode 0o755 96 | path '/etc/init.d/mesos-slave' 97 | source 'sysvinit_debian.erb' 98 | when 'upstart' 99 | path '/etc/init/mesos-slave.conf' 100 | source 'upstart.erb' 101 | end 102 | variables(name: 'mesos-slave', 103 | wrapper: '/etc/mesos-chef/mesos-slave') 104 | end 105 | 106 | # Reload systemd on template change 107 | execute 'systemctl-daemon-reload' do 108 | command '/bin/systemctl --system daemon-reload' 109 | subscribes :run, 'template[mesos-master-init]' 110 | subscribes :run, 'template[mesos-slave-init]' 111 | action :nothing 112 | only_if { node['mesos']['init'] == 'systemd' } 113 | end 114 | 115 | # Disable services by default 116 | service 'mesos-master-default' do 117 | service_name 'mesos-master' 118 | case node['mesos']['init'] 119 | when 'systemd' 120 | provider Chef::Provider::Service::Systemd 121 | when 'sysvinit_debian' 122 | provider Chef::Provider::Service::Init::Debian 123 | when 'upstart' 124 | provider Chef::Provider::Service::Upstart 125 | end 126 | action [:stop, :disable] 127 | not_if { node['recipes'].include?('mesos::master') } 128 | end 129 | 130 | service 'mesos-slave-default' do 131 | service_name 'mesos-slave' 132 | case node['mesos']['init'] 133 | when 'systemd' 134 | provider Chef::Provider::Service::Systemd 135 | when 'sysvinit_debian' 136 | provider Chef::Provider::Service::Init::Debian 137 | when 'upstart' 138 | provider Chef::Provider::Service::Upstart 139 | end 140 | action [:stop, :disable] 141 | not_if { node['recipes'].include?('mesos::slave') } 142 | end 143 | -------------------------------------------------------------------------------- /recipes/master.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: mesos 3 | # Recipe:: master 4 | # 5 | # Copyright (C) 2015 Medidata Solutions, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | class Chef::Recipe 21 | include MesosHelper 22 | end 23 | 24 | include_recipe 'mesos::install' 25 | 26 | # Mesos configuration validation 27 | ruby_block 'mesos-master-configuration-validation' do 28 | block do 29 | # Get Mesos --help 30 | help = Mixlib::ShellOut.new("#{node['mesos']['master']['bin']} --help") 31 | help.run_command 32 | help.error! 33 | # Extract options 34 | options = help.stdout.strip.scan(/^ --(?:\[no-\])?(\w+)/).flatten - ['help'] 35 | # Check flags are in the list 36 | node['mesos']['master']['flags'].keys.each do |flag| 37 | unless options.include?(flag) 38 | Chef::Application.fatal!("Invalid Mesos configuration option: #{flag}. Aborting!", 1000) 39 | end 40 | end 41 | end 42 | end 43 | 44 | # ZooKeeper Exhibitor discovery 45 | if node['mesos']['zookeeper_exhibitor_discovery'] && node['mesos']['zookeeper_exhibitor_url'] 46 | zk_nodes = MesosHelper.discover_zookeepers_with_retry(node['mesos']['zookeeper_exhibitor_url']) 47 | 48 | if zk_nodes.nil? 49 | Chef::Application.fatal!('Failed to discover zookeepers. Cannot continue.') 50 | end 51 | 52 | node.override['mesos']['master']['flags']['zk'] = 'zk://' + zk_nodes['servers'].sort.map { |s| "#{s}:#{zk_nodes['port']}" }.join(',') + '/' + node['mesos']['zookeeper_path'] 53 | end 54 | 55 | # Mesos master configuration wrapper 56 | template 'mesos-master-wrapper' do 57 | path '/etc/mesos-chef/mesos-master' 58 | owner 'root' 59 | group 'root' 60 | mode '0750' 61 | source 'wrapper.erb' 62 | variables(env: node['mesos']['master']['env'], 63 | bin: node['mesos']['master']['bin'], 64 | flags: node['mesos']['master']['flags'], 65 | syslog: node['mesos']['master']['syslog']) 66 | end 67 | 68 | # Mesos master service definition 69 | service 'mesos-master' do 70 | case node['mesos']['init'] 71 | when 'systemd' 72 | provider Chef::Provider::Service::Systemd 73 | when 'sysvinit_debian' 74 | provider Chef::Provider::Service::Init::Debian 75 | when 'upstart' 76 | provider Chef::Provider::Service::Upstart 77 | end 78 | supports status: true, restart: true 79 | subscribes :restart, 'template[mesos-master-init]' 80 | subscribes :restart, 'template[mesos-master-wrapper]' 81 | action [:enable, :start] 82 | end 83 | -------------------------------------------------------------------------------- /recipes/repo.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: mesos 3 | # Recipe:: repo 4 | # 5 | # Copyright (C) 2015 Medidata Solutions, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | case node['platform_family'] 21 | when 'debian' 22 | include_recipe 'apt' 23 | 24 | apt_repository 'mesosphere' do 25 | uri "http://repos.mesosphere.io/#{node['platform']}" 26 | distribution node['lsb']['codename'] 27 | keyserver 'hkp://keyserver.ubuntu.com:80' 28 | key 'E56151BF' 29 | components ['main'] 30 | end 31 | when 'rhel' 32 | include_recipe 'yum' 33 | 34 | version = case node['platform'] 35 | when 'amazon' then '6' 36 | else node['platform_version'].split('.').first 37 | end 38 | yum_repository 'mesosphere' do 39 | description 'Mesosphere Packages for Enteprise Linux' 40 | baseurl "http://repos.mesosphere.io/el/#{version}/$basearch/" 41 | gpgkey 'https://repos.mesosphere.io/el/RPM-GPG-KEY-mesosphere' 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /recipes/slave.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: mesos 3 | # Recipe:: slave 4 | # 5 | # Copyright (C) 2015 Medidata Solutions, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | class Chef::Recipe 21 | include MesosHelper 22 | end 23 | 24 | include_recipe 'mesos::install' 25 | 26 | # Mesos configuration validation 27 | ruby_block 'mesos-slave-configuration-validation' do 28 | block do 29 | # Get Mesos --help 30 | help = Mixlib::ShellOut.new("#{node['mesos']['slave']['bin']} --help --work_dir=#{node['mesos']['slave']['flags']['work_dir']}") 31 | help.run_command 32 | help.error! 33 | # Extract options 34 | options = help.stdout.strip.scan(/^ --(?:\[no-\])?(\w+)/).flatten - ['help'] 35 | # Check flags are in the list 36 | node['mesos']['slave']['flags'].keys.each do |flag| 37 | unless options.include?(flag) 38 | Chef::Application.fatal!("Invalid Mesos configuration option: #{flag}. Aborting!", 1000) 39 | end 40 | end 41 | end 42 | end 43 | 44 | # ZooKeeper Exhibitor discovery 45 | if node['mesos']['zookeeper_exhibitor_discovery'] && node['mesos']['zookeeper_exhibitor_url'] 46 | zk_nodes = MesosHelper.discover_zookeepers_with_retry(node['mesos']['zookeeper_exhibitor_url']) 47 | node.override['mesos']['slave']['flags']['master'] = 'zk://' + zk_nodes['servers'].map { |s| "#{s}:#{zk_nodes['port']}" }.join(',') + '/' + node['mesos']['zookeeper_path'] 48 | end 49 | 50 | # this directory doesn't exist on newer versions of Mesos, i.e. 0.21.0+ 51 | directory '/usr/local/var/mesos/deploy/' do 52 | recursive true 53 | end 54 | 55 | # Mesos slave configuration wrapper 56 | template 'mesos-slave-wrapper' do 57 | path '/etc/mesos-chef/mesos-slave' 58 | owner 'root' 59 | group 'root' 60 | mode '0750' 61 | source 'wrapper.erb' 62 | variables(env: node['mesos']['slave']['env'], 63 | bin: node['mesos']['slave']['bin'], 64 | flags: node['mesos']['slave']['flags'], 65 | syslog: node['mesos']['slave']['syslog']) 66 | end 67 | 68 | # Mesos master service definition 69 | service 'mesos-slave' do 70 | case node['mesos']['init'] 71 | when 'systemd' 72 | provider Chef::Provider::Service::Systemd 73 | when 'sysvinit_debian' 74 | provider Chef::Provider::Service::Init::Debian 75 | when 'upstart' 76 | provider Chef::Provider::Service::Upstart 77 | end 78 | supports status: true, restart: true 79 | subscribes :restart, 'template[mesos-slave-init]' 80 | subscribes :restart, 'template[mesos-slave-wrapper]' 81 | action [:enable, :start] 82 | end 83 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'chefspec' 2 | require 'chefspec/berkshelf' 3 | 4 | at_exit { ChefSpec::Coverage.report! } 5 | -------------------------------------------------------------------------------- /spec/unit/recipes/default_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: mesos 3 | # Spec:: default 4 | # 5 | 6 | require 'spec_helper' 7 | 8 | describe 'mesos::default' do 9 | context 'It should include recipe install' do 10 | let(:chef_run) do 11 | runner = ChefSpec::SoloRunner.new(platform: 'centos', version: '7.1.1503') 12 | runner.converge(described_recipe) 13 | end 14 | it 'includes mesos::install recipe' do 15 | expect(chef_run).to include_recipe('mesos::install') 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/unit/recipes/install_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: mesos 3 | # Spec:: install 4 | # 5 | 6 | require 'spec_helper' 7 | 8 | describe 'mesos::install' do 9 | context 'When all attributes are default, on CentOS 7' do 10 | let(:chef_run) do 11 | runner = ChefSpec::ServerRunner.new(platform: 'centos', version: '7.1.1503') 12 | runner.converge(described_recipe) 13 | end 14 | it 'Includes recipe Java' do 15 | expect(chef_run).to include_recipe('java') 16 | end 17 | it 'Includes recipe mesos::repo' do 18 | expect(chef_run).to include_recipe('mesos::repo') 19 | end 20 | it 'Installs util packages' do 21 | expect(chef_run).to install_yum_package('unzip') 22 | expect(chef_run).to install_yum_package('libcurl') 23 | expect(chef_run).to install_yum_package('subversion') 24 | end 25 | it 'Installs mesos' do 26 | expect(chef_run).to install_yum_package('mesos') 27 | end 28 | it 'Creates directory for storing the configuration' do 29 | expect(chef_run).to create_directory('/etc/mesos-chef') 30 | end 31 | it 'Rolls out systemd image for mesos-master' do 32 | expect(chef_run).to render_file('/etc/systemd/system/mesos-master.service') 33 | end 34 | it 'Rolls out systemd image for mesos-slave' do 35 | expect(chef_run).to render_file('/etc/systemd/system/mesos-slave.service') 36 | end 37 | it 'Stop and disable both master and slave services' do 38 | expect(chef_run).to stop_service('mesos-master') 39 | expect(chef_run).to disable_service('mesos-master') 40 | expect(chef_run).to stop_service('mesos-slave') 41 | expect(chef_run).to disable_service('mesos-slave') 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /spec/unit/recipes/master_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: mesos 3 | # Spec:: master 4 | # 5 | 6 | require 'spec_helper' 7 | 8 | describe 'mesos::master' do 9 | context 'When all attributes are default, on CentOS 7' do 10 | let(:chef_run) do 11 | runner = ChefSpec::ServerRunner.new(platform: 'centos', version: '7.1.1503') 12 | runner.converge(described_recipe) 13 | end 14 | it 'Includes recipe mesos::install' do 15 | expect(chef_run).to include_recipe('mesos::install') 16 | end 17 | it 'Includes renders template for start script' do 18 | expect(chef_run).to create_template('/etc/mesos-chef/mesos-master').with( 19 | owner: 'root', 20 | group: 'root', 21 | mode: '0750', 22 | source: 'wrapper.erb' 23 | ) 24 | end 25 | it 'Starts and enable mesos-master service' do 26 | expect(chef_run).to start_service('mesos-master') 27 | expect(chef_run).to enable_service('mesos-master') 28 | end 29 | it 'Subscribes the service to mesos-master-init template' do 30 | service = chef_run.service('mesos-master') 31 | expect(service).to subscribe_to('template[mesos-master-init]').on(:restart) 32 | end 33 | it 'Subscribes the service to mesos-master-wrapper template' do 34 | service = chef_run.service('mesos-master') 35 | expect(service).to subscribe_to('template[mesos-master-wrapper]').on(:restart) 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /spec/unit/recipes/repo_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: mesos 3 | # Spec:: repo 4 | # 5 | 6 | require 'spec_helper' 7 | 8 | describe 'mesos::install' do 9 | context 'When all attributes are default, on CentOS 7' do 10 | let(:chef_run) do 11 | runner = ChefSpec::ServerRunner.new(platform: 'centos', version: '7.1.1503') 12 | runner.converge(described_recipe) 13 | end 14 | it 'Includes mesosphere repo' do 15 | expect(chef_run).to create_yum_repository('mesosphere') 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/unit/recipes/slave_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: mesos 3 | # Spec:: slave 4 | # 5 | 6 | require 'spec_helper' 7 | 8 | describe 'mesos::slave' do 9 | context 'When all attributes are default, on CentOS 7' do 10 | let(:chef_run) do 11 | runner = ChefSpec::ServerRunner.new(platform: 'centos', version: '7.1.1503') 12 | runner.converge(described_recipe) 13 | end 14 | it 'Includes recipe mesos::install' do 15 | expect(chef_run).to include_recipe('mesos::install') 16 | end 17 | it 'Creates deploy directory' do 18 | expect(chef_run).to create_directory('/usr/local/var/mesos/deploy/') 19 | end 20 | it 'Includes renders template for start script' do 21 | expect(chef_run).to create_template('/etc/mesos-chef/mesos-slave').with( 22 | owner: 'root', 23 | group: 'root', 24 | mode: '0750', 25 | source: 'wrapper.erb' 26 | ) 27 | end 28 | it 'Starts and enable mesos-slave service' do 29 | expect(chef_run).to start_service('mesos-slave') 30 | expect(chef_run).to enable_service('mesos-slave') 31 | end 32 | it 'Subscribes the service to mesos-slave-init template' do 33 | service = chef_run.service('mesos-slave') 34 | expect(service).to subscribe_to('template[mesos-slave-init]').on(:restart) 35 | end 36 | it 'Subscribes the service to mesos-slave-wrapper template' do 37 | service = chef_run.service('mesos-slave') 38 | expect(service).to subscribe_to('template[mesos-slave-wrapper]').on(:restart) 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /templates/default/systemd.erb: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Mesos <%= @name %> 3 | After=network.target 4 | Wants=network.target 5 | 6 | [Service] 7 | ExecStart=<%= @wrapper %> 8 | Restart=always 9 | RestartSec=20 10 | LimitNOFILE=16384 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /templates/default/sysvinit_debian.erb: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: <%= @name %> 4 | # Required-Start: $local_fs $remote_fs $network $syslog 5 | # Required-Stop: $local_fs $remote_fs $network $syslog 6 | # Default-Start: 2 3 4 5 7 | # Default-Stop: 0 1 6 8 | # Short-Description: starts <%= @name %> 9 | # Description: Mesos 10 | ### END INIT INFO 11 | set -ue 12 | 13 | NAME="<%= @name %>" 14 | DESC="<%= @name %>" 15 | 16 | . /lib/lsb/init-functions 17 | 18 | PID=/var/run/<%= @name %>.pid 19 | 20 | start() { 21 | start-stop-daemon --start --background --quiet \ 22 | --pidfile "$PID" --make-pidfile \ 23 | --exec <%= @wrapper %> 24 | } 25 | 26 | stop() { 27 | start-stop-daemon --stop --quiet --pidfile "$PID" 28 | } 29 | 30 | case "$1" in 31 | start) 32 | echo -n "Starting $DESC: " 33 | start 34 | echo "$NAME." 35 | ;; 36 | stop) 37 | echo -n "Stopping $DESC: " 38 | stop 39 | echo "$NAME." 40 | ;; 41 | restart) 42 | echo -n "Restarting $DESC: " 43 | stop 44 | sleep 1 45 | start 46 | echo "$NAME." 47 | ;; 48 | status) 49 | status_of_proc -p "$PID" "$NAME" "$NAME" 50 | ;; 51 | *) 52 | echo "Usage: $0 {start|stop|restart|status}" >&2 53 | exit 1 54 | ;; 55 | esac 56 | 57 | -------------------------------------------------------------------------------- /templates/default/upstart.erb: -------------------------------------------------------------------------------- 1 | description "Upstart job for <%= @name %>" 2 | 3 | start on stopped rc RUNLEVEL=[2345] 4 | respawn 5 | 6 | exec <%= @wrapper %> 7 | -------------------------------------------------------------------------------- /templates/default/wrapper.erb: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This file is generated by Chef 3 | 4 | # evironmental variables 5 | <%= @env.map{|k,v| "#{k}=\"#{v}\""}.join("\n") %> 6 | 7 | # set ulimit if defined 8 | [[ ! ${ULIMIT:-} ]] || ulimit $ULIMIT 9 | 10 | <%- if @syslog -%> 11 | # stdout and stderr to syslog 12 | exec 1> >(exec logger -p user.info -t "<%= ::File.basename(@bin) %>") 13 | exec 2> >(exec logger -p user.err -t "<%= ::File.basename(@bin) %>") 14 | <%- end -%> 15 | 16 | # mesos binary configuration 17 | exec <%= @bin %> \ 18 | <%- @flags.sort.each do |flag, value| -%> 19 | <%- case value -%> 20 | <%- when Hash -%> 21 | <%= "--#{flag}='"%><%= value.map{|k,v| "#{k}:#{v}"}.join(';') %><%= "'" %> \ 22 | <%- when String -%> 23 | <%= "--#{flag}='#{value}'" %> \ 24 | <%- when Integer -%> 25 | <%= "--#{flag}=#{value}" %> \ 26 | <%- else -%> 27 | <%= "--#{value ? '' : 'no-'}#{flag}" %> \ 28 | <%- end -%> 29 | <%- end -%> 30 | -------------------------------------------------------------------------------- /test/integration/1-0-0/serverspec/mesos_version.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe command('mesos-master --version') do 4 | its(:stdout) { should match(/mesos 1\.0\.0/) } 5 | end 6 | 7 | describe command('mesos-slave --version') do 8 | its(:stdout) { should match(/mesos 1\.0\.0/) } 9 | end 10 | -------------------------------------------------------------------------------- /test/integration/1-0-1/serverspec/mesos_version.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe command('mesos-master --version') do 4 | its(:stdout) { should match(/mesos 1\.0\.1/) } 5 | end 6 | 7 | describe command('mesos-slave --version') do 8 | its(:stdout) { should match(/mesos 1\.0\.1/) } 9 | end 10 | -------------------------------------------------------------------------------- /test/integration/1-1-0/serverspec/mesos_version.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe command('mesos-master --version') do 4 | its(:stdout) { should match(/mesos 1\.1\.0/) } 5 | end 6 | 7 | describe command('mesos-slave --version') do 8 | its(:stdout) { should match(/mesos 1\.1\.0/) } 9 | end 10 | -------------------------------------------------------------------------------- /test/integration/helpers/serverspec/mesos_install_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | # verify packages 4 | describe 'mesos install' do 5 | it 'should install required packages' do 6 | case RSpec.configuration.os 7 | when 'Debian' 8 | expect(package('unzip')).to be_installed 9 | expect(package('default-jre-headless')).to be_installed 10 | expect(package('libcurl3')).to be_installed 11 | expect(package('libsvn1')).to be_installed 12 | expect(package('mesos')).to be_installed 13 | when 'RedHat' 14 | expect(package('unzip')).to be_installed 15 | expect(package('libcurl')).to be_installed 16 | expect(package('mesos')).to be_installed 17 | end 18 | end 19 | end 20 | 21 | describe file('/usr/sbin/mesos-master') do 22 | it { should be_file } 23 | end 24 | -------------------------------------------------------------------------------- /test/integration/helpers/serverspec/mesos_master_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | # mesos master service 4 | describe 'mesos master service' do 5 | it 'should be running' do 6 | case RSpec.configuration.os 7 | when 'Debian' 8 | expect(service('mesos-master')).to be_running 9 | end 10 | end 11 | end 12 | 13 | describe port(5050) do 14 | it { should be_listening } 15 | end 16 | 17 | describe command('curl -sD - http://localhost:5050/health -o /dev/null') do 18 | its(:stdout) { should match(/200 OK/) } 19 | end 20 | 21 | describe file('/var/log/mesos/mesos-master.INFO') do 22 | its(:content) { should match(/INFO level logging started/) } 23 | its(:content) { should match(/Elected as the leading master!/) } 24 | end 25 | 26 | describe command('curl -sD - http://localhost:5050/state.json') do 27 | its(:stdout) { should match(/"logging_level":"INFO"/) } 28 | its(:stdout) { should match(/"cluster":"MyMesosCluster"/) } 29 | its(:stdout) { should match(/"authenticate_(slaves|agents)":"false"/) } 30 | its(:stdout) { should match(/"activated_(slaves|agents)":\s*1/) } 31 | end 32 | 33 | describe file('/etc/mesos-chef/mesos-master') do 34 | its(:content) { should contain 'exec 1> >\\(exec logger -p user.info -t "mesos-master"\\)' } 35 | its(:content) { should contain 'exec 2> >\\(exec logger -p user.err -t "mesos-master"\\)' } 36 | end 37 | -------------------------------------------------------------------------------- /test/integration/helpers/serverspec/mesos_slave_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | # mesos slave service 4 | describe 'mesos slave service' do 5 | it 'should be running' do 6 | case RSpec.configuration.os 7 | when 'Debian' 8 | expect(service('mesos-slave')).to be_running 9 | end 10 | end 11 | end 12 | 13 | describe port(5051) do 14 | it { should be_listening } 15 | end 16 | 17 | describe command('curl -sD - http://localhost:5051/health -o /dev/null') do 18 | its(:stdout) { should match(/200 OK/) } 19 | end 20 | 21 | describe file('/var/log/mesos/mesos-slave.INFO') do 22 | its(:content) { should match(/INFO level logging started/) } 23 | its(:content) { should match(/New master detected/) } 24 | end 25 | 26 | describe command('curl -sD - http://localhost:5051/state.json') do 27 | its(:stdout) { should match(/"logging_level":"INFO"/) } 28 | its(:stdout) { should match(/"revocable_cpu_low_priority":"true"/) } 29 | its(:stdout) { should match(/"switch_user":"true"/) } 30 | end 31 | 32 | describe file('/etc/mesos-chef/mesos-slave') do 33 | its(:content) { should contain 'exec 1> >\\(exec logger -p user.info -t "mesos-slave"\\)' } 34 | its(:content) { should contain 'exec 2> >\\(exec logger -p user.err -t "mesos-slave"\\)' } 35 | end 36 | -------------------------------------------------------------------------------- /test/integration/helpers/serverspec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'serverspec' 2 | 3 | # Required by serverspec 4 | set :backend, :exec 5 | --------------------------------------------------------------------------------