├── VERSION ├── .gitattributes ├── test ├── fixtures │ └── cookbooks │ │ └── test │ │ ├── recipes │ │ ├── default.rb │ │ ├── install_no_user.rb │ │ ├── win_package.rb │ │ ├── win_sup.rb │ │ ├── win_sup_toml_config.rb │ │ ├── install_for_chefspec.rb │ │ ├── win_config.rb │ │ ├── win_user_toml.rb │ │ ├── package.rb │ │ ├── user_toml.rb │ │ ├── config.rb │ │ ├── win_service.rb │ │ ├── sup.rb │ │ ├── sup_toml_config.rb │ │ └── service.rb │ │ ├── metadata.rb │ │ └── templates │ │ └── sup │ │ └── sup.toml.erb ├── solo.rb └── integration │ ├── install_for_chefspec │ └── default_spec.rb │ ├── install_no_user │ └── default_spec.rb │ ├── win_user_toml │ └── default_spec.rb │ ├── win_sup │ └── default_spec.rb │ ├── win_sup_toml_config │ └── default_spec.rb │ ├── win_package │ └── default_spec.rb │ ├── config │ └── default_spec.rb │ ├── user_toml │ └── default_spec.rb │ ├── win_service │ └── default_spec.rb │ ├── win_config │ └── default_spec.rb │ ├── package │ └── default_spec.rb │ ├── sup │ └── default_spec.rb │ ├── sup_toml_config │ └── default_spec.rb │ └── service │ └── default_spec.rb ├── .github ├── CODEOWNERS └── workflows │ ├── branchcleanup.yml │ └── delivery.yml ├── CODE_OF_CONDUCT.md ├── TESTING.md ├── CONTRIBUTING.md ├── recipes └── default.rb ├── .delivery └── project.toml ├── .vscode └── extensions.json ├── spec ├── spec_helper.rb └── unit │ ├── install_spec.rb │ ├── sup_toml_config_spec.rb │ ├── package_spec.rb │ ├── service_spec.rb │ └── sup_spec.rb ├── .expeditor ├── config.yml └── update_hab_release.sh ├── .editorconfig ├── Gemfile ├── templates ├── upstart │ └── hab-sup.conf.erb ├── windows │ └── HabService.dll.config.erb ├── sysvinit │ └── hab-sup.erb └── sup │ └── sup.toml.erb ├── metadata.rb ├── .gitignore ├── Policyfile.rb ├── libraries ├── resource_hab_package.rb ├── habitat_shared.rb ├── resource_hab_sup_sysvinit.rb ├── resource_hab_sup_upstart.rb ├── resource_hab_sup_systemd.rb ├── habitat_toml.rb ├── resource_hab_sup_windows.rb ├── provider_hab_package.rb └── resource_hab_sup.rb ├── chefignore ├── resources ├── user_toml.rb ├── config.rb ├── install.rb └── service.rb ├── kitchen.dokken.yml ├── kitchen.yml ├── LICENSE ├── README.md └── CHANGELOG.md /VERSION: -------------------------------------------------------------------------------- 1 | 2.2.4 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/default.rb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @chef-cookbooks/cookbook_engineering_team 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | Please refer to the Chef Community Code of Conduct at 2 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/metadata.rb: -------------------------------------------------------------------------------- 1 | name 'test' 2 | license 'Apache-2.0' 3 | version '0.0.1' 4 | depends 'habitat' 5 | -------------------------------------------------------------------------------- /test/solo.rb: -------------------------------------------------------------------------------- 1 | # used by GitHub Actions for Windows system testing 2 | cookbook_path ['test/fixtures/cookbooks', '../'] 3 | -------------------------------------------------------------------------------- /TESTING.md: -------------------------------------------------------------------------------- 1 | Please refer to 2 | 3 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Please refer to 2 | https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD 3 | -------------------------------------------------------------------------------- /recipes/default.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: habitat 3 | # Recipe:: default 4 | # 5 | # Copyright:: 2020, The Authors, All Rights Reserved. 6 | -------------------------------------------------------------------------------- /.delivery/project.toml: -------------------------------------------------------------------------------- 1 | remote_file = "https://raw.githubusercontent.com/chef-cookbooks/community_cookbook_tools/master/delivery/project.toml" 2 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "chef-software.chef", 4 | "rebornix.ruby", 5 | "editorconfig.editorconfig" 6 | ] 7 | } -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/install_no_user.rb: -------------------------------------------------------------------------------- 1 | hab_install 'no-users-here' do 2 | create_user false 3 | license 'accept' 4 | hab_version '1.5.71' 5 | end 6 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/win_package.rb: -------------------------------------------------------------------------------- 1 | hab_install 'default' do 2 | license 'accept' 3 | end 4 | 5 | hab_package 'skylerto/splunkforwarder' do 6 | version '7.0.3/20180418161444' 7 | end 8 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'chefspec' 2 | require 'chefspec/policyfile' 3 | 4 | RSpec.configure do |config| 5 | config.color = true 6 | config.formatter = 'doc' 7 | config.log_level = :fatal 8 | end 9 | -------------------------------------------------------------------------------- /test/integration/install_for_chefspec/default_spec.rb: -------------------------------------------------------------------------------- 1 | describe user('hab') do 2 | it { should exist } 3 | end 4 | 5 | describe command('hab -V') do 6 | its('stdout') { should match(%r{^hab.*/}) } 7 | its('exit_status') { should eq 0 } 8 | end 9 | -------------------------------------------------------------------------------- /test/integration/install_no_user/default_spec.rb: -------------------------------------------------------------------------------- 1 | describe user('hab') do 2 | it { should_not exist } 3 | end 4 | 5 | describe command('hab -V') do 6 | its('stdout') { should match(%r{^hab 1.5.71/}) } 7 | its('exit_status') { should eq 0 } 8 | end 9 | -------------------------------------------------------------------------------- /.expeditor/config.yml: -------------------------------------------------------------------------------- 1 | slack: 2 | notify_channel: ops-notify 3 | 4 | merge_actions: 5 | - built_in:update_changelog: 6 | ignore_labels: 7 | - "Expeditor: Skip All" 8 | 9 | subscriptions: 10 | - workload: artifact_published:stable:habitat:* 11 | actions: 12 | - bash:.expeditor/update_hab_release.sh 13 | -------------------------------------------------------------------------------- /test/integration/win_user_toml/default_spec.rb: -------------------------------------------------------------------------------- 1 | describe file('C:\habitat\hab.exe') do 2 | it { should exist } 3 | end 4 | 5 | splunkserviceapi = '(Invoke-RestMethod http://localhost:9631/services/splunkforwarder/default).cfg | ConvertTo-Json' 6 | describe json(command: splunkserviceapi) do 7 | its(%w(directories path)) { should eq ['C:/hab/pkgs/.../*.log'] } 8 | end 9 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/win_sup.rb: -------------------------------------------------------------------------------- 1 | hab_sup 'tester' do 2 | license 'accept' 3 | bldr_url 'https://willem.habitat.sh' 4 | listen_http '0.0.0.0:9999' 5 | listen_gossip '0.0.0.0:9998' 6 | end 7 | 8 | ruby_block 'wait-for-sup-default-startup' do 9 | block do 10 | raise unless system('hab sup status') 11 | end 12 | retries 30 13 | retry_delay 1 14 | end 15 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/win_sup_toml_config.rb: -------------------------------------------------------------------------------- 1 | hab_sup 'tester' do 2 | license 'accept' 3 | bldr_url 'https://willem.habitat.sh' 4 | listen_http '0.0.0.0:9999' 5 | listen_gossip '0.0.0.0:9998' 6 | toml_config true 7 | end 8 | 9 | ruby_block 'wait-for-sup-default-startup' do 10 | block do 11 | raise unless system('hab sup status') 12 | end 13 | retries 30 14 | retry_delay 1 15 | end 16 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root=true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | # 2 space indentation 12 | indent_style = space 13 | indent_size = 2 14 | 15 | # Avoid issues parsing cookbook files later 16 | charset = utf-8 17 | 18 | # Avoid cookstyle warnings 19 | trim_trailing_whitespace = true 20 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/install_for_chefspec.rb: -------------------------------------------------------------------------------- 1 | # This recipe is used for running the `install_spec` tests, it should 2 | # not be used in the other recipes. 3 | hab_install 'install habitat' do 4 | license 'accept' 5 | end 6 | 7 | hab_install 'install habitat with depot url' do 8 | bldr_url 'https://localhost' 9 | license 'accept' 10 | end 11 | 12 | hab_install 'install habitat with tmp_dir' do 13 | tmp_dir '/foo/bar' 14 | license 'accept' 15 | end 16 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # This gemfile provides additional gems for testing and releasing this cookbook 2 | # It is meant to be installed on top of ChefDK / Chef Workstation which provide the majority 3 | # of the necessary gems for testing this cookbook 4 | # 5 | # Run 'chef exec bundle install' to install these dependencies 6 | 7 | source 'https://rubygems.org' 8 | 9 | gem 'community_cookbook_releaser' 10 | 11 | # local development and testing requires this gem is installed. 12 | # gem 'toml-rb' 13 | -------------------------------------------------------------------------------- /.github/workflows/branchcleanup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Branch Cleanup 3 | # This workflow is triggered on all closed pull requests. 4 | # However the script does not do anything if a merge was not performed. 5 | "on": 6 | pull_request: 7 | types: [closed] 8 | 9 | env: 10 | NO_BRANCH_DELETED_EXIT_CODE: 0 11 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: jessfraz/branch-cleanup-action@master 18 | -------------------------------------------------------------------------------- /templates/upstart/hab-sup.conf.erb: -------------------------------------------------------------------------------- 1 | description "The Habitat Supervisor" 2 | 3 | start on (filesystem and net-device-up IFACE!=lo) 4 | stop on runlevel [!2345] 5 | 6 | respawn 7 | respawn limit 5 30 8 | 9 | <% if @auth_token %> 10 | env HAB_AUTH_TOKEN=<%= @auth_token %> 11 | <% end %> 12 | <% if @gateway_auth_token %> 13 | env HAB_SUP_GATEWAY_AUTH_TOKEN=<%= @gateway_auth_token %> 14 | <% end %> 15 | 16 | script 17 | exec /bin/hab sup run <%= @exec_start_options %> 18 | end script 19 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/win_config.rb: -------------------------------------------------------------------------------- 1 | hab_sup 'default' do 2 | license 'accept' 3 | end 4 | 5 | ruby_block 'wait-for-sup-default-startup' do 6 | block do 7 | raise unless system('hab sup status') 8 | end 9 | retries 30 10 | retry_delay 1 11 | end 12 | 13 | hab_service 'skylerto/splunkforwarder' 14 | 15 | hab_config 'splunkforwarder.default' do 16 | config( 17 | directories: { 18 | path: [ 19 | 'C:/hab/pkgs/.../*.log', 20 | ], 21 | } 22 | ) 23 | end 24 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/win_user_toml.rb: -------------------------------------------------------------------------------- 1 | hab_sup 'default' do 2 | license 'accept' 3 | end 4 | 5 | ruby_block 'wait-for-sup-default-startup' do 6 | block do 7 | raise unless system('hab sup status') 8 | end 9 | retries 30 10 | retry_delay 1 11 | end 12 | 13 | hab_user_toml 'splunkforwarder' do 14 | config( 15 | directories: { 16 | path: [ 17 | 'C:/hab/pkgs/.../*.log', 18 | ], 19 | } 20 | ) 21 | end 22 | 23 | hab_service 'skylerto/splunkforwarder' 24 | -------------------------------------------------------------------------------- /metadata.rb: -------------------------------------------------------------------------------- 1 | name 'habitat' 2 | maintainer 'Chef Software, Inc.' 3 | maintainer_email 'cookbooks@chef.io' 4 | license 'Apache-2.0' 5 | description 'Habitat related resources for chef-client' 6 | source_url 'https://github.com/chef-cookbooks/habitat' 7 | issues_url 'https://github.com/chef-cookbooks/habitat/issues' 8 | chef_version '>= 12.20.3' 9 | version '2.2.4' 10 | 11 | %w(ubuntu debian redhat centos suse scientific oracle amazon opensuse opensuseleap windows).each do |os| 12 | supports os 13 | end 14 | 15 | # gem 'toml-rb' 16 | -------------------------------------------------------------------------------- /test/integration/win_sup/default_spec.rb: -------------------------------------------------------------------------------- 1 | describe command('C:\habitat\hab.exe sup -h') do 2 | its(:stdout) { should match(/The Habitat Supervisor/) } 3 | end 4 | 5 | describe powershell('(get-service habitat).Status') do 6 | its(:stdout) { should match(/Running/) } 7 | end 8 | 9 | restart_script = <<-EOH 10 | restart-service habitat 11 | EOH 12 | 13 | describe powershell(restart_script) do 14 | its(:exit_status) { should eq(0) } 15 | end 16 | 17 | # Removing these two tests temporarily, this needs to be validated and rewritten with the fixture then tested 18 | describe port(9998) do 19 | it { should be_listening } 20 | end 21 | 22 | describe port(9999) do 23 | it { should be_listening } 24 | end 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.rbc 2 | .config 3 | InstalledFiles 4 | lib/bundler/man 5 | pkg 6 | test/tmp 7 | test/version_tmp 8 | tmp 9 | _Store 10 | *~ 11 | *# 12 | .#* 13 | \#*# 14 | *.un~ 15 | *.tmp 16 | *.bk 17 | *.bkup 18 | 19 | # editor temp files 20 | .idea 21 | .*.sw[a-z] 22 | 23 | # ruby/bundler files 24 | .ruby-version 25 | .ruby-gemset 26 | .rvmrc 27 | Gemfile.lock 28 | .bundle 29 | *.gem 30 | coverage 31 | spec/reports 32 | 33 | # YARD / rdoc artifacts 34 | .yardoc 35 | _yardoc 36 | doc/ 37 | rdoc 38 | 39 | # chef infra stuff 40 | Berksfile.lock 41 | .kitchen 42 | kitchen.local.yml 43 | vendor/ 44 | .coverage/ 45 | .zero-knife.rb 46 | Policyfile.lock.json 47 | 48 | # vagrant stuff 49 | .vagrant/ 50 | .vagrant.d/ 51 | -------------------------------------------------------------------------------- /Policyfile.rb: -------------------------------------------------------------------------------- 1 | # Policyfile.rb - Describe how you want Chef Infra Client to build your system. 2 | # 3 | # For more information on the Policyfile feature, visit 4 | # https://docs.chef.io/policyfile.html 5 | 6 | # A name that describes what the system you're building with Chef does. 7 | name 'habitat' 8 | 9 | # Where to find external cookbooks: 10 | default_source :chef_repo, '.' 11 | 12 | # Specify a custom source for a single cookbook: 13 | cookbook 'habitat', path: '.' 14 | cookbook 'test', path: './test/fixtures/cookbooks/test' 15 | 16 | run_list 'habitat' 17 | 18 | tests = (Dir.entries('./test/fixtures/cookbooks/test/recipes').select { |f| !File.directory? f }) 19 | tests.each do |test| 20 | test = test.gsub('.rb', '') 21 | named_run_list :"#{test.to_sym}", "test::#{test}" 22 | end 23 | -------------------------------------------------------------------------------- /spec/unit/install_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::install_for_chefspec' do 4 | cached(:chef_run) do 5 | ChefSpec::ServerRunner.new( 6 | platform: 'ubuntu' 7 | ).converge(described_recipe) 8 | end 9 | 10 | context 'when compiling the install recipe for chefspec' do 11 | it 'install habitat' do 12 | expect(chef_run).to install_hab_install('install habitat') 13 | end 14 | 15 | it 'installs habitat with a depot url' do 16 | expect(chef_run).to install_hab_install('install habitat with depot url') 17 | .with(bldr_url: 'https://localhost') 18 | end 19 | 20 | it 'installs habitat with tmp_dir' do 21 | expect(chef_run).to install_hab_install('install habitat with tmp_dir') 22 | .with(tmp_dir: '/foo/bar') 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /templates/windows/HabService.dll.config.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <% if @auth_token %> 6 | 7 | <% end %> 8 | <% if @gateway_auth_token %> 9 | 10 | <% end %> 11 | <% if @bldr_url %> 12 | 13 | <% end %> 14 | <%if @exec_start_options %> 15 | 16 | <% end %> 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/package.rb: -------------------------------------------------------------------------------- 1 | apt_update 2 | 3 | hab_install 'default' do 4 | license 'accept' 5 | end 6 | 7 | hab_package 'core/redis' 8 | 9 | hab_package 'lamont-granquist/ruby' do 10 | channel 'unstable' 11 | version '2.3.1' 12 | end 13 | 14 | hab_package 'core/bundler' do 15 | channel 'unstable' 16 | version '1.13.3/20161011123917' 17 | end 18 | 19 | hab_package 'core/htop' do 20 | options '--binlink' 21 | end 22 | 23 | hab_package 'core/hab-sup' do 24 | bldr_url 'https://bldr.habitat.sh' 25 | end 26 | 27 | hab_package 'binlink' do 28 | package_name 'core/nginx' 29 | version '1.15.2' 30 | binlink true 31 | end 32 | 33 | hab_package 'binlink_force' do 34 | package_name 'core/nginx' 35 | version '1.15.6/20181212185120' 36 | binlink :force 37 | end 38 | 39 | hab_package 'core/nginx' do 40 | action :remove 41 | end 42 | -------------------------------------------------------------------------------- /test/integration/win_sup_toml_config/default_spec.rb: -------------------------------------------------------------------------------- 1 | describe command('C:\habitat\hab.exe sup -h') do 2 | its(:stdout) { should match(/The Habitat Supervisor/) } 3 | end 4 | 5 | describe powershell('(get-service habitat).Status') do 6 | its(:stdout) { should match(/Running/) } 7 | end 8 | 9 | restart_script = <<-EOH 10 | restart-service habitat 11 | EOH 12 | 13 | describe powershell(restart_script) do 14 | its(:exit_status) { should eq(0) } 15 | end 16 | 17 | # Removing these two tests temporarily, this needs to be validated and rewritten with the fixture then tested 18 | describe port(9998) do 19 | it { should be_listening } 20 | end 21 | 22 | describe port(9999) do 23 | it { should be_listening } 24 | end 25 | 26 | describe file('C:/hab/sup/default/config/sup.toml') do 27 | it { should exist } 28 | its('content') { should match(/bldr_url.*willem.habitat.sh/) } 29 | end 30 | -------------------------------------------------------------------------------- /test/integration/win_package/default_spec.rb: -------------------------------------------------------------------------------- 1 | describe file('C:\habitat\hab.exe') do 2 | it { should exist } 3 | end 4 | 5 | # This needs to be updated each time Habitat is released so we ensure we're getting the version 6 | # required by this cookbook. 7 | # TODO: Inspec session seems to not have the updated windows system path when run with 'kitchen test' 8 | # Works fine if you run a converge and then a verify as two seperate commands 9 | # For now, hitting hab.exe directly to avoid test failure 10 | describe command('C:\habitat\hab.exe -V') do 11 | its('stdout') { should match(%r{^hab.*/}) } 12 | its('exit_status') { should eq 0 } 13 | end 14 | 15 | describe directory('C:\hab\pkgs\skylerto\splunkforwarder') do 16 | it { should exist } 17 | end 18 | 19 | # TODO: Same issue as above 20 | describe command('C:\habitat\hab.exe pkg path skylerto/splunkforwarder') do 21 | its('exit_status') { should eq 0 } 22 | its('stdout') { should match(/C:\\hab\\pkgs\\skylerto\\splunkforwarder/) } 23 | end 24 | -------------------------------------------------------------------------------- /spec/unit/sup_toml_config_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::sup_toml_config' do 4 | context 'When toml_config flag is set to true for hab_sup' do 5 | cached(:chef_run) do 6 | ChefSpec::ServerRunner.new( 7 | step_into: ['hab_sup'], 8 | platform: 'ubuntu', 9 | version: '16.04' 10 | ).converge(described_recipe) 11 | end 12 | 13 | before(:each) do 14 | allow(Chef::Platform::ServiceHelpers).to receive(:service_resource_providers).and_return([:systemd]) 15 | allow(Dir).to receive(:exist?).and_call_original 16 | allow(Dir).to receive(:exist?).with('/hab').and_return(true) 17 | allow(Dir).to receive(:exist?).with('/hab/sup/default/config').and_return(true) 18 | end 19 | 20 | it 'Creates Supervisor toml configuration file' do 21 | expect(chef_run).to create_directory('/hab/sup/default/config') 22 | expect(chef_run).to create_template('/hab/sup/default/config/sup.toml') 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /test/integration/config/default_spec.rb: -------------------------------------------------------------------------------- 1 | describe user('hab') do 2 | it { should exist } 3 | end 4 | 5 | describe file('/bin/hab') do 6 | it { should exist } 7 | it { should be_symlink } 8 | end 9 | 10 | # This needs to be updated each time Habitat is released so we ensure we're getting the version 11 | # required by this cookbook. 12 | describe command('hab -V') do 13 | its('stdout') { should match(%r{^hab.*/}) } 14 | its('exit_status') { should eq 0 } 15 | end 16 | 17 | describe file('/hab/svc/nginx/config/nginx.conf') do 18 | its('content') { should include('worker_processes 2') } 19 | its('content') { should include('keepalive_timeout 120') } 20 | end 21 | 22 | nginxserviceapi = 'curl -v -H "Authorization: Bearer secret" http://localhost:9631/services/nginx/default | jq .cfg' 23 | describe json(command: nginxserviceapi) do 24 | its(%w(http keepalive_timeout)) { should eq 120 } 25 | its(%w(http listen port)) { should eq 80 } 26 | its(['worker_processes']) { should eq 2 } 27 | end 28 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/user_toml.rb: -------------------------------------------------------------------------------- 1 | apt_update 2 | 3 | hab_sup 'default' do 4 | license 'accept' 5 | end 6 | 7 | ruby_block 'wait-for-sup-default-startup' do 8 | block do 9 | raise unless system('hab sup status') 10 | end 11 | retries 30 12 | retry_delay 1 13 | end 14 | 15 | hab_package 'core/jq-static' do 16 | binlink true 17 | end 18 | 19 | hab_user_toml 'nginx' do 20 | config( 21 | worker_processes: 2, 22 | http: { 23 | keepalive_timeout: 120, 24 | } 25 | ) 26 | end 27 | 28 | hab_package 'core/nginx' 29 | hab_service 'core/nginx' 30 | 31 | # we need to sleep to let the nginx service have enough time to 32 | # startup properly before we can configure it. 33 | # This is here due to https://github.com/habitat-sh/habitat/issues/3155 and 34 | # can be removed if that issue is fixed. 35 | ruby_block 'wait-for-nginx-startup' do 36 | block do 37 | sleep 3 38 | end 39 | action :nothing 40 | subscribes :run, 'hab_service[core/nginx]', :immediately 41 | end 42 | -------------------------------------------------------------------------------- /test/integration/user_toml/default_spec.rb: -------------------------------------------------------------------------------- 1 | describe user('hab') do 2 | it { should exist } 3 | end 4 | 5 | describe file('/bin/hab') do 6 | it { should exist } 7 | it { should be_symlink } 8 | end 9 | 10 | # This needs to be updated each time Habitat is released so we ensure we're getting the version 11 | # required by this cookbook. 12 | describe command('hab -V') do 13 | its('stdout') { should match(%r{^hab.*/}) } 14 | its('exit_status') { should eq 0 } 15 | end 16 | 17 | nginx_content = <<-EOF 18 | worker_processes = 2 19 | [http] 20 | keepalive_timeout = 120 21 | EOF 22 | 23 | describe file('/hab/user/nginx/config/user.toml') do 24 | it { should exist } 25 | its('content') { should match(nginx_content) } 26 | end 27 | 28 | nginxserviceapi = 'curl -v -H "Authorization: Bearer secret" http://localhost:9631/services/nginx/default | jq .cfg' 29 | describe json(command: nginxserviceapi) do 30 | its(%w(http keepalive_timeout)) { should eq 120 } 31 | its(%w(http listen port)) { should eq 80 } 32 | its(['worker_processes']) { should eq 2 } 33 | end 34 | -------------------------------------------------------------------------------- /test/integration/win_service/default_spec.rb: -------------------------------------------------------------------------------- 1 | describe directory('C:\hab\pkgs\skylerto\splunkforwarder') do 2 | it { should exist } 3 | end 4 | 5 | describe directory('C:\hab\pkgs\ncr_devops_platform\sensu-agent-win') do 6 | it { should exist } 7 | end 8 | 9 | describe file('C:\hab\sup\default\specs\splunkforwarder.spec') do 10 | it { should_not exist } 11 | end 12 | 13 | servicecheck = <<-EOH 14 | $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" 15 | $headers.Add("Content-Type", "application/json") 16 | $headers.Add("Authorization", "Bearer secret") 17 | $uri = "http://localhost:9631/services" 18 | $reply = (Invoke-RestMethod -Headers $headers -uri $uri) | Convertto-Json 19 | $reply 20 | EOH 21 | 22 | describe json(command: servicecheck) do 23 | its(['bldr_url']) { should eq 'https://bldr.habitat.sh/' } 24 | its(%w(cfg id)) { should eq 'hab-sensu-agent' } 25 | its(%w(cfg backend-urls)) { should eq ['ws://127.0.0.1:8081'] } 26 | its(['channel']) { should eq 'stable' } 27 | its(['desired_state']) { should eq 'Down' } 28 | its(['spec_file']) { should eq 'C:\\hab/sup\\default\\specs\\sensu-agent-win.spec' } 29 | its(['topology']) { should eq 'standalone' } 30 | its(['update_strategy']) { should eq 'rolling' } 31 | end 32 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/config.rb: -------------------------------------------------------------------------------- 1 | apt_update 2 | 3 | hab_sup 'default' do 4 | gateway_auth_token 'secret' 5 | license 'accept' 6 | end 7 | 8 | ruby_block 'wait-for-sup-default-startup' do 9 | block do 10 | raise unless system('hab sup status') 11 | end 12 | retries 30 13 | retry_delay 1 14 | end 15 | 16 | hab_package 'core/jq-static' do 17 | binlink true 18 | end 19 | 20 | # we need to sleep to let the nginx service have enough time to 21 | # startup properly before we can configure it. 22 | # This is here due to https://github.com/habitat-sh/habitat/issues/3155 and 23 | # can be removed if that issue is fixed. 24 | ruby_block 'wait-for-nginx-startup' do 25 | block do 26 | sleep 20 27 | end 28 | action :nothing 29 | subscribes :run, 'hab_service[core/nginx]', :immediately 30 | end 31 | 32 | hab_config 'nginx.default' do 33 | config( 34 | worker_processes: 2, 35 | http: { 36 | keepalive_timeout: 120, 37 | } 38 | ) 39 | gateway_auth_token 'secret' 40 | end 41 | 42 | hab_service 'core/nginx' do 43 | gateway_auth_token 'secret' 44 | end 45 | 46 | # Allow some time for the config to apply before running tests 47 | ruby_block 'wait-for-nginx-config' do 48 | block do 49 | sleep 3 50 | end 51 | action :nothing 52 | subscribes :run, 'hab_config[nginx.default]', :immediately 53 | end 54 | -------------------------------------------------------------------------------- /libraries/resource_hab_package.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: AJ Christensen () 3 | # Copyright:: Copyright 2008-2018, Chef Software, Inc. 4 | # License:: Apache License, Version 2.0 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | require 'chef/resource/package' 20 | 21 | class Chef 22 | class Resource 23 | class HartPackage < Chef::Resource::Package 24 | resource_name :hab_package 25 | provides :hab_package 26 | 27 | property :bldr_url, String, default: 'https://bldr.habitat.sh' 28 | property :channel, String, default: 'stable' 29 | property :auth_token, String 30 | property :binlink, [true, false, :force], default: false 31 | property :keep_latest, String 32 | property :exclude, String 33 | property :no_deps, [true, false], default: false 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /test/integration/win_config/default_spec.rb: -------------------------------------------------------------------------------- 1 | describe file('C:\habitat\hab.exe') do 2 | it { should exist } 3 | end 4 | 5 | # This needs to be updated each time Habitat is released so we ensure we're getting the version 6 | # required by this cookbook. 7 | # TODO: Inspec session seems to not have the updated windows system path when run with 'kitchen test' 8 | # Works fine if you run a converge and then a verify as two seperate commands 9 | # For now, hitting hab.exe directly to avoid test failure 10 | describe command('C:\habitat\hab.exe -V') do 11 | its('stdout') { should match(%r{^hab.*/}) } 12 | its('exit_status') { should eq 0 } 13 | end 14 | 15 | splunkserviceapi = '(Invoke-RestMethod http://localhost:9631/services/splunkforwarder/default).cfg | ConvertTo-Json' 16 | describe json(command: splunkserviceapi) do 17 | its(%w(directories path)) { should eq ['C:/hab/pkgs/.../*.log'] } 18 | end 19 | 20 | # This test needs to be re-written to hit the supervisor API 21 | # describe json('C:\hab\sup\default\data\census.dat') do 22 | # scpath = ['census_groups', 'splunkforwarder.default', 'service_config'] 23 | # # Incarnation is just the current timestamp, so we can't compare to an exact 24 | # # value. Instead just make sure it looks right. 25 | # its(scpath + ['incarnation']) { should be > 1_500_000_000 } 26 | # its(scpath + %w(value directories path)) { should eq ['C:/hab/pkgs/.../*.log'] } 27 | # end 28 | -------------------------------------------------------------------------------- /.expeditor/update_hab_release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Updates the Habitat version everywhere in this cookbook so it works with new 4 | # versions of Habitat. 5 | # 6 | set -evx 7 | 8 | if [[ -z $EXPEDITOR_VERSION ]]; then 9 | echo "ERROR: Version undefined, cannot continue, exiting" 10 | exit 1 11 | fi 12 | 13 | branch="expeditor/${EXPEDITOR_VERSION}" 14 | git checkout -b ${branch} 15 | 16 | sed -i "s/%r{^hab .*\/}/%r{^hab ${EXPEDITOR_VERSION}\/}/" test/integration/config/default_spec.rb 17 | sed -i "s/%r{^hab .*\/}/%r{^hab ${EXPEDITOR_VERSION}\/}/" test/integration/package/default_spec.rb 18 | sed -i "s/%r{^hab .*\/}/%r{^hab ${EXPEDITOR_VERSION}\/}/" test/integration/user-toml/default_spec.rb 19 | sed -i "s/HAB_VERSION = '.*'.freeze/HAB_VERSION = '${EXPEDITOR_VERSION}'.freeze/" libraries/habitat_shared.rb 20 | sed -i "s/^- Habitat version: .*/- Habitat version: ${EXPEDITOR_VERSION}/" README.md 21 | sed -i "s/^version '.*'/version '${EXPEDITOR_VERSION}'/" metadata.rb 22 | 23 | echo "${EXPEDITOR_VERSION}" > VERSION 24 | 25 | git add . 26 | git commit --message "Update to habitat $EXPEDITOR_VERSION" --message "This pull request was triggered automatically via Expeditor when Habitat $EXPEDITOR_VERSION was promoted to stable." --message "This change falls under the obvious fix policy so no Developer Certificate of Origin (DCO) sign-off is required." 27 | 28 | . /helper_functions.sh 29 | open_pull_request 30 | 31 | git checkout - 32 | git branch -D ${branch} 33 | -------------------------------------------------------------------------------- /libraries/habitat_shared.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright:: 2017-2\ Chef Software, Inc. 3 | # License:: Apache License, Version 2.0 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # li 16 | 17 | module Habitat 18 | module Shared 19 | def hab(*command) 20 | # Windows shell_out does not support arrays, so manually cleaning and joining 21 | hab_cmd = if platform_family?('windows') 22 | (['hab'] + command).flatten.compact.join(' ') 23 | else 24 | (['hab'] + command) 25 | end 26 | 27 | if Gem::Requirement.new('>= 14.3.20').satisfied_by?(Gem::Version.new(Chef::VERSION)) 28 | shell_out!(hab_cmd) 29 | else 30 | shell_out_compact!(hab_cmd) # cookstyle: disable ChefDeprecations/DeprecatedShelloutMethods 31 | end 32 | rescue Errno::ENOENT 33 | Chef::Log.fatal("'hab' binary not found, use the 'hab_install' resource to install it first") 34 | raise 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /test/integration/package/default_spec.rb: -------------------------------------------------------------------------------- 1 | describe user('hab') do 2 | it { should exist } 3 | end 4 | 5 | describe file('/bin/hab') do 6 | it { should exist } 7 | it { should be_symlink } 8 | end 9 | 10 | # This needs to be updated each time Habitat is released so we ensure we're getting the version 11 | # required by this cookbook. 12 | describe command('hab -V') do 13 | its('stdout') { should match(%r{^hab.*/}) } 14 | its('exit_status') { should eq 0 } 15 | end 16 | 17 | describe directory('/hab/pkgs/core/redis') do 18 | it { should exist } 19 | end 20 | 21 | describe command('hab pkg path core/redis') do 22 | its('exit_status') { should eq 0 } 23 | its('stdout') { should match(%r{/hab/pkgs/core/redis}) } 24 | end 25 | 26 | describe directory('/hab/pkgs/lamont-granquist/ruby/2.3.1') do 27 | it { should exist } 28 | end 29 | 30 | describe command('hab pkg path lamont-granquist/ruby/2.3.1') do 31 | its('exit_status') { should eq 0 } 32 | its('stdout') { should match(%r{/hab/pkgs/lamont-granquist/ruby/2.3.1}) } 33 | end 34 | 35 | describe directory('/hab/pkgs/core/bundler/1.13.3/20161011123917') do 36 | it { should exist } 37 | end 38 | 39 | describe command('hab pkg path core/bundler/1.13.3/20161011123917') do 40 | its('exit_status') { should eq 0 } 41 | its('stdout') { should match(%r{/hab/pkgs/core/bundler/1.13.3/20161011123917}) } 42 | end 43 | 44 | describe file('/bin/htop') do 45 | it { should be_symlink } 46 | its(:link_path) { should match(%r{/hab/pkgs/core/htop}) } 47 | end 48 | 49 | describe file('/bin/nginx') do 50 | it { should_not exist } 51 | end 52 | -------------------------------------------------------------------------------- /spec/unit/package_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::package' do 4 | cached(:chef_run) do 5 | ChefSpec::ServerRunner.new( 6 | platform: 'ubuntu' 7 | ).converge(described_recipe) 8 | end 9 | 10 | context 'when compiling the package recipe' do 11 | it 'installs core/redis' do 12 | expect(chef_run).to install_hab_package('core/redis') 13 | end 14 | 15 | it 'installs lamont-granquist/ruby with a specific version' do 16 | expect(chef_run).to install_hab_package('lamont-granquist/ruby') 17 | .with(version: '2.3.1') 18 | end 19 | 20 | it 'installs core/bundler with a specific release' do 21 | expect(chef_run).to install_hab_package('core/bundler') 22 | .with(version: '1.13.3/20161011123917') 23 | end 24 | 25 | it 'installs core/hab-sup with a specific depot url' do 26 | expect(chef_run).to install_hab_package('core/hab-sup') 27 | .with(bldr_url: 'https://bldr.habitat.sh') 28 | end 29 | 30 | it 'installs core/htop with binlink option' do 31 | expect(chef_run).to install_hab_package('core/htop') 32 | .with(options: ['--binlink']) 33 | end 34 | 35 | it 'installs core/foo with binlink parameters' do 36 | expect(chef_run).to install_hab_package('binlink') 37 | .with(binlink: true) 38 | end 39 | 40 | it 'installs core/foo by forcing binlink' do 41 | expect(chef_run).to install_hab_package('binlink_force') 42 | .with(binlink: :force) 43 | end 44 | 45 | it 'removes core/nginx with remove action' do 46 | expect(chef_run).to remove_hab_package('core/nginx') 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/win_service.rb: -------------------------------------------------------------------------------- 1 | hab_sup 'default' do 2 | license 'accept' 3 | gateway_auth_token 'secret' 4 | end 5 | 6 | ruby_block 'wait-for-sup-default-startup' do 7 | block do 8 | raise unless system('hab sup status') 9 | end 10 | retries 30 11 | retry_delay 1 12 | end 13 | 14 | hab_service 'skylerto/splunkforwarder' do 15 | gateway_auth_token 'secret' 16 | end 17 | 18 | # we need this sleep to let splunkforwarder start and for the hab supervisor to 19 | # recognize this and write the state file out otherwise our functional 20 | # tests fail. 21 | ruby_block 'wait-for-splunkforwarder-start' do 22 | block do 23 | sleep 3 24 | end 25 | action :nothing 26 | subscribes :run, 'hab_service[skylerto/splunkforwarder]', :immediately 27 | end 28 | 29 | hab_service 'skylerto/splunkforwarder unload' do 30 | service_name 'skylerto/splunkforwarder' 31 | gateway_auth_token 'secret' 32 | action :unload 33 | end 34 | 35 | hab_service 'ncr_devops_platform/sensu-agent-win' do 36 | strategy 'rolling' 37 | update_condition 'latest' 38 | channel :stable 39 | gateway_auth_token 'secret' 40 | action :load 41 | end 42 | 43 | # we need this sleep to let sensu-agent-win start and for the hab supervisor to 44 | # recognize this and write the state file out otherwise our functional 45 | # tests fail. 46 | ruby_block 'wait-for-sensu-agent-win-start' do 47 | block do 48 | sleep 5 49 | end 50 | action :nothing 51 | subscribes :run, 'hab_service[ncr_devops_platform/sensu-agent-win]', :immediately 52 | end 53 | 54 | hab_service 'ncr_devops_platform/sensu-agent-win stop' do 55 | service_name 'ncr_devops_platform/sensu-agent-win' 56 | gateway_auth_token 'secret' 57 | action :stop 58 | end 59 | -------------------------------------------------------------------------------- /chefignore: -------------------------------------------------------------------------------- 1 | # Put files/directories that should be ignored in this file when uploading 2 | # to a Chef Infra Server or Supermarket. 3 | # Lines that start with '# ' are comments. 4 | 5 | # OS generated files # 6 | ###################### 7 | .DS_Store 8 | ehthumbs.db 9 | Icon? 10 | nohup.out 11 | Thumbs.db 12 | .envrc 13 | 14 | # EDITORS # 15 | ########### 16 | .#* 17 | .project 18 | .settings 19 | *_flymake 20 | *_flymake.* 21 | *.bak 22 | *.sw[a-z] 23 | *.tmproj 24 | *~ 25 | \#* 26 | REVISION 27 | TAGS* 28 | tmtags 29 | .vscode 30 | .editorconfig 31 | 32 | ## COMPILED ## 33 | ############## 34 | *.class 35 | *.com 36 | *.dll 37 | *.exe 38 | *.o 39 | *.pyc 40 | *.so 41 | */rdoc/ 42 | a.out 43 | mkmf.log 44 | 45 | # Testing # 46 | ########### 47 | .circleci/* 48 | .codeclimate.yml 49 | .delivery/* 50 | .foodcritic 51 | .kitchen* 52 | .mdlrc 53 | .overcommit.yml 54 | .rspec 55 | .rubocop.yml 56 | .travis.yml 57 | .watchr 58 | .yamllint 59 | azure-pipelines.yml 60 | Dangerfile 61 | examples/* 62 | features/* 63 | Guardfile 64 | kitchen.yml* 65 | mlc_config.json 66 | Procfile 67 | Rakefile 68 | spec/* 69 | test/* 70 | 71 | # SCM # 72 | ####### 73 | .git 74 | .gitattributes 75 | .gitconfig 76 | .github/* 77 | .gitignore 78 | .gitkeep 79 | .gitmodules 80 | .svn 81 | */.bzr/* 82 | */.git 83 | */.hg/* 84 | */.svn/* 85 | 86 | # Berkshelf # 87 | ############# 88 | Berksfile 89 | Berksfile.lock 90 | cookbooks/* 91 | tmp 92 | 93 | # Bundler # 94 | ########### 95 | vendor/* 96 | Gemfile 97 | Gemfile.lock 98 | 99 | # Policyfile # 100 | ############## 101 | Policyfile.rb 102 | Policyfile.lock.json 103 | 104 | # Documentation # 105 | ############# 106 | CODE_OF_CONDUCT* 107 | CONTRIBUTING* 108 | documentation/* 109 | TESTING* 110 | UPGRADING* 111 | 112 | # Vagrant # 113 | ########### 114 | .vagrant 115 | Vagrantfile 116 | -------------------------------------------------------------------------------- /test/integration/sup/default_spec.rb: -------------------------------------------------------------------------------- 1 | describe command('/bin/hab sup -h') do 2 | its(:stdout) { should match(/The Habitat Supervisor/) } 3 | end 4 | 5 | svc_manager = if command('systemctl --help').exit_status == 0 6 | 'systemd' 7 | elsif command('initctl --help').exit_status == 0 8 | 'upstart' 9 | else 10 | 'sysv' 11 | end 12 | 13 | describe send("#{svc_manager}_service", 'hab-sup') do 14 | it { should be_running } 15 | end 16 | 17 | cmd = case svc_manager 18 | when 'systemd' 19 | 'systemctl restart hab-sup' 20 | when 'upstart' 21 | 'initctl restart hab-sup' 22 | when 'sysv' 23 | '/etc/init.d/hab-sup restart' 24 | end 25 | 26 | describe command(cmd) do 27 | its(:exit_status) { should eq(0) } 28 | end 29 | 30 | describe send("#{svc_manager}_service", 'hab-sup') do 31 | it { should be_running } 32 | end 33 | 34 | # Validate HAB_AUTH_TOKEN 35 | case svc_manager 36 | when 'systemd' 37 | describe file('/etc/systemd/system/hab-sup.service') do 38 | its('content') { should_not match('Environment = HAB_AUTH_TOKEN=test') } 39 | its('content') { should_not match('Environment = HAB_SUP_GATEWAY_AUTH_TOKEN=secret') } 40 | its('content') { should_not match('LimitNOFILE = 65536') } 41 | end 42 | when 'upstart' 43 | describe file('/etc/init/hab-sup.conf') do 44 | its('content') { should_not match('env HAB_AUTH_TOKEN=test') } 45 | its('content') { should_not match('env HAB_SUP_GATEWAY_AUTH_TOKEN=secret') } 46 | end 47 | when 'sysv' 48 | describe file('/etc/init.d/hab-sup') do 49 | its('content') { should_not match('export HAB_AUTH_TOKEN=test') } 50 | its('content') { should_not match('export HAB_SUP_GATEWAY_AUTH_TOKEN=secret') } 51 | end 52 | end 53 | 54 | describe port(7999) do 55 | it { should be_listening } 56 | end 57 | 58 | describe port(7998) do 59 | it { should be_listening } 60 | end 61 | -------------------------------------------------------------------------------- /libraries/resource_hab_sup_sysvinit.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright:: 2017-2018 Chef Software, Inc. 3 | # License:: Apache License, Version 2.0 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | require_relative 'resource_hab_sup' 19 | 20 | class Chef 21 | class Resource 22 | class HabSupSysvinit < HabSup 23 | provides :hab_sup_sysvinit 24 | provides :hab_sup 25 | 26 | action :run do 27 | super() 28 | 29 | template '/etc/init.d/hab-sup' do 30 | source 'sysvinit/hab-sup.erb' 31 | cookbook 'habitat' 32 | owner 'root' 33 | group 'root' 34 | mode '0755' 35 | variables(name: 'hab-sup', 36 | exec_start_options: exec_start_options, 37 | auth_token: new_resource.auth_token, 38 | gateway_auth_token: new_resource.gateway_auth_token) 39 | action :create 40 | end 41 | 42 | service 'hab-sup' do 43 | subscribes :restart, 'template[/etc/init.d/hab-sup]' 44 | subscribes :restart, 'hab_package[core/hab-sup]' 45 | subscribes :restart, 'hab_package[core/hab-launcher]' 46 | subscribes :restart, 'template[/hab/sup/default/config/sup.toml]' 47 | action [:enable, :start] 48 | not_if { node['chef_packages']['chef']['chef_root'].include?('/pkgs/chef/chef-infra-client') } 49 | end 50 | end 51 | 52 | action :stop do 53 | service 'hab-sup' do 54 | action :stop 55 | end 56 | end 57 | end 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /test/integration/sup_toml_config/default_spec.rb: -------------------------------------------------------------------------------- 1 | describe command('/bin/hab sup -h') do 2 | its(:stdout) { should match(/The Habitat Supervisor/) } 3 | end 4 | 5 | svc_manager = if command('systemctl --help').exit_status == 0 6 | 'systemd' 7 | elsif command('initctl --help').exit_status == 0 8 | 'upstart' 9 | else 10 | 'sysv' 11 | end 12 | 13 | describe send("#{svc_manager}_service", 'hab-sup') do 14 | it { should be_running } 15 | end 16 | 17 | cmd = case svc_manager 18 | when 'systemd' 19 | 'systemctl restart hab-sup' 20 | when 'upstart' 21 | 'initctl restart hab-sup' 22 | when 'sysv' 23 | '/etc/init.d/hab-sup restart' 24 | end 25 | 26 | describe command(cmd) do 27 | its(:exit_status) { should eq(0) } 28 | end 29 | 30 | describe send("#{svc_manager}_service", 'hab-sup') do 31 | it { should be_running } 32 | end 33 | 34 | # Validate HAB_AUTH_TOKEN 35 | case svc_manager 36 | when 'systemd' 37 | describe file('/etc/systemd/system/hab-sup.service') do 38 | its('content') { should_not match('Environment = HAB_AUTH_TOKEN=test') } 39 | its('content') { should_not match('Environment = HAB_SUP_GATEWAY_AUTH_TOKEN=secret') } 40 | its('content') { should_not match('LimitNOFILE = 65536') } 41 | end 42 | when 'upstart' 43 | describe file('/etc/init/hab-sup.conf') do 44 | its('content') { should_not match('env HAB_AUTH_TOKEN=test') } 45 | its('content') { should_not match('env HAB_SUP_GATEWAY_AUTH_TOKEN=secret') } 46 | end 47 | when 'sysv' 48 | describe file('/etc/init.d/hab-sup') do 49 | its('content') { should_not match('export HAB_AUTH_TOKEN=test') } 50 | its('content') { should_not match('export HAB_SUP_GATEWAY_AUTH_TOKEN=secret') } 51 | end 52 | end 53 | 54 | describe port(7999) do 55 | it { should be_listening } 56 | end 57 | 58 | describe port(7998) do 59 | it { should be_listening } 60 | end 61 | 62 | describe file('/hab/sup/default/config/sup.toml') do 63 | it { should exist } 64 | its('content') { should match(/peer.*127.0.0.2:9632.*127.0.0.3:9632/) } 65 | end 66 | -------------------------------------------------------------------------------- /resources/user_toml.rb: -------------------------------------------------------------------------------- 1 | # Copyright:: 2017-2018, Chef Software Inc. 2 | # License:: Apache License, Version 2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing 14 | resource_name :hab_user_toml 15 | provides :hab_user_toml 16 | 17 | property :config, Mash, 18 | required: true, 19 | coerce: proc { |m| m.is_a?(Hash) ? Mash.new(m) : m } 20 | property :service_name, String, name_property: true, desired_state: false 21 | 22 | action :create do 23 | directory config_directory do 24 | mode '0755' 25 | owner root_owner 26 | group node['root_group'] 27 | recursive true 28 | end 29 | 30 | file "#{config_directory}/user.toml" do 31 | mode '0600' 32 | owner root_owner 33 | group node['root_group'] 34 | content toml_dump(new_resource.config) 35 | sensitive true 36 | end 37 | end 38 | 39 | action :delete do 40 | file "#{config_directory}/user.toml" do 41 | sensitive true 42 | action :delete 43 | end 44 | end 45 | 46 | action_class do 47 | include Habitat::Toml 48 | 49 | def config_directory 50 | platform_family?('windows') ? "C:/hab/user/#{new_resource.service_name}/config" : "/hab/user/#{new_resource.service_name}/config" 51 | end 52 | 53 | def wmi_property_from_query(wmi_property, wmi_query) 54 | @wmi = ::WIN32OLE.connect('winmgmts://') 55 | result = @wmi.ExecQuery(wmi_query) 56 | return unless result.each.count > 0 57 | result.each.next.send(wmi_property) 58 | end 59 | 60 | def root_owner 61 | if platform_family?('windows') 62 | wmi_property_from_query(:name, "select * from Win32_UserAccount where sid like 'S-1-5-21-%-500' and LocalAccount=True") 63 | else 64 | 'root' 65 | end 66 | end 67 | end 68 | -------------------------------------------------------------------------------- /libraries/resource_hab_sup_upstart.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright:: 2017-2018 Chef Software, Inc. 3 | # License:: Apache License, Version 2.0 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | require_relative 'resource_hab_sup' 19 | 20 | class Chef 21 | class Resource 22 | class HabSupUpstart < HabSup 23 | provides :hab_sup_upstart 24 | provides :hab_sup do |_node| 25 | provs = Chef::Platform::ServiceHelpers.service_resource_providers 26 | !provs.include?(:systemd) && provs.include?(:upstart) 27 | end 28 | 29 | action :run do 30 | super() 31 | template '/etc/init/hab-sup.conf' do 32 | source 'upstart/hab-sup.conf.erb' 33 | cookbook 'habitat' 34 | owner 'root' 35 | group 'root' 36 | mode '0644' 37 | variables( 38 | exec_start_options: exec_start_options, 39 | auth_token: new_resource.auth_token, 40 | gateway_auth_token: new_resource.gateway_auth_token 41 | ) 42 | action :create 43 | end 44 | 45 | service 'hab-sup' do 46 | # RHEL 6 includes Upstart but Chef won't use it unless we specify the provider. 47 | provider Chef::Provider::Service::Upstart 48 | subscribes :restart, 'template[/etc/init/hab-sup.conf]' 49 | subscribes :restart, 'hab_package[core/hab-sup]' 50 | subscribes :restart, 'hab_package[core/hab-launcher]' 51 | subscribes :restart, 'template[/hab/sup/default/config/sup.toml]' 52 | action [:enable, :start] 53 | not_if { node['chef_packages']['chef']['chef_root'].include?('/pkgs/chef/chef-infra-client') } 54 | end 55 | end 56 | 57 | action :stop do 58 | service 'hab-sup' do 59 | action :stop 60 | end 61 | end 62 | end 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /test/integration/service/default_spec.rb: -------------------------------------------------------------------------------- 1 | describe directory('/hab/pkgs/core/nginx') do 2 | it { should exist } 3 | end 4 | 5 | describe directory('/hab/pkgs/core/redis') do 6 | it { should exist } 7 | end 8 | 9 | describe file('/hab/sup/default/specs/haproxy.spec') do 10 | it { should_not exist } 11 | end 12 | 13 | describe file('/hab/sup/default/specs/prometheus.spec') do 14 | it { should exist } 15 | end 16 | 17 | grafanaserviceapi = 'curl -v -H "Authorization: Bearer secret" http://localhost:9631/services/grafana/test | jq' 18 | describe json(command: grafanaserviceapi) do 19 | its(['binding_mode']) { should eq 'relaxed' } 20 | its(['binds']) { should eq ['prom:prometheus.default'] } 21 | its(['bldr_url']) { should eq 'https://bldr-test.habitat.sh/' } 22 | its(['channel']) { should eq 'bldr-1321420393699319808' } 23 | its(%w(health_check_interval secs)) { should eq 32 } 24 | its(%w(pkg ident)) { should eq 'core/grafana/6.4.3/20191105024430' } 25 | its(['service_group']) { should eq 'grafana.test' } 26 | its(['topology']) { should eq 'standalone' } 27 | its(['update_condition']) { should eq 'latest' } 28 | its(['update_strategy']) { should eq 'at-once' } 29 | end 30 | 31 | describe directory('/hab/pkgs/core/grafana/6.4.3/20191105024430') do 32 | it { should exist } 33 | end 34 | 35 | describe directory('/hab/pkgs/core/vault/1.1.5') do 36 | it { should exist } 37 | end 38 | 39 | describe file('/hab/sup/default/specs/vault.spec') do 40 | it { should exist } 41 | its(:content) { should match(%r{ident = "core/vault/1.1.5"}) } 42 | end 43 | 44 | describe file('/hab/sup/default/specs/consul.spec') do 45 | it { should exist } 46 | its(:content) { should match(%r{ident = "core/consul"}) } 47 | end 48 | 49 | describe file('/hab/sup/default/specs/redis.spec') do 50 | it { should exist } 51 | its(:content) { should match(/desired_state = "up"/) } 52 | its(:content) { should match(/channel = "stable"/) } 53 | end 54 | 55 | describe file('/hab/sup/default/specs/memcached.spec') do 56 | it { should exist } 57 | its(:content) { should match(/^desired_state = "up"$/) } 58 | end 59 | 60 | describe file('/hab/sup/default/specs/sensu.spec') do 61 | it { should exist } 62 | its(:content) { should match(/binds = \["rabbitmq:rabbitmq.default", "redis:redis.default"\]/) } 63 | end 64 | 65 | describe file('/hab/sup/default/specs/sensu-backend.spec') do 66 | it { should exist } 67 | its(:content) { should match(/^desired_state = "up"$/) } 68 | end 69 | -------------------------------------------------------------------------------- /spec/unit/service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::service' do 4 | cached(:chef_run) do 5 | ChefSpec::ServerRunner.new( 6 | platform: 'ubuntu' 7 | ).converge(described_recipe) 8 | end 9 | 10 | before(:each) do 11 | allow(Chef::Platform::ServiceHelpers).to receive(:service_resource_providers).and_return([:systemd]) 12 | end 13 | 14 | context 'when compiling the service recipe for chefspec' do 15 | it 'loads service' do 16 | expect(chef_run).to load_hab_service('core/nginx') 17 | end 18 | 19 | it 'stops service' do 20 | expect(chef_run).to stop_hab_service('core/redis stop') 21 | end 22 | 23 | it 'unloads service' do 24 | expect(chef_run).to unload_hab_service('core/nginx unload') 25 | end 26 | 27 | it 'loads a service with version' do 28 | expect(chef_run).to load_hab_service('core/vault version change').with( 29 | service_name: 'core/vault/1.1.5' 30 | ) 31 | end 32 | 33 | it 'loads a service with version and release' do 34 | expect(chef_run).to load_hab_service('core/grafana full identifier').with( 35 | service_name: 'core/grafana/6.4.3/20191105024430' 36 | ) 37 | end 38 | 39 | it 'loads a service with options' do 40 | expect(chef_run).to load_hab_service('core/grafana property change from custom values').with( 41 | service_group: 'test', 42 | bldr_url: 'https://bldr-test.habitat.sh', 43 | channel: :'bldr-1321420393699319808', 44 | topology: :standalone, 45 | strategy: :'at-once', 46 | update_condition: :latest, 47 | binding_mode: :relaxed, 48 | shutdown_timeout: 10, 49 | health_check_interval: 32, 50 | gateway_auth_token: 'secret' 51 | ) 52 | end 53 | 54 | it 'loads a service with a single bind' do 55 | expect(chef_run).to load_hab_service('core/grafana binding').with( 56 | bind: [ 57 | 'prom:prometheus.default', 58 | ] 59 | ) 60 | end 61 | 62 | it 'loads a service with multiple binds' do 63 | expect(chef_run).to load_hab_service('core/sensu').with( 64 | bind: [ 65 | 'rabbitmq:rabbitmq.default', 66 | 'redis:redis.default', 67 | ] 68 | ) 69 | end 70 | 71 | it 'reloads a service' do 72 | expect(chef_run).to reload_hab_service('core/consul reload') 73 | end 74 | 75 | it 'restarts a service' do 76 | expect(chef_run).to restart_hab_service('core/consul restart') 77 | end 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /resources/config.rb: -------------------------------------------------------------------------------- 1 | # Copyright:: 2017-2018, Chef Software Inc. 2 | # License:: Apache License, Version 2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | require 'net/http' 17 | require 'json' 18 | 19 | resource_name :hab_config 20 | provides :hab_config 21 | 22 | property :config, Mash, 23 | required: true, 24 | coerce: proc { |m| m.is_a?(Hash) ? Mash.new(m) : m } 25 | property :service_group, String, name_property: true, desired_state: false 26 | property :remote_sup, String, default: '127.0.0.1:9632', desired_state: false 27 | # Http port needed for querying/comparing current config value 28 | property :remote_sup_http, String, default: '127.0.0.1:9631', desired_state: false 29 | property :gateway_auth_token, String, desired_state: false 30 | property :user, String, desired_state: false 31 | 32 | load_current_value do 33 | http_uri = "http://#{remote_sup_http}" 34 | 35 | begin 36 | headers = {} 37 | headers['Authorization'] = "Bearer #{gateway_auth_token}" if property_is_set?(:gateway_auth_token) 38 | census = Mash.new(Chef::HTTP::SimpleJSON.new(http_uri).get('/census', headers)) 39 | sc = census['census_groups'][service_group]['service_config']['value'] 40 | rescue 41 | # Default to a blank config if anything (http error, json parsing, finding 42 | # the config object) goes wrong 43 | sc = {} 44 | end 45 | config sc 46 | end 47 | 48 | action :apply do 49 | converge_if_changed do 50 | # Use the current timestamp as the serial number/incarnation 51 | incarnation = Time.now.tv_sec 52 | 53 | opts = [] 54 | # opts gets flattened by shell_out_compact later 55 | opts << ['--remote-sup', new_resource.remote_sup] if new_resource.remote_sup 56 | opts << ['--user', new_resource.user] if new_resource.user 57 | 58 | tempfile = Tempfile.new(['hab_config', '.toml']) 59 | begin 60 | tempfile.write(toml_dump(new_resource.config)) 61 | tempfile.close 62 | 63 | hab('config', 'apply', opts, new_resource.service_group, incarnation, tempfile.path) 64 | ensure 65 | tempfile.close 66 | tempfile.unlink 67 | end 68 | end 69 | end 70 | 71 | action_class do 72 | include Habitat::Shared 73 | include Habitat::Toml 74 | end 75 | -------------------------------------------------------------------------------- /kitchen.dokken.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: dokken 4 | privileged: true # because Docker and SystemD/Upstart 5 | chef_license: accept-no-persist 6 | 7 | transport: 8 | name: dokken 9 | 10 | provisioner: 11 | name: dokken 12 | deprecations_as_errors: true 13 | 14 | verifier: 15 | name: inspec 16 | 17 | platforms: 18 | - name: amazonlinux 19 | driver: 20 | image: dokken/amazonlinux 21 | pid_one_command: /sbin/init 22 | 23 | - name: amazonlinux-2 24 | driver: 25 | image: dokken/amazonlinux-2 26 | pid_one_command: /usr/lib/systemd/systemd 27 | 28 | - name: debian-8 29 | driver: 30 | image: dokken/debian-8 31 | pid_one_command: /bin/systemd 32 | intermediate_instructions: 33 | - RUN /usr/bin/apt-get update 34 | 35 | - name: debian-9 36 | driver: 37 | image: dokken/debian-9 38 | pid_one_command: /bin/systemd 39 | intermediate_instructions: 40 | - RUN /usr/bin/apt-get update 41 | 42 | - name: debian-10 43 | driver: 44 | image: dokken/debian-10 45 | pid_one_command: /bin/systemd 46 | intermediate_instructions: 47 | - RUN /usr/bin/apt-get update 48 | 49 | - name: centos-6 50 | driver: 51 | image: dokken/centos-6 52 | pid_one_command: /sbin/init 53 | chef_version: 16.7 # patch for chef/chef:latest not working with el6 54 | 55 | - name: centos-7 56 | driver: 57 | image: dokken/centos-7 58 | pid_one_command: /usr/lib/systemd/systemd 59 | 60 | - name: centos-8 61 | driver: 62 | image: dokken/centos-8 63 | pid_one_command: /usr/lib/systemd/systemd 64 | 65 | - name: oraclelinux-6 66 | driver: 67 | image: dokken/oraclelinux-6 68 | pid_one_command: /sbin/init 69 | chef_version: 16.7 # patch for chef/chef:latest not working with el6 70 | 71 | - name: oraclelinux-7 72 | driver: 73 | image: dokken/oraclelinux-7 74 | pid_one_command: /usr/lib/systemd/systemd 75 | 76 | # - name: oraclelinux-8 77 | # driver: 78 | # image: dokken/oraclelinux-8 79 | # pid_one_command: /usr/lib/systemd/systemd 80 | 81 | - name: fedora-latest 82 | driver: 83 | image: dokken/fedora-latest 84 | pid_one_command: /usr/lib/systemd/systemd 85 | 86 | - name: ubuntu-16.04 87 | driver: 88 | image: dokken/ubuntu-16.04 89 | pid_one_command: /bin/systemd 90 | intermediate_instructions: 91 | - RUN /usr/bin/apt-get update 92 | 93 | - name: ubuntu-18.04 94 | driver: 95 | image: dokken/ubuntu-18.04 96 | pid_one_command: /bin/systemd 97 | intermediate_instructions: 98 | - RUN /usr/bin/apt-get update 99 | 100 | - name: opensuse-leap-15 101 | driver: 102 | image: dokken/opensuse-leap-15 103 | pid_one_command: /bin/systemd 104 | -------------------------------------------------------------------------------- /libraries/resource_hab_sup_systemd.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright:: 2017-2018 Chef Software, Inc. 3 | # License:: Apache License, Version 2.0 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | require_relative 'resource_hab_sup' 19 | 20 | class Chef 21 | class Resource 22 | class HabSupSystemd < HabSup 23 | provides :hab_sup_systemd 24 | provides :hab_sup do |_node| 25 | Chef::Platform::ServiceHelpers.service_resource_providers.include?(:systemd) 26 | end 27 | 28 | action :run do 29 | super() 30 | 31 | service_environment = [] 32 | service_environment.push("HAB_BLDR_URL=#{new_resource.bldr_url}") if new_resource.bldr_url 33 | service_environment.push("HAB_AUTH_TOKEN=#{new_resource.auth_token}") if new_resource.auth_token 34 | service_environment.push("HAB_SUP_GATEWAY_AUTH_TOKEN=#{new_resource.gateway_auth_token}") if new_resource.gateway_auth_token 35 | systemd_unit 'hab-sup.service' do 36 | content(Unit: { 37 | Description: 'The Habitat Supervisor', 38 | }, 39 | Service: { 40 | LimitNOFILE: new_resource.limit_no_files, 41 | Environment: service_environment, 42 | ExecStart: "/bin/hab sup run #{exec_start_options}", 43 | ExecStop: '/bin/hab sup term', 44 | Restart: 'on-failure', 45 | }.compact, 46 | Install: { 47 | WantedBy: 'default.target', 48 | }) 49 | action :create 50 | end 51 | 52 | service 'hab-sup' do 53 | subscribes :restart, 'systemd_unit[hab-sup.service]' 54 | subscribes :restart, 'hab_package[core/hab-sup]' 55 | subscribes :restart, 'hab_package[core/hab-launcher]' 56 | subscribes :restart, 'template[/hab/sup/default/config/sup.toml]' 57 | action [:enable, :start] 58 | not_if { node['chef_packages']['chef']['chef_root'].include?('/pkgs/chef/chef-infra-client') } 59 | end 60 | end 61 | 62 | action :stop do 63 | service 'hab-sup' do 64 | action :stop 65 | end 66 | end 67 | end 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /templates/sysvinit/hab-sup.erb: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ### BEGIN INIT INFO 4 | # Provides: <%= @name %> 5 | # Required-Start: $remote_fs $network 6 | # Required-Stop: $remote_fs $network 7 | # Default-Start: 2 3 4 5 8 | # Default-Stop: 0 1 6 9 | # Short-Description: The Habitat Supervisor 10 | # Description: 11 | # Manages the Habitat supervisor process. 12 | ### END INIT INFO 13 | 14 | PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin 15 | 16 | NAME=<%= @name %> 17 | DESC="Habitat Supervisor" 18 | HAB=/bin/hab 19 | OPTIONS="<%= @exec_start_options %>" 20 | PIDFILE=/var/run/$NAME.pid 21 | 22 | . /lib/lsb/init-functions 23 | 24 | if [ ! -x $HAB ]; then 25 | log_failure_msg "$HAB not present or not executable" 26 | exit 1 27 | fi 28 | 29 | pid() { 30 | pidofproc -p $PIDFILE 31 | } 32 | 33 | running() { 34 | start-stop-daemon --status --pidfile $PIDFILE 35 | return $? 36 | } 37 | 38 | start() { 39 | start-stop-daemon --start \ 40 | --background \ 41 | --pidfile $PIDFILE \ 42 | --make-pidfile \ 43 | --exec $HAB -- sup run $OPTIONS 44 | return $? 45 | } 46 | 47 | stop() { 48 | start-stop-daemon --stop --pidfile $PIDFILE 49 | return $? 50 | } 51 | 52 | case "$1" in 53 | start) 54 | <% if @auth_token %> 55 | log_daemon_msg "Setting HAB_AUTH_TOKEN for $DESC" "$NAME" 56 | export HAB_AUTH_TOKEN=<%= @auth_token %> 57 | <% end %> 58 | 59 | <% if @gateway_auth_token %> 60 | log_daemon_msg "Setting HAB_SUP_GATEWAY_AUTH_TOKEN for $DESC" "$NAME" 61 | export HAB_SUP_GATEWAY_AUTH_TOKEN=<%= @gateway_auth_token %> 62 | <% end %> 63 | 64 | log_daemon_msg "Starting $DESC" "$NAME" 65 | if running; then 66 | log_progress_msg "already running ($(pid))" 67 | log_end_msg 0 68 | else 69 | start 70 | resp=$? 71 | log_end_msg $resp 72 | [ $resp != 0 ] && exit $resp 73 | fi 74 | ;; 75 | stop) 76 | log_daemon_msg "Stopping $DESC" "$NAME" 77 | if running; then 78 | log_progress_msg "($(pid))" 79 | stop 80 | resp=$? 81 | log_end_msg $resp 82 | [ $resp != 0 ] && exit $resp 83 | else 84 | log_progress_msg "already stopped" 85 | log_end_msg 0 86 | fi 87 | ;; 88 | restart) 89 | log_daemon_msg "Restarting $DESC" "$NAME" 90 | if running; then 91 | stop 92 | resp=$? 93 | if [ $resp = 0 ]; then 94 | sleep 1 95 | else 96 | log_progress_msg "failed to stop" 97 | log_end_msg $resp 98 | exit $resp 99 | fi 100 | fi 101 | start 102 | resp=$? 103 | log_end_msg $resp 104 | [ $resp != 0 ] && exit $resp 105 | ;; 106 | status) 107 | status_of_proc -p "$PIDFILE" "$HAB" "$DESC" 108 | exit $? 109 | ;; 110 | *) 111 | echo "Usage: $0 $NAME {start|stop|restart|status}" 112 | exit 1 113 | ;; 114 | esac 115 | 116 | exit 0 117 | -------------------------------------------------------------------------------- /libraries/habitat_toml.rb: -------------------------------------------------------------------------------- 1 | 2 | module Habitat 3 | module Toml 4 | class Dumper 5 | attr_reader :toml_str 6 | 7 | def initialize(hash) 8 | @toml_str = '' 9 | 10 | visit(hash, []) 11 | end 12 | 13 | private 14 | 15 | def visit(hash, prefix, extra_brackets = false) 16 | simple_pairs, nested_pairs, table_array_pairs = sort_pairs hash 17 | 18 | if prefix.any? && (simple_pairs.any? || hash.empty?) 19 | print_prefix prefix, extra_brackets 20 | end 21 | 22 | dump_pairs simple_pairs, nested_pairs, table_array_pairs, prefix 23 | end 24 | 25 | def sort_pairs(hash) 26 | nested_pairs = [] 27 | simple_pairs = [] 28 | table_array_pairs = [] 29 | 30 | hash.keys.sort.each do |key| 31 | val = hash[key] 32 | element = [key, val] 33 | 34 | if val.is_a? Hash 35 | nested_pairs << element 36 | elsif val.is_a?(Array) && val.first.is_a?(Hash) 37 | table_array_pairs << element 38 | else 39 | simple_pairs << element 40 | end 41 | end 42 | 43 | [simple_pairs, nested_pairs, table_array_pairs] 44 | end 45 | 46 | def dump_pairs(simple, nested, table_array, prefix = []) 47 | # First add simple pairs, under the prefix 48 | dump_simple_pairs simple 49 | dump_nested_pairs nested, prefix 50 | dump_table_array_pairs table_array, prefix 51 | end 52 | 53 | def dump_simple_pairs(simple_pairs) 54 | simple_pairs.each do |key, val| 55 | key = quote_key(key) unless bare_key? key 56 | @toml_str << "#{key} = #{to_toml(val)}\n" 57 | end 58 | end 59 | 60 | def dump_nested_pairs(nested_pairs, prefix) 61 | nested_pairs.each do |key, val| 62 | key = quote_key(key) unless bare_key? key 63 | 64 | visit val, prefix + [key], false 65 | end 66 | end 67 | 68 | def dump_table_array_pairs(table_array_pairs, prefix) 69 | table_array_pairs.each do |key, val| 70 | key = quote_key(key) unless bare_key? key 71 | aux_prefix = prefix + [key] 72 | 73 | val.each do |child| 74 | print_prefix aux_prefix, true 75 | args = sort_pairs(child) << aux_prefix 76 | 77 | dump_pairs(*args) 78 | end 79 | end 80 | end 81 | 82 | def print_prefix(prefix, array = false) 83 | new_prefix = prefix.join('.') 84 | new_prefix = "[#{new_prefix}]" if array 85 | 86 | @toml_str += "[#{new_prefix}]\n" 87 | end 88 | 89 | def to_toml(obj) 90 | if obj.is_a?(Time) || obj.is_a?(DateTime) 91 | obj.strftime('%Y-%m-%dT%H:%M:%SZ') 92 | elsif obj.is_a?(Date) 93 | obj.strftime('%Y-%m-%d') 94 | elsif obj.is_a? Regexp 95 | obj.inspect.inspect 96 | elsif obj.is_a? String 97 | obj.inspect.gsub(/\\(#[$@{])/, '\1') 98 | else 99 | obj.inspect 100 | end 101 | end 102 | 103 | def bare_key?(key) 104 | !!key.to_s.match(/^[a-zA-Z0-9_-]*$/) 105 | end 106 | 107 | def quote_key(key) 108 | '"' + key.gsub('"', '\\"') + '"' 109 | end 110 | end 111 | 112 | def toml_dump(hash) 113 | Dumper.new(hash).toml_str 114 | end 115 | end 116 | end 117 | -------------------------------------------------------------------------------- /.github/workflows/delivery.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: ci 3 | 4 | on: 5 | pull_request: 6 | push: 7 | branches: 8 | - master 9 | - main 10 | 11 | jobs: 12 | delivery: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Check out code 16 | uses: actions/checkout@main 17 | - name: Run Chef Delivery 18 | uses: actionshub/chef-delivery@main 19 | env: 20 | CHEF_LICENSE: accept-no-persist 21 | 22 | dokken: 23 | needs: [delivery] 24 | runs-on: ubuntu-latest 25 | strategy: 26 | matrix: 27 | os: 28 | - 'amazonlinux' 29 | - 'amazonlinux-2' 30 | - 'debian-9' 31 | - 'debian-10' 32 | - 'centos-6' 33 | - 'centos-7' 34 | - 'centos-8' 35 | - 'oraclelinux-6' 36 | - 'oraclelinux-7' 37 | # - 'oraclelinux-8' 38 | - 'fedora-latest' 39 | - 'ubuntu-1604' 40 | - 'ubuntu-1804' 41 | - 'opensuse-leap-15' 42 | 43 | suite: 44 | - 'install-for-chefspec' 45 | - 'install-no-user' 46 | - 'package' 47 | - 'service' 48 | - 'sup' 49 | - 'sup-toml-config' 50 | - 'config' 51 | - 'user-toml' 52 | - 'config-chef-13' 53 | fail-fast: false 54 | 55 | steps: 56 | - name: Check out code 57 | uses: actions/checkout@main 58 | - name: Install Chef 59 | uses: actionshub/chef-install@main 60 | - name: Dokken 61 | uses: actionshub/kitchen-dokken@main 62 | env: 63 | CHEF_LICENSE: accept-no-persist 64 | KITCHEN_LOCAL_YAML: kitchen.dokken.yml 65 | with: 66 | suite: ${{ matrix.suite }} 67 | os: ${{ matrix.os }} 68 | 69 | windows: 70 | needs: [delivery] 71 | runs-on: windows-2019 72 | strategy: 73 | matrix: 74 | os: 75 | - 'windows-2019' 76 | suite: 77 | - 'win_config' 78 | - 'win_package' 79 | - 'win_service' 80 | - 'win_sup' 81 | - 'win_user_toml' 82 | - 'win_sup_toml_config' 83 | fail-fast: false 84 | steps: 85 | - name: Check out code 86 | uses: actions/checkout@main 87 | - name: Install Chef Workstation 88 | run: . { iwr -useb https://omnitruck.chef.io/install.ps1 } | iex; install -channel stable -project chef-workstation 89 | shell: powershell 90 | - name: Add Chef Workstation to PATH 91 | run: | 92 | if ( $env:PATH -like "*chef-workstation*" ) { 93 | write-output 'Path already set, no action to perform' 94 | } else { 95 | write-output 'Adding c:\opscode\chef-workstation\bin to path.' 96 | echo "c:\opscode\chef-workstation\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append 97 | } 98 | shell: powershell 99 | - name: Chef Infra Client Run 100 | run: C:\opscode\chef-workstation\bin\chef-solo -c test/solo.rb -o "test::${{ matrix.suite }}" 101 | shell: powershell 102 | env: 103 | CHEF_LICENSE: accept-no-persist 104 | - name: Integration Testing 105 | run: C:\opscode\chef-workstation\bin\inspec exec test\integration\${{ matrix.suite }}\default_spec.rb 106 | shell: powershell 107 | env: 108 | CHEF_LICENSE: accept-no-persist 109 | -------------------------------------------------------------------------------- /libraries/resource_hab_sup_windows.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright:: 2017-2018 Chef Software, Inc. 3 | # License:: Apache License, Version 2.0 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | require 'win32/service' if RUBY_PLATFORM =~ /mswin|mingw32|windows/ 19 | require_relative 'resource_hab_sup' 20 | 21 | class Chef 22 | class Resource 23 | class HabSupWindows < HabSup 24 | provides :hab_sup_windows 25 | provides :hab_sup do |node| 26 | node['platform_family'] == 'windows' 27 | end 28 | 29 | service_file = 'windows/HabService.dll.config.erb' 30 | win_service_config = 'C:/hab/svc/windows-service/HabService.dll.config' 31 | 32 | action :run do 33 | super() 34 | 35 | # TODO: There has to be a better way to handle auth token on windows 36 | # than the system wide environment variable 37 | auth_action = new_resource.auth_token ? :create : :delete 38 | env 'HAB_AUTH_TOKEN' do 39 | value new_resource.auth_token if new_resource.auth_token 40 | action auth_action 41 | end 42 | 43 | gateway_auth_action = new_resource.gateway_auth_token ? :create : :delete 44 | env 'HAB_SUP_GATEWAY_AUTH_TOKEN' do 45 | value new_resource.gateway_auth_token if new_resource.gateway_auth_token 46 | action gateway_auth_action 47 | end 48 | 49 | bldr_action = new_resource.bldr_url ? :create : :delete 50 | env 'HAB_BLDR_URL' do 51 | value new_resource.bldr_url if new_resource.bldr_url 52 | action bldr_action 53 | end 54 | 55 | hab_package 'core/windows-service' do 56 | bldr_url new_resource.bldr_url if new_resource.bldr_url 57 | version new_resource.service_version if new_resource.service_version 58 | end 59 | 60 | execute 'hab pkg exec core/windows-service install' do 61 | not_if { ::Win32::Service.exists?('Habitat') } 62 | end 63 | 64 | # win_version = `dir /D /B C:\\hab\\pkgs\\core\\hab-launcher`.split().last 65 | 66 | template win_service_config.to_s do 67 | source service_file.to_s 68 | cookbook 'habitat' 69 | variables exec_start_options: exec_start_options, 70 | bldr_url: new_resource.bldr_url, 71 | auth_token: new_resource.auth_token, 72 | gateway_auth_token: new_resource.gateway_auth_token 73 | # win_launcher: win_version 74 | action :touch 75 | end 76 | 77 | service 'Habitat' do 78 | subscribes :restart, 'env[HAB_AUTH_TOKEN]' 79 | subscribes :restart, 'env[HAB_SUP_GATEWAY_AUTH_TOKEN]' 80 | subscribes :restart, 'env[HAB_BLDR_URL]' 81 | subscribes :restart, "template[#{win_service_config}]" 82 | subscribes :restart, 'hab_package[core/hab-sup]' 83 | subscribes :restart, 'hab_package[core/hab-launcher]' 84 | subscribes :restart, 'template[C:/hab/sup/default/config/sup.toml]' 85 | action [:enable, :start] 86 | not_if { node['chef_packages']['chef']['chef_root'].include?('/pkgs/chef/chef-infra-client') } 87 | end 88 | end 89 | end 90 | end 91 | end 92 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/sup.rb: -------------------------------------------------------------------------------- 1 | directory '/hab/sup' do 2 | recursive true 3 | action :nothing 4 | retries 30 5 | retry_delay 1 6 | end 7 | 8 | hab_sup 'tester' do 9 | bldr_url 'https://willem.habitat.sh' 10 | license 'accept' 11 | sup_version '1.6.139' 12 | launcher_version '13458' 13 | end 14 | 15 | ruby_block 'wait-for-sup-default-startup' do 16 | block do 17 | raise unless system('hab sup status') 18 | end 19 | retries 30 20 | retry_delay 1 21 | end 22 | 23 | hab_sup 'test-options' do 24 | license 'accept' 25 | listen_http '0.0.0.0:9999' 26 | listen_gossip '0.0.0.0:9998' 27 | notifies :stop, 'hab_sup[tester]', :before 28 | notifies :delete, 'directory[/hab/sup]', :before 29 | end 30 | 31 | ruby_block 'wait-for-sup-chef-es-startup' do 32 | block do 33 | raise unless system('hab sup status') 34 | end 35 | retries 30 36 | retry_delay 1 37 | end 38 | 39 | hab_sup 'test-auth-token' do 40 | license 'accept' 41 | auth_token 'test' 42 | listen_http '0.0.0.0:10001' 43 | listen_gossip '0.0.0.0:10000' 44 | notifies :stop, 'hab_sup[test-options]', :before 45 | notifies :delete, 'directory[/hab/sup]', :before 46 | end 47 | 48 | ruby_block 'wait-for-sup-test-auth-token-startup' do 49 | block do 50 | raise unless system('hab sup status') 51 | end 52 | retries 30 53 | retry_delay 1 54 | end 55 | 56 | hab_sup 'test-gateway-auth-token' do 57 | license 'accept' 58 | gateway_auth_token 'secret' 59 | listen_http '0.0.0.0:10001' 60 | listen_gossip '0.0.0.0:10000' 61 | notifies :stop, 'hab_sup[test-auth-token]', :before 62 | notifies :delete, 'directory[/hab/sup]', :before 63 | end 64 | 65 | ruby_block 'wait-for-sup-test-gateway-auth-token-startup' do 66 | block do 67 | raise unless system('hab sup status') 68 | end 69 | retries 30 70 | retry_delay 1 71 | end 72 | 73 | hab_sup 'test-gateway-auth-and-auth-token' do 74 | license 'accept' 75 | auth_token 'test' 76 | gateway_auth_token 'secret' 77 | listen_http '0.0.0.0:10001' 78 | listen_gossip '0.0.0.0:10000' 79 | notifies :stop, 'hab_sup[test-gateway-auth-token]', :before 80 | notifies :delete, 'directory[/hab/sup]', :before 81 | end 82 | 83 | ruby_block 'wait-for-sup-test-gateway-auth-and-auth-token-startup' do 84 | block do 85 | raise unless system('hab sup status') 86 | end 87 | retries 30 88 | retry_delay 1 89 | end 90 | 91 | hab_sup 'single_peer' do 92 | license 'accept' 93 | listen_http '0.0.0.0:8999' 94 | listen_gossip '0.0.0.0:8998' 95 | peer '127.0.0.2' 96 | notifies :stop, 'hab_sup[test-gateway-auth-and-auth-token]', :before 97 | notifies :delete, 'directory[/hab/sup]', :before 98 | end 99 | 100 | ruby_block 'wait-for-sup-single_peer-startup' do 101 | block do 102 | raise unless system('hab sup status') 103 | end 104 | retries 30 105 | retry_delay 1 106 | end 107 | 108 | hab_sup 'health_check_interval' do 109 | license 'accept' 110 | health_check_interval 60 111 | listen_http '0.0.0.0:7999' 112 | listen_gossip '0.0.0.0:7998' 113 | notifies :stop, 'hab_sup[single_peer]', :before 114 | notifies :delete, 'directory[/hab/sup]', :before 115 | end 116 | 117 | ruby_block 'wait-for-sup-health_check_interval-startup' do 118 | block do 119 | raise unless system('hab sup status') 120 | end 121 | retries 30 122 | retry_delay 1 123 | end 124 | 125 | hab_sup 'set_file_limit' do 126 | license 'accept' 127 | limit_no_files '65536' 128 | notifies :stop, 'hab_sup[single_peer]', :before 129 | notifies :delete, 'directory[/hab/sup]', :before 130 | end 131 | 132 | ruby_block 'wait-for-sup-set_file_limit-startup' do 133 | block do 134 | raise unless system('hab sup status') 135 | end 136 | retries 30 137 | retry_delay 1 138 | end 139 | 140 | hab_sup 'multiple_peers' do 141 | license 'accept' 142 | peer ['127.0.0.2', '127.0.0.3'] 143 | listen_http '0.0.0.0:7999' 144 | listen_gossip '0.0.0.0:7998' 145 | notifies :stop, 'hab_sup[single_peer]', :before 146 | notifies :delete, 'directory[/hab/sup]', :before 147 | end 148 | 149 | ruby_block 'wait-for-sup-multiple_peers-startup' do 150 | block do 151 | raise unless system('hab sup status') 152 | end 153 | retries 30 154 | retry_delay 1 155 | end 156 | -------------------------------------------------------------------------------- /kitchen.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: vagrant 4 | customize: 5 | memory: 4096 6 | gui: false 7 | 8 | provisioner: 9 | name: chef_zero 10 | always_update_cookbooks: true 11 | deprecations_as_errors: true 12 | chef_license: accept-no-persist 13 | 14 | verifier: 15 | name: inspec 16 | 17 | platforms: 18 | - name: amazonlinux 19 | driver_config: 20 | box: mvbcoding/awslinux 21 | - name: amazonlinux-2 22 | - name: centos-6 23 | - name: centos-7 24 | driver: 25 | box: bento/centos-7 26 | - name: centos-8 27 | - name: debian-9 28 | - name: debian-10 29 | - name: fedora-latest 30 | - name: opensuse-leap-15 31 | - name: ubuntu-16.04 32 | - name: ubuntu-18.04 33 | - name: windows-2016 34 | driver: 35 | box: tas50/windows_2016 36 | - name: windows-2019 37 | driver: 38 | box: tas50/windows_2019 39 | 40 | suites: 41 | # Testing Linux stuff here: 42 | - name: package 43 | named_run_list: package 44 | verifier: 45 | inspec_tests: 46 | - test/integration/package 47 | excludes: 48 | - windows-2016 49 | - windows-2019 50 | - name: service 51 | named_run_list: service 52 | verifier: 53 | inspec_tests: 54 | - test/integration/service 55 | excludes: 56 | - windows-2016 57 | - windows-2019 58 | - name: sup 59 | named_run_list: sup 60 | verifier: 61 | inspec_tests: 62 | - test/integration/sup 63 | excludes: 64 | - windows-2016 65 | - windows-2019 66 | - name: sup-toml-config 67 | named_run_list: sup_toml_config 68 | excludes: 69 | - windows-2016 70 | - windows-2019 71 | verifier: 72 | inspec_tests: 73 | - path: test/integration/sup_toml_config/default_spec.rb 74 | - name: install_no_user 75 | named_run_list: install_no_user 76 | verifier: 77 | inspec_tests: 78 | - test/integration/install_no_user 79 | excludes: 80 | - windows-2016 81 | - windows-2019 82 | - name: install_for_chefspec 83 | named_run_list: install_for_chefspec 84 | verifier: 85 | inspec_tests: 86 | - test/integration/install_for_chefspec 87 | excludes: 88 | - windows-2016 89 | - windows-2019 90 | - name: config 91 | named_run_list: config 92 | verifier: 93 | inspec_tests: 94 | - test/integration/config 95 | excludes: 96 | - windows-2016 97 | - windows-2019 98 | - name: user-toml 99 | named_run_list: user_toml 100 | verifier: 101 | inspec_tests: 102 | - test/integration/user_toml 103 | excludes: 104 | - windows-2016 105 | - windows-2019 106 | - name: config-chef-13 107 | named_run_list: config 108 | verifier: 109 | inspec_tests: 110 | - test/integration/config 111 | excludes: 112 | - windows-2016 113 | - windows-2019 114 | provisioner: 115 | product_name: chef 116 | product_version: 13.6.4 117 | 118 | # Testing windows stuff here: 119 | - name: win-package 120 | named_run_list: win_package 121 | verifier: 122 | inspec_tests: 123 | - test/integration/win_package 124 | includes: 125 | - windows-2016 126 | - windows-2019 127 | - name: win-service 128 | named_run_list: win_service 129 | verifier: 130 | inspec_tests: 131 | - test/integration/win_service 132 | includes: 133 | - windows-2016 134 | - windows-2019 135 | - name: win-sup 136 | named_run_list: win_sup 137 | verifier: 138 | inspec_tests: 139 | - test/integration/win_sup 140 | includes: 141 | - windows-2016 142 | - windows-2019 143 | - name: win-sup-toml-config 144 | named_run_list: win_sup_toml_config 145 | verifier: 146 | inspec_tests: 147 | - test/integration/win_sup_toml_config 148 | includes: 149 | - windows-2016 150 | - windows-2019 151 | - name: win-config 152 | named_run_list: win_config 153 | verifier: 154 | inspec_tests: 155 | - test/integration/win_config 156 | includes: 157 | - windows-2016 158 | - windows-2019 159 | - name: win-user-toml 160 | named_run_list: win_user_toml 161 | verifier: 162 | inspec_tests: 163 | - test/integration/win_user_toml 164 | includes: 165 | - windows-2016 166 | - windows-2019 167 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/sup_toml_config.rb: -------------------------------------------------------------------------------- 1 | directory '/hab/sup' do 2 | recursive true 3 | action :nothing 4 | retries 30 5 | retry_delay 1 6 | end 7 | 8 | hab_sup 'tester' do 9 | bldr_url 'https://willem.habitat.sh' 10 | license 'accept' 11 | sup_version '1.6.139' 12 | launcher_version '13458' 13 | toml_config true 14 | end 15 | 16 | ruby_block 'wait-for-sup-default-startup' do 17 | block do 18 | raise unless system('hab sup status') 19 | end 20 | retries 30 21 | retry_delay 1 22 | end 23 | 24 | hab_sup 'test-options' do 25 | license 'accept' 26 | listen_http '0.0.0.0:9999' 27 | listen_gossip '0.0.0.0:9998' 28 | notifies :stop, 'hab_sup[tester]', :before 29 | notifies :delete, 'directory[/hab/sup]', :before 30 | toml_config true 31 | end 32 | 33 | ruby_block 'wait-for-sup-chef-es-startup' do 34 | block do 35 | raise unless system('hab sup status') 36 | end 37 | retries 30 38 | retry_delay 1 39 | end 40 | 41 | hab_sup 'test-auth-token' do 42 | license 'accept' 43 | auth_token 'test' 44 | listen_http '0.0.0.0:10001' 45 | listen_gossip '0.0.0.0:10000' 46 | notifies :stop, 'hab_sup[test-options]', :before 47 | notifies :delete, 'directory[/hab/sup]', :before 48 | toml_config true 49 | end 50 | 51 | ruby_block 'wait-for-sup-test-auth-token-startup' do 52 | block do 53 | raise unless system('hab sup status') 54 | end 55 | retries 30 56 | retry_delay 1 57 | end 58 | 59 | hab_sup 'test-gateway-auth-token' do 60 | license 'accept' 61 | gateway_auth_token 'secret' 62 | listen_http '0.0.0.0:10001' 63 | listen_gossip '0.0.0.0:10000' 64 | notifies :stop, 'hab_sup[test-auth-token]', :before 65 | notifies :delete, 'directory[/hab/sup]', :before 66 | toml_config true 67 | end 68 | 69 | ruby_block 'wait-for-sup-test-gateway-auth-token-startup' do 70 | block do 71 | raise unless system('hab sup status') 72 | end 73 | retries 30 74 | retry_delay 1 75 | end 76 | 77 | hab_sup 'test-gateway-auth-and-auth-token' do 78 | license 'accept' 79 | auth_token 'test' 80 | gateway_auth_token 'secret' 81 | listen_http '0.0.0.0:10001' 82 | listen_gossip '0.0.0.0:10000' 83 | notifies :stop, 'hab_sup[test-gateway-auth-token]', :before 84 | notifies :delete, 'directory[/hab/sup]', :before 85 | toml_config true 86 | end 87 | 88 | ruby_block 'wait-for-sup-test-gateway-auth-and-auth-token-startup' do 89 | block do 90 | raise unless system('hab sup status') 91 | end 92 | retries 30 93 | retry_delay 1 94 | end 95 | 96 | hab_sup 'single_peer' do 97 | license 'accept' 98 | listen_http '0.0.0.0:8999' 99 | listen_gossip '0.0.0.0:8998' 100 | peer '127.0.0.2' 101 | notifies :stop, 'hab_sup[test-gateway-auth-and-auth-token]', :before 102 | notifies :delete, 'directory[/hab/sup]', :before 103 | toml_config true 104 | end 105 | 106 | ruby_block 'wait-for-sup-single_peer-startup' do 107 | block do 108 | raise unless system('hab sup status') 109 | end 110 | retries 30 111 | retry_delay 1 112 | end 113 | 114 | hab_sup 'health_check_interval' do 115 | license 'accept' 116 | health_check_interval 60 117 | listen_http '0.0.0.0:7999' 118 | listen_gossip '0.0.0.0:7998' 119 | notifies :stop, 'hab_sup[single_peer]', :before 120 | notifies :delete, 'directory[/hab/sup]', :before 121 | toml_config true 122 | end 123 | 124 | ruby_block 'wait-for-sup-health_check_interval-startup' do 125 | block do 126 | raise unless system('hab sup status') 127 | end 128 | retries 30 129 | retry_delay 1 130 | end 131 | 132 | hab_sup 'set_file_limit' do 133 | license 'accept' 134 | limit_no_files '65536' 135 | notifies :stop, 'hab_sup[single_peer]', :before 136 | notifies :delete, 'directory[/hab/sup]', :before 137 | toml_config true 138 | end 139 | 140 | ruby_block 'wait-for-sup-set_file_limit-startup' do 141 | block do 142 | raise unless system('hab sup status') 143 | end 144 | retries 30 145 | retry_delay 1 146 | end 147 | 148 | hab_sup 'multiple_peers' do 149 | license 'accept' 150 | peer ['127.0.0.2', '127.0.0.3'] 151 | listen_http '0.0.0.0:7999' 152 | listen_gossip '0.0.0.0:7998' 153 | notifies :stop, 'hab_sup[single_peer]', :before 154 | notifies :delete, 'directory[/hab/sup]', :before 155 | toml_config true 156 | end 157 | 158 | ruby_block 'wait-for-sup-multiple_peers-startup' do 159 | block do 160 | raise unless system('hab sup status') 161 | end 162 | retries 30 163 | retry_delay 1 164 | end 165 | -------------------------------------------------------------------------------- /templates/sup/sup.toml.erb: -------------------------------------------------------------------------------- 1 | # sup.toml 2 | # Used for passing configuration options to the Chef Habitat supervisor 3 | # This file is controlled by the 'habitat' cookbook and should not be modified by hand -- local modifications may be overwritten. 4 | 5 | ### The listen address for the Gossip Gateway 6 | <% if @listen_gossip %> 7 | listen_gossip = "<%= @listen_gossip %>" 8 | <% end %> 9 | 10 | ### Start the supervisor in local mode 11 | # local_gossip_mode = 12 | 13 | ### The listen address for the HTTP Gateway 14 | <% if @listen_http %> 15 | listen_http = "<%= @listen_http %>" 16 | <% end %> 17 | ### Disable the HTTP Gateway completely 18 | # http_disable = 19 | 20 | ### The listen address for the Control Gateway 21 | <% if @listen_ctl %> 22 | listen_ctl = "<%= @listen_ctl %>" 23 | <% end %> 24 | ### The organization the Supervisor and its services are part of 25 | <% if @organization %> 26 | organization = "<%= @organization %>" 27 | <% end %> 28 | ### The listen address of one or more initial peers (IP[:PORT]) 29 | <% if @peer %> 30 | peer = <%= @peer %> 31 | <% end %> 32 | ### Make this Supervisor a permanent peer 33 | <% if @permanent_peer %> 34 | permanent_peer = <%= @permanent_peer %> 35 | <% end %> 36 | ### Watch this file for connecting to the ring 37 | # peer_watch_file = 38 | 39 | ### Cache for creating and searching for encryption keys 40 | # cache_key_path = 41 | 42 | ### The name of the ring used by the Supervisor when running with wire encryption 43 | <% if @ring %> 44 | ring = "<%= @ring %>" 45 | <% end %> 46 | ### Use the package config from this path rather than the package itself 47 | # config_from = 48 | 49 | ### Enable automatic updates for the Supervisor itself 50 | <% if @auto_update %> 51 | auto_update = <%= @auto_update %> 52 | <% end %> 53 | ### The period of time in seconds between Supervisor update checks 54 | # auto_update_period = 55 | 56 | ### The period of time in seconds between service update checks 57 | # service_update_period = 58 | 59 | ### The private key for HTTP Gateway TLS encryption 60 | ### 61 | ### Read the private key from KEY_FILE. This should be an RSA private key or PKCS8-encoded private key in PEM format. 62 | # key_file = 63 | 64 | ### The server certificates for HTTP Gateway TLS encryption 65 | ### 66 | ### Read server certificates from CERT_FILE. This should contain PEM-format certificates in the right order. The first certificate should certify KEY_FILE. The last should be a root CA. 67 | # cert_file = 68 | 69 | ### The CA certificate for HTTP Gateway TLS encryption 70 | ### 71 | ### Read the CA certificate from CA_CERT_FILE. This should contain PEM-format certificate that can be used to validate client requests 72 | # ca_cert_file = 73 | 74 | ### Load a Habitat package as part of the Supervisor startup 75 | ### 76 | ### The package can be specified by a package identifier (ex: core/redis) or filepath to a Habitat artifact (ex: /home/core-redis-3.0.7-21120102031201-x86_64-linux.hart). 77 | # pkg_ident_or_artifact = 78 | 79 | ### Verbose output showing file and line/column numbers 80 | # verbose = 81 | 82 | ### Turn ANSI color off 83 | # no_color = 84 | 85 | ### Use structured JSON logging for the Supervisor 86 | ### 87 | ### This option also sets NO_COLOR. 88 | # json_logging = 89 | 90 | ### The IPv4 address to use as the `sys.ip` template variable 91 | ### 92 | ### If this argument is not set, the supervisor tries to dynamically determine an IP address. If that fails, the supervisor defaults to using `127.0.0.1`. 93 | # sys_ip_address = 94 | 95 | ### The name of the application for event stream purposes 96 | ### 97 | ### This will be attached to all events generated by this Supervisor. 98 | <% if @event_stream_application %> 99 | event_stream_application = "<%= @event_stream_application %>" 100 | <% end %> 101 | ### The name of the environment for event stream purposes 102 | ### 103 | ### This will be attached to all events generated by this Supervisor. 104 | <% if @event_stream_environment %> 105 | event_stream_environment = "<%= @event_stream_environment %>" 106 | <% end %> 107 | ### Event stream connection timeout before exiting the Supervisor 108 | ### 109 | ### Set to '0' to immediately start the Supervisor and continue running regardless of the initial connection status. 110 | # event_stream_connect_timeout = 111 | 112 | ### The event stream connection url used to send events to Chef Automate 113 | ### 114 | ### This enables the event stream and requires EVENT_STREAM_APPLICATION, EVENT_STREAM_ENVIRONMENT, and EVENT_STREAM_TOKEN also be set. 115 | <% if @event_stream_url %> 116 | event_stream_url = "<%= @event_stream_url %>" 117 | <% end %> 118 | ### The name of the site where this Supervisor is running for event stream purposes 119 | <% if @event_stream_site %> 120 | event_stream_site = "<%= @event_stream_site %>" 121 | <% end %> 122 | ### The authentication token for connecting the event stream to Chef Automate 123 | <% if @event_stream_token %> 124 | event_stream_token = "<%= @event_stream_token %>" 125 | <% end %> 126 | ### An arbitrary key-value pair to add to each event generated by this Supervisor 127 | # event_meta = [] 128 | 129 | ### The path to Chef Automate's event stream certificate used to establish a TLS connection 130 | ### 131 | ### The certificate should be in PEM format. 132 | <% if @event_stream_server_certificate %> 133 | event_stream_server_certificate = "<%= @event_stream_server_certificate %>" 134 | <% end %> 135 | ### Automatically cleanup old packages 136 | ### 137 | ### The Supervisor will automatically cleanup old packages only keeping the KEEP_LATEST_PACKAGES latest packages. If this argument is not specified, no automatic package cleanup is performed. 138 | <% if @keep_latest_packages %> 139 | keep_latest_packages = "<%= @keep_latest_packages %>" 140 | <% end %> 141 | ### Receive updates from the specified release channel 142 | # channel = 143 | 144 | ### Specify an alternate Builder endpoint. If not specified, the value will be taken from the HAB_BLDR_URL environment variable if defined. (default: https://bldr.habitat.sh) 145 | <% if @bldr_url %> 146 | bldr_url = "<%= @bldr_url %>" 147 | <% end %> 148 | ### The service group with shared config and topology 149 | # group = 150 | 151 | ### Service topology 152 | # topology = 153 | 154 | ### The update strategy 155 | # strategy = 156 | 157 | ### The condition dictating when this service should update 158 | ### 159 | ### latest: Runs the latest package that can be found in the configured channel and local packages. 160 | ### 161 | ### track-channel: Always run what is at the head of a given channel. This enables service rollback where demoting a package from a channel will cause the package to rollback to an older version of the package. A ramification of enabling this condition is packages newer than the package at the head of the channel will be automatically uninstalled during a service rollback. 162 | <% if @update_condition %> 163 | update_condition = "<%= @update_condition %>" 164 | <% end %> 165 | ### One or more service groups to bind to a configuration 166 | # bind = [] 167 | 168 | ### Governs how the presence or absence of binds affects service startup 169 | ### 170 | ### strict: blocks startup until all binds are present. 171 | # binding_mode = 172 | 173 | ### The interval in seconds on which to run health checks 174 | # health_check_interval = 175 | 176 | ### The delay in seconds after sending the shutdown signal to wait before killing the service process 177 | ### 178 | ### The default value can be set in the packages plan file. 179 | # shutdown_timeout = 180 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/templates/sup/sup.toml.erb: -------------------------------------------------------------------------------- 1 | # sup.toml 2 | # Used for passing configuration options to the Chef Habitat supervisor 3 | # This file is controlled by the 'habitat' cookbook and should not be modified by hand -- local modifications may be overwritten. 4 | 5 | ### The listen address for the Gossip Gateway 6 | <% if @listen_gossip %> 7 | listen_gossip = "<%= @listen_gossip %>" 8 | <% end %> 9 | 10 | ### Start the supervisor in local mode 11 | # local_gossip_mode = 12 | 13 | ### The listen address for the HTTP Gateway 14 | <% if @listen_http %> 15 | listen_http = "<%= @listen_http %>" 16 | <% end %> 17 | ### Disable the HTTP Gateway completely 18 | # http_disable = 19 | 20 | ### The listen address for the Control Gateway 21 | <% if @listen_ctl %> 22 | listen_ctl = "<%= @listen_ctl %>" 23 | <% end %> 24 | ### The organization the Supervisor and its services are part of 25 | <% if @organization %> 26 | organization = "<%= @organization %>" 27 | <% end %> 28 | ### The listen address of one or more initial peers (IP[:PORT]) 29 | <% if @peer %> 30 | peer = <%= @peer %> 31 | <% end %> 32 | ### Make this Supervisor a permanent peer 33 | <% if @permanent_peer %> 34 | permanent_peer = <%= @permanent_peer %> 35 | <% end %> 36 | ### Watch this file for connecting to the ring 37 | # peer_watch_file = 38 | 39 | ### Cache for creating and searching for encryption keys 40 | # cache_key_path = 41 | 42 | ### The name of the ring used by the Supervisor when running with wire encryption 43 | <% if @ring %> 44 | ring = "<%= @ring %>" 45 | <% end %> 46 | ### Use the package config from this path rather than the package itself 47 | # config_from = 48 | 49 | ### Enable automatic updates for the Supervisor itself 50 | <% if @auto_update %> 51 | auto_update = <%= @auto_update %> 52 | <% end %> 53 | ### The period of time in seconds between Supervisor update checks 54 | # auto_update_period = 55 | 56 | ### The period of time in seconds between service update checks 57 | # service_update_period = 58 | 59 | ### The private key for HTTP Gateway TLS encryption 60 | ### 61 | ### Read the private key from KEY_FILE. This should be an RSA private key or PKCS8-encoded private key in PEM format. 62 | # key_file = 63 | 64 | ### The server certificates for HTTP Gateway TLS encryption 65 | ### 66 | ### Read server certificates from CERT_FILE. This should contain PEM-format certificates in the right order. The first certificate should certify KEY_FILE. The last should be a root CA. 67 | # cert_file = 68 | 69 | ### The CA certificate for HTTP Gateway TLS encryption 70 | ### 71 | ### Read the CA certificate from CA_CERT_FILE. This should contain PEM-format certificate that can be used to validate client requests 72 | # ca_cert_file = 73 | 74 | ### Load a Habitat package as part of the Supervisor startup 75 | ### 76 | ### The package can be specified by a package identifier (ex: core/redis) or filepath to a Habitat artifact (ex: /home/core-redis-3.0.7-21120102031201-x86_64-linux.hart). 77 | # pkg_ident_or_artifact = 78 | 79 | ### Verbose output showing file and line/column numbers 80 | # verbose = 81 | 82 | ### Turn ANSI color off 83 | # no_color = 84 | 85 | ### Use structured JSON logging for the Supervisor 86 | ### 87 | ### This option also sets NO_COLOR. 88 | # json_logging = 89 | 90 | ### The IPv4 address to use as the `sys.ip` template variable 91 | ### 92 | ### If this argument is not set, the supervisor tries to dynamically determine an IP address. If that fails, the supervisor defaults to using `127.0.0.1`. 93 | # sys_ip_address = 94 | 95 | ### The name of the application for event stream purposes 96 | ### 97 | ### This will be attached to all events generated by this Supervisor. 98 | <% if @event_stream_application %> 99 | event_stream_application = "<%= @event_stream_application %>" 100 | <% end %> 101 | ### The name of the environment for event stream purposes 102 | ### 103 | ### This will be attached to all events generated by this Supervisor. 104 | <% if @event_stream_environment %> 105 | event_stream_environment = "<%= @event_stream_environment %>" 106 | <% end %> 107 | ### Event stream connection timeout before exiting the Supervisor 108 | ### 109 | ### Set to '0' to immediately start the Supervisor and continue running regardless of the initial connection status. 110 | # event_stream_connect_timeout = 111 | 112 | ### The event stream connection url used to send events to Chef Automate 113 | ### 114 | ### This enables the event stream and requires EVENT_STREAM_APPLICATION, EVENT_STREAM_ENVIRONMENT, and EVENT_STREAM_TOKEN also be set. 115 | <% if @event_stream_url %> 116 | event_stream_url = "<%= @event_stream_url %>" 117 | <% end %> 118 | ### The name of the site where this Supervisor is running for event stream purposes 119 | <% if @event_stream_site %> 120 | event_stream_site = "<%= @event_stream_site %>" 121 | <% end %> 122 | ### The authentication token for connecting the event stream to Chef Automate 123 | <% if @event_stream_token %> 124 | event_stream_token = "<%= @event_stream_token %>" 125 | <% end %> 126 | ### An arbitrary key-value pair to add to each event generated by this Supervisor 127 | # event_meta = [] 128 | 129 | ### The path to Chef Automate's event stream certificate used to establish a TLS connection 130 | ### 131 | ### The certificate should be in PEM format. 132 | <% if @event_stream_server_certificate %> 133 | event_stream_server_certificate = "<%= @event_stream_server_certificate %>" 134 | <% end %> 135 | ### Automatically cleanup old packages 136 | ### 137 | ### The Supervisor will automatically cleanup old packages only keeping the KEEP_LATEST_PACKAGES latest packages. If this argument is not specified, no automatic package cleanup is performed. 138 | <% if @keep_latest_packages %> 139 | keep_latest_packages = "<%= @keep_latest_packages %>" 140 | <% end %> 141 | ### Receive updates from the specified release channel 142 | # channel = 143 | 144 | ### Specify an alternate Builder endpoint. If not specified, the value will be taken from the HAB_BLDR_URL environment variable if defined. (default: https://bldr.habitat.sh) 145 | <% if @bldr_url %> 146 | bldr_url = "<%= @bldr_url %>" 147 | <% end %> 148 | ### The service group with shared config and topology 149 | # group = 150 | 151 | ### Service topology 152 | # topology = 153 | 154 | ### The update strategy 155 | # strategy = 156 | 157 | ### The condition dictating when this service should update 158 | ### 159 | ### latest: Runs the latest package that can be found in the configured channel and local packages. 160 | ### 161 | ### track-channel: Always run what is at the head of a given channel. This enables service rollback where demoting a package from a channel will cause the package to rollback to an older version of the package. A ramification of enabling this condition is packages newer than the package at the head of the channel will be automatically uninstalled during a service rollback. 162 | <% if @update_condition %> 163 | update_condition = "<%= @update_condition %>" 164 | <% end %> 165 | ### One or more service groups to bind to a configuration 166 | # bind = [] 167 | 168 | ### Governs how the presence or absence of binds affects service startup 169 | ### 170 | ### strict: blocks startup until all binds are present. 171 | # binding_mode = 172 | 173 | ### The interval in seconds on which to run health checks 174 | # health_check_interval = 175 | 176 | ### The delay in seconds after sending the shutdown signal to wait before killing the service process 177 | ### 178 | ### The default value can be set in the packages plan file. 179 | # shutdown_timeout = 180 | -------------------------------------------------------------------------------- /spec/unit/sup_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::sup' do 4 | context 'when compiling the sup recipe for chefspec' do 5 | shared_examples_for 'any platform' do 6 | it 'runs hab sup' do 7 | expect(chef_run).to run_hab_sup('tester') 8 | end 9 | 10 | it 'runs hab sup with a custom org' do 11 | expect(chef_run).to run_hab_sup('test-options') 12 | .with( 13 | listen_http: '0.0.0.0:9999', 14 | listen_gossip: '0.0.0.0:9998' 15 | ) 16 | end 17 | 18 | it 'runs hab sup with a auth options' do 19 | expect(chef_run).to run_hab_sup('test-auth-token') 20 | .with( 21 | listen_http: '0.0.0.0:10001', 22 | listen_gossip: '0.0.0.0:10000', 23 | auth_token: 'test' 24 | ) 25 | end 26 | 27 | it 'runs hab sup with a gateway auth token' do 28 | expect(chef_run).to run_hab_sup('test-gateway-auth-token') 29 | .with( 30 | listen_http: '0.0.0.0:10001', 31 | listen_gossip: '0.0.0.0:10000', 32 | gateway_auth_token: 'secret' 33 | ) 34 | end 35 | 36 | it 'run hab sup with a single peer' do 37 | expect(chef_run).to run_hab_sup('single_peer').with( 38 | peer: ['127.0.0.2'] 39 | ) 40 | end 41 | 42 | it 'runs hab sup with multiple peers' do 43 | expect(chef_run).to run_hab_sup('multiple_peers') 44 | .with( 45 | peer: ['127.0.0.2', '127.0.0.3'] 46 | ) 47 | end 48 | # Commenting out 20201030 - test works locally but failing in GitHub delivery 49 | # it 'handles installing hab for us' do 50 | # expect(chef_run).to install_hab_install('tester') 51 | # end 52 | 53 | it 'installs hab-sup package' do 54 | expect(chef_run).to install_hab_package('core/hab-sup') 55 | end 56 | 57 | it 'installs hab-launcher package' do 58 | expect(chef_run).to install_hab_package('core/hab-launcher') 59 | end 60 | end 61 | 62 | context 'a Systemd platform' do 63 | cached(:chef_run) do 64 | ChefSpec::ServerRunner.new( 65 | step_into: ['hab_sup'], 66 | platform: 'ubuntu', 67 | version: '16.04' 68 | ).converge(described_recipe) 69 | end 70 | 71 | before(:each) do 72 | allow(Chef::Platform::ServiceHelpers).to receive(:service_resource_providers).and_return([:systemd]) 73 | end 74 | 75 | it_behaves_like 'any platform' 76 | 77 | it 'runs hab sup with a set file limit' do 78 | expect(chef_run).to run_hab_sup('set_file_limit') 79 | .with( 80 | limit_no_files: '65536' 81 | ) 82 | end 83 | 84 | it 'renders a systemd_unit file with default options' do 85 | expect(chef_run).to create_systemd_unit('hab-sup.service').with( 86 | content: { 87 | Unit: { 88 | Description: 'The Habitat Supervisor', 89 | }, 90 | Service: { 91 | Environment: [], 92 | ExecStart: '/bin/hab sup run --listen-gossip 0.0.0.0:7998 --listen-http 0.0.0.0:7999 --peer 127.0.0.2 --peer 127.0.0.3', 93 | ExecStop: '/bin/hab sup term', 94 | Restart: 'on-failure', 95 | }, 96 | Install: { 97 | WantedBy: 'default.target', 98 | }, 99 | } 100 | ) 101 | end 102 | 103 | it 'starts the hab-sup service' do 104 | expect(chef_run).to start_service('hab-sup') 105 | expect(chef_run.service('hab-sup')) 106 | .to subscribe_to('systemd_unit[hab-sup.service]') 107 | .on(:restart).delayed 108 | expect(chef_run.service('hab-sup')) 109 | .to subscribe_to('hab_package[core/hab-sup]') 110 | .on(:restart).delayed 111 | expect(chef_run.service('hab-sup')) 112 | .to subscribe_to('hab_package[core/hab-launcher]') 113 | .on(:restart).delayed 114 | end 115 | end 116 | 117 | context 'an Upstart platform' do 118 | cached(:chef_run) do 119 | # cookstyle: disable ChefDeprecations/DeprecatedChefSpecPlatform 120 | ChefSpec::ServerRunner.new( 121 | step_into: ['hab_sup'], 122 | platform: 'ubuntu', 123 | version: '14.04' 124 | ).converge(described_recipe) 125 | end 126 | 127 | before(:each) do 128 | allow(Chef::Platform::ServiceHelpers).to receive(:service_resource_providers).and_return([:upstart]) 129 | end 130 | 131 | it_behaves_like 'any platform' 132 | 133 | it 'renders a upstart config with default options' do 134 | expect(chef_run).to create_template('/etc/init/hab-sup.conf').with( 135 | source: 'upstart/hab-sup.conf.erb', 136 | cookbook: 'habitat', 137 | owner: 'root', 138 | group: 'root', 139 | mode: '0644', 140 | variables: { 141 | exec_start_options: '--listen-gossip 0.0.0.0:7998 --listen-http 0.0.0.0:7999 --peer 127.0.0.2 --peer 127.0.0.3', 142 | auth_token: nil, 143 | gateway_auth_token: nil, 144 | } 145 | ) 146 | end 147 | 148 | it 'starts the hab-sup service' do 149 | expect(chef_run).to start_service('hab-sup') 150 | .with(provider: Chef::Provider::Service::Upstart) 151 | expect(chef_run.service('hab-sup')) 152 | .to subscribe_to('template[/etc/init/hab-sup.conf]') 153 | .on(:restart).delayed 154 | expect(chef_run.service('hab-sup')) 155 | .to subscribe_to('hab_package[core/hab-sup]') 156 | .on(:restart).delayed 157 | expect(chef_run.service('hab-sup')) 158 | .to subscribe_to('hab_package[core/hab-launcher]') 159 | .on(:restart).delayed 160 | end 161 | end 162 | 163 | context 'a Sysvinit platform' do 164 | cached(:chef_run) do 165 | ChefSpec::ServerRunner.new( 166 | step_into: ['hab_sup'], 167 | platform: 'redhat', 168 | version: '6' 169 | ).converge(described_recipe) 170 | end 171 | 172 | before(:each) do 173 | allow(Chef::Platform::ServiceHelpers).to receive(:service_resource_providers).and_return([]) 174 | end 175 | 176 | it_behaves_like 'any platform' 177 | 178 | it 'renders an init script with default options' do 179 | expect(chef_run).to create_template('/etc/init.d/hab-sup').with( 180 | source: 'sysvinit/hab-sup.erb', 181 | cookbook: 'habitat', 182 | owner: 'root', 183 | group: 'root', 184 | mode: '0755', 185 | variables: { 186 | name: 'hab-sup', 187 | exec_start_options: '--listen-gossip 0.0.0.0:7998 --listen-http 0.0.0.0:7999 --peer 127.0.0.2 --peer 127.0.0.3', 188 | auth_token: nil, 189 | gateway_auth_token: nil, 190 | } 191 | ) 192 | end 193 | 194 | it 'starts the hab-sup service' do 195 | expect(chef_run).to start_service('hab-sup') 196 | expect(chef_run.service('hab-sup')) 197 | .to subscribe_to('template[/etc/init.d/hab-sup]') 198 | .on(:restart).delayed 199 | expect(chef_run.service('hab-sup')) 200 | .to subscribe_to('hab_package[core/hab-sup]') 201 | .on(:restart).delayed 202 | expect(chef_run.service('hab-sup')) 203 | .to subscribe_to('hab_package[core/hab-launcher]') 204 | .on(:restart).delayed 205 | end 206 | end 207 | end 208 | end 209 | -------------------------------------------------------------------------------- /resources/install.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Thom May () 3 | # Copyright:: 2017-2018 Chef Software, Inc. 4 | # 5 | # Copyright:: Copyright (c) 2016 Chef Software, Inc. 6 | # License:: Apache License, Version 2.0 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | require 'chef/http/simple' 21 | 22 | resource_name :hab_install 23 | provides :hab_install 24 | 25 | property :name, String, default: '' 26 | # The following are only used on *nix 27 | property :install_url, String, default: 'https://raw.githubusercontent.com/habitat-sh/habitat/master/components/hab/install.sh' 28 | property :bldr_url, String 29 | property :create_user, [true, false], default: true 30 | property :tmp_dir, String 31 | property :license, String, equal_to: ['accept'] 32 | property :hab_version, String 33 | 34 | action :install do 35 | if ::File.exist?(hab_path) 36 | cmd = shell_out!([hab_path, '--version'].flatten.compact.join(' ')) 37 | version = %r{hab (\d*\.\d*\.\d[^\/]*)}.match(cmd.stdout)[1] 38 | return if version == new_resource.hab_version 39 | end 40 | 41 | if platform_family?('windows') 42 | # Retrieve version information 43 | uri = 'https://packages.chef.io/files' 44 | package_name = 'hab-x86_64-windows' 45 | zipfile = "#{Chef::Config[:file_cache_path]}/#{package_name}.zip" 46 | 47 | # TODO: Figure out how to properly validate the shasum for windows. Doesn't seem it's published 48 | # as a .sha265sum like for the linux .tar.gz 49 | download = "#{uri}/stable/habitat/latest/hab-x86_64-windows.zip" 50 | 51 | remote_file zipfile do 52 | source download 53 | end 54 | 55 | if Chef::VERSION.to_i < 15 56 | chef_gem 'rubyzip' do 57 | compile_time false 58 | version '< 2.0.0' 59 | end 60 | ruby_block "#{package_name}.zip" do 61 | block do 62 | require 'zip' 63 | Zip::File.open(zipfile) do |zip_file| 64 | zip_file.each do |f| 65 | fpath = "#{Chef::Config[:file_cache_path]}/habitat/" + f.name 66 | zip_file.extract(f, fpath) # unless ::File.exist?(fpath) 67 | end 68 | end 69 | end 70 | action :run 71 | not_if { ::Dir.exist?('c:\habitat') } 72 | end 73 | else 74 | archive_file "#{package_name}.zip" do 75 | path zipfile 76 | destination "#{Chef::Config[:file_cache_path]}/habitat" 77 | action :extract 78 | not_if { ::Dir.exist?('c:\habitat') } 79 | end 80 | end 81 | 82 | directory 'c:\habitat' do 83 | notifies :run, 'powershell_script[installing from archive]', :immediately 84 | end 85 | 86 | powershell_script 'installing from archive' do 87 | code <<-EOH 88 | Move-Item -Path #{Chef::Config[:file_cache_path]}/habitat/hab-*/* -Destination C:/habitat -Force 89 | EOH 90 | action :nothing 91 | end 92 | 93 | # TODO: This won't self heal if missing until the next upgrade 94 | if Chef::VERSION.to_i < 14 95 | env 'PATH_c-habitat' do 96 | key_name 'PATH' 97 | delim ';' # this was missing 98 | value 'C:\habitat' 99 | action :modify 100 | end 101 | else 102 | windows_path 'C:\habitat' do 103 | action :add 104 | end 105 | end 106 | else 107 | package %w(curl tar gzip) 108 | 109 | if new_resource.create_user 110 | group 'hab' 111 | 112 | user 'hab' do 113 | gid 'hab' 114 | system true 115 | end 116 | end 117 | 118 | remote_file ::File.join(Chef::Config[:file_cache_path], 'hab-install.sh') do 119 | source new_resource.install_url 120 | sensitive true 121 | end 122 | 123 | execute 'installing with hab-install.sh' do 124 | command hab_command 125 | environment( 126 | { 127 | 'HAB_BLDR_URL' => 'bldr_url', 128 | 'TMPDIR' => 'tmp_dir', 129 | }.each_with_object({}) do |(var, property), env| 130 | env[var] = new_resource.send(property.to_sym) if new_resource.send(property.to_sym) 131 | end 132 | ) 133 | end 134 | end 135 | execute 'hab license accept' if new_resource.license == 'accept' 136 | end 137 | 138 | # TODO: Work out how to unfreeze the versions safely 139 | action :upgrade do 140 | if platform_family?('windows') 141 | # Retrieve version information 142 | uri = 'https://packages.chef.io/files' 143 | package_name = 'hab-x86_64-windows' 144 | zipfile = "#{Chef::Config[:file_cache_path]}/#{package_name}.zip" 145 | 146 | # TODO: Figure out how to properly validate the shasum for windows. Doesn't seem it's published 147 | # as a .sha265sum like for the linux .tar.gz 148 | download = "#{uri}/stable/habitat/latest/hab-x86_64-windows.zip" 149 | 150 | remote_file zipfile do 151 | source download 152 | end 153 | 154 | if Chef::VERSION.to_i < 15 155 | ruby_block "#{package_name}.zip" do 156 | block do 157 | require 'zip' 158 | Zip::File.open(zipfile) do |zip_file| 159 | zip_file.each do |f| 160 | fpath = "#{Chef::Config[:file_cache_path]}/habitat/" + f.name 161 | zip_file.extract(f, fpath) # unless ::File.exist?(fpath) 162 | end 163 | end 164 | end 165 | action :run 166 | end 167 | else 168 | archive_file "#{package_name}.zip" do 169 | path zipfile 170 | destination "#{Chef::Config[:file_cache_path]}/habitat" 171 | action :extract 172 | end 173 | end 174 | 175 | powershell_script 'installing from archive' do 176 | code <<-EOH 177 | Move-Item -Path #{Chef::Config[:file_cache_path]}/habitat/hab-*/* -Destination C:/habitat -Force 178 | EOH 179 | end 180 | 181 | # TODO: This won't self heal if missing until the next upgrade 182 | if Chef::VERSION.to_i < 14 183 | env 'PATH_c-habitat' do 184 | key_name 'PATH' 185 | delim ';' # this was missing 186 | value 'C:\habitat' 187 | action :modify 188 | end 189 | else 190 | windows_path 'C:\habitat' do 191 | action :add 192 | end 193 | end 194 | else 195 | remote_file ::File.join(Chef::Config[:file_cache_path], 'hab-install.sh') do 196 | source new_resource.install_url 197 | sensitive true 198 | end 199 | 200 | execute 'installing with hab-install.sh' do 201 | command hab_command 202 | environment( 203 | { 204 | 'HAB_BLDR_URL' => 'bldr_url', 205 | 'TMPDIR' => 'tmp_dir', 206 | }.each_with_object({}) do |(var, property), env| 207 | env[var] = new_resource.send(property.to_sym) if new_resource.send(property.to_sym) 208 | end 209 | ) 210 | not_if { ::File.exist?('/bin/hab') } 211 | end 212 | end 213 | end 214 | 215 | action_class do 216 | include Habitat::Shared 217 | 218 | def hab_path 219 | if platform_family?('mac_os_x') 220 | '/usr/local/bin/hab' 221 | elsif platform_family?('windows') 222 | 'C:/habitat/hab.exe' 223 | else 224 | '/bin/hab' 225 | end 226 | end 227 | 228 | def hab_command 229 | cmd = "bash #{Chef::Config[:file_cache_path]}/hab-install.sh" 230 | cmd << " -v #{new_resource.hab_version} " if new_resource.hab_version 231 | cmd << ' -t x86_64-linux-kernel2' if node['kernel']['release'].to_i < 3 232 | cmd 233 | end 234 | end 235 | -------------------------------------------------------------------------------- /libraries/provider_hab_package.rb: -------------------------------------------------------------------------------- 1 | # Copyright:: 2016-2018, Chef Software Inc. 2 | # License:: Apache License, Version 2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | require 'chef/provider/package' 18 | require 'chef/http/simple' 19 | require 'chef/json_compat' 20 | require 'chef/exceptions' 21 | 22 | # Bring in needed shared methods 23 | include Habitat::Shared 24 | 25 | class Chef 26 | class Provider 27 | class Package 28 | class Hart < Chef::Provider::Package 29 | use_multipackage_api 30 | 31 | provides :hab_package 32 | 33 | # 34 | # TODO list for `hab pkg`: 35 | # 36 | # kinda sorta analogous to: 37 | # apt-cache search 38 | # dpkg -l 39 | # dpkg -r / dpkg -P (without depsolving?) 40 | # apt-get remove/purge (with depsolving?) 41 | # 42 | # - hab pkg search ruby 43 | # - hab pkg info lamont-granquist/ruby 44 | # - hab pkg info lamont-granquist/ruby/2.3.1 45 | # - hab pkg info lamont-granquist/ruby/2.3.1/20160101010101 46 | # ^^^^^ these will all need client-side caches for the "universe" of the depot 47 | # - hab pkg uninstall lamont-granquist/ruby 48 | # - hab pkg uninstall lamont-granquist/ruby/2.3.1 49 | # - hab pkg uninstall lamont-granquist/ruby/2.3.1/20160101010101 50 | # - hab pkg list (localinfo?) lamont-granquist/ruby 51 | # - hab pkg list (localinfo?) lamont-granquist/ruby/2.3.1 52 | # - hab pkg list (localinfo?) lamont-granquist/ruby/2.3.1/20160101010101 53 | # ^^^^^ need a better name 54 | # 55 | # Probably also want to support installation of local packages 56 | # Service resource supports running services from locally installed packages 57 | # But we provide no way to handle installation 58 | 59 | def load_current_resource 60 | @current_resource = Chef::Resource::HartPackage.new(new_resource.name) 61 | current_resource.package_name(strip_version(new_resource.package_name)) 62 | 63 | @candidate_version = candidate_versions 64 | current_resource.version(current_versions) 65 | 66 | current_resource 67 | end 68 | 69 | def install_package(names, versions) 70 | names.zip(versions).map do |n, v| 71 | opts = ['pkg', 'install', '--channel', new_resource.channel, '--url', new_resource.bldr_url] 72 | opts += ['--auth', new_resource.auth_token] if new_resource.auth_token 73 | opts += ["#{strip_version(n)}/#{v}", new_resource.options] 74 | opts += ['--binlink'] if new_resource.binlink 75 | opts += ['--force'] if new_resource.binlink.eql? :force 76 | hab(opts) 77 | end 78 | end 79 | 80 | alias_method :upgrade_package, :install_package 81 | 82 | def remove_package(names, versions) 83 | # raise 'It is too dangerous to :remove packages with the hab_package resource right now. This functionality should be deferred to the hab cli.' 84 | names.zip(versions).map do |n, v| 85 | opts = %w(pkg uninstall) 86 | opts += ['--keep-latest', new_resource.keep_latest ] if new_resource.keep_latest 87 | opts += ["#{strip_version(n).chomp('/')}#{v}", new_resource.options] 88 | opts += ['--exclude'] if new_resource.exclude 89 | opts += ['--no-deps'] if new_resource.no_deps 90 | hab(opts) 91 | # action :remove 92 | end 93 | end 94 | end 95 | 96 | alias_method :purge_package, :remove_package 97 | 98 | private 99 | 100 | def validate_name!(name) 101 | raise ArgumentError, "package name must be specified as 'origin/name', use the 'version' property to specify a version" unless name.squeeze('/').count('/') < 2 102 | end 103 | 104 | def strip_version(name) 105 | validate_name!(name) 106 | n = name.squeeze('/').chomp('/').sub(%r{^\/}, '') 107 | n = n[0..(n.rindex('/') - 1)] while n.count('/') >= 2 108 | n 109 | end 110 | 111 | def platform_target 112 | if platform_family?('windows') 113 | 'target=x86_64-windows' 114 | elsif node['kernel']['release'].to_i < 3 115 | 'target=x86_64-linux-kernel2' 116 | else 117 | '' 118 | end 119 | end 120 | 121 | def depot_package(name, version = nil) 122 | @depot_package ||= {} 123 | @depot_package[name] ||= 124 | begin 125 | origin, pkg_name = name.split('/') 126 | name_version = [pkg_name, version].compact.join('/').squeeze('/').chomp('/').sub(%r{^\/}, '') 127 | url = if new_resource.bldr_url.include?('/v1/') 128 | "#{new_resource.bldr_url.chomp('/')}/depot/channels/#{origin}/#{new_resource.channel}/pkgs/#{name_version}" 129 | else 130 | "#{new_resource.bldr_url.chomp('/')}/v1/depot/channels/#{origin}/#{new_resource.channel}/pkgs/#{name_version}" 131 | end 132 | url << '/latest' unless name_version.count('/') >= 2 133 | url << "?#{platform_target}" unless platform_target.empty? 134 | 135 | headers = {} 136 | headers['Authorization'] = "Bearer #{new_resource.auth_token}" if new_resource.auth_token 137 | 138 | Chef::JSONCompat.parse(http.get(url, headers)) 139 | rescue Net::HTTPServerException 140 | nil 141 | end 142 | end 143 | 144 | def package_version(name, version = nil) 145 | p = depot_package(name, version) 146 | "#{p['ident']['version']}/#{p['ident']['release']}" unless p.nil? 147 | end 148 | 149 | def http 150 | # FIXME: use SimpleJSON when the depot mime-type is fixed 151 | @http ||= Chef::HTTP::Simple.new(new_resource.bldr_url.to_s) 152 | end 153 | 154 | def candidate_versions 155 | package_name_array.zip(new_version_array).map do |n, v| 156 | package_version(n, v) 157 | end 158 | end 159 | 160 | def current_versions 161 | package_name_array.map do |n| 162 | installed_version(n) 163 | end 164 | end 165 | 166 | def installed_version(ident) 167 | hab('pkg', 'path', ident).stdout.chomp.split(platform_family?('windows') ? '\\' : '/')[-2..-1].join('/') 168 | rescue Mixlib::ShellOut::ShellCommandFailed 169 | nil 170 | end 171 | 172 | # This is used by the superclass Chef::Provider::Package 173 | def version_requirement_satisfied?(current_version, new_version) 174 | return false if new_version.nil? || current_version.nil? 175 | 176 | nv_parts = new_version.squeeze('/').split('/') 177 | 178 | if nv_parts.count < 2 179 | current_version.squeeze('/').split('/')[0] == new_version.squeeze('/') 180 | else 181 | current_version.squeeze('/') == new_resource.version.squeeze('/') 182 | end 183 | end 184 | 185 | # This is used by the superclass Chef::Provider::Package 186 | def version_compare(v1, v2) 187 | return unless Chef::Provider::Package.methods.include?(:version_compare) 188 | 189 | # Convert the package version (X.Y.Z/DATE) into a version that Mixlib::Versioning understands (X.Y.Z+DATE) 190 | hab_v1 = Mixlib::Versioning.parse(v1.tr('/', '+')) 191 | hab_v2 = Mixlib::Versioning.parse(v2.tr('/', '+')) 192 | 193 | hab_v1 <=> hab_v2 194 | end 195 | end 196 | end 197 | end 198 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/service.rb: -------------------------------------------------------------------------------- 1 | hab_sup 'default' do 2 | hab_channel 'stable' 3 | license 'accept' 4 | gateway_auth_token 'secret' 5 | end 6 | 7 | ruby_block 'wait-for-sup-default-startup' do 8 | block do 9 | raise unless system('hab sup status') 10 | end 11 | retries 30 12 | retry_delay 1 13 | end 14 | 15 | hab_package 'core/jq-static' do 16 | binlink true 17 | end 18 | 19 | # Test 1: Load Service (memcached) 20 | hab_service 'core/memcached' do 21 | gateway_auth_token 'secret' 22 | end 23 | 24 | # Test 2: Load, then Unload Service (nginx) 25 | hab_service 'core/nginx' do 26 | gateway_auth_token 'secret' 27 | end 28 | 29 | # Wait for load before attempting unload 30 | ruby_block 'wait-for-nginx-load' do 31 | block do 32 | raise 'nginx not loaded' unless system 'hab svc status core/nginx' 33 | end 34 | retries 5 35 | retry_delay 10 36 | action :nothing 37 | subscribes :run, 'hab_service[core/nginx]', :immediately 38 | end 39 | ruby_block 'wait-for-nginx-up' do 40 | block do 41 | raise 'nginx not loaded' unless `hab svc status core/nginx`.match(/standalone\s+up\s+up/) 42 | end 43 | retries 5 44 | retry_delay 10 45 | action :nothing 46 | subscribes :run, 'ruby_block[wait-for-nginx-load]', :immediately 47 | end 48 | 49 | hab_service 'core/nginx unload' do 50 | service_name 'core/nginx' 51 | gateway_auth_token 'secret' 52 | action :unload 53 | end 54 | 55 | # Test 3: Load, then stop service (redis) 56 | hab_service 'core/redis' do 57 | strategy :rolling 58 | topology :standalone 59 | update_condition 'latest' 60 | channel :stable 61 | gateway_auth_token 'secret' 62 | end 63 | 64 | # We need this sleep to let redis start and for the hab supervisor to 65 | # recognize this and write the state file out otherwise our functional 66 | # tests fail. 67 | ruby_block 'wait-for-redis-load' do 68 | block do 69 | sleep 10 70 | raise 'redis not loaded' unless system 'hab svc status core/redis' 71 | end 72 | retries 5 73 | retry_delay 10 74 | action :nothing 75 | subscribes :run, 'hab_service[core/redis]', :immediately 76 | end 77 | ruby_block 'wait-for-redis-started' do 78 | block do 79 | sleep 10 80 | raise 'redis not started' unless `hab svc status core/redis`.match(/standalone\s+up\s+up/) 81 | end 82 | retries 5 83 | retry_delay 10 84 | action :nothing 85 | subscribes :run, 'ruby_block[wait-for-redis-load]', :immediately 86 | end 87 | 88 | hab_service 'core/redis stop' do 89 | gateway_auth_token 'secret' 90 | service_name 'core/redis' 91 | action :stop 92 | end 93 | 94 | ruby_block 'wait-for-redis-stopped' do 95 | block do 96 | sleep 10 97 | raise 'redis not stopped' unless `hab svc status core/redis`.match(/standalone\s+down\s+down/) 98 | end 99 | retries 5 100 | retry_delay 10 101 | action :nothing 102 | subscribes :run, 'hab_service[core/redis stop]', :immediately 103 | end 104 | 105 | hab_service 'core/redis start' do 106 | strategy :rolling 107 | topology :standalone 108 | service_name 'core/redis' 109 | update_condition 'latest' 110 | channel :stable 111 | gateway_auth_token 'secret' 112 | action :start 113 | end 114 | 115 | # Test 4: Full Identifier Test (grafana/6.4.3) 116 | hab_service 'core/grafana full identifier' do 117 | service_name 'core/grafana/6.4.3/20191105024430' 118 | gateway_auth_token 'secret' 119 | end 120 | 121 | ruby_block 'wait-for-grafana-startup' do 122 | block do 123 | raise 'grafana not loaded' unless system 'hab svc status core/grafana' 124 | end 125 | retries 5 126 | retry_delay 10 127 | action :nothing 128 | subscribes :run, 'hab_service[core/grafana full identifier]', :immediately 129 | end 130 | 131 | hab_service 'core/grafana full identifier idempotence' do 132 | service_name 'core/grafana/6.4.3/20191105024430' 133 | gateway_auth_token 'secret' 134 | end 135 | 136 | # Test 5: Change version (core/vault) 137 | hab_service 'core/vault' do 138 | gateway_auth_token 'secret' 139 | end 140 | 141 | ruby_block 'wait-for-vault-load' do 142 | block do 143 | raise 'vault not loaded' unless system 'hab svc status core/vault' 144 | end 145 | retries 5 146 | retry_delay 10 147 | action :nothing 148 | subscribes :run, 'hab_service[core/vault]', :immediately 149 | end 150 | 151 | hab_service 'core/vault version change' do 152 | service_name 'core/vault/1.1.5' 153 | gateway_auth_token 'secret' 154 | end 155 | 156 | # Test 6: Property Changes 157 | hab_service 'core/grafana property change from defaults' do 158 | action :load 159 | service_name 'core/grafana/6.4.3/20191105024430' 160 | service_group 'test-1' 161 | bldr_url 'https://bldr-test-1.habitat.sh' 162 | strategy 'rolling' 163 | update_condition 'latest' 164 | shutdown_timeout 9 165 | health_check_interval 31 166 | gateway_auth_token 'secret' 167 | end 168 | 169 | hab_service 'core/grafana property change from custom values' do 170 | action :load 171 | service_name 'core/grafana/6.4.3/20191105024430' 172 | service_group 'test' 173 | bldr_url 'https://bldr-test.habitat.sh' 174 | channel 'bldr-1321420393699319808' 175 | topology :standalone 176 | strategy :'at-once' 177 | update_condition 'latest' 178 | binding_mode :relaxed 179 | shutdown_timeout 10 180 | health_check_interval 32 181 | gateway_auth_token 'secret' 182 | end 183 | 184 | # Test 7: Single Bind 185 | hab_service 'core/prometheus' do 186 | gateway_auth_token 'secret' 187 | end 188 | 189 | ruby_block 'wait-for-prometheus-startup' do 190 | block do 191 | raise 'prometheus not loaded' unless system 'hab svc status core/prometheus' 192 | end 193 | retries 5 194 | retry_delay 10 195 | action :nothing 196 | subscribes :run, 'hab_service[core/prometheus]', :immediately 197 | end 198 | 199 | hab_service 'core/grafana binding' do 200 | action :load 201 | service_name 'core/grafana/6.4.3/20191105024430' 202 | service_group 'test' 203 | bldr_url 'https://bldr-test.habitat.sh' 204 | channel 'bldr-1321420393699319808' 205 | topology :standalone 206 | strategy 'at-once' 207 | update_condition 'latest' 208 | bind 'prom:prometheus.default' 209 | binding_mode :relaxed 210 | shutdown_timeout 10 211 | health_check_interval 32 212 | gateway_auth_token 'secret' 213 | end 214 | 215 | # Test 8: Test Service Name Matching & Multiple Binds (sensu-backend & sensu + rabbitmq) 216 | hab_service 'core/rabbitmq' do 217 | gateway_auth_token 'secret' 218 | end 219 | 220 | hab_service 'core/sensu-backend' do 221 | gateway_auth_token 'secret' 222 | end 223 | 224 | hab_service 'core/sensu' do 225 | bind [ 226 | 'rabbitmq:rabbitmq.default', 227 | 'redis:redis.default', 228 | ] 229 | gateway_auth_token 'secret' 230 | end 231 | 232 | # Test 9: Restart the package 233 | hab_service 'core/consul' do 234 | gateway_auth_token 'secret' 235 | end 236 | 237 | ruby_block 'wait-for-consul-load' do 238 | block do 239 | raise 'consul not loaded' unless system 'hab svc status core/consul' 240 | end 241 | retries 5 242 | retry_delay 10 243 | action :nothing 244 | subscribes :run, 'hab_service[core/consul]', :immediately 245 | end 246 | ruby_block 'wait-for-consul-startup' do 247 | block do 248 | raise 'consul not started' unless `hab svc status core/consul`.match(/standalone\s+up\s+up/) 249 | end 250 | retries 5 251 | retry_delay 10 252 | action :nothing 253 | subscribes :run, 'ruby_block[wait-for-consul-load]', :immediately 254 | end 255 | 256 | ruby_block 'wait-for-consul-up-for-30s' do 257 | block do 258 | uptime = `hab svc status core/consul`.match(/standalone\s+up\s+up\s+([0-9]+)/) 259 | raise 'consul not started for 30s' unless uptime.size == 2 && Integer(uptime[1]) > 30 260 | end 261 | retries 30 262 | retry_delay 2 263 | action :nothing 264 | subscribes :run, 'ruby_block[wait-for-consul-startup]', :immediately 265 | end 266 | 267 | hab_service 'core/consul restart' do 268 | service_name 'core/consul' 269 | gateway_auth_token 'secret' 270 | action :restart 271 | end 272 | 273 | ruby_block 'wait-for-consul-restart' do 274 | block do 275 | uptime = `hab svc status core/consul`.match(/standalone\s+up\s+up\s+([0-9]+)/) 276 | raise 'consul not restarted' unless !uptime.nil? && uptime.size == 2 && Integer(uptime[1]) < 30 277 | end 278 | retries 60 279 | retry_delay 1 280 | action :nothing 281 | subscribes :run, 'hab_service[core/consul restart]', :immediately 282 | end 283 | 284 | # Test 10: Reload the package 285 | ruby_block 'wait-for-consul-up-for-30s' do 286 | block do 287 | uptime = `hab svc status core/consul`.match(/standalone\s+up\s+up\s+([0-9]+)/) 288 | raise 'consul not started for 30s' unless uptime.size == 2 && Integer(uptime[1]) > 30 289 | end 290 | retries 30 291 | retry_delay 1 292 | action :nothing 293 | subscribes :run, 'ruby_block[wait-for-consul-startup]', :immediately 294 | end 295 | 296 | hab_service 'core/consul reload' do 297 | service_name 'core/consul' 298 | gateway_auth_token 'secret' 299 | action :reload 300 | end 301 | 302 | ruby_block 'wait-for-consul-restart' do 303 | block do 304 | uptime = `hab svc status core/consul`.match(/standalone\s+up\s+up\s+([0-9]+)/) 305 | raise 'consul not restarted' unless !uptime.nil? && uptime.size == 2 && Integer(uptime[1]) < 30 306 | end 307 | retries 5 308 | retry_delay 10 309 | action :nothing 310 | subscribes :run, 'hab_service[core/consul restart]', :immediately 311 | end 312 | -------------------------------------------------------------------------------- /libraries/resource_hab_sup.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright:: 2017-2018 Chef Software, Inc. 3 | # License:: Apache License, Version 2.0 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | require 'chef/resource' 19 | 20 | class Chef 21 | class Resource 22 | class HabSup < Resource 23 | provides :hab_sup do |_node| 24 | false 25 | end 26 | 27 | property :bldr_url, String 28 | property :permanent_peer, [true, false], default: false 29 | property :listen_ctl, String 30 | property :listen_gossip, String 31 | property :listen_http, String 32 | property :org, String, default: 'default' 33 | property :peer, [String, Array], coerce: proc { |b| b.is_a?(String) ? [b] : b } 34 | property :ring, String 35 | property :hab_channel, String 36 | property :auto_update, [true, false], default: false 37 | property :auth_token, String 38 | property :gateway_auth_token, String 39 | property :update_condition, String 40 | property :limit_no_files, String 41 | property :license, String, equal_to: ['accept'] 42 | property :health_check_interval, [String, Integer], coerce: proc { |h| h.is_a?(String) ? h : h.to_s } 43 | property :event_stream_application, String 44 | property :event_stream_environment, String 45 | property :event_stream_site, String 46 | property :event_stream_url, String 47 | property :event_stream_token, String 48 | property :event_stream_cert, String 49 | property :sup_version, String 50 | property :launcher_version, String 51 | property :service_version, String # Windows only 52 | property :keep_latest, String 53 | property :toml_config, [true, false], default: false 54 | 55 | action :run do 56 | hab_install new_resource.name do 57 | license new_resource.license 58 | hab_version new_resource.sup_version if new_resource.sup_version 59 | not_if { ::File.exist?('/bin/hab') } 60 | not_if { ::File.exist?('/usr/bin/hab') } 61 | not_if { ::File.exist?('c:/habitat/hab.exe') } 62 | not_if { ::File.exist?('c:/ProgramData/Habitat/hab.exe') } 63 | end 64 | 65 | hab_package 'core/hab-sup' do 66 | bldr_url new_resource.bldr_url if new_resource.bldr_url 67 | version new_resource.sup_version if new_resource.sup_version 68 | end 69 | 70 | hab_package 'core/hab-launcher' do 71 | bldr_url new_resource.bldr_url if new_resource.bldr_url 72 | version new_resource.launcher_version if new_resource.launcher_version 73 | end 74 | 75 | if platform_family?('windows') 76 | directory 'C:/hab/sup/default/config' do 77 | recursive true 78 | only_if { ::Dir.exist?('C:/hab') } 79 | only_if { use_toml_config() } 80 | action :create 81 | end 82 | 83 | template 'C:/hab/sup/default/config/sup.toml' do 84 | source 'sup/sup.toml.erb' 85 | sensitive true 86 | variables( 87 | bldr_url: new_resource.bldr_url, 88 | permanent_peer: new_resource.permanent_peer, 89 | listen_ctl: new_resource.listen_ctl, 90 | listen_gossip: new_resource.listen_gossip, 91 | listen_http: new_resource.listen_http, 92 | organization: new_resource.org, 93 | peer: peer_list_with_port, 94 | ring: new_resource.ring, 95 | auto_update: new_resource.auto_update, 96 | update_condition: new_resource.update_condition, 97 | health_check_interval: new_resource.health_check_interval, 98 | event_stream_application: new_resource.event_stream_application, 99 | event_stream_environment: new_resource.event_stream_environment, 100 | event_stream_site: new_resource.event_stream_site, 101 | event_stream_url: new_resource.event_stream_url, 102 | event_stream_token: new_resource.event_stream_token, 103 | event_stream_server_certificate: new_resource.event_stream_cert, 104 | keep_latest_packages: new_resource.keep_latest 105 | ) 106 | only_if { use_toml_config() } 107 | only_if { ::Dir.exist?('C:/hab/sup/default/config') } 108 | end 109 | else 110 | directory '/hab/sup/default/config' do 111 | mode '0755' 112 | recursive true 113 | only_if { use_toml_config() } 114 | only_if { ::Dir.exist?('/hab') } 115 | action :create 116 | end 117 | 118 | template '/hab/sup/default/config/sup.toml' do 119 | source 'sup/sup.toml.erb' 120 | sensitive true 121 | variables( 122 | bldr_url: new_resource.bldr_url, 123 | permanent_peer: new_resource.permanent_peer, 124 | listen_ctl: new_resource.listen_ctl, 125 | listen_gossip: new_resource.listen_gossip, 126 | listen_http: new_resource.listen_http, 127 | organization: new_resource.org, 128 | peer: peer_list_with_port, 129 | ring: new_resource.ring, 130 | auto_update: new_resource.auto_update, 131 | update_condition: new_resource.update_condition, 132 | health_check_interval: new_resource.health_check_interval, 133 | event_stream_application: new_resource.event_stream_application, 134 | event_stream_environment: new_resource.event_stream_environment, 135 | event_stream_site: new_resource.event_stream_site, 136 | event_stream_url: new_resource.event_stream_url, 137 | event_stream_token: new_resource.event_stream_token, 138 | event_stream_server_certificate: new_resource.event_stream_cert, 139 | keep_latest_packages: new_resource.keep_latest 140 | ) 141 | only_if { use_toml_config() } 142 | only_if { ::Dir.exist?('/hab/sup/default/config') } 143 | end 144 | end 145 | end 146 | 147 | action_class do 148 | include Habitat::Shared 149 | # validate that peers have been passed with a port # for toml file 150 | def peer_list_with_port 151 | if new_resource.peer 152 | peer_list = [] 153 | new_resource.peer.each do |p| 154 | peer_list << if p !~ /.*:.*/ 155 | p + ':9632' 156 | else 157 | p 158 | end 159 | end 160 | peer_list 161 | end 162 | end 163 | 164 | # Specify whether toml configuration should be used in place of service arguments. 165 | def use_toml_config 166 | new_resource.toml_config 167 | end 168 | 169 | def exec_start_options 170 | # Populate exec_start_options which will pass to 'hab sup run' for platforms if use_toml_config is not 'true' 171 | unless use_toml_config() 172 | opts = [] 173 | opts << '--permanent-peer' if new_resource.permanent_peer 174 | opts << "--listen-ctl #{new_resource.listen_ctl}" if new_resource.listen_ctl 175 | opts << "--listen-gossip #{new_resource.listen_gossip}" if new_resource.listen_gossip 176 | opts << "--listen-http #{new_resource.listen_http}" if new_resource.listen_http 177 | opts << "--org #{new_resource.org}" unless new_resource.org == 'default' 178 | opts.push(*new_resource.peer.map { |b| "--peer #{b}" }) if new_resource.peer 179 | opts << "--ring #{new_resource.ring}" if new_resource.ring 180 | opts << '--auto-update' if new_resource.auto_update 181 | opts << "--update-condition #{new_resource.update_condition}" if new_resource.update_condition 182 | opts << "--health-check-interval #{new_resource.health_check_interval}" if new_resource.health_check_interval 183 | opts << "--event-stream-application #{new_resource.event_stream_application}" if new_resource.event_stream_application 184 | opts << "--event-stream-environment #{new_resource.event_stream_environment}" if new_resource.event_stream_environment 185 | opts << "--event-stream-site #{new_resource.event_stream_site}" if new_resource.event_stream_site 186 | opts << "--event-stream-url #{new_resource.event_stream_url}" if new_resource.event_stream_url 187 | opts << "--event-stream-token #{new_resource.event_stream_token}" if new_resource.event_stream_token 188 | opts << "--event-stream-server-certificate #{new_resource.event_stream_cert}" if new_resource.event_stream_cert 189 | opts << "--keep-latest-packages #{new_resource.keep_latest}" if new_resource.keep_latest 190 | opts.join(' ') 191 | end 192 | end 193 | end 194 | end 195 | end 196 | end 197 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /resources/service.rb: -------------------------------------------------------------------------------- 1 | # Copyright:: 2017-2018 Chef Software, Inc. 2 | # License:: Apache License, Version 2.0 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | resource_name :hab_service 18 | provides :hab_service 19 | 20 | property :service_name, String, name_property: true 21 | property :loaded, [true, false], default: false 22 | property :running, [true, false], default: false 23 | 24 | # hab svc options which get included based on the action of the resource 25 | property :strategy, [Symbol, String], equal_to: [:none, 'none', :'at-once', 'at-once', :rolling, 'rolling'], default: :none, coerce: proc { |s| s.is_a?(String) ? s.to_sym : s } 26 | property :topology, [Symbol, String], equal_to: [:standalone, 'standalone', :leader, 'leader'], default: :standalone, coerce: proc { |s| s.is_a?(String) ? s.to_sym : s } 27 | property :bldr_url, String, default: 'https://bldr.habitat.sh/' 28 | property :channel, [Symbol, String], default: :stable, coerce: proc { |s| s.is_a?(String) ? s.to_sym : s } 29 | property :bind, [String, Array], coerce: proc { |b| b.is_a?(String) ? [b] : b }, default: [] 30 | property :binding_mode, [Symbol, String], equal_to: [:strict, 'strict', :relaxed, 'relaxed'], default: :strict, coerce: proc { |s| s.is_a?(String) ? s.to_sym : s } 31 | property :service_group, String, default: 'default' 32 | property :shutdown_timeout, Integer, default: 8 33 | property :health_check_interval, Integer, default: 30 34 | property :remote_sup, String, default: '127.0.0.1:9632', desired_state: false 35 | # Http port needed for querying/comparing current config value 36 | property :remote_sup_http, String, default: '127.0.0.1:9631', desired_state: false 37 | property :gateway_auth_token, String, desired_state: false 38 | property :update_condition, [Symbol, String], equal_to: [:latest, 'latest', :'track-channel', 'track-channel'], default: :latest, coerce: proc { |s| s.is_a?(String) ? s.to_sym : s } 39 | 40 | load_current_value do 41 | service_details = get_service_details(service_name) 42 | 43 | running service_up?(service_details) 44 | loaded service_loaded?(service_details) 45 | 46 | if loaded 47 | service_name get_spec_identifier(service_details) 48 | strategy get_update_strategy(service_details) 49 | update_condition get_update_condition(service_details) 50 | topology get_topology(service_details) 51 | bldr_url get_builder_url(service_details) 52 | channel get_channel(service_details) 53 | bind get_binds(service_details) 54 | binding_mode get_binding_mode(service_details) 55 | service_group get_service_group(service_details) 56 | shutdown_timeout get_shutdown_timeout(service_details) 57 | health_check_interval get_health_check_interval(service_details) 58 | end 59 | 60 | Chef::Log.debug("service #{service_name} service name: #{service_name}") 61 | Chef::Log.debug("service #{service_name} running state: #{running}") 62 | Chef::Log.debug("service #{service_name} loaded state: #{loaded}") 63 | Chef::Log.debug("service #{service_name} strategy: #{strategy}") 64 | Chef::Log.debug("service #{service_name} update condition: #{update_condition}") 65 | Chef::Log.debug("service #{service_name} topology: #{topology}") 66 | Chef::Log.debug("service #{service_name} builder url: #{bldr_url}") 67 | Chef::Log.debug("service #{service_name} channel: #{channel}") 68 | Chef::Log.debug("service #{service_name} binds: #{bind}") 69 | Chef::Log.debug("service #{service_name} binding mode: #{binding_mode}") 70 | Chef::Log.debug("service #{service_name} service group: #{service_group}") 71 | Chef::Log.debug("service #{service_name} shutdown timeout: #{shutdown_timeout}") 72 | Chef::Log.debug("service #{service_name} health check interval: #{health_check_interval}") 73 | end 74 | 75 | # This method is defined here otherwise it isn't usable in the 76 | # `load_current_value` method. 77 | # 78 | # It performs a check with TCPSocket to ensure that the HTTP API is 79 | # available first. If it cannot connect, it assumes that the service 80 | # is not running. It then attempts to reach the `/services` path of 81 | # the API to get a list of services. If this fails for some reason, 82 | # then it assumes the service is not running. 83 | # 84 | # Finally, it walks the services returned by the API to look for the 85 | # service we're configuring. If it is "Up", then we know the service 86 | # is running and fully operational according to Habitat. This is 87 | # wrapped in a begin/rescue block because if the service isn't 88 | # present and `sup_for_service_name` will be nil and we will get a 89 | # NoMethodError. 90 | # 91 | def get_service_details(svc_name) 92 | http_uri = "http://#{remote_sup_http}" 93 | 94 | begin 95 | TCPSocket.new(URI(http_uri).host, URI(http_uri).port).close 96 | rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH 97 | Chef::Log.debug("Could not connect to #{http_uri} to retrieve status for #{service_name}") 98 | return false 99 | end 100 | 101 | begin 102 | headers = {} 103 | headers['Authorization'] = "Bearer #{gateway_auth_token}" if property_is_set?(:gateway_auth_token) 104 | svcs = Chef::HTTP::SimpleJSON.new(http_uri).get('/services', headers) 105 | rescue 106 | Chef::Log.debug("Could not connect to #{http_uri}/services to retrieve status for #{service_name}") 107 | return false 108 | end 109 | 110 | origin, name, _version, _release = svc_name.split('/') 111 | svcs.find do |s| 112 | s['pkg']['origin'] == origin && s['pkg']['name'] == name 113 | end 114 | end 115 | 116 | def service_up?(service_details) 117 | service_details['process']['state'] == 'up' 118 | rescue 119 | Chef::Log.debug("#{service_name} not found on the Habitat supervisor") 120 | false 121 | end 122 | 123 | def service_loaded?(service_details) 124 | if service_details 125 | true 126 | else 127 | false 128 | end 129 | end 130 | 131 | def get_spec_identifier(service_details) 132 | service_details['spec_ident']['spec_identifier'] 133 | rescue 134 | Chef::Log.debug("#{service_name} not found on the Habitat supervisor") 135 | nil 136 | end 137 | 138 | def get_update_strategy(service_details) 139 | service_details['update_strategy'].to_sym 140 | rescue 141 | Chef::Log.debug("Update Strategy for #{service_name} not found on Supervisor API") 142 | 'none' 143 | end 144 | 145 | def get_update_condition(service_details) 146 | service_details['update_condition'].to_sym 147 | rescue 148 | Chef::Log.debug("Update condition #{service_name} not found on Supervisor API") 149 | 'latest' 150 | end 151 | 152 | def get_topology(service_details) 153 | service_details['topology'].to_sym 154 | rescue 155 | Chef::Log.debug("Topology for #{service_name} not found on Supervisor API") 156 | 'standalone' 157 | end 158 | 159 | def get_builder_url(service_details) 160 | service_details['bldr_url'] 161 | rescue 162 | Chef::Log.debug("Builder URL for #{service_name} not found on Supervisor API") 163 | 'https://bldr.habitat.sh' 164 | end 165 | 166 | def get_channel(service_details) 167 | service_details['channel'].to_sym 168 | rescue 169 | Chef::Log.debug("Channel for #{service_name} not found on Supervisor API") 170 | 'stable' 171 | end 172 | 173 | def get_binds(service_details) 174 | service_details['binds'] 175 | rescue 176 | Chef::Log.debug("Update Strategy for #{service_name} not found on Supervisor API") 177 | [] 178 | end 179 | 180 | def get_binding_mode(service_details) 181 | service_details['binding_mode'].to_sym 182 | rescue 183 | Chef::Log.debug("Binding mode for #{service_name} not found on Supervisor API") 184 | 'strict' 185 | end 186 | 187 | def get_service_group(service_details) 188 | service_details['service_group'].split('.').last 189 | rescue 190 | Chef::Log.debug("Service Group for #{service_name} not found on Supervisor API") 191 | 'default' 192 | end 193 | 194 | def get_shutdown_timeout(service_details) 195 | service_details['pkg']['shutdown_timeout'] 196 | rescue 197 | Chef::Log.debug("Shutdown Timeout for #{service_name} not found on Supervisor API") 198 | 8 199 | end 200 | 201 | def get_health_check_interval(service_details) 202 | service_details['health_check_interval']['secs'] 203 | rescue 204 | Chef::Log.debug("Health Check Interval for #{service_name} not found on Supervisor API") 205 | 30 206 | end 207 | 208 | action :load do 209 | modified = false 210 | converge_if_changed :service_name do 211 | modified = true 212 | end 213 | converge_if_changed :strategy do 214 | modified = true 215 | end 216 | converge_if_changed :update_condition do 217 | modified = true 218 | end 219 | converge_if_changed :topology do 220 | modified = true 221 | end 222 | converge_if_changed :bldr_url do 223 | modified = true 224 | end 225 | converge_if_changed :channel do 226 | modified = true 227 | end 228 | converge_if_changed :bind do 229 | modified = true 230 | end 231 | converge_if_changed :binding_mode do 232 | modified = true 233 | end 234 | converge_if_changed :service_group do 235 | modified = true 236 | end 237 | converge_if_changed :shutdown_timeout do 238 | modified = true 239 | end 240 | converge_if_changed :health_check_interval do 241 | modified = true 242 | end 243 | 244 | options = svc_options 245 | if current_resource.loaded && modified 246 | Chef::Log.debug("Reloading #{current_resource.service_name} using --force due to parameter change") 247 | options << '--force' 248 | end 249 | 250 | unless current_resource.loaded && !modified 251 | execute 'test' do 252 | command "hab svc load #{new_resource.service_name} #{options.join(' ')}" 253 | retry_delay 10 254 | retries 5 255 | end 256 | end 257 | end 258 | 259 | action :unload do 260 | if current_resource.loaded 261 | execute "hab svc unload #{new_resource.service_name} #{svc_options.join(' ')}" 262 | wait_for_service_unloaded 263 | end 264 | end 265 | 266 | action :start do 267 | unless current_resource.loaded 268 | Chef::Log.fatal("No service named #{new_resource.service_name} is loaded on the Habitat supervisor") 269 | raise "No service named #{new_resource.service_name} is loaded on the Habitat supervisor" 270 | end 271 | 272 | execute "hab svc start #{new_resource.service_name} #{svc_options.join(' ')}" unless current_resource.running 273 | end 274 | 275 | action :stop do 276 | unless current_resource.loaded 277 | Chef::Log.fatal("No service named #{new_resource.service_name} is loaded on the Habitat supervisor") 278 | raise "No service named #{new_resource.service_name} is loaded on the Habitat supervisor" 279 | end 280 | 281 | if current_resource.running 282 | execute "hab svc stop #{new_resource.service_name} #{svc_options.join(' ')}" 283 | wait_for_service_stopped 284 | end 285 | end 286 | 287 | action :restart do 288 | action_stop 289 | action_start 290 | end 291 | 292 | action :reload do 293 | action_unload 294 | action_load 295 | end 296 | 297 | action_class do 298 | def svc_options 299 | opts = [] 300 | 301 | # certain options are only valid for specific `hab svc` subcommands. 302 | case action 303 | when :load 304 | opts.push(*new_resource.bind.map { |b| "--bind #{b}" }) if new_resource.bind 305 | opts << "--binding-mode #{new_resource.binding_mode}" 306 | opts << "--url #{new_resource.bldr_url}" if new_resource.bldr_url 307 | opts << "--channel #{new_resource.channel}" if new_resource.channel 308 | opts << "--group #{new_resource.service_group}" if new_resource.service_group 309 | opts << "--strategy #{new_resource.strategy}" if new_resource.strategy 310 | opts << "--update-condition #{new_resource.update_condition}" if new_resource.update_condition 311 | opts << "--topology #{new_resource.topology}" if new_resource.topology 312 | opts << "--health-check-interval #{new_resource.health_check_interval}" if new_resource.health_check_interval 313 | opts << "--shutdown-timeout #{new_resource.shutdown_timeout}" if new_resource.shutdown_timeout 314 | when :unload, :stop 315 | opts << "--shutdown-timeout #{new_resource.shutdown_timeout}" if new_resource.shutdown_timeout 316 | end 317 | 318 | opts << "--remote-sup #{new_resource.remote_sup}" if new_resource.remote_sup 319 | 320 | opts.map(&:split).flatten.compact 321 | end 322 | 323 | def wait_for_service_unloaded 324 | ruby_block 'wait-for-service-unloaded' do 325 | block do 326 | raise "#{new_resource.service_name} still loaded" if service_loaded?(get_service_details(new_resource.service_name)) 327 | end 328 | retries get_shutdown_timeout(new_resource.service_name) + 1 329 | retry_delay 1 330 | end 331 | 332 | ruby_block 'update current_resource' do 333 | block do 334 | current_resource.loaded = service_loaded?(get_service_details(new_resource.service_name)) 335 | end 336 | action :nothing 337 | subscribes :run, 'ruby_block[wait-for-service-unloaded]', :immediately 338 | end 339 | end 340 | 341 | def wait_for_service_stopped 342 | ruby_block 'wait-for-service-stopped' do 343 | block do 344 | raise "#{new_resource.service_name} still running" if service_up?(get_service_details(new_resource.service_name)) 345 | end 346 | retries get_shutdown_timeout(new_resource.service_name) + 1 347 | retry_delay 1 348 | 349 | ruby_block 'update current_resource' do 350 | block do 351 | current_resource.running = service_up?(get_service_details(new_resource.service_name)) 352 | end 353 | action :nothing 354 | subscribes :run, 'ruby_block[wait-for-service-stopped]', :immediately 355 | end 356 | end 357 | end 358 | end 359 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Habitat Cookbook 2 | 3 | [![Cookbook Version](https://img.shields.io/cookbook/v/habitat.svg?style=flat)](https://supermarket.chef.io/cookbooks/habitat) 4 | [![CI State](https://github.com/chef-cookbooks/habitat/workflows/delivery/badge.svg)](https://github.com/chef-cookbooks/habitat/actions?query=workflow%3Adelivery) 5 | [![License](https://img.shields.io/badge/License-Apache%202.0-green.svg)](https://opensource.org/licenses/Apache-2.0) 6 | 7 | ## Deprecation 8 | 9 | Great news: The habitat resources from this cookbook are now included directly in Chef Infra Client 17.3 or later. Due to this we will no longer be making enhancements to this cookbook. If you have any feature requests or would like to open a PR with improvements please direct them to https://github.com/chef/chef 10 | 11 | ## Description 12 | 13 | This cookbook provides resources for working with [Habitat](https://habitat.sh). It is intended that these resources will be included in core Chef at some point in the future, so it is important to note: 14 | 15 | - APIs are subject to change 16 | - Habitat is a rapidly changing product, and this cookbook may change rapidly as well 17 | 18 | ## License Note 19 | 20 | Habitat requires acceptance of a license before any habitat commands can be run. To accept the Habitat license using this cookbook, the `license` parameter can be set to `accept` for either the `hab_install` or `hab_sup` resources as shown in the below examples: 21 | 22 | ```ruby 23 | hab_install 'install habitat' do 24 | license 'accept' 25 | end 26 | ``` 27 | 28 | ```ruby 29 | hab_sup 'default' do 30 | license 'accept' 31 | end 32 | ``` 33 | 34 | PLEASE NOTE: Without performing one of the above license acceptance steps, all other resources in the habitat cookbook will fail with an error prompting that the license must be accepted. 35 | 36 | ## Requirements 37 | 38 | ### Platforms 39 | 40 | - RHEL 6+ 41 | - Ubuntu 16.04+ 42 | - Debian 9+ 43 | - Windows 2016+ 44 | 45 | ### Habitat 46 | 47 | - Habitat version: 1.6.56+ `You can also pin to older versions if desired` 48 | 49 | This cookbook used to base version number off of the latest stable Habitat release and install a specific version of Habitat based upon the cookbook version. Current behavior is now that the cookbook will install the latest stable release of Habitat on the source Habitat Builder which is contacted by default, but allows for explicit version pinning to be set via cookbook resources. 50 | 51 | ### Chef 52 | 53 | - Chef 12.20.3+ 54 | 55 | ### Cookbooks 56 | 57 | - None 58 | 59 | ## Resources 60 | 61 | ### hab_install 62 | 63 | Installs Habitat on the system using the [install script](https://raw.githubusercontent.com/habitat-sh/habitat/master/components/hab/install.sh). 64 | 65 | #### Actions 66 | 67 | - `install`: Installs Habitat. Does nothing if the `hab` binary is found in the default location for the system (`/bin/hab` on Linux, `/usr/local/bin/hab` on macOS, `C:/habitat/hab.exe` on Windows) 68 | - `upgrade`: Installs the latest version of Habitat, does not check if the binary exists 69 | 70 | #### Properties 71 | 72 | - `install_url`: URL to the install script, default is from the [habitat repo](https://raw.githubusercontent.com/habitat-sh/habitat/master/components/hab/install.sh) 73 | - `bldr_url`: Optional URL to an alternate Builder (defaults to the public Builder) 74 | - `create_user`: Creates the `hab` system user (defaults to `true`) 75 | - `tmp_dir`: Sets TMPDIR environment variable for location to place temp files. (required if `/tmp` and `/var/tmp` are mounted `noexec`) 76 | - `license`: Specifies acceptance of habitat license when set to `accept` (defaults to empty string). 77 | - `hab_version`: Specify the version of `Habitat` you would like to install (defaults to latest) 78 | 79 | #### Examples 80 | 81 | ```ruby 82 | 83 | # Nameless Installation 84 | hab_install 85 | 86 | # Instalaltion specifying a bldr URL 87 | hab_install 'install habitat' do 88 | bldr_url 'http://localhost' 89 | end 90 | 91 | # Installtation specifying version and bldr URL 92 | hab_install 'install habitat' do 93 | bldr_url 'http://localhost' 94 | hab_version '1.5.50' 95 | end 96 | 97 | ``` 98 | 99 | ### hab_package 100 | 101 | Install the specified Habitat package from builder. Requires that Habitat is installed 102 | 103 | #### actions 104 | 105 | - `install`: installs the specified package 106 | - `upgrade`: installs the specified package. If a newer version is available in the configured channel, upgrades to that version 107 | - `remove`: Will remove packages no longer wanted. 108 | 109 | #### Properties 110 | 111 | - `package_name`: A Habitat package name, must include the origin and package name separated by `/`, for example, `core/redis` 112 | - `version`: A Habitat version which contains the version and optionally a release separated by `/`, for example, `3.2.3` or `3.2.3/20160920131015` 113 | - `bldr_url`: The habitat builder url where packages will be downloaded from (defaults to public habitat builder) 114 | - `channel`: The release channel to install from (defaults to `stable`) 115 | - `auth_token`: Auth token for installing a package from a private organization on builder 116 | - `binlink`: If habitat should attempt to binlink the package. Acceptable values: `true`, `false`, `:force`. Will faill on binlinking if set to `true` and binary or binlink exists. 117 | - `options`: Pass any additional parameters to the habitat install command. 118 | - `keep_latest`: Ability to uninstall while retaining a specified version (Default is not set. `This feature only works in Habitat 1.5.86+`) 119 | - `no_deps`: Remove package but retain dependencies (Default is `false`) 120 | 121 | While it is valid to pass the version and release with a Habitat package as a fully qualified package identifier when using the `hab` CLI, they must be specified using the `version` property when using this resource. See the examples below. 122 | 123 | #### Examples 124 | 125 | ```ruby 126 | hab_package 'core/redis' 127 | 128 | hab_package 'core/redis' do 129 | version '3.2.3' 130 | channel 'unstable' 131 | end 132 | 133 | hab_package 'core/redis' do 134 | version '3.2.3/20160920131015' 135 | end 136 | 137 | hab_package 'core/nginx' do 138 | binlink :force 139 | end 140 | 141 | hab_package 'core/nginx' do 142 | options '--binlink' 143 | end 144 | 145 | # Remove all 146 | hab_package 'core/nginx' 147 | action :remove 148 | end 149 | 150 | # Remove specified 151 | hab_package 'core/nginx/3.2.3' 152 | action :remove 153 | end 154 | 155 | # Remove but retain some versions (only available as of Habitat 1.5.86) 156 | hab_package 'core/nginx' 157 | keep_latest '2' 158 | action :remove 159 | end 160 | 161 | # Renove but keep dependencies 162 | hab_package 'core/nginx' 163 | no_deps false 164 | action :remove 165 | end 166 | ``` 167 | 168 | ### hab_service 169 | 170 | Manages a Habitat application service using `hab sup`/`hab service`. This requires that `core/hab-sup` be running as a service. See the `hab_sup` resource documentation below for more information about how to set that up with this cookbook. 171 | 172 | _Note:_ Applications may run as a specific user. Often with Habitat, the default is `hab`, or `root`. If the application requires another user, then it should be created with Chef's `user` resource. 173 | 174 | #### Actions 175 | 176 | - `:load`: (default action) runs `hab service load` to load and start the specified application service 177 | - `:unload`: runs `hab service unload` to unload and stop the specified application service 178 | - `:reload`: runs the `:unload` and then `:load` actions 179 | - `:start`: runs `hab service start` to start the specified application service 180 | - `:stop`: runs `hab service stop` to stop the specified application service 181 | - `:restart`: runs the `:stop` and then `:start` actions 182 | 183 | #### Properties 184 | 185 | The remote_sup property is valid for all actions. 186 | 187 | - `remote_sup`: Address to a remote Supervisor's Control Gateway [default: 127.0.0.1:9632] 188 | - `remote_sup_http`: Address for remote supervisor http port. Used to pull existing configuration data. If this is invalid, config will be applied on every Chef run. 189 | - `gateway_auth_token`: Auth token for accessing the remote supervisor's http port. 190 | 191 | The follow properties are valid for the `load` action. 192 | 193 | - `service_name`: name property, the name of the service, must be in the form of `origin/name` 194 | - `loaded`: state property indicating whether the service is loaded in the supervisor 195 | - `running`: state property indicating whether the service is running in the supervisor 196 | - `strategy`: Passes `--strategy` with the specified update strategy to the hab command. Defaults to `:none`. Other options are `:'at-once'` and `:rolling` 197 | - `update_condition`: Passes `--update-condition` dictating when this service should updated. Defaults to `latest`. Options are `latest` or `track-channel` **_Note: This requires a minimum habitat version of 1.5.71_** 198 | - `latest`: Runs the latest package that can be found in the configured channel and local packages. 199 | - `track-channel`: Always run what is at the head of a given channel. This enables service rollback where demoting a package from a channel will cause the package to rollback to an older version of the package. A ramification of enabling this condition is packages newer than the package at the head of the channel will be automatically uninstalled during a service rollback. 200 | - `topology`: Passes `--topology` with the specified service topology to the hab command 201 | - `bldr_url`: Passes `--url` with the specified Builder URL to the hab command. Depending on the type of Builder you are connecting to, this URL will look different, here are the **3** current types: 202 | - Public Builder (default) - `https://bldr.habitat.sh` 203 | - On-Prem Builder installed using the [Source Install Method](https://github.com/habitat-sh/on-prem-builder) - `https://your.bldr.url` 204 | - On-Prem Builder installed using the [Automate Installer](https://automate.chef.io/docs/on-prem-builder/) - `https://your.bldr.url/bldr/v1` 205 | - `channel`: Passes `--channel` with the specified channel to the hab command 206 | - `bind`: Passes `--bind` with the specified services to bind to the hab command. If an array of multiple service binds are specified then a `--bind` flag is added for each. 207 | - `binding_mode`: Passes `--binding-mode` with the specified binding mode. Defaults to `:strict`. Options are `:strict` or `:relaxed` 208 | - `service_group`: Passes `--group` with the specified service group to the hab command 209 | 210 | #### Examples 211 | 212 | ```ruby 213 | # install and load nginx 214 | hab_package 'core/nginx' 215 | hab_service 'core/nginx' 216 | 217 | hab_service 'core/nginx unload' do 218 | service_name 'core/nginx' 219 | action :unload 220 | end 221 | 222 | # pass the strategy and topology options to hab service commands (load by default) 223 | hab_service 'core/redis' do 224 | strategy 'rolling' 225 | topology 'standalone' 226 | end 227 | 228 | # Using update_condition 229 | hab_service 'core/redis' do 230 | strategy 'rolling' 231 | update_condition 'track-channel' 232 | topology 'standalone' 233 | end 234 | ``` 235 | 236 | If the service has it's own user specified that is not the `hab` user, don't create the `hab` user on install, and instead create the application user with Chef's `user` resource 237 | 238 | ```ruby 239 | hab_install 'install habitat' do 240 | create_user false 241 | end 242 | 243 | user 'acme-apps' do 244 | system true 245 | end 246 | 247 | hab_service 'acme/apps' 248 | ``` 249 | 250 | ### hab_sup 251 | 252 | Runs a Habitat Supervisor for one or more Habitat Services. It is used in conjunction with `hab_service` which will manage the services loaded and started within the supervisor. 253 | 254 | The `run` action handles installing Habitat using the `hab_install` resource, ensures that the appropriate versions of the `core/hab-sup` and `core/hab-launcher` packages are installed using `hab_package`, and then drops off the appropriate init system definitions and manages the service. 255 | 256 | All `event_stream_*` properties are optional, and allow the Habitat Supervisor to display details about it's status and running services via the [Chef Automate Applications Dashboard](https://automate.chef.io/docs/applications-dashboard/). 257 | **_Note: Automate has TLS on by default. You will need to follow these instructions to make sure habitat has the proper certificates for `event*stram*_` [Share the TLS Certificate with Chef Habitat](https://automate.chef.io/docs/applications-setup/#share-the-tls-certificate-with-chef-habitat)\*** 258 | 259 | #### Actions 260 | 261 | - `run`: starts the `hab-sup` service 262 | 263 | #### Properties 264 | 265 | - `toml_config`: Supports using the Supervisor toml configuration instead of passing exec parameters to the service, default is `false`. [reference](https://www.habitat.sh/docs/reference/#supervisor-config) 266 | - `bldr_url`: The Builder URL for the `hab_package` resource, if needed 267 | - `permanent_peer`: Only valid for `:run` action, passes `--permanent-peer` to the hab command 268 | - `listen_ctl`: Only valid for `:run` action, passes `--listen-ctl` with the specified address and port, e.g., `0.0.0.0:9632`, to the hab command 269 | - `listen_gossip`: Only valid for `:run` action, passes `--listen-gossip` with the specified address and port, e.g., `0.0.0.0:9638`, to the hab command 270 | - `listen_http`: Only valid for `:run` action, passes `--listen-http` with the specified address and port, e.g., `0.0.0.0:9631`, to the hab command 271 | - `org`: Only valid for `:run` action, passes `--org` with the specified org name to the hab command 272 | - `peer`: Only valid for `:run` action, passes `--peer` with the specified initial peer to the hab command 273 | - `ring`: Only valid for `:run` action, passes `--ring` with the specified ring key name to the hab command 274 | - `auto_update`: Passes `--auto-update`. This will set the Habitat supervisor to automatically update itself any time a stable version has been released 275 | - `update_condition`: Passes `--update-condition` dictating when this service should updated. Defaults to `latest`. Options are `latest` or `track-channel` **_Note: This requires a minimum habitat version of 1.5.71_** 276 | - `latest`: Runs the latest package that can be found in the configured channel and local packages. 277 | - `track-channel`: Always run what is at the head of a given channel. This enables service rollback where demoting a package from a channel will cause the package to rollback to an older version of the package. A ramification of enabling this condition is packages newer than the package at the head of the channel will be automatically uninstalled during a service rollback. 278 | - `hab_channel`: The channel to install Habitat from. Defaults to stable 279 | - `auth_token`: Auth token for accessing a private organization on bldr. This value is templated into the appropriate service file. 280 | - `gateway_auth_token`: Auth token for accessing the supervisor's HTTP gateway. This value is templated into the appropriate service file. 281 | - `license`: Specifies acceptance of habitat license when set to `accept` (defaults to empty string). 282 | - `health_check_interval`: The interval (seconds) on which to run health checks (defaults to 30). 283 | - `event_stream_application`: The name of your application that will be displayed in the Chef Automate Applications Dashboard 284 | - `event_stream_environment`: The application environment for the supervisor, this is for grouping in the Applications Dashboard 285 | - `event_stream_site`: Application Dashboard label for the "site" of the application - can be filtered in the dashboard 286 | - `event_stream_url`: `AUTOMATE_HOSTNAME:4222` - the Chef Automate URL with port 4222 specified (can be changed if needed) 287 | - `event_stream_token`: Chef Automate token for sending application event stream data 288 | - `event_stream_cert`: With `Intermediary Certificates` or, Automate 2 being set to use TLS with a valid cert, you will need to provide `Habitat` with your certificate for communication with Automate to work. [Follow these steps!](https://automate.chef.io/docs/applications-setup/#share-the-tls-certificate-with-chef-habitat) 289 | - `sup_verstion`: Allows you to choose which version of supervisor you would like to install. Defaults to `latest`. (If a version is provided, it will also install that version of habitat if not previously installed) 290 | - `launcher_version`: Allows you to choose which version of launcher to install. Defaults to `latest` 291 | - `service_version`: Allows you to choose which version of the **_Windows Service_** to install. Defaults to `latest` 292 | - `keep_latest`: Automatically cleans up old packages. If this flag is enabled, service startup will initiate an uninstall of all previous versions of the associated package. This also applies when a service is restarted due to an update. If a number is passed to this argument, that number of latest versions will be kept. The same logic applies to the Supervisor packag `env:HAB_KEEP_LATEST_PACKAGES=1` (This requires Habitat version `1.5.86+`) 293 | 294 | #### Examples 295 | 296 | ```ruby 297 | # set up with just the defaults 298 | hab_sup 'default' 299 | 300 | # Update listen ports and use Supervisor toml config 301 | hab_sup 'test-options' do 302 | listen_http '0.0.0.0:9999' 303 | listen_gossip '0.0.0.0:9998' 304 | toml_config true 305 | end 306 | 307 | # Use with an on-prem Builder 308 | # Access to public builder may not be available 309 | hab_sup 'default' do 310 | bldr_url 'https://bldr.private.net' 311 | end 312 | 313 | # Using update_condition 314 | hab_sup 'default' do 315 | bldr_url 'https://bldr.private.net' 316 | hab_channel 'dev' 317 | update_condition 'track-channel' 318 | end 319 | 320 | # Provide event_stream_* information 321 | hab_sup 'default' do 322 | license 'accept' 323 | event_stream_application 'myapp' 324 | event_stream_environment 'production' 325 | event_stream_site 'MySite' 326 | event_stream_url 'automate.private.net:4222' 327 | event_stream_token 'myawesomea2clitoken=' 328 | event_stream_cert '/hab/cache/ssl/mycert.crt' 329 | end 330 | 331 | # Provide specific versions 332 | hab_sup 'default' do 333 | bldr_url 'https://bldr.private.net' 334 | sup_version '1.5.50' 335 | launcher_version '13458' 336 | service_version '0.6.0' # WINDOWS ONLY 337 | end 338 | 339 | # Set latest version of packages to retain 340 | hab_sup 'default' do 341 | bldr_url 'https://bldr.private.net' 342 | sup_version '1.5.86' 343 | launcher_version '13458' 344 | service_version '0.6.0' # WINDOWS ONLY 345 | keep_latest '2' 346 | end 347 | ``` 348 | 349 | ### hab_config 350 | 351 | Applies a given configuration to a habitat service using `hab config apply`. 352 | 353 | #### Actions 354 | 355 | - `apply`: (default action) apply the given configuration 356 | 357 | #### Properties 358 | 359 | - `service_group`: The service group to apply the configuration to, for example, `nginx.default` 360 | - `config`: The configuration to apply as a ruby hash, for example, `{ worker_count: 2, http: { keepalive_timeout: 120 } }` 361 | - `remote_sup`: Address to a remote Supervisor's Control Gateway [default: 127.0.0.1:9632] 362 | - `remote_sup_http`: Address for remote supervisor http port. Used to pull existing configuration data. If this is invalid, config will be applied on every Chef run. 363 | - `gateway_auth_token`: Auth token for accessing the remote supervisor's http port. 364 | - `user`: Name of user key to use for encryption. Passes `--user` to `hab config apply` 365 | 366 | #### Notes 367 | 368 | The version number of the configuration is automatically generated and will be the current timestamp in seconds since 1970-01-01 00:00:00 UTC. 369 | 370 | #### Examples 371 | 372 | ```ruby 373 | hab_config 'nginx.default' do 374 | config({ 375 | worker_count: 2, 376 | http: { 377 | keepalive_timeout: 120 378 | } 379 | }) 380 | end 381 | ``` 382 | 383 | ### hab_user_toml 384 | 385 | Templates a user.toml for the specified service. This is written to `/hab/user//config/user.toml`. User.toml can be used to set configuration overriding the default.toml for a given package as an alternative to applying service group level configuration. 386 | 387 | #### Actions 388 | 389 | - `create`: (default action) Create the user.toml from the specified config. 390 | - `delete`: Delete the user.toml 391 | 392 | #### Properties 393 | 394 | - `service_name`: The service group to apply the configuration to, for example, `nginx.default` 395 | - `config`: Only valid for `:create` action. The configuration to apply as a ruby hash, for example, `{ worker_count: 2, http: { keepalive_timeout: 120 } }` 396 | 397 | #### Examples 398 | 399 | ```ruby 400 | hab_user_toml 'nginx' do 401 | config({ 402 | worker_count: 2, 403 | http: { 404 | keepalive_timeout: 120 405 | } 406 | }) 407 | end 408 | ``` 409 | 410 | ## Maintainers 411 | 412 | This cookbook is maintained by the following maintainers: 413 | 414 | - Jon Cowie [jcowie@chef.io](mailto:jcowie@chef.io) 415 | - Jeff Brimager [jbrimager@chef.io](mailto:jbrimager@chef.io) 416 | - Collin Mcneese [cmcneese@chef.io](mailto:cmcneese@chef.io) 417 | 418 | The goal of the Community Cookbook Engineering team is to improve cookbook quality and to aid the community in contributing to cookbooks. To learn more about our team, process, and design goals see our [team documentation](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/COOKBOOK_TEAM.MD). To learn more about contributing to cookbooks like this see our [contributing documentation](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD), or if you have general questions about this cookbook come chat with us in #cookbok-engineering on the [Chef Community Slack](http://community-slack.chef.io/) 419 | 420 | ## License 421 | 422 | **Copyright:** 2016-2018, Chef Software, Inc. 423 | 424 | ``` 425 | Licensed under the Apache License, Version 2.0 (the "License"); 426 | you may not use this file except in compliance with the License. 427 | You may obtain a copy of the License at 428 | 429 | http://www.apache.org/licenses/LICENSE-2.0 430 | 431 | Unless required by applicable law or agreed to in writing, software 432 | distributed under the License is distributed on an "AS IS" BASIS, 433 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 434 | See the License for the specific language governing permissions and 435 | limitations under the License. 436 | ``` 437 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Habitat Cookbook CHANGELOG 2 | 3 | This file is used to list changes made in each version of the habitat cookbook. 4 | 5 | ## Unreleased 6 | 7 | 8 | ## Unreleased 9 | 10 | #### Merged Pull Requests 11 | - pipeline testing updates [#259](https://github.com/chef-cookbooks/habitat/pull/259) ([collinmcneese](https://github.com/collinmcneese)) 12 | - Cookstyle Bot Auto Corrections with Cookstyle 7.5.2 [#257](https://github.com/chef-cookbooks/habitat/pull/257) ([cookstyle[bot]](https://github.com/cookstyle[bot])) 13 | 14 | 15 | ## [2.2.4](https://github.com/chef-cookbooks/habitat/tree/2.2.4) (2020-11-19) 16 | 17 | #### Merged Pull Requests 18 | - Changelog [#255](https://github.com/chef-cookbooks/habitat/pull/255) ([sam1el](https://github.com/sam1el)) 19 | 20 | 21 | 22 | ## 2.2.4 (2020-11-19) 23 | 24 | #### Merged Pull Requests 25 | 26 | - Adds support for Supervisor toml config [#254](https://github.com/chef-cookbooks/habitat/pull/254) ([collinmcneese](https://github.com/collinmcneese)) 27 | - Cookstyle Bot Auto Corrections with Cookstyle 6.18.8 [#253](https://github.com/chef-cookbooks/habitat/pull/253) ([cookstyle[bot]](https://github.com/cookstyle[bot])) 28 | - Automated PR: Standardising Files [#252](https://github.com/chef-cookbooks/habitat/pull/252) ([xorimabot](https://github.com/xorimabot)) 29 | - Fixed hab_service flapping on bldr_url and update_condition [#251](https://github.com/chef-cookbooks/habitat/pull/251) ([mattray](https://github.com/mattray)) 30 | - It's `event_stream_cert` in the code [#249](https://github.com/chef-cookbooks/habitat/pull/249) ([mattray](https://github.com/mattray)) 31 | - Automated PR: Standardising Files [#248](https://github.com/chef-cookbooks/habitat/pull/248) ([xorimabot](https://github.com/xorimabot)) 32 | 33 | ## 2.2.3 (2020-06-25) 34 | 35 | #### Merged Pull Requests 36 | 37 | - correcting some documentation and fixing tagging [#247](https://github.com/chef-cookbooks/habitat/pull/247) ([sam1el](https://github.com/sam1el)) 38 | 39 | ## 2.2.2 (2020-06-18) 40 | 41 | #### Merged Pull Requests 42 | 43 | - updates custom resources to add resource_name [#246](https://github.com/chef-cookbooks/habitat/pull/246) ([collinmcneese](https://github.com/collinmcneese)) 44 | - Automated PR: Standardising Files [#244](https://github.com/chef-cookbooks/habitat/pull/244) ([xorimabot](https://github.com/xorimabot)) 45 | - Automated PR: Cookstyle Changes [#243](https://github.com/chef-cookbooks/habitat/pull/243) ([xorimabot](https://github.com/xorimabot)) 46 | 47 | ## 2.2.1 (2020-05-28) 48 | 49 | - With the new availabilty of an embedded Builder server with A2 we wanted to add the option of using it with this cookbook. As this changes the URL to the api, we needed to alter the resources that use it. 50 | - Had idempotance issues with the install resource. Those are now corrected 51 | 52 | #### Merged Pull Requests 53 | 54 | - Automated PR: Standardising Files [#242](https://github.com/chef-cookbooks/habitat/pull/242) ([xorimabot](https://github.com/xorimabot)) 55 | - updating how we handle the bldr_url to accommodate on-prem installed with Automate [#241](https://github.com/chef-cookbooks/habitat/pull/241) ([danielcbright](https://github.com/danielcbright)) 56 | - fixes hab_install guard for resource_hab_sup [#239](https://github.com/chef-cookbooks/habitat/pull/239) ([collinmcneese](https://github.com/collinmcneese)) 57 | - correcting all syntax issue [#238](https://github.com/chef-cookbooks/habitat/pull/238) ([sam1el](https://github.com/sam1el)) 58 | - Automated PR: Cookstyle Changes [#237](https://github.com/chef-cookbooks/habitat/pull/237) ([xorimabot](https://github.com/xorimabot)) 59 | 60 | ## 2.1.0 (2020-05-07) 61 | 62 | - Integrated Toml functions as a helper library to remove external gem dependencies. This will also make airgap usage easier 63 | 64 | #### Merged Pull Requests 65 | 66 | - Feature/toml [#236](https://github.com/chef-cookbooks/habitat/pull/236) ([sam1el](https://github.com/sam1el)) 67 | - adding effortless compatibility [#235](https://github.com/chef-cookbooks/habitat/pull/235) ([sam1el](https://github.com/sam1el)) 68 | 69 | ## 2.0.5 (2020-04-30) 70 | 71 | - There was an issue where the windows service was not correctly setting the launcher version in the service condig. This cause a broken install and/or update when unpinning your version. We have corrected this issue and all version changes are now populating as expected. 72 | 73 | #### Merged Pull Requests 74 | 75 | - Fix for windows-launcher config (#234) 76 | 77 | ## 2.0.4 (2020-04-29) 78 | 79 | - Correcting merge conflict issues which broke the cookbook at compile time 80 | 81 | ## 2.0.3 (2020-04-28) 82 | 83 | - correcting windows launcher path issue which caused the windows service to no longer start. 84 | 85 | #### Merged Pull Requests 86 | 87 | - correcting launcher path issue (#13) - [@sam1el](https://github.com/sam1el) 88 | 89 | ## 2.0.2 (2020-04-08) 90 | 91 | - Able to unintall packages using the `hab_package` resource. This includes the `--no-deps` and the `--keep-latest`. Keep latest is only available on habitat 1.5.86+ 92 | - Able to select the version of habitat installed as wells as, supervisor, launcher and, windows-servcie 93 | - All current `--event-stream` functions are now available to habitat versions 1.5.86 and up for the `hab_sup` resource 94 | - `windows-service` Can now be configured properly with `--event-stream` as well has your `HAB_AUTH_TOKEN` `HAB_BLDR_URL` and, `HAB_AUTH_GATEWAY_TOKEN` 95 | 96 | **\*See README.MD for usage of all new functions** 97 | 98 | #### Merged Pull Requests 99 | 100 | - Automated PR: Standardising Files [#229](https://github.com/chef-cookbooks/habitat/pull/229) ([xorimabot](https://github.com/xorimabot)) 101 | - Overhaul to testing and cookbook resources [#228](https://github.com/chef-cookbooks/habitat/pull/228) 102 | - Automated PR: Standardising Files [#226](https://github.com/chef-cookbooks/habitat/pull/226) ([xorimabot](https://github.com/xorimabot)) 103 | - Automated PR: Cookstyle Changes [#225](https://github.com/chef-cookbooks/habitat/pull/225) ([xorimabot](https://github.com/xorimabot)) 104 | - resolved cookstyle error: libraries/provider_hab_package.rb:174:13 convention: `Style/RedundantReturn` 105 | - resolved cookstyle error: libraries/provider_hab_package.rb:176:13 convention: `Style/RedundantReturn` 106 | 107 | ## 1.7.0 (2020-04-08) 108 | 109 | - adds windows Github Actions testing for issue #193 [#224](https://github.com/chef-cookbooks/habitat/pull/224) ([collinmcneese](https://github.com/collinmcneese)) 110 | - changing the windows service cofig to better reflect newer functional… [#223](https://github.com/chef-cookbooks/habitat/pull/223) ([sam1el](https://github.com/sam1el)) 111 | - removing update-confition defaults and tests [#221](https://github.com/chef-cookbooks/habitat/pull/221) ([sam1el](https://github.com/sam1el)) 112 | - Added optional settings for Windows service to recongize local or provided envoringment variables including 113 | - HAB_AUTH_TOKEN 114 | - HAB_GATEWAY_AUTH_TOKEN 115 | - HAB_BLDR_URL 116 | 117 | ## 1.6.2 (2020-04-07) 118 | 119 | #### Merged Pull Requests 120 | 121 | - changing the windows service cofig to better reflect newer functional… [#223](https://github.com/chef-cookbooks/habitat/pull/223) ([sam1el](https://github.com/sam1el)) 122 | - removing update-confition defaults and tests [#221](https://github.com/chef-cookbooks/habitat/pull/221) ([sam1el](https://github.com/sam1el)) 123 | 124 | ## 1.6.0 (2020-04-02) 125 | 126 | #### Merged Pull Requests - complete overhaul of the windows-service config to refplect current best practice 127 | 128 | - adding --update-condition funtionality that was added in habitat 1.5.71 [#217](https://github.com/chef-cookbooks/habitat/pull/217) ([sam1el](https://github.com/sam1el)) 129 | - added --update-condition funtionality that was added in habitat 1.5.71. See README.MD for info on usage 130 | - complete overhaul of the windows-service config to refplect current best practice 131 | 132 | ## 1.5.10 (2020-04-01) 133 | 134 | #### Merged Pull Requests 135 | 136 | - Versioning [#215](https://github.com/chef-cookbooks/habitat/pull/215) ([sam1el](https://github.com/sam1el)) 137 | 138 | ## 1.5.9 (2020-03-30) 139 | 140 | #### Merged Pull Requests 141 | 142 | - updates to be backwards compatible with 12.20.3+ [#214](https://github.com/chef-cookbooks/habitat/pull/214) ([collinmcneese](https://github.com/collinmcneese)) 143 | 144 | ## 1.5.8 (2020-03-09) 145 | 146 | #### Merged Pull Requests 147 | 148 | - fixing idempotence on hab_sup_systemd. [#211](https://github.com/chef-cookbooks/habitat/pull/211) ([sam1el](https://github.com/sam1el)) 149 | 150 | ## 1.5.7 (2020-03-06) 151 | 152 | - Hab version bumped to 1.5.50 153 | 154 | #### Merged Pull Requests 155 | 156 | - Hab version [#210](https://github.com/chef-cookbooks/habitat/pull/210) ([sam1el](https://github.com/sam1el)) 157 | 158 | ## 1.5.6 (2020-03-02) 159 | 160 | - Cookstyle fixes - [@Xorima](https://github.com/Xorima) 161 | - opensuse requires gzip to be installer for hab install script - [@Xorima](https://github.com/Xorima) 162 | - fix readme - [@Xorima](https://github.com/Xorima) 163 | - updated hab sup resource to include new Application Dashboard options (#206) - [@danielcbright](https://github.com/danielcbright) 164 | 165 | #### Merged Pull Requests 166 | 167 | - Delete Merged Branches [#209](https://github.com/chef-cookbooks/habitat/pull/209) ([Xorima](https://github.com/Xorima)) 168 | - Use Github actions badge in the readme [#208](https://github.com/chef-cookbooks/habitat/pull/208) ([Xorima](https://github.com/Xorima)) 169 | - Migrate testing to Github Actions and add support for installing on SUSE [#207](https://github.com/chef-cookbooks/habitat/pull/207) ([Xorima](https://github.com/Xorima)) 170 | 171 | ## 1.5.5 (2020-02-26) 172 | 173 | #### Merged Pull Requests 174 | 175 | - Extending Windows chef-client compatibility [#205](https://github.com/chef-cookbooks/habitat/pull/205) ([sam1el](https://github.com/sam1el)) 176 | 177 | ## 1.5.4 (2020-02-25) 178 | 179 | #### Merged Pull Requests 180 | 181 | - adding delay loop to the load function in the service resouce [#204](https://github.com/chef-cookbooks/habitat/pull/204) ([sam1el](https://github.com/sam1el)) 182 | 183 | ## 1.5.3 (2020-02-24) 184 | 185 | - Fix linux installer issues 186 | 187 | #### Merged Pull Requests 188 | 189 | - [BUG FIX] Linux installers [#203](https://github.com/chef-cookbooks/habitat/pull/203) ([sam1el](https://github.com/sam1el)) 190 | 191 | ## 1.5.2 (2020-02-20) 192 | 193 | - Fix windows habitat install 194 | 195 | #### Merged Pull Requests 196 | 197 | - [BUG FIX] Windows install to correct issue #199 [#202](https://github.com/chef-cookbooks/habitat/pull/202) ([sam1el](https://github.com/sam1el)) 198 | - Additional cookstyle fixes [#189](https://github.com/chef-cookbooks/habitat/pull/189) ([tas50](https://github.com/tas50)) 199 | 200 | ## 1.5.1 (2020-01-31) 201 | 202 | - Fix windows package download URL to use packages.chef.io 203 | 204 | #### Merged Pull Requests 205 | 206 | - Fix windows package download URL [#198](https://github.com/chef-cookbooks/habitat/pull/198) ([jonlives](https://github.com/jonlives)) 207 | 208 | ## [1.5.0](https://github.com/chef-cookbooks/habitat/tree/1.5.0) (2020-01-29) 209 | 210 | - Update cookbook to Habitat 1.5.0 211 | - Fix habitat installs on Windows when using installation archives 212 | 213 | #### Merged Pull Requests 214 | 215 | - WIP: Update to hab 1.5 and update launchers and windows-service pins [#195](https://github.com/chef-cookbooks/habitat/pull/195) ([jonlives](https://github.com/jonlives)) 216 | - Fix Habitat install on windows [#194](https://github.com/chef-cookbooks/habitat/pull/194) ([emachnic](https://github.com/emachnic)) 217 | 218 | ## 0.88.2 (2020-01-24) 219 | 220 | - Add support for supervisor HTTP gateway auth token 221 | - Service Properties, Reload/Restart Fixes, Idempotence Improvements 222 | 223 | #### Merged Pull Requests 224 | 225 | - Service Properties, Reload/Restart Fixes, Idempotence Improvements [#187](https://github.com/chef-cookbooks/habitat/pull/187) ([sirajrauff](https://github.com/sirajrauff)) 226 | - Add option for Supervisor HTTP gateway authentication token [#186](https://github.com/chef-cookbooks/habitat/pull/186) ([rarenerd](https://github.com/rarenerd)) 227 | 228 | ## 0.88.1 (2019-11-25) 229 | 230 | - Cookstyle 5.10 fixes 231 | - Fixes to properly support loading of services using full ident 232 | 233 | #### Merged Pull Requests 234 | 235 | - Feature/service full ident fix [#185](https://github.com/chef-cookbooks/habitat/pull/185) ([sirajrauff](https://github.com/sirajrauff)) 236 | - Cookstyle 5.10 fixes [#183](https://github.com/chef-cookbooks/habitat/pull/183) ([tas50](https://github.com/tas50)) 237 | 238 | ## [0.88.0](https://github.com/chef-cookbooks/habitat/tree/0.88.0) (2019-10-24) 239 | 240 | - Update to hab 0.88.0 241 | - Enable setting of open file limits for hab sup systemd unit file 242 | - Update windows hab-launcher version 243 | 244 | #### Merged Pull Requests 245 | 246 | - Update to habitat 0.88.0 [#182](https://github.com/chef-cookbooks/habitat/pull/182) ([chef-expeditor[bot]](https://github.com/chef-expeditor[bot])) 247 | - allow setting open file limit on the hab sup systemd unit file [#181](https://github.com/chef-cookbooks/habitat/pull/181) ([devoptimist](https://github.com/devoptimist)) 248 | - updating the hab-launcher version to match the dependencies of window… [#179](https://github.com/chef-cookbooks/habitat/pull/179) ([devoptimist](https://github.com/devoptimist)) 249 | 250 | ## [0.83.0](https://github.com/chef-cookbooks/habitat/tree/0.83.0) (2019-07-30) 251 | 252 | - Update to hab 0.83.0 253 | - Support hab_config resource under Chef 13 254 | - Fix license acceptance behaviour under Windows 255 | - Support added for health check interval parameter 256 | 257 | #### Merged Pull Requests 258 | 259 | - Update to habitat 0.83.0 [#177](https://github.com/chef-cookbooks/habitat/pull/177) ([chef-ci](https://github.com/chef-ci)) 260 | - Add health check interval option to hab_sup resource [#176](https://github.com/chef-cookbooks/habitat/pull/176) ([gscho](https://github.com/gscho)) 261 | - Support config apply for chef 13 [#175](https://github.com/chef-cookbooks/habitat/pull/175) ([gscho](https://github.com/gscho)) 262 | - Fix license accept for windows [#174](https://github.com/chef-cookbooks/habitat/pull/174) ([gscho](https://github.com/gscho)) 263 | - Add missing end quotes in the README example [#172](https://github.com/chef-cookbooks/habitat/pull/172) ([teknofire](https://github.com/teknofire)) 264 | 265 | ## 0.81.0 (2019-05-29) 266 | 267 | - Update to hab 0.81.0 268 | - Implement new habitat license agreement requirements for `hab_install` and `hab_sup` resources 269 | 270 | #### Merged Pull Requests 271 | 272 | - WIP: Update to hab 0.81.0 (#171) 273 | 274 | ## [0.81.0](https://github.com/chef-cookbooks/habitat/tree/0.81.0) (2019-05-29) 275 | 276 | #### Merged Pull Requests 277 | 278 | - WIP: Update to hab 0.81.0 [#171](https://github.com/chef-cookbooks/habitat/pull/171) ([jonlives](https://github.com/jonlives)) 279 | 280 | ## 0.79.1 (2019-04-26) 281 | 282 | - Update to habitat 0.79.1 283 | 284 | #### Merged Pull Requests 285 | 286 | - Update to habitat 0.79.1 [#169](https://github.com/chef-cookbooks/habitat/pull/169) ([chef-ci](https://github.com/chef-ci)) 287 | 288 | ## [0.78.0](https://github.com/chef-cookbooks/habitat/tree/0.78.0) (2019-04-02) 289 | 290 | - Update to habitat 0.78.0 291 | - Improve service name matching to include version 292 | 293 | #### Merged Pull Requests 294 | 295 | - Update to habitat 0.78.0 [#165](https://github.com/chef-cookbooks/habitat/pull/165) ([chef-ci](https://github.com/chef-ci)) 296 | - Include version when matching service name [#164](https://github.com/chef-cookbooks/habitat/pull/164) ([gscho](https://github.com/gscho)) 297 | 298 | ## [0.75.0](https://github.com/chef-cookbooks/habitat/tree/0.75.0) (2019-02-22) 299 | 300 | -Update to habitat 0.75.0 301 | 302 | #### Merged Pull Requests 303 | 304 | - Update to habitat 0.75.0 [#161](https://github.com/chef-cookbooks/habitat/pull/161) ([chef-ci](https://github.com/chef-ci)) 305 | - Fix expeditor automation and bump to 0.74.0 [#160](https://github.com/chef-cookbooks/habitat/pull/160) ([jonlives](https://github.com/jonlives)) 306 | 307 | ## 0.74.0 (2019-02-14) 308 | 309 | - Update to habitat 0.74.0 310 | 311 | ## 0.73.1 (2019-01-30) 312 | 313 | - remove duplicate windows query param 314 | 315 | #### Merged Pull Requests 316 | 317 | - remove duplicate windows query param [#156](https://github.com/chef-cookbooks/habitat/pull/156) ([skylerto](https://github.com/skylerto)) 318 | 319 | ## 0.73.0 (2019-01-25) 320 | 321 | - Update Hab to 0.73.0 and launcher to 9167 322 | - Add binlinking support to hab_package resource 323 | - Support target architectures correctly in API queries 324 | - Improved Windows support 325 | 326 | #### Merged Pull Requests 327 | 328 | - Update hab to 0.73.0 and launcher to 9167 [#154](https://github.com/chef-cookbooks/habitat/pull/154) ([jonlives](https://github.com/jonlives)) 329 | - Install hab-sup from stable release [#153](https://github.com/chef-cookbooks/habitat/pull/153) ([jonlives](https://github.com/jonlives)) 330 | - Full Windows Support For Cookbook [#143](https://github.com/chef-cookbooks/habitat/pull/143) ([wduncanfraser](https://github.com/wduncanfraser)) 331 | - Add binlink property to hab_package resource. Closes #138 [#139](https://github.com/chef-cookbooks/habitat/pull/139) ([qubitrenegade](https://github.com/qubitrenegade)) 332 | - fix incorrect documentation for hab_package action [#142](https://github.com/chef-cookbooks/habitat/pull/142) ([st-h](https://github.com/st-h)) 333 | - Support targets for API query [#152](https://github.com/chef-cookbooks/habitat/pull/152) ([skylerto](https://github.com/skylerto)) 334 | 335 | ## 0.67.0 (2018-11-01) 336 | 337 | - Update README with accurate maintainer info 338 | - bug fixes for windows on newer chef versions and path seperators 339 | - Update to habitat 0.67.0 (#146) 340 | 341 | ## 0.63.0 (2018-09-18) 342 | 343 | - Update to habitat 0.63.0 344 | 345 | ## 0.62.1 (2018-09-07) 346 | 347 | - Update hab version to 0.62.1 and pin supervisor version to 8380 348 | - Refactor cookbook resources for 0.62.1 compatibility 349 | - Add user_toml resource 350 | - Add remote supervisor support 351 | - Add multiple peer support 352 | - Add auth token support to package resource 353 | - Add basic support for Windows 354 | 355 | #### Merged Pull Requests 356 | 357 | - Refactor hab_service resource [#124](https://github.com/chef-cookbooks/habitat/pull/124) ([wduncanfraser](https://github.com/wduncanfraser)) 358 | - Update to 0.62.1 and launcher 8380 [#129](https://github.com/chef-cookbooks/habitat/pull/129) ([jonlives](https://github.com/jonlives)) 359 | - Added auth token support to package resource [#125](https://github.com/chef-cookbooks/habitat/pull/125) ([wduncanfraser](https://github.com/wduncanfraser)) 360 | - Updated Supervisor Resource for 0.56 and to Support Auth Token [#123](https://github.com/chef-cookbooks/habitat/pull/123) ([wduncanfraser](https://github.com/wduncanfraser)) 361 | - Added user-toml resource [#121](https://github.com/chef-cookbooks/habitat/pull/121) ([wduncanfraser](https://github.com/wduncanfraser)) 362 | - Change expeditor notification channel [#128](https://github.com/chef-cookbooks/habitat/pull/128) ([mivok](https://github.com/mivok)) 363 | - adding supervisor and service multiple peering support [#101](https://github.com/chef-cookbooks/habitat/pull/101) ([jkerry](https://github.com/jkerry)) 364 | - Basic support for windows platform [#89](https://github.com/chef-cookbooks/habitat/pull/89) ([skylerto](https://github.com/skylerto)) 365 | - Allow any channel in a service [#120](https://github.com/chef-cookbooks/habitat/pull/120) ([jsirex](https://github.com/jsirex)) 366 | - fix hashbang in expeditor update script [#118](https://github.com/chef-cookbooks/habitat/pull/118) ([joshbrand](https://github.com/joshbrand)) 367 | 368 | ## 0.59.0 (2018-07-17) 369 | 370 | - Update README to reflect new version of Hab 371 | - address chef 14.3.x shell_out deprecations 372 | - fix shell_out_compact deprecation 373 | - move to after tempfile creation 374 | - Update CHANGELOG.md with details from pull request #111 375 | - Use the new kitchen config file names 376 | - Cookstyle fixes 377 | 378 | #### Merged Pull Requests 379 | 380 | - address chef 14.3.x shell_out deprecations [#111](https://github.com/chef-cookbooks/habitat/pull/111) ([lamont-granquist](https://github.com/lamont-granquist)) 381 | 382 | ## 0.57.0 (2018-06-19) 383 | 384 | - Fix #103 385 | - Add @jonlives as a maintainer 386 | - Source helper functions script 387 | 388 | #### Merged Pull Requests 389 | 390 | - Source helper functions script [#105](https://github.com/chef-cookbooks/habitat/pull/105) ([jtimberman](https://github.com/jtimberman)) 391 | - Fix #103 and remove options from svc start [#104](https://github.com/chef-cookbooks/habitat/pull/104) ([jonlives](https://github.com/jonlives)) 392 | 393 | ## 0.56.1 (2018-06-06) 394 | 395 | - Support passing TMPDIR attribute to Habitat install.sh script. Addresses Issue #90 396 | - Add: bldr_url property for hab_sup 397 | - Fix hab_svc when using custom ip:port for supervisor 398 | - Include toml in the bundle 399 | - Update CHANGELOG.md with details from pull request #96 400 | 401 | #### Merged Pull Requests 402 | 403 | - Fix hab_svc when using custom ip:port for supervisor [#96](https://github.com/chef-cookbooks/habitat/pull/96) ([JonathanTron](https://github.com/JonathanTron)) 404 | - Add: bldr_url property for hab_sup [#93](https://github.com/chef-cookbooks/habitat/pull/93) ([Atalanta](https://github.com/Atalanta)) 405 | - Support passing TMPDIR attribute to Habitat install.sh script. #90 [#91](https://github.com/chef-cookbooks/habitat/pull/91) ([qubitrenegade](https://github.com/qubitrenegade)) 406 | - Include toml in the bundle [#100](https://github.com/chef-cookbooks/habitat/pull/100) ([jtimberman](https://github.com/jtimberman)) 407 | 408 | ## 0.56.0 (2018-06-05) 409 | 410 | - Update for 0.56.0 411 | - Cookstyle fix 412 | - Disable FC113 for now 413 | - Update the platforms we test 414 | - Update CHANGELOG.md with details from pull request #97 415 | 416 | ## 0.55.0 (2018-03-22) 417 | 418 | - Adding ability to use local repos 419 | - Add expeditor configuration 420 | - update for 0.55.0 421 | 422 | ## 0.54.0 (2018-02-22) 423 | 424 | - Add auto_update property to hab_sup resource. 425 | - update for 0.54.0 release 426 | 427 | ## 0.53.0 (2018-02-07) 428 | 429 | - Set supervisor service to enable 430 | - Remove the legacy version property 431 | - Update copyrights and format 432 | - Test on the latest Fedora 433 | - Remove the suite from dokken. 434 | - Move installation into config and package 435 | - Use a non-deprecated Fauxhai mock 436 | - Remove author info from the test recipe 437 | - Remove the install test recipe 438 | - Remove the ChefSpec matchers 439 | - Make sure package and curl are installed in the install resource 440 | - Add Debian 7+ to the readme as supported 441 | - Allow nameless hab_install resource 442 | - Turns out we don't even need to install before installing the sup 443 | - Update the hab_install readme examples 444 | - update to habitat 0.53.0 445 | 446 | ## 0.52.0 (2018-01-23) 447 | 448 | - Remove Debian 7 testing 449 | - Remove stove gem that's in ChefDK now 450 | - Align Chef in readme with Chef in metadata 451 | - Format readme markdown 452 | - Remove implementation detail 453 | - Actions are symbols so document them that way 454 | - Remove reference to old Hab since we require the latest now 455 | - update to habitat 0.52.0 456 | 457 | ## 0.51.0 (2018-01-08) 458 | 459 | - Update for Habitat version 0.51.0 460 | 461 | ## 0.50.3 (2017-12-04) 462 | 463 | - Update for Habitat version 0.50.3 464 | 465 | ## 0.40.0 (2017-11-30) 466 | 467 | - Update for Habitat version 0.40.0 468 | 469 | ## 0.39.2 (2017-11-28) 470 | 471 | - Add Supervisor service support for non-Systemd platforms 472 | 473 | Development environment/CI changes: 474 | 475 | - need to install toml gem for travis 476 | - Ignore failure when installing from acceptance 477 | 478 | ## 0.39.1 (2017-11-27) 479 | 480 | - update for 0.39.1 481 | - fix rubocop findings too 482 | 483 | ## 0.39.0 (2017-11-17) 484 | 485 | - Install version 0.39.0 486 | - Defer running check to a predicate method in service resource 487 | 488 | ## 0.38.0 (2017-10-30) 489 | 490 | - update version to install for habitat 0.38.0 491 | 492 | ## 0.37.1 (2017-10-26) 493 | 494 | - create user in `hab_install` 495 | 496 | ## 0.37.0 (2017-10-19) 497 | 498 | - update for habitat 0.37.0 release 499 | 500 | ## 0.36.0 (2017-10-09) 501 | 502 | - Simplify `Chef::Provider::Package::Hart#current_versions`. 503 | - honor options from package provider 504 | - update for habitat 0.36.0 505 | 506 | ## 0.34.3 (2017-10-06) 507 | 508 | - Clarify in the README about action-specific properties 509 | 510 | ## 0.34.2 (2017-10-06) 511 | 512 | - Add `hab_config` resource 513 | - Add `toml` gem to metadata for older versions of Chef that don't have it 514 | - Require Chef 12.20.3 or higher to make use of helper methods and classes in newer versions of Chef 515 | 516 | ## 0.34.1 (2017-10-04) 517 | 518 | - Add `version_compare` method to work with latest Chef 519 | 520 | ## 0.34.0 (2017-10-03) 521 | 522 | - Update `hab_install` to Habitat version 0.34.1 523 | 524 | ## 0.33.0 (2017-09-25) 525 | 526 | **Breaking change** 527 | 528 | This version is a compatibility change. All users of this cookbook must upgrade the cookbook to use current versions of Habitat. 529 | 530 | - Fix to account for [habitat-sh/habitat#3239](https://github.com/habitat-sh/habitat/pull/3239) - do not provide `/v1/depot` to Depot URL. 531 | - Pin the version of this cookbook along with the version of Habitat we install. This should match minor, but not necessarily patch versions. 532 | 533 | ## 0.28.0 (2017-09-19) 534 | 535 | - Add channel support to sup load/start 536 | 537 | ## 0.27.0 (2017-09-11) 538 | 539 | - Add hab_version and hab_channel to the sup service 540 | - Support multiple binds with hab_service 541 | 542 | ## 0.26.1 (2017-07-21) 543 | 544 | - `hab_package` now properly selects latest version from the specified channel. 545 | 546 | ## 0.26.0 (2017-07-17) 547 | 548 | ### Breaking Changes 549 | 550 | This cookbook was updated to be compatible with the changes made in Habitat 0.26. With these updates the cookbook now requires Habitat 0.26 or later. The version has been updated to match that of habitat. In the event of future breaking habitat changes the version of this cookbook will be updated to reflect the new minimum habitat release. 551 | 552 | - The cookbook now correctly parses the process status returned by the hab sup services endpoint 553 | - Packages now pull from the 'stable' channel by default. If you need to pull from another channel there is a new 'channel' property in the package resource that accepts a string. 554 | 555 | ### Other Changes 556 | 557 | - Resolves deprecation warnings introduced in Chef 13.2 558 | - Removed references in the readme to Chefstyle and simplified some of the requirements information 559 | - Added maintainer information to the readme and removed the maintainers file 560 | 561 | ## v0.4.0 (2017-04-26) 562 | 563 | - Backwards incompatible version, requires habitat 0.20 or higher 564 | - Add `hab_sup` resource for managing Habitat supervisor. See readme for usage. 565 | - Rewrite `hab_service` resource to manage services in Habitat supervisor 566 | 567 | ## v0.3.0 (2017-02-21) 568 | 569 | - Add property for ExecStart options. See readme for usage 570 | - Add property for depot_url. See readme for usage 571 | - Added restart action to the resource 572 | 573 | ## v0.2.0 (2016-11-30) 574 | 575 | - Added `version` and `channel` properties to install resource 576 | - Added `depot_url` property to hab_package resource 577 | 578 | ## v0.1.1 (2016-11-10) 579 | 580 | - Removed Chef 11 compatibility in the metadata 581 | - Resolved Chefstyle warnings 582 | - Resolved foodcritic warnings 583 | - Added a chefignore file 584 | - Updated the gitignore file 585 | - Improve the readme format and add badges 586 | - Update all test deps to current 587 | - Remove the apt testing dependency 588 | - Add integration testing in Travis using kitchen-dokken 589 | 590 | ## v0.1.0 (2016-11-08) 591 | 592 | - add `hab_service` resource 593 | - make the `hab_package` resource convergent 594 | - add chefspec and inspec tests 595 | - better documentation through README updates 596 | 597 | ## v0.0.3 (2016-07-14) 598 | 599 | - Initial release, includes `hab_package` and `hab_install` resources --------------------------------------------------------------------------------