diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..d77700e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +# editorconfig.org + +# MANAGED BY MODULESYNC + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +tab_width = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/.fixtures.yml b/.fixtures.yml new file mode 100644 index 0000000..76561a6 --- /dev/null +++ b/.fixtures.yml @@ -0,0 +1,9 @@ +--- +fixtures: + repositories: + archive: 'https://github.com/voxpupuli/puppet-archive.git' + cron: 'https://github.com/voxpupuli/puppet-cron.git' + stdlib: 'https://github.com/puppetlabs/puppetlabs-stdlib.git' + yumrepo_core: + repo: 'https://github.com/puppetlabs/puppetlabs-yumrepo_core' + puppet_version: '>= 6.0.0' diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 5bb969e..0000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.pp linguist-language=Puppet diff --git a/.gitignore b/.gitignore index 54d5afb..e9b3cf4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,20 @@ -*.log -*~ -.DS_Store -*.tmp -.librarian -pkg/* +pkg/ Gemfile.lock -spec/fixtures/modules/* -.vagrant +Gemfile.local +vendor/ +.vendor/ +spec/fixtures/manifests/ +spec/fixtures/modules/ +.vagrant/ +.bundle/ +.ruby-version +coverage/ +log/ +.idea/ +.dependencies/ +.librarian/ Puppetfile.lock -README.html +*.iml +.*.sw? +.yardoc/ +Guardfile diff --git a/.msync.yml b/.msync.yml new file mode 100644 index 0000000..2825b0c --- /dev/null +++ b/.msync.yml @@ -0,0 +1 @@ +modulesync_config_version: '2.11.0' diff --git a/.overcommit.yml b/.overcommit.yml new file mode 100644 index 0000000..1b03fad --- /dev/null +++ b/.overcommit.yml @@ -0,0 +1,64 @@ +# Managed by https://github.com/voxpupuli/modulesync_configs +# +# Hooks are only enabled if you take action. +# +# To enable the hooks run: +# +# ``` +# bundle exec overcommit --install +# # ensure .overcommit.yml does not harm to you and then +# bundle exec overcommit --sign +# ``` +# +# (it will manage the .git/hooks directory): +# +# Examples howto skip a test for a commit or push: +# +# ``` +# SKIP=RuboCop git commit +# SKIP=PuppetLint git commit +# SKIP=RakeTask git push +# ``` +# +# Don't invoke overcommit at all: +# +# ``` +# OVERCOMMIT_DISABLE=1 git commit +# ``` +# +# Read more about overcommit: https://github.com/brigade/overcommit +# +# To manage this config yourself in your module add +# +# ``` +# .overcommit.yml: +# unmanaged: true +# ``` +# +# to your modules .sync.yml config +--- +PreCommit: + RuboCop: + enabled: true + description: 'Runs rubocop on modified files only' + command: ['bundle', 'exec', 'rubocop'] + PuppetLint: + enabled: true + description: 'Runs puppet-lint on modified files only' + command: ['bundle', 'exec', 'puppet-lint'] + YamlSyntax: + enabled: true + JsonSyntax: + enabled: true + TrailingWhitespace: + enabled: true + +PrePush: + RakeTarget: + enabled: true + description: 'Run rake targets' + targets: + - 'validate' + - 'test' + - 'rubocop' + command: [ 'bundle', 'exec', 'rake' ] diff --git a/.pmtignore b/.pmtignore index 2be21dd..4e6d54b 100644 --- a/.pmtignore +++ b/.pmtignore @@ -1,4 +1,21 @@ -junit/ -log/ -spec/fixtures/modules/ +docs/ pkg/ +Gemfile.lock +Gemfile.local +vendor/ +.vendor/ +spec/fixtures/manifests/ +spec/fixtures/modules/ +.vagrant/ +.bundle/ +.ruby-version +coverage/ +log/ +.idea/ +.dependencies/ +.librarian/ +Puppetfile.lock +*.iml +.*.sw? +.yardoc/ +Dockerfile diff --git a/.puppet-lint.rc b/.puppet-lint.rc index 79185fc..a8e50fa 100644 --- a/.puppet-lint.rc +++ b/.puppet-lint.rc @@ -1,2 +1 @@ ---no-documentation-check ---no-class_inherits_from_params_class-check +--no-anchor_resource-check diff --git a/.rspec b/.rspec index 4bccf96..8c18f1a 100644 --- a/.rspec +++ b/.rspec @@ -1,5 +1,2 @@ --format documentation --color ---pattern "spec/*/*_spec.rb" -#--backtrace -#--fail-fast diff --git a/.rspec_parallel b/.rspec_parallel new file mode 100644 index 0000000..e4d136b --- /dev/null +++ b/.rspec_parallel @@ -0,0 +1 @@ +--format progress diff --git a/.rubocop.yml b/.rubocop.yml index e4d810a..c2ebc88 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,480 +1,546 @@ +require: rubocop-rspec AllCops: +# Puppet Server 5 defaults to jruby 1.7 so TargetRubyVersion must stay at 1.9 until we drop support for puppet 5 + TargetRubyVersion: 1.9 + Include: + - ./**/*.rb Exclude: - # Ignore HTML related things - - '**/*.erb' - # Ignore vendored gems - - 'vendor/**/*' - # Ignore code from test fixtures - - 'spec/fixtures/**/*' - + - files/**/* + - vendor/**/* + - .vendor/**/* + - pkg/**/* + - spec/fixtures/**/* + - Gemfile + - Rakefile + - Guardfile + - Vagrantfile Lint/ConditionPosition: - Enabled: true + Enabled: True Lint/ElseLayout: - Enabled: true + Enabled: True Lint/UnreachableCode: - Enabled: true + Enabled: True Lint/UselessComparison: - Enabled: true + Enabled: True Lint/EnsureReturn: - Enabled: true + Enabled: True Lint/HandleExceptions: - Enabled: true + Enabled: True Lint/LiteralInCondition: - Enabled: true + Enabled: True Lint/ShadowingOuterLocalVariable: - Enabled: true + Enabled: True Lint/LiteralInInterpolation: - Enabled: true + Enabled: True + +Style/HashSyntax: + Enabled: True Style/RedundantReturn: - Enabled: true + Enabled: True + +Layout/EndOfLine: + Enabled: False Lint/AmbiguousOperator: - Enabled: true + Enabled: True Lint/AssignmentInCondition: - Enabled: true + Enabled: True -Style/SpaceBeforeComment: - Enabled: true +Layout/SpaceBeforeComment: + Enabled: True -# DISABLED - not useful -Style/HashSyntax: - Enabled: false - -# USES: as shortcut for non nil&valid checking a = x() and a.empty? -# DISABLED - not useful Style/AndOr: - Enabled: false + Enabled: True -# DISABLED - not useful Style/RedundantSelf: - Enabled: false + Enabled: True -# DISABLED - not useful +Metrics/BlockLength: + Enabled: False + +# Method length is not necessarily an indicator of code quality Metrics/MethodLength: - Enabled: false + Enabled: False + +# Module length is not necessarily an indicator of code quality +Metrics/ModuleLength: + Enabled: False -# DISABLED - not useful Style/WhileUntilModifier: - Enabled: false + Enabled: True -# DISABLED - the offender is just haskell envy Lint/AmbiguousRegexpLiteral: - Enabled: false + Enabled: True -# DISABLED -Lint/Eval: - Enabled: false +Security/Eval: + Enabled: True -# DISABLED Lint/BlockAlignment: - Enabled: false + Enabled: True -# DISABLED Lint/DefEndAlignment: - Enabled: false + Enabled: True -# DISABLED Lint/EndAlignment: - Enabled: false + Enabled: True -# DISABLED Lint/DeprecatedClassMethods: - Enabled: false + Enabled: True -# DISABLED Lint/Loop: - Enabled: false + Enabled: True -# DISABLED Lint/ParenthesesAsGroupedExpression: - Enabled: false + Enabled: True Lint/RescueException: - Enabled: false + Enabled: True Lint/StringConversionInInterpolation: - Enabled: false + Enabled: True Lint/UnusedBlockArgument: - Enabled: false + Enabled: True Lint/UnusedMethodArgument: - Enabled: false + Enabled: True Lint/UselessAccessModifier: - Enabled: true + Enabled: True Lint/UselessAssignment: - Enabled: true + Enabled: True Lint/Void: - Enabled: true + Enabled: True -Style/AccessModifierIndentation: - Enabled: false +Layout/AccessModifierIndentation: + Enabled: True Style/AccessorMethodName: - Enabled: false + Enabled: True Style/Alias: - Enabled: false + Enabled: True -Style/AlignArray: - Enabled: false +Layout/AlignArray: + Enabled: True -Style/AlignHash: - Enabled: false +Layout/AlignHash: + Enabled: True -Style/AlignParameters: - Enabled: false +Layout/AlignParameters: + Enabled: True Metrics/BlockNesting: - Enabled: false + Enabled: True Style/AsciiComments: - Enabled: false + Enabled: True Style/Attr: - Enabled: false + Enabled: True Style/BracesAroundHashParameters: - Enabled: false + Enabled: True Style/CaseEquality: - Enabled: false + Enabled: True -Style/CaseIndentation: - Enabled: false +Layout/CaseIndentation: + Enabled: True Style/CharacterLiteral: - Enabled: false + Enabled: True Style/ClassAndModuleCamelCase: - Enabled: false + Enabled: True Style/ClassAndModuleChildren: - Enabled: false + Enabled: False Style/ClassCheck: - Enabled: false + Enabled: True +# Class length is not necessarily an indicator of code quality Metrics/ClassLength: - Enabled: false + Enabled: False Style/ClassMethods: - Enabled: false + Enabled: True Style/ClassVars: - Enabled: false + Enabled: True Style/WhenThen: - Enabled: false + Enabled: True -# DISABLED - not useful Style/WordArray: - Enabled: false + Enabled: True Style/UnneededPercentQ: - Enabled: false + Enabled: True -Style/Tab: - Enabled: false +Layout/Tab: + Enabled: True -Style/SpaceBeforeSemicolon: - Enabled: false +Layout/SpaceBeforeSemicolon: + Enabled: True -Style/TrailingBlankLines: - Enabled: false +Layout/TrailingBlankLines: + Enabled: True -Style/SpaceInsideBlockBraces: - Enabled: false +Layout/SpaceInsideBlockBraces: + Enabled: True -Style/SpaceInsideBrackets: - Enabled: false +Layout/SpaceInsideBrackets: + Enabled: True -Style/SpaceInsideHashLiteralBraces: - Enabled: false +Layout/SpaceInsideHashLiteralBraces: + Enabled: True -Style/SpaceInsideParens: - Enabled: false +Layout/SpaceInsideParens: + Enabled: True -Style/LeadingCommentSpace: - Enabled: false +Layout/LeadingCommentSpace: + Enabled: True -Style/SingleSpaceBeforeFirstArg: - Enabled: false - -Style/SpaceAfterColon: - Enabled: false +Layout/SpaceBeforeFirstArg: + Enabled: True -Style/SpaceAfterComma: - Enabled: false +Layout/SpaceAfterColon: + Enabled: True -Style/SpaceAfterControlKeyword: - Enabled: false +Layout/SpaceAfterComma: + Enabled: True -Style/SpaceAfterMethodName: - Enabled: false +Layout/SpaceAfterMethodName: + Enabled: True -Style/SpaceAfterNot: - Enabled: false +Layout/SpaceAfterNot: + Enabled: True -Style/SpaceAfterSemicolon: - Enabled: false +Layout/SpaceAfterSemicolon: + Enabled: True -Style/SpaceAroundEqualsInParameterDefault: - Enabled: false +Layout/SpaceAroundEqualsInParameterDefault: + Enabled: True -Style/SpaceAroundOperators: - Enabled: false +Layout/SpaceAroundOperators: + Enabled: True -Style/SpaceBeforeBlockBraces: - Enabled: false +Layout/SpaceBeforeBlockBraces: + Enabled: True -Style/SpaceBeforeComma: - Enabled: false +Layout/SpaceBeforeComma: + Enabled: True Style/CollectionMethods: - Enabled: false + Enabled: True -Style/CommentIndentation: - Enabled: false +Layout/CommentIndentation: + Enabled: True Style/ColonMethodCall: - Enabled: false + Enabled: True Style/CommentAnnotation: - Enabled: false + Enabled: True +# 'Complexity' is very relative Metrics/CyclomaticComplexity: - Enabled: false + Enabled: False Style/ConstantName: - Enabled: false + Enabled: True Style/Documentation: - Enabled: false + Enabled: False Style/DefWithParentheses: - Enabled: false + Enabled: True -Style/DeprecatedHashMethods: - Enabled: false +Style/PreferredHashMethods: + Enabled: True -Style/DotPosition: - Enabled: false +Layout/DotPosition: + EnforcedStyle: trailing -# DISABLED - used for converting to bool Style/DoubleNegation: - Enabled: false + Enabled: True Style/EachWithObject: - Enabled: false + Enabled: True -Style/EmptyLineBetweenDefs: - Enabled: false +Layout/EmptyLineBetweenDefs: + Enabled: True -Style/IndentArray: - Enabled: false +Layout/IndentArray: + Enabled: True -Style/IndentHash: - Enabled: false +Layout/IndentHash: + Enabled: True -Style/IndentationConsistency: - Enabled: false +Layout/IndentationConsistency: + Enabled: True -Style/IndentationWidth: - Enabled: false +Layout/IndentationWidth: + Enabled: True -Style/EmptyLines: - Enabled: false +Layout/EmptyLines: + Enabled: True -Style/EmptyLinesAroundAccessModifier: - Enabled: false +Layout/EmptyLinesAroundAccessModifier: + Enabled: True Style/EmptyLiteral: - Enabled: false + Enabled: True +# Configuration parameters: AllowURI, URISchemes. Metrics/LineLength: - Enabled: false + Enabled: False -Style/MethodCallParentheses: - Enabled: false +Style/MethodCallWithoutArgsParentheses: + Enabled: True Style/MethodDefParentheses: - Enabled: false + Enabled: True Style/LineEndConcatenation: - Enabled: false + Enabled: True -Style/TrailingWhitespace: - Enabled: false +Layout/TrailingWhitespace: + Enabled: True Style/StringLiterals: - Enabled: false + Enabled: True -Style/TrailingComma: - Enabled: false +Style/TrailingCommaInArguments: + Enabled: True + +Style/TrailingCommaInLiteral: + Enabled: True Style/GlobalVars: - Enabled: false + Enabled: True Style/GuardClause: - Enabled: false + Enabled: True Style/IfUnlessModifier: - Enabled: false + Enabled: True Style/MultilineIfThen: - Enabled: false + Enabled: True Style/NegatedIf: - Enabled: false + Enabled: True Style/NegatedWhile: - Enabled: false + Enabled: True Style/Next: - Enabled: false + Enabled: True Style/SingleLineBlockParams: - Enabled: false + Enabled: True Style/SingleLineMethods: - Enabled: false + Enabled: True Style/SpecialGlobalVars: - Enabled: false + Enabled: True Style/TrivialAccessors: - Enabled: false + Enabled: True Style/UnlessElse: - Enabled: false + Enabled: True Style/VariableInterpolation: - Enabled: false + Enabled: True Style/VariableName: - Enabled: false + Enabled: True Style/WhileUntilDo: - Enabled: false + Enabled: True Style/EvenOdd: - Enabled: false + Enabled: True Style/FileName: - Enabled: false + Enabled: True Style/For: - Enabled: false + Enabled: True Style/Lambda: - Enabled: false + Enabled: True Style/MethodName: - Enabled: false + Enabled: True Style/MultilineTernaryOperator: - Enabled: false + Enabled: True Style/NestedTernaryOperator: - Enabled: false + Enabled: True Style/NilComparison: - Enabled: false + Enabled: True Style/FormatString: - Enabled: false + Enabled: True Style/MultilineBlockChain: - Enabled: false + Enabled: True Style/Semicolon: - Enabled: false + Enabled: True Style/SignalException: - Enabled: false + Enabled: True Style/NonNilCheck: - Enabled: false + Enabled: True Style/Not: - Enabled: false + Enabled: True Style/NumericLiterals: - Enabled: false + Enabled: True Style/OneLineConditional: - Enabled: false + Enabled: True Style/OpMethod: - Enabled: false + Enabled: True Style/ParenthesesAroundCondition: - Enabled: false + Enabled: True Style/PercentLiteralDelimiters: - Enabled: false + Enabled: True Style/PerlBackrefs: - Enabled: false + Enabled: True Style/PredicateName: - Enabled: false + Enabled: True Style/RedundantException: - Enabled: false + Enabled: True Style/SelfAssignment: - Enabled: false + Enabled: True Style/Proc: - Enabled: false + Enabled: True Style/RaiseArgs: - Enabled: false + Enabled: True Style/RedundantBegin: - Enabled: false + Enabled: True Style/RescueModifier: - Enabled: false + Enabled: True +# based on https://github.com/voxpupuli/modulesync_config/issues/168 Style/RegexpLiteral: - Enabled: false + EnforcedStyle: percent_r + Enabled: True Lint/UnderscorePrefixedVariableName: - Enabled: false + Enabled: True Metrics/ParameterLists: - Enabled: false + Enabled: False Lint/RequireParentheses: - Enabled: false - -Lint/SpaceBeforeFirstArg: - Enabled: false + Enabled: True Style/ModuleFunction: - Enabled: false + Enabled: True Lint/Debugger: - Enabled: false + Enabled: True Style/IfWithSemicolon: - Enabled: false + Enabled: True Style/Encoding: + Enabled: True + +Style/BlockDelimiters: + Enabled: True + +Layout/MultilineBlockLayout: + Enabled: True + +# 'Complexity' is very relative +Metrics/AbcSize: + Enabled: False + +# 'Complexity' is very relative +Metrics/PerceivedComplexity: + Enabled: False + +Lint/UselessAssignment: + Enabled: True + +Layout/ClosingParenthesisIndentation: + Enabled: True + +# RSpec + +RSpec/BeforeAfterAll: + Exclude: + - spec/acceptance/**/* + +# We don't use rspec in this way +RSpec/DescribeClass: + Enabled: False + +# Example length is not necessarily an indicator of code quality +RSpec/ExampleLength: + Enabled: False + +RSpec/NamedSubject: + Enabled: False + +# disabled for now since they cause a lot of issues +# these issues aren't easy to fix +RSpec/RepeatedDescription: + Enabled: False + +RSpec/NestedGroups: + Enabled: False + +# this is broken on ruby1.9 +Layout/IndentHeredoc: + Enabled: False + +# disable Yaml safe_load. This is needed to support ruby2.0.0 development envs +Security/YAMLLoad: + Enabled: false + +# This affects hiera interpolation, as well as some configs that we push. +Style/FormatStringToken: + Enabled: false + +# This is useful, but sometimes a little too picky about where unit tests files +# are located. +RSpec/FilePath: Enabled: false diff --git a/.sync.yml b/.sync.yml new file mode 100644 index 0000000..a75759b --- /dev/null +++ b/.sync.yml @@ -0,0 +1,28 @@ +--- +.github/CONTRIBUTING.md: + delete: true + +.github/ISSUE_TEMPLATE.md: + delete: true + +.github/PULL_REQUEST_TEMPLATE.md: + delete: true + +.travis.yml: + docker_sets: + - set: debian8-64 + - set: debian9-64 + - set: debian10-64 + - set: ubuntu1604-64 + - set: ubuntu1804-64 + - set: centos6-64 + - set: centos7-64 + irc: false + user: 'deric' + secure: '' + +Rakefile: + config.user: 'deric' + +spec/spec_helper.rb: + spec_overrides: "require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb'))" diff --git a/.travis.yml b/.travis.yml index 6fb5263..76dea6a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,36 +1,98 @@ -# linter: http://lint.travis-ci.org/ +--- +dist: bionic language: ruby -sudo: false -bundler_args: --without development -cache: - bundler: true - directories: - - $HOME/librarian-puppet +cache: bundler +before_install: + - yes | gem update --system + - bundle --version script: - - RAKE_ENV=ci bundle exec puppet --version - - RAKE_ENV=ci bundle exec rake validate - - RAKE_ENV=ci bundle exec rake spec - - RAKE_ENV=ci bundle exec rake lint -rvm: - - 2.4.4 - - 2.5.3 -env: - global: - - LIBRARIAN_PUPPET_TMP="$HOME/librarian-puppet" - matrix: - - PUPPET_VERSION="~> 5.0" STRICT_VARIABLES=yes - - PUPPET_VERSION="~> 6.0" STRICT_VARIABLES=yes + - 'bundle exec rake $CHECK' matrix: + fast_finish: true include: - - rvm: 2.4.4 - dist: trusty - env: RAKE_ENV=ci BEAKER_debug=true BEAKER_set=default - script: bundle exec rake acceptance - services: docker - sudo: required - - rvm: 2.4.4 - dist: trusty - env: RAKE_ENV=ci BEAKER_debug=true BEAKER_set=debian9-6.3 - script: bundle exec rake acceptance - services: docker - sudo: required + - rvm: 2.4.4 + bundler_args: --without system_tests development release + env: PUPPET_VERSION="~> 5.0" CHECK=test + - rvm: 2.5.3 + bundler_args: --without system_tests development release + env: PUPPET_VERSION="~> 6.0" CHECK=test_with_coveralls + - rvm: 2.5.3 + bundler_args: --without system_tests development release + env: PUPPET_VERSION="~> 6.0" CHECK=rubocop + - rvm: 2.4.4 + bundler_args: --without system_tests development release + env: PUPPET_VERSION="~> 5.0" CHECK=build DEPLOY_TO_FORGE=yes + - rvm: 2.5.3 + bundler_args: --without development release + env: PUPPET_INSTALL_TYPE=agent BEAKER_PUPPET_COLLECTION=puppet5 BEAKER_debug=true BEAKER_setfile=debian8-64 BEAKER_HYPERVISOR=docker CHECK=beaker + services: docker + - rvm: 2.5.3 + bundler_args: --without development release + env: PUPPET_INSTALL_TYPE=agent BEAKER_PUPPET_COLLECTION=puppet6 BEAKER_debug=true BEAKER_setfile=debian8-64 BEAKER_HYPERVISOR=docker CHECK=beaker + services: docker + - rvm: 2.5.3 + bundler_args: --without development release + env: PUPPET_INSTALL_TYPE=agent BEAKER_PUPPET_COLLECTION=puppet5 BEAKER_debug=true BEAKER_setfile=debian9-64 BEAKER_HYPERVISOR=docker CHECK=beaker + services: docker + - rvm: 2.5.3 + bundler_args: --without development release + env: PUPPET_INSTALL_TYPE=agent BEAKER_PUPPET_COLLECTION=puppet6 BEAKER_debug=true BEAKER_setfile=debian9-64 BEAKER_HYPERVISOR=docker CHECK=beaker + services: docker + - rvm: 2.5.3 + bundler_args: --without development release + env: PUPPET_INSTALL_TYPE=agent BEAKER_PUPPET_COLLECTION=puppet5 BEAKER_debug=true BEAKER_setfile=debian10-64 BEAKER_HYPERVISOR=docker CHECK=beaker + services: docker + - rvm: 2.5.3 + bundler_args: --without development release + env: PUPPET_INSTALL_TYPE=agent BEAKER_PUPPET_COLLECTION=puppet6 BEAKER_debug=true BEAKER_setfile=debian10-64 BEAKER_HYPERVISOR=docker CHECK=beaker + services: docker + - rvm: 2.5.3 + bundler_args: --without development release + env: PUPPET_INSTALL_TYPE=agent BEAKER_PUPPET_COLLECTION=puppet5 BEAKER_debug=true BEAKER_setfile=ubuntu1604-64 BEAKER_HYPERVISOR=docker CHECK=beaker + services: docker + - rvm: 2.5.3 + bundler_args: --without development release + env: PUPPET_INSTALL_TYPE=agent BEAKER_PUPPET_COLLECTION=puppet6 BEAKER_debug=true BEAKER_setfile=ubuntu1604-64 BEAKER_HYPERVISOR=docker CHECK=beaker + services: docker + - rvm: 2.5.3 + bundler_args: --without development release + env: PUPPET_INSTALL_TYPE=agent BEAKER_PUPPET_COLLECTION=puppet5 BEAKER_debug=true BEAKER_setfile=ubuntu1804-64 BEAKER_HYPERVISOR=docker CHECK=beaker + services: docker + - rvm: 2.5.3 + bundler_args: --without development release + env: PUPPET_INSTALL_TYPE=agent BEAKER_PUPPET_COLLECTION=puppet6 BEAKER_debug=true BEAKER_setfile=ubuntu1804-64 BEAKER_HYPERVISOR=docker CHECK=beaker + services: docker + - rvm: 2.5.3 + bundler_args: --without development release + env: PUPPET_INSTALL_TYPE=agent BEAKER_PUPPET_COLLECTION=puppet5 BEAKER_debug=true BEAKER_setfile=centos6-64 BEAKER_HYPERVISOR=docker CHECK=beaker + services: docker + - rvm: 2.5.3 + bundler_args: --without development release + env: PUPPET_INSTALL_TYPE=agent BEAKER_PUPPET_COLLECTION=puppet6 BEAKER_debug=true BEAKER_setfile=centos6-64 BEAKER_HYPERVISOR=docker CHECK=beaker + services: docker + - rvm: 2.5.3 + bundler_args: --without development release + env: PUPPET_INSTALL_TYPE=agent BEAKER_PUPPET_COLLECTION=puppet5 BEAKER_debug=true BEAKER_setfile=centos7-64 BEAKER_HYPERVISOR=docker CHECK=beaker + services: docker + - rvm: 2.5.3 + bundler_args: --without development release + env: PUPPET_INSTALL_TYPE=agent BEAKER_PUPPET_COLLECTION=puppet6 BEAKER_debug=true BEAKER_setfile=centos7-64 BEAKER_HYPERVISOR=docker CHECK=beaker + services: docker +branches: + only: + - master + - /^v\d/ +notifications: + email: false + webhooks: https://voxpupu.li/incoming/travis +deploy: + provider: puppetforge + user: deric + password: + secure: "" + on: + tags: true + # all_branches is required to use tags + all_branches: true + # Only publish the build marked with "DEPLOY_TO_FORGE" + condition: "$DEPLOY_TO_FORGE = yes" diff --git a/.yardopts b/.yardopts new file mode 100644 index 0000000..3687f51 --- /dev/null +++ b/.yardopts @@ -0,0 +1,2 @@ +--markup markdown +--output-dir docs/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6fd6342 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +FROM ruby:2.5.3 + +WORKDIR /opt/puppet + +# https://github.com/puppetlabs/puppet/blob/06ad255754a38f22fb3a22c7c4f1e2ce453d01cb/lib/puppet/provider/service/runit.rb#L39 +RUN mkdir -p /etc/sv + +ARG PUPPET_VERSION="~> 6.0" +ARG PARALLEL_TEST_PROCESSORS=4 + +# Cache gems +COPY Gemfile . +RUN bundle install --without system_tests development release --path=${BUNDLE_PATH:-vendor/bundle} + +COPY . . + +RUN bundle install +RUN bundle exec rake release_checks + +# Container should not saved +RUN exit 1 diff --git a/Gemfile b/Gemfile index e092eb4..8b4adb5 100644 --- a/Gemfile +++ b/Gemfile @@ -1,43 +1,86 @@ -source 'https://rubygems.org' - -group :tests do - puppetversion = ENV.key?('PUPPET_VERSION') ? "#{ENV['PUPPET_VERSION']}" : ['>= 5.5.8', '< 7.0'] - gem 'puppet', puppetversion - gem 'rake' - gem 'puppet-lint' - gem 'puppetlabs_spec_helper' - gem 'librarian-puppet', '>= 2.0' - gem 'highline' - gem 'simplecov' - gem 'simplecov-console' - gem 'rspec-puppet-facts' - gem 'rspec', '>= 3.0.0' - gem 'rspec-puppet', '>= 2.3.0' - gem 'metadata-json-lint', require: false +source ENV['GEM_SOURCE'] || "https://rubygems.org" + +def location_for(place, fake_version = nil) + if place =~ /^(git[:@][^#]*)#(.*)/ + [fake_version, { :git => $1, :branch => $2, :require => false }].compact + elsif place =~ /^file:\/\/(.*)/ + ['>= 0', { :path => File.expand_path($1), :require => false }] + else + [place, { :require => false }] + end end -# xmlrpc used to be bundled with Ruby until 2.4 -if RUBY_VERSION >= '2.4.0' - gem 'xmlrpc' +group :test do + gem 'puppetlabs_spec_helper', '>= 2.14.0', :require => false + gem 'rspec-puppet-facts', '>= 1.9.5', :require => false + gem 'rspec-puppet-utils', :require => false + gem 'puppet-lint-leading_zero-check', :require => false + gem 'puppet-lint-trailing_comma-check', :require => false + gem 'puppet-lint-version_comparison-check', :require => false + gem 'puppet-lint-classes_and_types_beginning_with_digits-check', :require => false + gem 'puppet-lint-unquoted_string-check', :require => false + gem 'puppet-lint-variable_contains_upcase', :require => false + gem 'puppet-lint-absolute_classname-check', '>= 2.0.0', :require => false + gem 'puppet-lint-topscope-variable-check', :require => false + gem 'puppet-lint-legacy_facts-check', :require => false + gem 'puppet-lint-anchor-check', :require => false + gem 'metadata-json-lint', :require => false + gem 'redcarpet', :require => false + gem 'rubocop', '~> 0.49.1', :require => false + gem 'rubocop-rspec', '~> 1.15.0', :require => false + gem 'mocha', '~> 1.4.0', :require => false + gem 'coveralls', :require => false + gem 'simplecov-console', :require => false + gem 'parallel_tests', :require => false end group :development do - gem 'rubocop', '>= 0.49.0' - gem 'puppet-blacksmith', git: 'https://github.com/deric/puppet-blacksmith', branch: 'tag-order' + gem 'travis', :require => false + gem 'travis-lint', :require => false + gem 'guard-rake', :require => false + gem 'overcommit', '>= 0.39.1', :require => false end group :system_tests do - # beaker-rspec will require beaker gem - if RUBY_VERSION >= '2.2.5' - gem 'beaker' + gem 'winrm', :require => false + if beaker_version = ENV['BEAKER_VERSION'] + gem 'beaker', *location_for(beaker_version) else - gem 'beaker', '< 3' + gem 'beaker', '>= 4.2.0', :require => false end - gem 'pry' - gem 'beaker-rspec' - gem 'beaker-docker' - gem 'serverspec' - gem 'beaker-hostgenerator' - gem 'beaker-puppet_install_helper' - gem 'master_manipulator' + if beaker_rspec_version = ENV['BEAKER_RSPEC_VERSION'] + gem 'beaker-rspec', *location_for(beaker_rspec_version) + else + gem 'beaker-rspec', :require => false + end + gem 'serverspec', :require => false + gem 'beaker-hostgenerator', '>= 1.1.22', :require => false + gem 'beaker-docker', :require => false + gem 'beaker-puppet', :require => false + gem 'beaker-puppet_install_helper', :require => false + gem 'beaker-module_install_helper', :require => false + gem 'rbnacl', '>= 4', :require => false + gem 'rbnacl-libsodium', :require => false + gem 'bcrypt_pbkdf', :require => false + gem 'ed25519', :require => false +end + +group :release do + gem 'github_changelog_generator', :require => false, :git => 'https://github.com/voxpupuli/github-changelog-generator', :branch => 'voxpupuli_essential_fixes' + gem 'puppet-blacksmith', :require => false + gem 'voxpupuli-release', :require => false + gem 'puppet-strings', '>= 2.2', :require => false end + + + +if facterversion = ENV['FACTER_GEM_VERSION'] + gem 'facter', facterversion.to_s, :require => false, :groups => [:test] +else + gem 'facter', :require => false, :groups => [:test] +end + +ENV['PUPPET_VERSION'].nil? ? puppetversion = '~> 6.0' : puppetversion = ENV['PUPPET_VERSION'].to_s +gem 'puppet', puppetversion, :require => false, :groups => [:test] + +# vim: syntax=ruby diff --git a/README.md b/README.md index a09771c..63c1114 100644 --- a/README.md +++ b/README.md @@ -1,379 +1,380 @@ # puppet-zookeeper [![Puppet Forge](http://img.shields.io/puppetforge/v/deric/zookeeper.svg)](https://forge.puppetlabs.com/deric/zookeeper) [![Build Status](https://travis-ci.org/deric/puppet-zookeeper.png?branch=master)](https://travis-ci.org/deric/puppet-zookeeper) [![Puppet Forge Downloads](http://img.shields.io/puppetforge/dt/deric/zookeeper.svg)](https://forge.puppetlabs.com/deric/zookeeper/scores) A puppet receipt for [Apache Zookeeper](http://zookeeper.apache.org/). ZooKeeper is a high-performance coordination service for maintaining configuration information, naming, providing distributed synchronization, and providing group services. ## Requirements * Puppet * Binary or ZooKeeper source code archive Compatibility matrix: | `puppet-zookeeper`| Puppet 3.x | Puppet 4.x | Puppet 5.x | Puppet 6.x | | ----------------- | ------------- |--------------| -----------|----------------| | `0.7.x` | :heavy_check_mark: | :heavy_check_mark: | :question: | :x: | | `0.8.x` | :x: | :heavy_check_mark: | :heavy_check_mark: | :x: | | `0.9.x` | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | ## Basic Usage: ```puppet class { 'zookeeper': } ``` ## Cluster setup When running ZooKeeper in the distributed mode each node must have unique ID (`1-255`). The easiest way how to setup multiple ZooKeepers, is by using Hiera. `hiera/host/zk1.example.com.yaml`: ```yaml zookeeper::id: '1' ``` `hiera/host/zk2.example.com.yaml`: ```yaml zookeeper::id: '2' ``` `hiera/host/zk3.example.com.yaml`: ```yaml zookeeper::id: '3' ``` A ZooKeeper quorum should consist of odd number of nodes (usually `3` or `5`). For defining a quorum it is enough to list all IP addresses of all its members. ```puppet class { 'zookeeper': servers => { 1 => '192.168.1.1', 2 => '192.168.1.2', 3 => '192.168.1.3', }, } ``` In case that an array is passed as `servers`, first ZooKeeper will be assigned `ID = 1`. This would produce following configuration: ``` server.1=192.168.1.1:2888:3888 server.2=192.168.1.2:2888:3888 server.3=192.168.1.3:2888:3888 ``` where first port is `election_port` and second one `leader_port`. Both ports could be customized for each ZooKeeper instance. ```puppet class { 'zookeeper': election_port => 2889, leader_port => 3889, servers => { 1 => '192.168.1.1', 2 => '192.168.1.2', 3 => '192.168.1.3', } } ``` ### Observers [Observers](http://zookeeper.apache.org/doc/r3.3.0/zookeeperObservers.html) were introduced in ZooKeeper 3.3.0. To enable this feature simply state which of ZooKeeper servers are observing: ```puppet class { 'zookeeper': servers => ['192.168.1.1', '192.168.1.2', '192.168.1.3', '192.168.1.4', '192.168.1.5'], observers => ['192.168.1.4', '192.168.1.5'] } ``` **Note**: Currently observer server needs to be listed between standard servers (this behavior might change in feature). ### Set binding interface By default ZooKeeper should bind to all interfaces. When you specify `client_ip` only single interface will be used. If `$::ipaddress` is not your public IP (e.g. you are using Docker) make sure to setup correct IP: ```puppet class { 'zookeeper': client_ip => $::ipaddress_eth0 } ``` or in Hiera: ```yaml zookeeper::client_ip: "%{::ipaddress_eth0}" ``` This is a workaround for a a [Facter issue](https://tickets.puppetlabs.com/browse/FACT-380). ### ZooKeeper service Use `service_provider` to override Puppet detection for starting service. ```puppet class { 'zookeeper': service_provider => 'init', manage_service_file => false, } ``` Some reasonable values are: + * `init` * `systemd` * `runit` * `exhibitor` - zookeeper process and config will be managed by exhibitor (https://github.com/soabase/exhibitor). Exhibitor is not managed by this module. * `none` - service won't be installed Parameter `manage_service_file` controls whether service definition should be managed by Puppet (default: `false`). Currently supported for `systemd` and `init`. ### Systemd Unit 'After' and 'Want' control By default the module will create the following Unit section in /etc/systemd/system/multi-user.target.wants/zookeeper.service ```` [Unit] Description=Apache ZooKeeper After=network.target ```` Both After and Want (omitted when using the module defaults) can be controled using this module. E.g on CentOS 7 those might have to be configured for 'netwrok-online.target' using the following syntax: ```puppet class { 'zookeeper': systemd_unit_after => 'network-online.target', systemd_unit_want => 'network-online.target', } ``` Which will modify the Unit section to look like: ```` [Unit] Description=Apache ZooKeeper Want=network-online.target After=network-online.target ```` ## Parameters - `id` - cluster-unique zookeeper's instance id (1-255) - `datastore` - `datalogstore` - specifying this configures the `dataLogDir` ZooKeeper config values and allows for transaction logs to be stored in a different location, improving IO performance - `log_dir` - `purge_interval` - automatically will delete ZooKeeper logs (available since ZooKeeper 3.4.0) - `snap_retain_count` - number of snapshots that will be kept after purging (since ZooKeeper 3.4.0) - `min_session_timeout` - the minimum session timeout in milliseconds that the server will allow the client to negotiate. Defaults to 2 times the **tickTime** (since ZooKeeper 3.3.0) - `max_session_timeout` - the maximum session timeout in milliseconds that the server will allow the client to negotiate. Defaults to 20 times the **tickTime** (since ZooKeeper 3.3.0) - `global_outstanding_limit` - ZooKeeper will throttle clients so that there is no more than `global_outstanding_limit` outstanding requests in the system. - `manage_service` (default: `true`) whether Puppet should ensure running service - `manage_service_file` when enabled on RHEL 7.0 a systemd config will be managed - `ensure_account` controls whether `zookeeper` user and group will be ensured (set to `false` to disable this feature) - `install_method` controls whether ZooKeeper is installed from binary (`package`) or source (`archive`) packages - `archive_version` allows to specify an arbitrary version of ZooKeeper when using source packages - `archive_install_dir` controls the installation directory when using source packages (defaults to `/opt`) - `archive_symlink` controls the name of a version-independent symlink when using source packages - `archive_dl_url` allows to change the download URL for source packages (defaults to apache.org) - `systemd_path` where to put `systemd` service files (applies only if `manage_service_file` and `service_provider == 'systemd'`) - `restart_on_change` whether ZooKeeper service should be restarted on configuration files change (default: `true`) - `remove_host_principal` whether to remove host from Kerberos principal (default: `false`) - `remove_realm_principal` whether to remove relam from Kerberos principal (default: `false`) - `whitelist_4lw` Fine grained control over the set of commands ZooKeeper can execute (an array e.g. `whitelist_4lw = ['*']`) and many others, see the `params.pp` file for more details. If your distribution has multiple packages for ZooKeeper, you can provide all package names as an array. ```puppet class { 'zookeeper': packages => ['zookeeper', 'zookeeper-java'] } ``` ## Logging ZooKeeper uses log4j, following variables can be configured: ```puppet class { 'zookeeper': console_threshold => 'INFO', rollingfile_threshold => 'INFO', tracefile_threshold => 'TRACE', maxfilesize => '256MB', maxbackupindex => 20, } ``` Threshold supported values are: `ALL`, `DEBUG`, `ERROR`, `FATAL`, `INFO`, `OFF`, `TRACE` and `WARN`. [Maxfilesize](https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/RollingFileAppender.html#maxFileSize) [MaxBackupIndex](https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/RollingFileAppender.html#maxBackupIndex) By default console, rolling file and trace logging can be configured. Additional log appenders (vulgo log methods) can be configured by adding a hash `extra_appenders`. The following sets up syslog logging and points the root logger towards syslog (note that you must have syslog listening on port 514/udp for this to work): ```puppet class { 'zookeeper': log4j_prop => 'INFO,SYSLOG', extra_appenders => { 'Syslog' => { 'class' => 'org.apache.log4j.net.SyslogAppender', 'layout' => 'org.apache.log4j.PatternLayout', 'layout.conversionPattern' => "${hostname} zookeeper[id:%X{myid}] - %-5p [%t:%C{1}@%L][%x] - %m%n", 'syslogHost' => 'localhost', 'facility' => 'user', }, }, } ``` ## Hiera Support All parameters could be defined in hiera files, e.g. `common.yaml`, `Debian.yaml` or `zookeeper.yaml`: ```yaml zookeeper::id: 1 zookeeper::client_port: 2181 zookeeper::datastore: '/var/lib/zookeeper' zookeeper::datalogstore: '/disk2/zookeeper' ``` ## Cloudera package In Cloudera distribution ZooKeeper package does not provide init scripts (same as in Debian). Package containing init scripts is called `zookeeper-server` and the service as well. Moreover there's initialization script which should be called after installation. So, the configuration might look like this: ```puppet class { 'zookeeper': packages => ['zookeeper', 'zookeeper-server'], service_name => 'zookeeper-server', initialize_datastore => true } ``` ### Managing repository For RedHat family currently we support also managing a `cloudera` yum repo versions 4, and 5. It can be enabled with `repo` parameter: ```puppet class { 'zookeeper': repo => 'cloudera', cdhver => '5', } ``` #### Custom RPM repository Optionally you can specify a custom repository, using a hash configuration. ```puppet class { 'zookeeper': cdhver => '5', repo => { name => 'myrepo', url => 'http://cusom.url', descr => 'description' } } ``` ## Source package Source packages provide the ability to install arbitrary versions of ZooKeeper on any platform. Note that you'll likely have to use the `manage_service_file` in order to be able to control the ZooKeeper service (because source packages do not install service files). ```puppet class { 'zookeeper': install_method => 'archive', archive_version => '3.4.8', } ``` Optionally you can specify a `proxy_server`: ```puppet class { 'zookeeper': install_method => 'archive', archive_version => '3.4.8', proxy_server => 'http://10.0.0.1:8080' } ``` ## Java installation Default: `false` By changing these two parameters you can ensure, that given Java package will be installed before ZooKeeper packages. ```puppet class { 'zookeeper': install_java => true, java_package => 'openjdk-7-jre-headless' } ``` ## Install ### Librarian (recommended) For [puppet-librarian](https://github.com/rodjek/librarian-puppet) just add to `Puppetfile` from Forge: ```ruby mod 'deric-zookeeper' ``` latest (development) version from GitHub ```ruby mod 'deric-zookeeper', git: 'git://github.com/deric/puppet-zookeeper.git' ``` ### submodules If you are versioning your puppet conf with git just add it as submodule, from your repository root: git submodule add git://github.com/deric/puppet-zookeeper.git modules/zookeeper ## Dependencies * stdlib `> 2.3.3` - function `ensure_resources` is required * puppet-archive `> 0.4.4` - provides capabilities to use archives instead of binary packages ## Acceptance testing Fastest way is to run tests on prepared Docker images: ``` BEAKER_set=debian9-6.3 bundle exec rake acceptance ``` For examining system state set Beaker's ENV variable `BEAKER_destroy=no`: ``` BEAKER_destroy=no BEAKER_set=default bundle exec rake acceptance ``` and after finishing tests connect to container: ``` docker exec -it adoring_shirley bash ``` When host machine is NOT provisioned (puppet installed, etc.): ``` PUPPET_install=yes BEAKER_set=debian-8 bundle exec rake acceptance ``` Run on specific OS (see `spec/acceptance/nodesets`), to see available sets: ``` rake beaker:sets ``` ## Supported platforms * Debian/Ubuntu * RedHat/CentOS/Fedora ### Tested on: * Debian (8, 9, 10) * Ubuntu (16.04, 18.04) * RHEL (6, 7) * CentOS (6, 7) diff --git a/Rakefile b/Rakefile index 07f736f..56700a9 100644 --- a/Rakefile +++ b/Rakefile @@ -1,51 +1,85 @@ -require 'rubygems' -require 'bundler/setup' - require 'puppetlabs_spec_helper/rake_tasks' -require 'puppet/version' -require 'puppet/vendor/semantic/lib/semantic' if Puppet.version.to_f >= 3.6 and Puppet.version.to_f < 6.0 -require 'puppet-lint/tasks/puppet-lint' -require 'puppet-syntax/tasks/puppet-syntax' -require 'metadata-json-lint/rake_task' - -# blacksmith does not support ruby 1.8.7 anymore -if ENV['RAKE_ENV'] != 'ci' && RUBY_VERSION.split('.')[0, 3].join.to_i > 187 - # rubocop is not needed on travis (requires ruby >= 2.0) - require 'rubocop/rake_task' - RuboCop::RakeTask.new - require 'puppet_blacksmith/rake_tasks' + +# load optional tasks for releases +# only available if gem group releases is installed +begin + require 'voxpupuli/release/rake_tasks' +rescue LoadError end -desc 'Lint metadata.json file' -task :meta do - sh 'metadata-json-lint metadata.json' +PuppetLint.configuration.log_format = '%{path}:%{line}:%{check}:%{KIND}:%{message}' + +desc 'Auto-correct puppet-lint offenses' +task 'lint:auto_correct' do + Rake::Task[:lint_fix].invoke end -exclude_paths = [ - 'bundle/**/*', - 'pkg/**/*', - 'vendor/**/*', - 'spec/**/*' -] +desc 'Run acceptance tests' +RSpec::Core::RakeTask.new(:acceptance) do |t| + t.pattern = 'spec/acceptance' +end -Rake::Task[:lint].clear -PuppetLint::RakeTask.new :lint do |config| - config.ignore_paths = exclude_paths +desc 'Run tests' +task test: [:release_checks] + +namespace :check do + desc 'Check for trailing whitespace' + task :trailing_whitespace do + Dir.glob('**/*.md', File::FNM_DOTMATCH).sort.each do |filename| + next if filename =~ %r{^((modules|acceptance|\.?vendor|spec/fixtures|pkg)/|REFERENCE.md)} + File.foreach(filename).each_with_index do |line, index| + if line =~ %r{\s\n$} + puts "#{filename} has trailing whitespace on line #{index + 1}" + exit 1 + end + end + end + end end +Rake::Task[:release_checks].enhance ['check:trailing_whitespace'] -desc 'Populate CONTRIBUTORS file' -task :contributors do - system("git log --format='%aN' | sort -u > CONTRIBUTORS") +desc "Run main 'test' task and report merged results to coveralls" +task test_with_coveralls: [:test] do + if Dir.exist?(File.expand_path('../lib', __FILE__)) + require 'coveralls/rake/task' + Coveralls::RakeTask.new + Rake::Task['coveralls:push'].invoke + else + puts 'Skipping reporting to coveralls. Module has no lib dir' + end end -task :librarian_spec_prep do - sh 'librarian-puppet install --path=spec/fixtures/modules/' +desc 'Generate REFERENCE.md' +task :reference, [:debug, :backtrace] do |t, args| + patterns = '' + Rake::Task['strings:generate:reference'].invoke(patterns, args[:debug], args[:backtrace]) end -task spec_prep: :librarian_spec_prep -task default: [:spec, :lint] -desc "Run acceptance tests" -RSpec::Core::RakeTask.new(:acceptance) do |t| - # just `spec/acceptance` caused runnin all specs - t.pattern = 'spec/acceptance/*_spec.rb' +begin + require 'github_changelog_generator/task' + GitHubChangelogGenerator::RakeTask.new :changelog do |config| + version = (Blacksmith::Modulefile.new).version + config.future_release = "v#{version}" if version =~ /^\d+\.\d+.\d+$/ + config.header = "# Changelog\n\nAll notable changes to this project will be documented in this file.\nEach new release typically also includes the latest modulesync defaults.\nThese should not affect the functionality of the module." + config.exclude_labels = %w{duplicate question invalid wontfix wont-fix modulesync skip-changelog} + config.user = 'deric' + metadata_json = File.join(File.dirname(__FILE__), 'metadata.json') + metadata = JSON.load(File.read(metadata_json)) + config.project = metadata['name'] + end + + # Workaround for https://github.com/github-changelog-generator/github-changelog-generator/issues/715 + require 'rbconfig' + if RbConfig::CONFIG['host_os'] =~ /linux/ + task :changelog do + puts 'Fixing line endings...' + changelog_file = File.join(__dir__, 'CHANGELOG.md') + changelog_txt = File.read(changelog_file) + new_contents = changelog_txt.gsub(%r{\r\n}, "\n") + File.open(changelog_file, "w") {|file| file.puts new_contents } + end + end + +rescue LoadError end +# vim: syntax=ruby diff --git a/manifests/config.pp b/manifests/config.pp index b44a621..f4776e5 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -1,90 +1,90 @@ # Class: zookeeper::config # # This module manages the configuration directories # # PRIVATE CLASS - do not use directly (use main `zookeeper` class). class zookeeper::config inherits zookeeper { - file { $::zookeeper::cfg_dir: + file { $zookeeper::cfg_dir: ensure => directory, - owner => $::zookeeper::user, - group => $::zookeeper::group, + owner => $zookeeper::user, + group => $zookeeper::group, recurse => true, mode => '0644', } - file { $::zookeeper::log_dir: + file { $zookeeper::log_dir: ensure => directory, - owner => $::zookeeper::user, - group => $::zookeeper::group, + owner => $zookeeper::user, + group => $zookeeper::group, recurse => false, mode => '0644', } - file { $::zookeeper::datastore: + file { $zookeeper::datastore: ensure => directory, - owner => $::zookeeper::user, - group => $::zookeeper::group, + owner => $zookeeper::user, + group => $zookeeper::group, mode => '0644', recurse => false, # intentionally, puppet run would take too long #41 } - if $::zookeeper::datalogstore { - file { $::zookeeper::datalogstore: + if $zookeeper::datalogstore { + file { $zookeeper::datalogstore: ensure => directory, - owner => $::zookeeper::user, - group => $::zookeeper::group, + owner => $zookeeper::user, + group => $zookeeper::group, mode => '0644', recurse => false, # intentionally, puppet run would take too long #41 } } - if $::zookeeper::service_provider != 'exhibitor' { - file { "${::zookeeper::cfg_dir}/zoo.cfg": - owner => $::zookeeper::user, - group => $::zookeeper::group, + if $zookeeper::service_provider != 'exhibitor' { + file { "${zookeeper::cfg_dir}/zoo.cfg": + owner => $zookeeper::user, + group => $zookeeper::group, mode => '0644', content => template("${module_name}/conf/zoo.cfg.erb"), } # we should notify Class['::zookeeper::service'] however it's not configured # at this point (first run), so we have to subscribe from service declaration - file { "${::zookeeper::cfg_dir}/myid": + file { "${zookeeper::cfg_dir}/myid": ensure => file, content => template("${module_name}/conf/myid.erb"), - owner => $::zookeeper::user, - group => $::zookeeper::group, + owner => $zookeeper::user, + group => $zookeeper::group, mode => '0644', - require => File[$::zookeeper::cfg_dir], + require => File[$zookeeper::cfg_dir], } - file { "${::zookeeper::datastore}/myid": + file { "${zookeeper::datastore}/myid": ensure => 'link', - target => "${::zookeeper::cfg_dir}/myid", + target => "${zookeeper::cfg_dir}/myid", } } - file { "${::zookeeper::cfg_dir}/${::zookeeper::environment_file}": - owner => $::zookeeper::user, - group => $::zookeeper::group, + file { "${zookeeper::cfg_dir}/${zookeeper::environment_file}": + owner => $zookeeper::user, + group => $zookeeper::group, mode => '0644', content => template("${module_name}/conf/environment.erb"), } - file { "${::zookeeper::cfg_dir}/log4j.properties": - owner => $::zookeeper::user, - group => $::zookeeper::group, + file { "${zookeeper::cfg_dir}/log4j.properties": + owner => $zookeeper::user, + group => $zookeeper::group, mode => '0644', content => template("${module_name}/conf/log4j.properties.erb"), } # Initialize the datastore if required - if $::zookeeper::initialize_datastore { + if $zookeeper::initialize_datastore { exec { 'initialize_datastore': - command => "/usr/bin/zookeeper-server-initialize --myid=${::zookeeper::id}", - user => $::zookeeper::user, - creates => "${::zookeeper::datastore}/version-2", - require => [ File[$::zookeeper::datastore], Class['zookeeper::install'] ] + command => "/usr/bin/zookeeper-server-initialize --myid=${zookeeper::id}", + user => $zookeeper::user, + creates => "${zookeeper::datastore}/version-2", + require => [ File[$zookeeper::datastore], Class['zookeeper::install'] ], } } } diff --git a/manifests/init.pp b/manifests/init.pp index 854badc..ef1b240 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,163 +1,163 @@ # Class: zookeeper # # This module manages ZooKeeper installation # # # Parameters: # * [global_outstanding_limit] Clients can submit requests faster than ZooKeeper can process them, # especially if there are a lot of clients. To prevent ZooKeeper from running out of memory due to # queued requests, ZooKeeper will throttle clients so that there is no more than globalOutstandingLimit # outstanding requests in the system # # # * [whitelist_4lw] Fine grained control over the set of commands ZooKeeper can execute # # whitelist_4lw = ['stat','ruok'] # class zookeeper( # meta options - String $ensure = $::zookeeper::params::ensure, - Variant[Boolean,String] $ensure_account = $::zookeeper::params::ensure_account, - Boolean $ensure_cron = $::zookeeper::params::ensure_cron, - String $group = $::zookeeper::params::group, - Boolean $system_group = $::zookeeper::params::system_group, - Array[String] $packages = $::zookeeper::params::packages, - String $shell = $::zookeeper::params::shell, - String $user = $::zookeeper::params::user, - Boolean $system_user = $::zookeeper::params::system_user, + String $ensure = $zookeeper::params::ensure, + Variant[Boolean,String] $ensure_account = $zookeeper::params::ensure_account, + Boolean $ensure_cron = $zookeeper::params::ensure_cron, + String $group = $zookeeper::params::group, + Boolean $system_group = $zookeeper::params::system_group, + Array[String] $packages = $zookeeper::params::packages, + String $shell = $zookeeper::params::shell, + String $user = $zookeeper::params::user, + Boolean $system_user = $zookeeper::params::system_user, # installation options - Hash $archive_checksum = $::zookeeper::params::archive_checksum, - Optional[String] $archive_dl_site = $::zookeeper::params::archive_dl_site, - Integer $archive_dl_timeout = $::zookeeper::params::archive_dl_timeout, - Optional[String] $archive_dl_url = $::zookeeper::params::archive_dl_url, - String $archive_install_dir = $::zookeeper::params::archive_install_dir, - Boolean $archive_symlink = $::zookeeper::params::archive_symlink, - String $archive_symlink_name = $::zookeeper::params::archive_symlink_name, - String $archive_version = $::zookeeper::params::archive_version, - Optional[String] $proxy_server = $::zookeeper::params::proxy_server, - Optional[String] $proxy_type = $::zookeeper::params::proxy_type, - Optional[String] $cdhver = $::zookeeper::params::cdhver, - Boolean $install_java = $::zookeeper::params::install_java, - String $install_method = $::zookeeper::params::install_method, - String $java_bin = $::zookeeper::params::java_bin, - String $java_opts = $::zookeeper::params::java_opts, - Optional[String] $java_package = $::zookeeper::params::java_package, - Optional[Variant[String,Hash]] $repo = $::zookeeper::params::repo, + Hash $archive_checksum = $zookeeper::params::archive_checksum, + Optional[String] $archive_dl_site = $zookeeper::params::archive_dl_site, + Integer $archive_dl_timeout = $zookeeper::params::archive_dl_timeout, + Optional[String] $archive_dl_url = $zookeeper::params::archive_dl_url, + String $archive_install_dir = $zookeeper::params::archive_install_dir, + Boolean $archive_symlink = $zookeeper::params::archive_symlink, + String $archive_symlink_name = $zookeeper::params::archive_symlink_name, + String $archive_version = $zookeeper::params::archive_version, + Optional[String] $proxy_server = $zookeeper::params::proxy_server, + Optional[String] $proxy_type = $zookeeper::params::proxy_type, + Optional[String] $cdhver = $zookeeper::params::cdhver, + Boolean $install_java = $zookeeper::params::install_java, + String $install_method = $zookeeper::params::install_method, + String $java_bin = $zookeeper::params::java_bin, + String $java_opts = $zookeeper::params::java_opts, + Optional[String] $java_package = $zookeeper::params::java_package, + Optional[Variant[String,Hash]] $repo = $zookeeper::params::repo, # service options - Boolean $manage_service = $::zookeeper::params::manage_service, - Boolean $manage_service_file = $::zookeeper::params::manage_service_file, - String $pid_dir = $::zookeeper::params::pid_dir, - Optional[String] $pid_file = $::zookeeper::params::pid_file, - Boolean $restart_on_change = $::zookeeper::params::restart_on_change, - String $service_ensure = $::zookeeper::params::service_ensure, - String $service_name = $::zookeeper::params::service_name, - Optional[String] $service_provider = $::zookeeper::params::service_provider, - Optional[String] $systemd_unit_want = $::zookeeper::params::systemd_unit_want, - String $systemd_unit_after = $::zookeeper::params::systemd_unit_after, - String $systemd_path = $::zookeeper::params::systemd_path, - String $zk_dir = $::zookeeper::params::zk_dir, + Boolean $manage_service = $zookeeper::params::manage_service, + Boolean $manage_service_file = $zookeeper::params::manage_service_file, + String $pid_dir = $zookeeper::params::pid_dir, + Optional[String] $pid_file = $zookeeper::params::pid_file, + Boolean $restart_on_change = $zookeeper::params::restart_on_change, + String $service_ensure = $zookeeper::params::service_ensure, + String $service_name = $zookeeper::params::service_name, + Optional[String] $service_provider = $zookeeper::params::service_provider, + Optional[String] $systemd_unit_want = $zookeeper::params::systemd_unit_want, + String $systemd_unit_after = $zookeeper::params::systemd_unit_after, + String $systemd_path = $zookeeper::params::systemd_path, + String $zk_dir = $zookeeper::params::zk_dir, # zookeeper config - String $cfg_dir = $::zookeeper::params::cfg_dir, - String $cleanup_sh = $::zookeeper::params::cleanup_sh, - Optional[String] $client_ip = $::zookeeper::params::client_ip, - Integer $client_port = $::zookeeper::params::client_port, - String $datastore = $::zookeeper::params::datastore, - Optional[String] $datalogstore = $::zookeeper::params::datalogstore, - Integer $election_port = $::zookeeper::params::election_port, - String $export_tag = $::zookeeper::params::export_tag, - String $id = $::zookeeper::params::id, - Integer $init_limit = $::zookeeper::params::init_limit, - Boolean $initialize_datastore = $::zookeeper::params::initialize_datastore, - Boolean $leader = $::zookeeper::params::leader, - Integer $leader_port = $::zookeeper::params::leader_port, - String $log_dir = $::zookeeper::params::log_dir, - Boolean $manual_clean = $::zookeeper::params::manual_clean, - Optional[Integer] $max_session_timeout = $::zookeeper::params::max_session_timeout, - Optional[Integer] $min_session_timeout = $::zookeeper::params::min_session_timeout, - Array[String] $observers = $::zookeeper::params::observers, - Integer $purge_interval = $::zookeeper::params::purge_interval, - Variant[Array[String],Hash[String,String]] $servers = $::zookeeper::params::servers, - Integer $snap_count = $::zookeeper::params::snap_count, - Integer $snap_retain_count = $::zookeeper::params::snap_retain_count, - Integer $sync_limit = $::zookeeper::params::sync_limit, - Integer $tick_time = $::zookeeper::params::tick_time, - Integer $global_outstanding_limit = $::zookeeper::params::global_outstanding_limit, - Boolean $use_sasl_auth = $::zookeeper::params::use_sasl_auth, - String $zoo_dir = $::zookeeper::params::zoo_dir, - String $zoo_main = $::zookeeper::params::zoo_main, + String $cfg_dir = $zookeeper::params::cfg_dir, + String $cleanup_sh = $zookeeper::params::cleanup_sh, + Optional[String] $client_ip = $zookeeper::params::client_ip, + Integer $client_port = $zookeeper::params::client_port, + String $datastore = $zookeeper::params::datastore, + Optional[String] $datalogstore = $zookeeper::params::datalogstore, + Integer $election_port = $zookeeper::params::election_port, + String $export_tag = $zookeeper::params::export_tag, + String $id = $zookeeper::params::id, + Integer $init_limit = $zookeeper::params::init_limit, + Boolean $initialize_datastore = $zookeeper::params::initialize_datastore, + Boolean $leader = $zookeeper::params::leader, + Integer $leader_port = $zookeeper::params::leader_port, + String $log_dir = $zookeeper::params::log_dir, + Boolean $manual_clean = $zookeeper::params::manual_clean, + Optional[Integer] $max_session_timeout = $zookeeper::params::max_session_timeout, + Optional[Integer] $min_session_timeout = $zookeeper::params::min_session_timeout, + Array[String] $observers = $zookeeper::params::observers, + Integer $purge_interval = $zookeeper::params::purge_interval, + Variant[Array[String],Hash[String,String]] $servers = $zookeeper::params::servers, + Integer $snap_count = $zookeeper::params::snap_count, + Integer $snap_retain_count = $zookeeper::params::snap_retain_count, + Integer $sync_limit = $zookeeper::params::sync_limit, + Integer $tick_time = $zookeeper::params::tick_time, + Integer $global_outstanding_limit = $zookeeper::params::global_outstanding_limit, + Boolean $use_sasl_auth = $zookeeper::params::use_sasl_auth, + String $zoo_dir = $zookeeper::params::zoo_dir, + String $zoo_main = $zookeeper::params::zoo_main, # log4j properties - String $environment_file = $::zookeeper::params::environment_file, - String $log4j_prop = $::zookeeper::params::log4j_prop, - String $maxfilesize = $::zookeeper::params::maxfilesize, - Integer $maxbackupindex = $::zookeeper::params::maxbackupindex, - Optional[Integer] $max_allowed_connections = $::zookeeper::params::max_allowed_connections, - String $peer_type = $::zookeeper::params::peer_type, - String $rollingfile_threshold = $::zookeeper::params::rollingfile_threshold, - String $tracefile_threshold = $::zookeeper::params::tracefile_threshold, - String $console_threshold = $::zookeeper::params::console_threshold, - Hash[String,Hash[String,String]] $extra_appenders = $::zookeeper::params::extra_appenders, + String $environment_file = $zookeeper::params::environment_file, + String $log4j_prop = $zookeeper::params::log4j_prop, + String $maxfilesize = $zookeeper::params::maxfilesize, + Integer $maxbackupindex = $zookeeper::params::maxbackupindex, + Optional[Integer] $max_allowed_connections = $zookeeper::params::max_allowed_connections, + String $peer_type = $zookeeper::params::peer_type, + String $rollingfile_threshold = $zookeeper::params::rollingfile_threshold, + String $tracefile_threshold = $zookeeper::params::tracefile_threshold, + String $console_threshold = $zookeeper::params::console_threshold, + Hash[String,Hash[String,String]] $extra_appenders = $zookeeper::params::extra_appenders, # sasl options - Hash[String, String] $sasl_users = $::zookeeper::params::sasl_users, - String $keytab_path = $::zookeeper::params::keytab_path, - String $principal = $::zookeeper::params::principal, - String $realm = $::zookeeper::params::realm, - Boolean $sasl_krb5 = $::zookeeper::params::sasl_krb5, - Boolean $store_key = $::zookeeper::params::store_key, - Boolean $use_keytab = $::zookeeper::params::use_keytab, - Boolean $use_ticket_cache = $::zookeeper::params::use_ticket_cache, - Boolean $remove_host_principal = $::zookeeper::params::remove_host_principal, - Boolean $remove_realm_principal = $::zookeeper::params::remove_realm_principal, + Hash[String, String] $sasl_users = $zookeeper::params::sasl_users, + String $keytab_path = $zookeeper::params::keytab_path, + String $principal = $zookeeper::params::principal, + String $realm = $zookeeper::params::realm, + Boolean $sasl_krb5 = $zookeeper::params::sasl_krb5, + Boolean $store_key = $zookeeper::params::store_key, + Boolean $use_keytab = $zookeeper::params::use_keytab, + Boolean $use_ticket_cache = $zookeeper::params::use_ticket_cache, + Boolean $remove_host_principal = $zookeeper::params::remove_host_principal, + Boolean $remove_realm_principal = $zookeeper::params::remove_realm_principal, # four letter words whitelist - Array[String] $whitelist_4lw = $::zookeeper::params::whitelist_4lw, + Array[String] $whitelist_4lw = $zookeeper::params::whitelist_4lw, ) inherits ::zookeeper::params { if $pid_file { $pid_path = $pid_file } else { $pid_path = "${pid_dir}/zookeeper.pid" } $repo_source = is_hash($repo) ? { true => 'custom', false => $repo } - if $::zookeeper::ensure_account { + if $zookeeper::ensure_account { group { $group: ensure => $ensure_account, system => $system_group, } user { $user: ensure => $ensure_account, home => $datastore, comment => 'Zookeeper', gid => $group, shell => $shell, system => $system_user, require => Group[$group], } } include zookeeper::install include zookeeper::config anchor { 'zookeeper::start': } -> Class['zookeeper::install'] -> Class['zookeeper::config'] if ($use_sasl_auth) { include zookeeper::sasl Class['zookeeper::config'] -> Class['zookeeper::sasl'] -> Class['zookeeper::service'] } if ($manage_service) and ($service_provider != 'exhibitor') { include zookeeper::service Class['zookeeper::config'] -> Class['zookeeper::service'] -> Anchor['zookeeper::end'] } anchor { 'zookeeper::end': } } diff --git a/manifests/install.pp b/manifests/install.pp index 3b13813..1a4ade1 100644 --- a/manifests/install.pp +++ b/manifests/install.pp @@ -1,66 +1,66 @@ # Class: zookeeper::install # # This module manages installation tasks. # # PRIVATE CLASS - do not use directly (use main `zookeeper` class). class zookeeper::install inherits zookeeper { anchor { 'zookeeper::install::begin': } $os_family = $facts['os']['family'] # Repo management case $os_family { 'RedHat': { include zookeeper::install::repo Anchor['zookeeper::install::begin'] -> Class['zookeeper::install::repo'] } default: {} # nothing to do } # Java installation - if ($::zookeeper::install_java) { - if !$::zookeeper::java_package { + if ($zookeeper::install_java) { + if !$zookeeper::java_package { fail('Java installation is required, but no java package was provided.') } - validate_string($::zookeeper::java_package) + validate_string($zookeeper::java_package) # Make sure the Java package is only installed once. anchor { 'zookeeper::install::java': } - ensure_resource('package', $::zookeeper::java_package, - {'ensure' => $::zookeeper::ensure, 'allow_virtual' => true, + ensure_resource('package', $zookeeper::java_package, + {'ensure' => $zookeeper::ensure, 'allow_virtual' => true, 'before' => Anchor['zookeeper::install::intermediate'], 'require' => Anchor['zookeeper::install::begin']} ) } anchor { 'zookeeper::install::intermediate': } # Package installation - case $::zookeeper::install_method { + case $zookeeper::install_method { 'archive': { include zookeeper::install::archive Anchor['zookeeper::install::intermediate'] -> Class['zookeeper::install::archive'] -> Anchor['zookeeper::install::end'] } 'package': { include zookeeper::install::package Anchor['zookeeper::install::intermediate'] -> Class['zookeeper::install::package'] -> Anchor['zookeeper::install::end'] } default: { fail('Valid installation methods are `package` or `archive`') } } anchor { 'zookeeper::install::end': } # Post installation tasks class { 'zookeeper::post_install': require => Anchor['zookeeper::install::end'], } } diff --git a/manifests/install/archive.pp b/manifests/install/archive.pp index 93bf7fc..653790c 100644 --- a/manifests/install/archive.pp +++ b/manifests/install/archive.pp @@ -1,82 +1,82 @@ # Class: zookeeper::install::archive # # This module manages archive installation # # PRIVATE CLASS - do not use directly (use main `zookeeper` class). class zookeeper::install::archive inherits zookeeper::install { # Apache updated the filename base for archive files in release 3.5.5 - if versioncmp($::zookeeper::archive_version, '3.5.5') >= 0 { - $filename = "apache-${module_name}-${::zookeeper::archive_version}-bin" - $archive_dl_site = $::zookeeper::archive_dl_site ? { + if versioncmp($zookeeper::archive_version, '3.5.5') >= 0 { + $filename = "apache-${module_name}-${zookeeper::archive_version}-bin" + $archive_dl_site = $zookeeper::archive_dl_site ? { undef => 'http://apache.org/dist/zookeeper', - default => $::zookeeper::archive_dl_site, + default => $zookeeper::archive_dl_site, } } else { - $filename = "${module_name}-${::zookeeper::archive_version}" - $archive_dl_site = $::zookeeper::archive_dl_site ? { + $filename = "${module_name}-${zookeeper::archive_version}" + $archive_dl_site = $zookeeper::archive_dl_site ? { undef => 'http://archive.apache.org/dist/zookeeper', - default => $::zookeeper::archive_dl_site, + default => $zookeeper::archive_dl_site, } } - $download_url = $::zookeeper::archive_dl_url ? { - undef => "${archive_dl_site}/${module_name}-${::zookeeper::archive_version}/${filename}.tar.gz", - default => $::zookeeper::archive_dl_url, + $download_url = $zookeeper::archive_dl_url ? { + undef => "${archive_dl_site}/${module_name}-${zookeeper::archive_version}/${filename}.tar.gz", + default => $zookeeper::archive_dl_url, } - $archive_file = "${::zookeeper::archive_install_dir}/${filename}.tar.gz" + $archive_file = "${zookeeper::archive_install_dir}/${filename}.tar.gz" archive { $archive_file: ensure => present, user => 'root', group => 'root', source => $download_url, - checksum => $::zookeeper::archive_checksum['hash'], - checksum_type => $::zookeeper::archive_checksum['type'], - extract_path => $::zookeeper::archive_install_dir, + checksum => $zookeeper::archive_checksum['hash'], + checksum_type => $zookeeper::archive_checksum['type'], + extract_path => $zookeeper::archive_install_dir, # Extract files as the user doing the extracting, which is the user # that runs Puppet, usually root extract_flags => '-x --no-same-owner -f', - creates => "${::zookeeper::archive_install_dir}/${filename}", + creates => "${zookeeper::archive_install_dir}/${filename}", extract => true, cleanup => true, notify => Exec['chown_zookeeper_directory'], } - if $::zookeeper::proxy_server { + if $zookeeper::proxy_server { Archive<| title == $archive_file |> { - proxy_server => $::zookeeper::proxy_server, - proxy_type => $::zookeeper::proxy_type, + proxy_server => $zookeeper::proxy_server, + proxy_type => $zookeeper::proxy_type, } } - $symlink_require = Archive["${::zookeeper::archive_install_dir}/${filename}.tar.gz"] + $symlink_require = Archive["${zookeeper::archive_install_dir}/${filename}.tar.gz"] exec { 'chown_zookeeper_directory': - command => "chown -R ${::zookeeper::user}:${::zookeeper::group} ${::zookeeper::archive_install_dir}/${filename}", + command => "chown -R ${zookeeper::user}:${zookeeper::group} ${zookeeper::archive_install_dir}/${filename}", path => ['/bin','/sbin'], refreshonly => true, require => $symlink_require, } - if $::zookeeper::archive_symlink { - file { $::zookeeper::archive_symlink_name: + if $zookeeper::archive_symlink { + file { $zookeeper::archive_symlink_name: ensure => link, require => $symlink_require, - target => "${::zookeeper::archive_install_dir}/${filename}", - owner => $::zookeeper::user, - group => $::zookeeper::group, + target => "${zookeeper::archive_install_dir}/${filename}", + owner => $zookeeper::user, + group => $zookeeper::group, } } # directory is required for creating conf subdirectory - if $::zookeeper::zk_dir { - file { $::zookeeper::zk_dir: + if $zookeeper::zk_dir { + file { $zookeeper::zk_dir: ensure => directory, - owner => $::zookeeper::user, - group => $::zookeeper::group, + owner => $zookeeper::user, + group => $zookeeper::group, } } } diff --git a/manifests/install/package.pp b/manifests/install/package.pp index 0f5314e..2a1e49a 100644 --- a/manifests/install/package.pp +++ b/manifests/install/package.pp @@ -1,17 +1,17 @@ # Class: zookeeper::install::package # # This module manages package installation # # PRIVATE CLASS - do not use directly (use main `zookeeper` class). class zookeeper::install::package inherits zookeeper::install { # Allow installing multiple packages, like zookeeper, zookeeper-bin etc. - ensure_resource('package', $::zookeeper::packages, {'ensure' => $::zookeeper::ensure}) + ensure_resource('package', $zookeeper::packages, {'ensure' => $zookeeper::ensure}) # Make sure, that service package was not installed earlier - if ($::zookeeper::service_provider == 'init.d' and (!member($::zookeeper::packages, $::zookeeper::service_package))) { - package { [$::zookeeper::service_package]: #init.d scripts for zookeeper - ensure => $::zookeeper::ensure, + if ($zookeeper::service_provider == 'init.d' and (!member($zookeeper::packages, $zookeeper::service_package))) { + package { [$zookeeper::service_package]: #init.d scripts for zookeeper + ensure => $zookeeper::ensure, } } } diff --git a/manifests/install/repo.pp b/manifests/install/repo.pp index a271bae..01f0288 100644 --- a/manifests/install/repo.pp +++ b/manifests/install/repo.pp @@ -1,99 +1,99 @@ # == Class zookeeper::install::repo # # This class manages yum repository for Zookeeper packages # # PRIVATE CLASS - do not use directly (use main `zookeeper` class). class zookeeper::install::repo inherits zookeeper::install { $os_release = $facts['os']['release']['major'] $os_hardware = $facts['os']['hardware'] - if $::zookeeper::repo_source { - case $::zookeeper::repo_source { + if $zookeeper::repo_source { + case $zookeeper::repo_source { undef: {} # nothing to do 'cloudera': { - if $::zookeeper::cdhver == undef { + if $zookeeper::cdhver == undef { fail('Cloudera repo is required, but no CDH version is provided.') } - case $::zookeeper::cdhver { + case $zookeeper::cdhver { '4': { case $os_hardware { 'i386', 'x86_64': { case $os_release { '6', '7': { $release = '6' } default: { - fail("Yum repository '${::zookeeper::repo_source}' is not supported for redhat version ${os_release}") + fail("Yum repository '${zookeeper::repo_source}' is not supported for redhat version ${os_release}") } } } default: { - fail("Yum repository '${::zookeeper::repo_source}' is not supported for architecture ${os_hardware}") + fail("Yum repository '${zookeeper::repo_source}' is not supported for architecture ${os_hardware}") } } } '5': { case $os_hardware { 'x86_64': { case $os_release { # CentOS uses os_release=2015 '6', '7', '2015': { $release = $os_release } default: { - fail("Yum repository '${::zookeeper::repo_source}' is not supported for redhat version ${os_release}") + fail("Yum repository '${zookeeper::repo_source}' is not supported for redhat version ${os_release}") } } } default: { - fail("Yum repository '${::zookeeper::repo_source}' is not supported for architecture ${os_hardware}") + fail("Yum repository '${zookeeper::repo_source}' is not supported for architecture ${os_hardware}") } } } default: { - fail("CDH version'${::zookeeper::cdhver}' is not a supported cloudera repo.") + fail("CDH version'${zookeeper::cdhver}' is not a supported cloudera repo.") } } # Puppet 4 compatibility: force variable to be a String - yumrepo { "cloudera-cdh${::zookeeper::cdhver}": - ensure => $::zookeeper::ensure, - descr => "Cloudera's Distribution for Hadoop, Version ${::zookeeper::cdhver}", - baseurl => "http://archive.cloudera.com/cdh${::zookeeper::cdhver}/redhat/${release}/${os_hardware}/cdh/${::zookeeper::cdhver}/", - gpgkey => "http://archive.cloudera.com/cdh${::zookeeper::cdhver}/redhat/${release}/${os_hardware}/cdh/RPM-GPG-KEY-cloudera", - gpgcheck => 1 + yumrepo { "cloudera-cdh${zookeeper::cdhver}": + ensure => $zookeeper::ensure, + descr => "Cloudera's Distribution for Hadoop, Version ${zookeeper::cdhver}", + baseurl => "http://archive.cloudera.com/cdh${zookeeper::cdhver}/redhat/${release}/${os_hardware}/cdh/${zookeeper::cdhver}/", + gpgkey => "http://archive.cloudera.com/cdh${zookeeper::cdhver}/redhat/${release}/${os_hardware}/cdh/RPM-GPG-KEY-cloudera", + gpgcheck => 1, } } 'custom':{ - $_config = $::zookeeper::repo + $_config = $zookeeper::repo validate_hash($_config) if $_config['name'] == undef or $_config['url'] == undef or $_config['descr'] == undef { fail('Invalid parameter settings for custom repo') } case $os_release { '6', '7': { # Puppet 4 compatibility: force variable to be a String yumrepo { $_config['name']: - ensure => $::zookeeper::ensure, + ensure => $zookeeper::ensure, descr => $_config['descr'], baseurl => $_config['url'], enabled => 1, sslverify => empty($_config['sslverify']) ? { true => 0, false => $_config['sslverify'] }, gpgcheck => empty($_config['gpgcheck']) ? { true => 0, false => $_config['gpgcheck'] }, } } default: { fail("Redhat '${os_release}' is not a supported.") } } } default: { - fail("\"${module_name}\" provides no repository information for yum repository \"${::zookeeper::repo_source}\"") + fail("\"${module_name}\" provides no repository information for yum repository \"${zookeeper::repo_source}\"") } } } } diff --git a/manifests/params.pp b/manifests/params.pp index 8066948..62e2deb 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -1,160 +1,164 @@ # OS specific configuration should be defined here # # PRIVATE CLASS - do not use directly (use main `zookeeper` class). class zookeeper::params { $_defaults = { 'packages' => ['zookeeper'], } $os_family = $facts['os']['family'] $os_name = $facts['os']['name'] $os_release = $facts['os']['release']['major'] case $os_family { 'Debian': { case $os_name { 'Debian', 'Ubuntu': { $initstyle = 'systemd' } default: { $initstyle = undef } } $_os_overrides = { 'packages' => ['zookeeper', 'zookeeperd'], 'service_name' => 'zookeeper', 'service_provider' => $initstyle, 'shell' => '/bin/false', } # 'environment' file probably read just by Debian # see #16, #81 $environment_file = 'environment' } 'RedHat': { case $os_name { 'RedHat', 'CentOS': { - $initstyle = 'systemd' + if versioncmp($os_release, '7') < 0 { + $initstyle = 'redhat' + } else { + $initstyle = 'systemd' + } } default: { $initstyle = undef } } $_os_overrides = { 'packages' => ['zookeeper', 'zookeeper-server'], 'service_name' => 'zookeeper-server', 'service_provider' => $initstyle, 'shell' => '/sbin/nologin', } $environment_file = 'java.env' } default: { fail("Module '${module_name}' is not supported on OS: '${os_name}', family: '${os_family}'") } } $_params = merge($_defaults, $_os_overrides) # meta options $ensure = present $ensure_account = present $ensure_cron = true $group = 'zookeeper' $system_group = false $packages = $_params['packages'] $shell = $_params['shell'] $user = 'zookeeper' $system_user = false # installation options $archive_checksum = {} $archive_dl_site = undef $archive_dl_timeout = 600 $archive_dl_url = undef $archive_install_dir = '/opt' $archive_symlink = true $archive_symlink_name = "${archive_install_dir}/zookeeper" $archive_version = '3.4.8' - $cdhver = undef + $cdhver = '5' $install_java = false $install_method = 'package' $java_bin = '/usr/bin/java' $java_opts = '' $java_package = undef - $repo = undef + $repo = 'cloudera' $proxy_server = undef $proxy_type = undef # service options $manage_service = true $manage_service_file = false $pid_dir = '/var/run' $pid_file = undef $restart_on_change = true $service_ensure = 'running' $service_name = $_params['service_name'] $service_provider = $_params['service_provider'] # systemd_unit_want and _after can be overridden to # donate the matching directives in the [Unit] section $systemd_unit_want = undef $systemd_unit_after = 'network.target' $systemd_path = '/etc/systemd/system' $zk_dir = '/etc/zookeeper' # zookeeper config $cfg_dir = '/etc/zookeeper/conf' $cleanup_sh = '/usr/share/zookeeper/bin/zkCleanup.sh' $client_ip = undef # use e.g. $::ipaddress if you want to bind to single interface $client_port = 2181 $datastore = '/var/lib/zookeeper' # datalogstore used to put transaction logs in separate location than snapshots $datalogstore = undef $election_port = 2888 $export_tag = 'zookeeper' $id = '1' $init_limit = 10 $initialize_datastore = false $leader = true $leader_port = 3888 $log_dir = '/var/log/zookeeper' $manual_clean = false $max_allowed_connections = undef $max_session_timeout = undef $min_session_timeout = undef $observers = [] # interval in hours, purging enabled when >= 1 $purge_interval = 0 $servers = [] $snap_count = 10000 # since zookeeper 3.4, for earlier version cron task might be used $snap_retain_count = 3 $sync_limit = 5 $tick_time = 2000 $global_outstanding_limit = 1000 $use_sasl_auth = false $zoo_dir = '/usr/lib/zookeeper' $zoo_main = 'org.apache.zookeeper.server.quorum.QuorumPeerMain' # log4j properties $log4j_prop = 'INFO,ROLLINGFILE' $peer_type = 'UNSET' $rollingfile_threshold = 'INFO' $console_threshold = 'INFO' $tracefile_threshold = 'TRACE' $maxfilesize = '256MB' $maxbackupindex = 20 $extra_appenders = {} # sasl options $sasl_krb5 = true $sasl_users = {} $keytab_path = '/etc/zookeeper/conf/zookeeper.keytab' - $principal = "zookeeper/${::fqdn}" + $principal = "zookeeper/${facts['networking']['fqdn']}" $realm = pick($trusted['domain'], $trusted['certname']) $store_key = true $use_keytab = true $use_ticket_cache = false $remove_host_principal = false $remove_realm_principal = false # whitelist of Four Letter Words commands, see https://zookeeper.apache.org/doc/r3.4.12/zookeeperAdmin.html#sc_zkCommands $whitelist_4lw = [] } diff --git a/manifests/post_install.pp b/manifests/post_install.pp index e88ae45..13d938b 100644 --- a/manifests/post_install.pp +++ b/manifests/post_install.pp @@ -1,74 +1,74 @@ # Class: zookeeper::post_install # # In order to maintain compatibility with older releases, there are # some post-install task to ensure same behaviour on all platforms. # # PRIVATE CLASS - do not use directly (use main `zookeeper` class). class zookeeper::post_install inherits zookeeper { $os_family = $facts['os']['family'] $os_name = $facts['os']['name'] $os_release = $facts['os']['release']['major'] - if ($::zookeeper::manual_clean) { + if ($zookeeper::manual_clean) { # User defined value - $_clean = $::zookeeper::manual_clean + $_clean = $zookeeper::manual_clean } else { # Autodetect: # Since ZooKeeper 3.4 there's no need for purging snapshots with cron case $os_family { 'Debian': { case $os_name { 'Debian', 'Ubuntu': { $_clean = false } default: { fail ("Family: '${os_family}' OS: '${os_name}' is not supported yet") } } } 'Redhat': { $_clean = false } default: { fail ("Family: '${os_family}' OS: '${os_name}' is not supported yet") } } } # If !$cleanup_count, then ensure this cron is absent. - if ($_clean and $::zookeeper::snap_retain_count > 0 and $::zookeeper::ensure != 'absent') { - if ($::zookeeper::ensure_cron){ + if ($_clean and $zookeeper::snap_retain_count > 0 and $zookeeper::ensure != 'absent') { + if ($zookeeper::ensure_cron){ include cron cron::job { 'zookeeper-cleanup': ensure => present, - command => "${::zookeeper::cleanup_sh} ${::zookeeper::datastore} ${::zookeeper::snap_retain_count}", + command => "${zookeeper::cleanup_sh} ${zookeeper::datastore} ${zookeeper::snap_retain_count}", hour => 2, minute => 42, - user => $::zookeeper::user, + user => $zookeeper::user, } }else { file { '/etc/cron.daily/zkcleanup': ensure => present, - content => "${::zookeeper::cleanup_sh} ${::zookeeper::datastore} ${::zookeeper::snap_retain_count}", + content => "${zookeeper::cleanup_sh} ${zookeeper::datastore} ${zookeeper::snap_retain_count}", } } } # Package removal - if($_clean and $::zookeeper::ensure == 'absent'){ - if ($::zookeeper::ensure_cron){ + if($_clean and $zookeeper::ensure == 'absent'){ + if ($zookeeper::ensure_cron){ class { 'cron': manage_package => false, } cron::job { 'zookeeper-cleanup': - ensure => $::zookeeper::ensure, + ensure => $zookeeper::ensure, } }else{ file { '/etc/cron.daily/zkcleanup': - ensure => $::zookeeper::ensure, + ensure => $zookeeper::ensure, } } } } diff --git a/manifests/sasl.pp b/manifests/sasl.pp index 1611165..6ae2fd5 100644 --- a/manifests/sasl.pp +++ b/manifests/sasl.pp @@ -1,13 +1,13 @@ # Class: zookeeper::sasl # # This module manages Zookeeper sasl auth # # PRIVATE CLASS - do not use directly (use main `zookeeper` class). class zookeeper::sasl inherits zookeeper { - file{"${::zookeeper::cfg_dir}/jaas.conf": + file{"${zookeeper::cfg_dir}/jaas.conf": ensure => present, - owner => $::zookeeper::user, - group => $::zookeeper::group, + owner => $zookeeper::user, + group => $zookeeper::group, content => template("${module_name}/conf/jaas.conf.erb"), } } diff --git a/manifests/service.pp b/manifests/service.pp index a653ff4..b56d4c3 100644 --- a/manifests/service.pp +++ b/manifests/service.pp @@ -1,49 +1,62 @@ # Class: zookeeper::service # # PRIVATE CLASS - do not use directly (use main `zookeeper` class). class zookeeper::service inherits zookeeper { - case $::zookeeper::install_method { + case $zookeeper::install_method { 'archive': { - $_zoo_dir = "${::zookeeper::archive_install_dir}/${module_name}" + $_zoo_dir = "${zookeeper::archive_install_dir}/${module_name}" } 'package': { - $_zoo_dir = $::zookeeper::zoo_dir + $_zoo_dir = $zookeeper::zoo_dir } default: { - fail("Install method '${::zookeeper::install_method}' is not supported.") + fail("Install method '${zookeeper::install_method}' is not supported.") } } - if $::zookeeper::manage_service_file == true { - file { "${::zookeeper::systemd_path}/${::zookeeper::service_name}.service": - ensure => 'present', - content => template("${module_name}/zookeeper.service.erb"), - } - ~> exec { 'systemctl daemon-reload # for zookeeper': - refreshonly => true, - path => $::path, - notify => Service[$::zookeeper::service_name], + if $zookeeper::manage_service_file == true { + if $zookeeper::service_provider == 'systemd' { + file { "${zookeeper::systemd_path}/${zookeeper::service_name}.service": + ensure => 'present', + content => template("${module_name}/zookeeper.service.erb"), + } + ~> exec { 'systemctl daemon-reload # for zookeeper': + refreshonly => true, + path => $::path, + notify => Service[$zookeeper::service_name], + } + } elsif ( + $zookeeper::service_provider == 'init' + or $zookeeper::service_provider == 'redhat' + ) { + file { "/etc/init.d/${zookeeper::service_name}": + ensure => present, + content => template("${module_name}/zookeeper.${facts['os']['family']}.init.erb"), + mode => '0755', + before => Service[$zookeeper::service_name], + notify => Service[$zookeeper::service_name], + } } } - service { $::zookeeper::service_name: - ensure => $::zookeeper::service_ensure, + service { $zookeeper::service_name: + ensure => $zookeeper::service_ensure, hasstatus => true, hasrestart => true, - provider => $::zookeeper::service_provider, + provider => $zookeeper::service_provider, enable => true, require => [ Class['::zookeeper::install'], - File["${::zookeeper::cfg_dir}/zoo.cfg"] + File["${zookeeper::cfg_dir}/zoo.cfg"] ], } - if $::zookeeper::restart_on_change { - File[$::zookeeper::log_dir] ~> Service[$::zookeeper::service_name] - File["${::zookeeper::cfg_dir}/myid"] ~> Service[$::zookeeper::service_name] - File["${::zookeeper::cfg_dir}/zoo.cfg"] ~> Service[$::zookeeper::service_name] - File["${::zookeeper::cfg_dir}/${::zookeeper::environment_file}"] ~> Service[$::zookeeper::service_name] - File["${::zookeeper::cfg_dir}/log4j.properties"] ~> Service[$::zookeeper::service_name] + if $zookeeper::restart_on_change { + File[$zookeeper::log_dir] ~> Service[$zookeeper::service_name] + File["${zookeeper::cfg_dir}/myid"] ~> Service[$zookeeper::service_name] + File["${zookeeper::cfg_dir}/zoo.cfg"] ~> Service[$zookeeper::service_name] + File["${zookeeper::cfg_dir}/${zookeeper::environment_file}"] ~> Service[$zookeeper::service_name] + File["${zookeeper::cfg_dir}/log4j.properties"] ~> Service[$zookeeper::service_name] } } diff --git a/metadata.json b/metadata.json index 3a45b1e..b1df1da 100644 --- a/metadata.json +++ b/metadata.json @@ -1,66 +1,66 @@ { "name": "deric-zookeeper", "version": "0.9.0-UNRELEASED", "author": "Tomas Barton", "summary": "Module for managing Apache Zookeeper", "license": "Apache-2.0", "source": "https://github.com/deric/puppet-zookeeper", "project_page": "https://github.com/deric/puppet-zookeeper", "issues_url": "https://github.com/deric/puppet-zookeeper/issues", "description": "ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services.", "dependencies": [ - { - "name": "puppetlabs/stdlib", - "version_requirement": ">= 2.3.3 < 7.0.0" - }, { "name": "puppet/archive", "version_requirement": ">= 0.4.4 < 5.0.0" }, { "name": "puppet/cron", "version_requirement": ">= 1.3.1" }, + { + "name": "puppetlabs/stdlib", + "version_requirement": ">= 2.3.3 < 7.0.0" + }, { "name": "puppetlabs/yumrepo_core", "version_requirement": ">= 1.0.3" } ], "operatingsystem_support": [ { "operatingsystem": "RedHat", "operatingsystemrelease": [ "6", "7" ] }, { "operatingsystem": "CentOS", "operatingsystemrelease": [ "6", "7" ] }, { "operatingsystem": "Debian", "operatingsystemrelease": [ "8", "9", "10" ] }, { "operatingsystem": "Ubuntu", "operatingsystemrelease": [ "16.04", "18.04" ] } ], "requirements": [ { "name": "puppet", "version_requirement": ">= 5.5.8 < 7.0.0" } ] } diff --git a/spec/acceptance/hiera.yaml b/spec/acceptance/hiera.yaml deleted file mode 100644 index 5c24f73..0000000 --- a/spec/acceptance/hiera.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -version: 5 -defaults: # Used for any hierarchy level that omits these keys. - datadir: hieradata # This path is relative to hiera.yaml's directory. - data_hash: yaml_data # Use the built-in YAML backend. - -hierarchy: - - name: "Default" - path: "default.yaml" \ No newline at end of file diff --git a/spec/acceptance/hieradata/default.yaml b/spec/acceptance/hieradata/default.yaml deleted file mode 100644 index 1058cfc..0000000 --- a/spec/acceptance/hieradata/default.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -classes: - - '::zookeeper' \ No newline at end of file diff --git a/spec/acceptance/nodesets/archlinux-2-x64.yml b/spec/acceptance/nodesets/archlinux-2-x64.yml new file mode 100644 index 0000000..89b6300 --- /dev/null +++ b/spec/acceptance/nodesets/archlinux-2-x64.yml @@ -0,0 +1,13 @@ +--- +# This file is managed via modulesync +# https://github.com/voxpupuli/modulesync +# https://github.com/voxpupuli/modulesync_config +HOSTS: + archlinux-2-x64: + roles: + - master + platform: archlinux-2-x64 + box: archlinux/archlinux + hypervisor: vagrant +CONFIG: + type: foss diff --git a/spec/acceptance/nodesets/debian9-6.3.yml b/spec/acceptance/nodesets/debian9-6.3.yml deleted file mode 100644 index 92e36ed..0000000 --- a/spec/acceptance/nodesets/debian9-6.3.yml +++ /dev/null @@ -1,13 +0,0 @@ -HOSTS: - debian-9-x64: - platform: debian-9-amd64 - hypervisor : docker - image: deric/stretch-puppet:6.3.0 - docker_preserve_image: false - roles: - - agent - debug: false -CONFIG: - masterless: true - log_level: debug - type: foss \ No newline at end of file diff --git a/spec/acceptance/nodesets/default.yml b/spec/acceptance/nodesets/default.yml deleted file mode 100644 index 7429230..0000000 --- a/spec/acceptance/nodesets/default.yml +++ /dev/null @@ -1,13 +0,0 @@ -HOSTS: - debian-9-x64: - platform: debian-9-amd64 - hypervisor : docker - image: deric/stretch-puppet:5.5.14 - docker_preserve_image: false - roles: - - agent - debug: false -CONFIG: - masterless: true - log_level: debug - type: foss \ No newline at end of file diff --git a/spec/acceptance/nodesets/ec2/amazonlinux-2016091.yml b/spec/acceptance/nodesets/ec2/amazonlinux-2016091.yml new file mode 100644 index 0000000..19dd43e --- /dev/null +++ b/spec/acceptance/nodesets/ec2/amazonlinux-2016091.yml @@ -0,0 +1,31 @@ +--- +# This file is managed via modulesync +# https://github.com/voxpupuli/modulesync +# https://github.com/voxpupuli/modulesync_config +# +# Additional ~/.fog config file with AWS EC2 credentials +# required. +# +# see: https://github.com/puppetlabs/beaker/blob/master/docs/how_to/hypervisors/ec2.md +# +# Amazon Linux is not a RHEL clone. +# +HOSTS: + amazonlinux-2016091-x64: + roles: + - master + platform: centos-6-x86_64 + hypervisor: ec2 + # refers to image_tempaltes.yaml AMI[vmname] entry: + vmname: amazonlinux-2016091-eu-central-1 + # refers to image_tempaltes.yaml entry inside AMI[vmname][:image]: + snapshot: aio + # t2.micro is free tier eligible (https://aws.amazon.com/en/free/): + amisize: t2.micro + # required so that beaker sanitizes sshd_config and root authorized_keys: + user: ec2-user +CONFIG: + type: aio + :ec2_yaml: spec/acceptance/nodesets/ec2/image_templates.yaml +... +# vim: syntax=yaml diff --git a/spec/acceptance/nodesets/ec2/image_templates.yaml b/spec/acceptance/nodesets/ec2/image_templates.yaml new file mode 100644 index 0000000..e50593e --- /dev/null +++ b/spec/acceptance/nodesets/ec2/image_templates.yaml @@ -0,0 +1,34 @@ +# This file is managed via modulesync +# https://github.com/voxpupuli/modulesync +# https://github.com/voxpupuli/modulesync_config +# +# see also: https://github.com/puppetlabs/beaker/blob/master/docs/how_to/hypervisors/ec2.md +# +# Hint: image IDs (ami-*) for the same image are different per location. +# +AMI: + # Amazon Linux AMI 2016.09.1 (HVM), SSD Volume Type + amazonlinux-2016091-eu-central-1: + :image: + :aio: ami-af0fc0c0 + :region: eu-central-1 + # Red Hat Enterprise Linux 7.3 (HVM), SSD Volume Type + rhel-73-eu-central-1: + :image: + :aio: ami-e4c63e8b + :region: eu-central-1 + # SUSE Linux Enterprise Server 12 SP2 (HVM), SSD Volume Type + sles-12sp2-eu-central-1: + :image: + :aio: ami-c425e4ab + :region: eu-central-1 + # Ubuntu Server 16.04 LTS (HVM), SSD Volume Type + ubuntu-1604-eu-central-1: + :image: + :aio: ami-fe408091 + :region: eu-central-1 + # Microsoft Windows Server 2016 Base + windows-2016-base-eu-central-1: + :image: + :aio: ami-88ec20e7 + :region: eu-central-1 diff --git a/spec/acceptance/nodesets/ec2/rhel-73-x64.yml b/spec/acceptance/nodesets/ec2/rhel-73-x64.yml new file mode 100644 index 0000000..7fac823 --- /dev/null +++ b/spec/acceptance/nodesets/ec2/rhel-73-x64.yml @@ -0,0 +1,29 @@ +--- +# This file is managed via modulesync +# https://github.com/voxpupuli/modulesync +# https://github.com/voxpupuli/modulesync_config +# +# Additional ~/.fog config file with AWS EC2 credentials +# required. +# +# see: https://github.com/puppetlabs/beaker/blob/master/docs/how_to/hypervisors/ec2.md +# +HOSTS: + rhel-73-x64: + roles: + - master + platform: el-7-x86_64 + hypervisor: ec2 + # refers to image_tempaltes.yaml AMI[vmname] entry: + vmname: rhel-73-eu-central-1 + # refers to image_tempaltes.yaml entry inside AMI[vmname][:image]: + snapshot: aio + # t2.micro is free tier eligible (https://aws.amazon.com/en/free/): + amisize: t2.micro + # required so that beaker sanitizes sshd_config and root authorized_keys: + user: ec2-user +CONFIG: + type: aio + :ec2_yaml: spec/acceptance/nodesets/ec2/image_templates.yaml +... +# vim: syntax=yaml diff --git a/spec/acceptance/nodesets/ec2/sles-12sp2-x64.yml b/spec/acceptance/nodesets/ec2/sles-12sp2-x64.yml new file mode 100644 index 0000000..8542154 --- /dev/null +++ b/spec/acceptance/nodesets/ec2/sles-12sp2-x64.yml @@ -0,0 +1,29 @@ +--- +# This file is managed via modulesync +# https://github.com/voxpupuli/modulesync +# https://github.com/voxpupuli/modulesync_config +# +# Additional ~/.fog config file with AWS EC2 credentials +# required. +# +# see: https://github.com/puppetlabs/beaker/blob/master/docs/how_to/hypervisors/ec2.md +# +HOSTS: + sles-12sp2-x64: + roles: + - master + platform: sles-12-x86_64 + hypervisor: ec2 + # refers to image_tempaltes.yaml AMI[vmname] entry: + vmname: sles-12sp2-eu-central-1 + # refers to image_tempaltes.yaml entry inside AMI[vmname][:image]: + snapshot: aio + # t2.micro is free tier eligible (https://aws.amazon.com/en/free/): + amisize: t2.micro + # required so that beaker sanitizes sshd_config and root authorized_keys: + user: ec2-user +CONFIG: + type: aio + :ec2_yaml: spec/acceptance/nodesets/ec2/image_templates.yaml +... +# vim: syntax=yaml diff --git a/spec/acceptance/nodesets/ec2/ubuntu-1604-x64.yml b/spec/acceptance/nodesets/ec2/ubuntu-1604-x64.yml new file mode 100644 index 0000000..9cf59d5 --- /dev/null +++ b/spec/acceptance/nodesets/ec2/ubuntu-1604-x64.yml @@ -0,0 +1,29 @@ +--- +# This file is managed via modulesync +# https://github.com/voxpupuli/modulesync +# https://github.com/voxpupuli/modulesync_config +# +# Additional ~/.fog config file with AWS EC2 credentials +# required. +# +# see: https://github.com/puppetlabs/beaker/blob/master/docs/how_to/hypervisors/ec2.md +# +HOSTS: + ubuntu-1604-x64: + roles: + - master + platform: ubuntu-16.04-amd64 + hypervisor: ec2 + # refers to image_tempaltes.yaml AMI[vmname] entry: + vmname: ubuntu-1604-eu-central-1 + # refers to image_tempaltes.yaml entry inside AMI[vmname][:image]: + snapshot: aio + # t2.micro is free tier eligible (https://aws.amazon.com/en/free/): + amisize: t2.micro + # required so that beaker sanitizes sshd_config and root authorized_keys: + user: ubuntu +CONFIG: + type: aio + :ec2_yaml: spec/acceptance/nodesets/ec2/image_templates.yaml +... +# vim: syntax=yaml diff --git a/spec/acceptance/nodesets/ec2/windows-2016-base-x64.yml b/spec/acceptance/nodesets/ec2/windows-2016-base-x64.yml new file mode 100644 index 0000000..0932e29 --- /dev/null +++ b/spec/acceptance/nodesets/ec2/windows-2016-base-x64.yml @@ -0,0 +1,29 @@ +--- +# This file is managed via modulesync +# https://github.com/voxpupuli/modulesync +# https://github.com/voxpupuli/modulesync_config +# +# Additional ~/.fog config file with AWS EC2 credentials +# required. +# +# see: https://github.com/puppetlabs/beaker/blob/master/docs/how_to/hypervisors/ec2.md +# +HOSTS: + windows-2016-base-x64: + roles: + - master + platform: windows-2016-64 + hypervisor: ec2 + # refers to image_tempaltes.yaml AMI[vmname] entry: + vmname: windows-2016-base-eu-central-1 + # refers to image_tempaltes.yaml entry inside AMI[vmname][:image]: + snapshot: aio + # t2.micro is free tier eligible (https://aws.amazon.com/en/free/): + amisize: t2.micro + # required so that beaker sanitizes sshd_config and root authorized_keys: + user: ec2-user +CONFIG: + type: aio + :ec2_yaml: spec/acceptance/nodesets/ec2/image_templates.yaml +... +# vim: syntax=yaml diff --git a/spec/acceptance/zookeeper_spec.rb b/spec/acceptance/zookeeper_spec.rb index d801d4b..ae1dcb5 100644 --- a/spec/acceptance/zookeeper_spec.rb +++ b/spec/acceptance/zookeeper_spec.rb @@ -1,68 +1,83 @@ require 'spec_helper_acceptance' -describe 'zookeeper defintion', :unless => UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do +case fact('osfamily') +when 'Debian' + service_name = 'zookeeper' +when 'RedHat' + service_name = 'zookeeper-server' +end + +describe 'zookeeper defintion' do context 'basic setup' do it 'install zookeeper' do - pp = <<-EOS - class{'zookeeper': - client_port => 2181, - service_provider => 'debian', - } - EOS + case fact('osfamily') + when 'Debian' + pp = <<-EOS + class { 'zookeeper': } + EOS + when 'RedHat' + pp = <<-EOS + class { 'zookeeper': + install_java => true, + java_package => 'java-1.8.0-openjdk-headless', + initialize_datastore => true, + service_provider => 'redhat', + } + EOS + end expect(apply_manifest(pp, - :catch_failures => false, - :debug => false - ).exit_code).to be_zero - end + catch_failures: false, + debug: false).exit_code).to be_zero + end - describe file('/etc/zookeeper') do - it { is_expected.to be_directory } - end + describe file('/etc/zookeeper') do + it { is_expected.to be_directory } + end - describe file('/etc/zookeeper/conf') do - it { is_expected.to be_directory } - end + describe file('/etc/zookeeper/conf') do + it { is_expected.to be_directory } + end describe user('zookeeper') do it { is_expected.to exist } end describe group('zookeeper') do it { is_expected.to exist } end - describe command('/etc/init.d/zookeeper status') do + describe command("/etc/init.d/#{service_name} status") do its(:exit_status) { is_expected.to eq 0 } - its(:stdout) { is_expected.to match /running/ } + its(:stdout) { is_expected.to match %r{running} } end # give zookeeper some time to boot describe command('sleep 2 && netstat -tulpn') do its(:exit_status) { is_expected.to eq 0 } - its(:stdout) { is_expected.to match /2181/ } + its(:stdout) { is_expected.to match %r{2181} } end describe command('cat /etc/zookeeper/conf/myid') do its(:exit_status) { is_expected.to eq 0 } - its(:stdout) { is_expected.to match /^1$/ } + its(:stdout) { is_expected.to match %r{^1$} } end describe file('/etc/zookeeper/conf/zoo.cfg') do it { is_expected.to be_file } it { is_expected.to be_writable.by('owner') } it { is_expected.to be_readable.by('group') } it { is_expected.to be_readable.by('others') } end describe command('cat /etc/zookeeper/conf/zoo.cfg') do its(:exit_status) { is_expected.to eq 0 } - its(:stdout) { is_expected.to match /^clientPort=2181$/ } + its(:stdout) { is_expected.to match %r{^clientPort=2181$} } end describe command('echo stat | nc 0.0.0.0 2181') do its(:exit_status) { is_expected.to eq 0 } - its(:stdout) { is_expected.to match /^Mode: standalone$/ } + its(:stdout) { is_expected.to match %r{^Mode: standalone$} } end end end diff --git a/spec/classes/config_spec.rb b/spec/classes/config_spec.rb index d8737b2..9a2b9f5 100644 --- a/spec/classes/config_spec.rb +++ b/spec/classes/config_spec.rb @@ -1,604 +1,594 @@ require 'spec_helper' -shared_examples 'zookeeper parameters' do |os_facts, precond| +shared_examples 'zookeeper parameters' do |_os_facts, precond| # load class, handle custom params let :pre_condition do precond end it do - is_expected.to contain_file(cfg_dir).with({ - 'ensure' => 'directory', - 'owner' => user, - 'group' => group, - }) + is_expected.to contain_file(cfg_dir).with('ensure' => 'directory', + 'owner' => user, + 'group' => group) end it do - is_expected.to contain_file(log_dir).with({ - 'ensure' => 'directory', - 'owner' => user, - 'group' => group, - }) + is_expected.to contain_file(log_dir).with('ensure' => 'directory', + 'owner' => user, + 'group' => group) end it do - is_expected.to contain_file(id_file).with({ - 'ensure' => 'file', - 'owner' => user, - 'group' => group, - }).with_content(myid) + is_expected.to contain_file(id_file).with('ensure' => 'file', + 'owner' => user, + 'group' => group).with_content(myid) end end shared_examples 'zookeeper common' do |os_facts| os_info = get_os_info(os_facts) environment_file = os_info[:environment_file] context 'extra parameters' do # set custom params let :pre_condition do 'class {"zookeeper": log4j_prop => "ERROR", snap_count => 15000, }' end it do - is_expected.to contain_file(environment_file).with_content(/ERROR/) - is_expected.to contain_file(environment_file).with_content(/CLASSPATH/) + is_expected.to contain_file(environment_file).with_content(%r{ERROR}) + is_expected.to contain_file(environment_file).with_content(%r{CLASSPATH}) end it do - is_expected.to contain_file('/etc/zookeeper/conf/zoo.cfg').with_content(/snapCount=15000/) + is_expected.to contain_file('/etc/zookeeper/conf/zoo.cfg').with_content(%r{snapCount=15000}) end # leave the default value to be determined by ZooKeeper it 'does not set maxClientCnxns by default' do # due to problem with should_not not matching, we're using more complicated way is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/^#maxClientCnxns=/) + ).with_content(%r{^#maxClientCnxns=}) end # by default do not set client IP address it do is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/^#clientPortAddress=/) + ).with_content(%r{^#clientPortAddress=}) end end context 'install from archive' do let :pre_condition do 'class {"zookeeper": - install_method: "archive", - archive_version: "3.4.9", + install_method => "archive", + archive_version => "3.4.9", }' + end - it {is_expected.to contain_file(environment_file).without_content(/CLASSPATH/)} + it do + is_expected.to contain_file(environment_file).without_content(%r{CLASSPATH}) end end context 'extra environment_file parameter' do - # set custom params - let :pre_condition do - 'class {"zookeeper": - log4j_prop => "ERROR", - environment_file => "java.env", - }' - end + # set custom params + let :pre_condition do + 'class {"zookeeper": + log4j_prop => "ERROR", + environment_file => "java.env", + }' + end - it do - should contain_file('/etc/zookeeper/conf/java.env').with_content(/ERROR/) - should_not contain_file('/etc/zookeeper/environment') - end + it do + is_expected.to contain_file('/etc/zookeeper/conf/java.env').with_content(%r{ERROR}) + is_expected.not_to contain_file('/etc/zookeeper/environment') + end end context 'max allowed connections' do let :pre_condition do 'class {"zookeeper": max_allowed_connections => 15, }' end it do is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/maxClientCnxns=15/) + ).with_content(%r{maxClientCnxns=15}) end end context 'set client ip address' do let :pre_condition do 'class {"zookeeper": client_ip => "192.168.1.1", }' end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/clientPortAddress=192.168.1.1/) + ).with_content(%r{clientPortAddress=192.168.1.1}) end end context 'setting tick time' do let :pre_condition do 'class {"zookeeper": tick_time => 3000, }' end it do - should contain_file('/etc/zookeeper/conf/zoo.cfg').with_content(/tickTime=3000/) + is_expected.to contain_file('/etc/zookeeper/conf/zoo.cfg').with_content(%r{tickTime=3000}) end end context 'setting init and sync limit' do let :pre_condition do 'class {"zookeeper": init_limit => 15, sync_limit => 10, }' end it do - should contain_file('/etc/zookeeper/conf/zoo.cfg').with_content(/initLimit=15/) + is_expected.to contain_file('/etc/zookeeper/conf/zoo.cfg').with_content(%r{initLimit=15}) end it do - should contain_file('/etc/zookeeper/conf/zoo.cfg').with_content(/syncLimit=10/) + is_expected.to contain_file('/etc/zookeeper/conf/zoo.cfg').with_content(%r{syncLimit=10}) end end context 'setting leader' do let :pre_condition do 'class {"zookeeper": leader => false, }' end it do - should contain_file('/etc/zookeeper/conf/zoo.cfg').with_content(/leaderServes=no/) + is_expected.to contain_file('/etc/zookeeper/conf/zoo.cfg').with_content(%r{leaderServes=no}) end end context 'myid link' do let :pre_condition do 'class {"zookeeper":}' end it do - should contain_file( + is_expected.to contain_file( '/var/lib/zookeeper/myid' - ).with({ - 'ensure' => 'link', - 'target' => '/etc/zookeeper/conf/myid', - }) + ).with('ensure' => 'link', + 'target' => '/etc/zookeeper/conf/myid') end end context 'without datalogstore parameter' do let :pre_condition do 'class {"zookeeper":}' end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/# dataLogDir=\/disk2\/zookeeper/) + ).with_content(%r{# dataLogDir=/disk2/zookeeper}) end end context 'with datalogstore parameter' do let :pre_condition do 'class {"zookeeper": datalogstore => "/zookeeper/transaction/device", }' end let(:datalogstore) { '/zookeeper/transaction/device' } it do - should contain_file(datalogstore).with({ - 'ensure' => 'directory', - }) + is_expected.to contain_file(datalogstore).with('ensure' => 'directory') end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/dataLogDir=\/zookeeper\/transaction\/device/) + ).with_content(%r{dataLogDir=/zookeeper/transaction/device}) end end context 'setting quorum of servers with custom ports' do let :pre_condition do 'class {"zookeeper": election_port => 3000, leader_port => 4000, servers => ["192.168.1.1", "192.168.1.2"], }' end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.1=192.168.1.1:3000:4000/) + ).with_content(%r{server.1=192.168.1.1:3000:4000}) end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.2=192.168.1.2:3000:4000/) + ).with_content(%r{server.2=192.168.1.2:3000:4000}) end end context 'setting quorum of servers with custom ports with servers as hash' do let :pre_condition do 'class {"zookeeper": election_port => 3000, leader_port => 4000, servers => {"12" => "192.168.1.1", "23" => "192.168.1.2"}, }' end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.12=192.168.1.1:3000:4000/) + ).with_content(%r{server.12=192.168.1.1:3000:4000}) end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.23=192.168.1.2:3000:4000/) + ).with_content(%r{server.23=192.168.1.2:3000:4000}) end end context 'setting quorum of servers with default ports' do let :pre_condition do 'class {"zookeeper": servers => ["192.168.1.1", "192.168.1.2"] }' end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.1=192.168.1.1:2888:3888/) + ).with_content(%r{server.1=192.168.1.1:2888:3888}) end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.2=192.168.1.2:2888:3888/) + ).with_content(%r{server.2=192.168.1.2:2888:3888}) end end context 'setting quorum of servers with default ports with servers as hash' do let :pre_condition do 'class {"zookeeper": servers => {"12" => "192.168.1.1", "23" => "192.168.1.2"}, }' end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.12=192.168.1.1:2888:3888/) + ).with_content(%r{server.12=192.168.1.1:2888:3888}) end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.23=192.168.1.2:2888:3888/) + ).with_content(%r{server.23=192.168.1.2:2888:3888}) end end context 'setting quorum of servers with default ports with observer' do let :pre_condition do 'class {"zookeeper": servers => ["192.168.1.1", "192.168.1.2", "192.168.1.3", "192.168.1.4", "192.168.1.5"], observers => ["192.168.1.4", "192.168.1.5"] }' end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.1=192.168.1.1:2888:3888/) + ).with_content(%r{server.1=192.168.1.1:2888:3888}) end it do - should_not contain_file( + is_expected.not_to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.1=192.168.1.1:2888:3888:observer/) + ).with_content(%r{server.1=192.168.1.1:2888:3888:observer}) end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.2=192.168.1.2:2888:3888/) + ).with_content(%r{server.2=192.168.1.2:2888:3888}) end it do - should_not contain_file( + is_expected.not_to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.2=192.168.1.2:2888:3888:observer/) + ).with_content(%r{server.2=192.168.1.2:2888:3888:observer}) end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.3=192.168.1.3:2888:3888/) + ).with_content(%r{server.3=192.168.1.3:2888:3888}) end it do - should_not contain_file( + is_expected.not_to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.3=192.168.1.3:2888:3888:observer/) + ).with_content(%r{server.3=192.168.1.3:2888:3888:observer}) end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.4=192.168.1.4:2888:3888:observer/) + ).with_content(%r{server.4=192.168.1.4:2888:3888:observer}) end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.5=192.168.1.5:2888:3888:observer/) + ).with_content(%r{server.5=192.168.1.5:2888:3888:observer}) end end context 'setting quorum of servers with default ports with observer with servers as hash' do let :pre_condition do 'class {"zookeeper": servers => {"12" => "192.168.1.1", "23" => "192.168.1.2", "34" => "192.168.1.3", "45" => "192.168.1.4", "56" => "192.168.1.5"}, observers => ["192.168.1.4", "192.168.1.5"] }' end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.12=192.168.1.1:2888:3888/) + ).with_content(%r{server.12=192.168.1.1:2888:3888}) end it do - should_not contain_file( + is_expected.not_to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.12=192.168.1.1:2888:3888:observer/) + ).with_content(%r{server.12=192.168.1.1:2888:3888:observer}) end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.23=192.168.1.2:2888:3888/) + ).with_content(%r{server.23=192.168.1.2:2888:3888}) end it do - should_not contain_file( + is_expected.not_to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.23=192.168.1.2:2888:3888:observer/) + ).with_content(%r{server.23=192.168.1.2:2888:3888:observer}) end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.34=192.168.1.3:2888:3888/) + ).with_content(%r{server.34=192.168.1.3:2888:3888}) end it do - should_not contain_file( + is_expected.not_to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.34=192.168.1.3:2888:3888:observer/) + ).with_content(%r{server.34=192.168.1.3:2888:3888:observer}) end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.45=192.168.1.4:2888:3888:observer/) + ).with_content(%r{server.45=192.168.1.4:2888:3888:observer}) end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.56=192.168.1.5:2888:3888:observer/) + ).with_content(%r{server.56=192.168.1.5:2888:3888:observer}) end end context 'setting minSessionTimeout' do let :pre_condition do 'class {"zookeeper": min_session_timeout => 5000 }' end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/minSessionTimeout=5000/) + ).with_content(%r{minSessionTimeout=5000}) end end context 'setting maxSessionTimeout' do let :pre_condition do 'class {"zookeeper": max_session_timeout => 50000 }' end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/maxSessionTimeout=50000/) + ).with_content(%r{maxSessionTimeout=50000}) end end context 'make sure port is not included in server IP/hostname' do let :pre_condition do 'class {"zookeeper": servers => ["192.168.1.1:2888", "192.168.1.2:2333"] }' end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.1=192.168.1.1:2888:3888/) + ).with_content(%r{server.1=192.168.1.1:2888:3888}) end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/server.2=192.168.1.2:2888:3888/) + ).with_content(%r{server.2=192.168.1.2:2888:3888}) end end context 'configure logging' do context 'by default set to INFO' do let :pre_condition do 'class {"zookeeper": }' end it do is_expected.to contain_file( '/etc/zookeeper/conf/log4j.properties' - ).with_content(/zookeeper.log.threshold=INFO/) + ).with_content(%r{zookeeper.log.threshold=INFO}) end it do is_expected.to contain_file( '/etc/zookeeper/conf/log4j.properties' - ).with_content(/zookeeper.console.threshold=INFO/) + ).with_content(%r{zookeeper.console.threshold=INFO}) end end context 'allow changing rollingfile loglevel' do let :pre_condition do 'class {"zookeeper": rollingfile_threshold => "TRACE", }' end it do is_expected.to contain_file( '/etc/zookeeper/conf/log4j.properties' - ).with_content(/zookeeper.log.threshold=TRACE/) + ).with_content(%r{zookeeper.log.threshold=TRACE}) end end context 'allow changing console loglevel' do let :pre_condition do 'class {"zookeeper": console_threshold => "TRACE", }' end it do is_expected.to contain_file( '/etc/zookeeper/conf/log4j.properties' - ).with_content(/zookeeper.console.threshold=TRACE/) + ).with_content(%r{zookeeper.console.threshold=TRACE}) end end context 'allow changing tracefile loglevel' do let :pre_condition do 'class {"zookeeper": tracefile_threshold => "DEBUG", }' end it do is_expected.to contain_file( '/etc/zookeeper/conf/log4j.properties' - ).with_content(/log4j.appender.TRACEFILE.Threshold=DEBUG/) + ).with_content(%r{log4j.appender.TRACEFILE.Threshold=DEBUG}) end end context 'setting 4lw whitelist' do let :pre_condition do 'class {"zookeeper": whitelist_4lw => ["ruok","stat"] }' end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/4lw.commands.whitelist=ruok,stat/) + ).with_content(%r{4lw.commands.whitelist=ruok,stat}) end end context 'set global outstanding limit' do let :pre_condition do 'class {"zookeeper": global_outstanding_limit => 2000 }' end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/globalOutstandingLimit=2000/) + ).with_content(%r{globalOutstandingLimit=2000}) end end end end describe 'zookeeper::config' do on_supported_os.each do |os, os_facts| os_facts[:os]['hardware'] = 'x86_64' context "on #{os}" do let(:facts) do - os_facts.merge({ - :ipaddress => '192.168.1.1', - }) + os_facts.merge(ipaddress: '192.168.1.1') end context 'with default parameters' do let(:user) { 'zookeeper' } let(:group) { 'zookeeper' } let(:cfg_dir) { '/etc/zookeeper/conf' } let(:log_dir) { '/var/lib/zookeeper' } let(:id_file) { '/etc/zookeeper/conf/myid' } - let(:myid) { /^1/ } + let(:myid) { %r{^1} } precond = 'class {"zookeeper": }' include_examples 'zookeeper parameters', os_facts, precond end context 'with custom parameters' do let(:user) { 'zoo' } let(:group) { 'zoo' } let(:cfg_dir) { '/var/lib/zookeeper/conf' } let(:log_dir) { '/var/lib/zookeeper/log' } let(:id_file) { '/var/lib/zookeeper/conf/myid' } - let(:myid) { /^2/ } + let(:myid) { %r{^2} } # set custom params precond = 'class {"zookeeper": id => "2", user => "zoo", group => "zoo", cfg_dir => "/var/lib/zookeeper/conf", log_dir => "/var/lib/zookeeper/log", }' include_examples 'zookeeper parameters', os_facts, precond end include_examples 'zookeeper common', os_facts end end end diff --git a/spec/classes/init_spec.rb b/spec/classes/init_spec.rb index 5434ac7..fcfc7f6 100644 --- a/spec/classes/init_spec.rb +++ b/spec/classes/init_spec.rb @@ -1,237 +1,274 @@ require 'spec_helper' shared_examples 'zookeeper' do |os_facts| let(:user) { 'zookeeper' } let(:group) { 'zookeeper' } os_info = get_os_info(os_facts) service_name = os_info[:service_name] environment_file = os_info[:environment_file] init_provider = os_info[:init_provider] should_install_zookeeperd = os_info[:should_install_zookeeperd] it { is_expected.to contain_class('zookeeper::config') } it { is_expected.to contain_class('zookeeper::install') } it { is_expected.to contain_class('zookeeper::service') } it { is_expected.to compile.with_all_deps } it { is_expected.to contain_service(service_name) } it { is_expected.to contain_service(service_name).that_subscribes_to('File[/etc/zookeeper/conf/myid]') } it { is_expected.to contain_service(service_name).that_subscribes_to('File[/etc/zookeeper/conf/zoo.cfg]') } it { is_expected.to contain_service(service_name).that_subscribes_to("File[#{environment_file}]") } it { is_expected.to contain_service(service_name).that_subscribes_to('File[/etc/zookeeper/conf/log4j.properties]') } context 'skip service restart' do let(:params) do { - :restart_on_change => false, + restart_on_change: false } end it { is_expected.to contain_service(service_name) } it { is_expected.not_to contain_service(service_name).that_subscribes_to('File[/etc/zookeeper/conf/myid]') } it { is_expected.not_to contain_service(service_name).that_subscribes_to('File[/etc/zookeeper/conf/zoo.cfg]') } it { is_expected.not_to contain_service(service_name).that_subscribes_to("File[#{environment_file}]") } it { is_expected.not_to contain_service(service_name).that_subscribes_to('File[/etc/zookeeper/conf/log4j.properties]') } end context 'allow installing multiple packages' do let(:params) do { - :packages => [ 'zookeeper', 'zookeeper-bin' ], + packages: ['zookeeper', 'zookeeper-bin'] } end it { is_expected.to compile.with_all_deps } - it { is_expected.to contain_package('zookeeper').with({:ensure => 'present'}) } - it { is_expected.to contain_package('zookeeper-bin').with({:ensure => 'present'}) } - it { is_expected.to contain_service(service_name).with({:ensure => 'running'}) } + it { is_expected.to contain_package('zookeeper').with(ensure: 'present') } + it { is_expected.to contain_package('zookeeper-bin').with(ensure: 'present') } + it { is_expected.to contain_service(service_name).with(ensure: 'running') } # datastore exec is not included by default it { is_expected.not_to contain_exec('initialize_datastore') } - it { is_expected.to contain_user('zookeeper').with({:ensure => 'present'}) } - it { is_expected.to contain_group('zookeeper').with({:ensure => 'present'}) } + it { is_expected.to contain_user('zookeeper').with(ensure: 'present') } + it { is_expected.to contain_group('zookeeper').with(ensure: 'present') } end context 'Cloudera packaging' do let(:params) do { - :packages => ['zookeeper','zookeeper-server'], - :service_name => 'zookeeper-server', - :initialize_datastore => true - } + packages: ['zookeeper', 'zookeeper-server'], + service_name: 'zookeeper-server', + initialize_datastore: true + } end - it { should contain_package('zookeeper').with({:ensure => 'present'}) } - it { should contain_package('zookeeper-server').with({:ensure => 'present'}) } - it { should contain_service('zookeeper-server').with({:ensure => 'running'}) } - it { should contain_exec('initialize_datastore') } + it { is_expected.to contain_package('zookeeper').with(ensure: 'present') } + it { is_expected.to contain_package('zookeeper-server').with(ensure: 'present') } + it { is_expected.to contain_service('zookeeper-server').with(ensure: 'running') } + it { is_expected.to contain_exec('initialize_datastore') } end context 'setting minSessionTimeout' do let(:params) do { - :min_session_timeout => 3000 - } + min_session_timeout: 3000 + } end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/minSessionTimeout=3000/) + ).with_content(%r{minSessionTimeout=3000}) end end context 'setting maxSessionTimeout' do let(:params) do { - :max_session_timeout => 60000 - } + max_session_timeout: 60_000 + } end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/maxSessionTimeout=60000/) + ).with_content(%r{maxSessionTimeout=60000}) end end context 'disable service management' do let(:params) do { - :manage_service => false, - } + manage_service: false + } end - it { should contain_package('zookeeper').with({:ensure => 'present'}) } - it { should_not contain_service(service_name).with({:ensure => 'running'}) } - it { should_not contain_class('zookeeper::service') } + it { is_expected.to contain_package('zookeeper').with(ensure: 'present') } + it { is_expected.not_to contain_service(service_name).with(ensure: 'running') } + it { is_expected.not_to contain_class('zookeeper::service') } end if os_facts[:osfamily] == 'RedHat' context 'use Cloudera RPM repo' do let(:params) do { - :repo => 'cloudera', - :cdhver => '5', - } + repo: 'cloudera', + cdhver: '5' + } end it { is_expected.to compile.with_all_deps } - it { should contain_class('zookeeper::install::repo') } - it { should contain_yumrepo('cloudera-cdh5') } + it { is_expected.to contain_class('zookeeper::install::repo') } + it { is_expected.to contain_yumrepo('cloudera-cdh5') } context 'custom RPM repo' do let(:params) do { - :repo => { - 'name' => 'myrepo', - 'url' => 'http://repo.url', - 'descr' => 'custom repo', - }, - :cdhver => '5', - } + repo: { + 'name' => 'myrepo', + 'url' => 'http://repo.url', + 'descr' => 'custom repo' + }, + cdhver: '5' + } end - it { should contain_yumrepo('myrepo').with({:baseurl => 'http://repo.url'}) } + + it { is_expected.to contain_yumrepo('myrepo').with(baseurl: 'http://repo.url') } end end end context 'service provider' do context 'autodetect provider' do - it { should contain_package('zookeeper').with({:ensure => 'present'}) } + it { is_expected.to contain_package('zookeeper').with(ensure: 'present') } if os_facts[:osfamily] == 'RedHat' - it { should contain_package('zookeeper-server').with({:ensure => 'present'}) } + it { is_expected.to contain_package('zookeeper-server').with(ensure: 'present') } else - it { should_not contain_package('zookeeper-server').with({:ensure => 'present'}) } + it { is_expected.not_to contain_package('zookeeper-server').with(ensure: 'present') } end it do - should contain_service(service_name).with({ - :ensure => 'running', - :provider => init_provider, - }) + is_expected.to contain_service(service_name).with(ensure: 'running', + provider: init_provider) end end - it { should contain_class('zookeeper::service') } + it { is_expected.to contain_class('zookeeper::service') } end context 'allow passing specific version' do - let(:version) {'3.4.5+dfsg-1'} + let(:version) { '3.4.5+dfsg-1' } let(:params) do { - :ensure => version, - } + ensure: version + } end - it { is_expected.to contain_package('zookeeper').with({:ensure => version}) } + it { is_expected.to contain_package('zookeeper').with(ensure: version) } if should_install_zookeeperd - it { is_expected.to contain_package('zookeeperd').with({:ensure => version}) } + it { is_expected.to contain_package('zookeeperd').with(ensure: version) } else - it { is_expected.not_to contain_package('zookeeperd').with({:ensure => version}) } + it { is_expected.not_to contain_package('zookeeperd').with(ensure: version) } end - it { is_expected.to contain_user('zookeeper').with({:ensure => 'present'}) } + it { is_expected.to contain_user('zookeeper').with(ensure: 'present') } + end + + context 'set pid file for init provider' do + let(:params) do + { + zoo_dir: '/usr/lib/zookeeper', + log_dir: '/var/log/zookeeper', + manage_service: true, + manage_service_file: true, + service_provider: 'init' + } + end + + it do + is_expected.to contain_file( + '/etc/zookeeper/conf/log4j.properties' + ).with_content(%r{zookeeper.log.dir=/var/log/zookeeper}) + end + + context 'set service provider' do + it { is_expected.to contain_package('zookeeper').with(ensure: 'present') } + it do + is_expected.to contain_service(service_name).with(ensure: 'running', + provider: 'init') + end + end + + if os_facts[:osfamily] == 'RedHat' + it do + is_expected.to contain_file( + "/etc/init.d/#{service_name}" + ).with_content(%r{pidfile=/var/run/zookeeper.pid}) + end + else + it do + is_expected.to contain_file( + environment_file + ).with_content(%r{PIDFILE=/var/run/zookeeper.pid}) + end + end end context 'create env file' do it do is_expected.to contain_file( environment_file ) end end context 'managed by exhibitor' do let(:params) do { - :service_provider => 'exhibitor', - :service_name => 'zookeeper', - :cfg_dir => '/opt/zookeeper/conf', + service_provider: 'exhibitor', + service_name: 'zookeeper', + cfg_dir: '/opt/zookeeper/conf' } end it { is_expected.not_to contain_class('zookeeper::service') } it { is_expected.not_to contain_service(service_name) } it { is_expected.not_to contain_file('/opt/zookeeper/conf/zoo.cfg') } it { is_expected.not_to contain_file('/opt/zookeeper/conf/myid') } end context 'install from archive' do let(:params) do { install_method: 'archive', - archive_version: '3.4.9', + archive_version: '3.4.9' } end it { is_expected.to compile.with_all_deps } it { is_expected.to contain_class('Zookeeper::Install::Archive') } - it { is_expected.not_to contain_package('zookeeper').with({:ensure => 'present'}) } - it { is_expected.to contain_service(service_name).with({:ensure => 'running'}) } + it { is_expected.not_to contain_package('zookeeper').with(ensure: 'present') } + it { is_expected.to contain_service(service_name).with(ensure: 'running') } - it { is_expected.to contain_user('zookeeper').with({:ensure => 'present'}) } - it { is_expected.to contain_group('zookeeper').with({:ensure => 'present'}) } + it { is_expected.to contain_user('zookeeper').with(ensure: 'present') } + it { is_expected.to contain_group('zookeeper').with(ensure: 'present') } end end -describe 'zookeeper', :type => :class do +describe 'zookeeper', type: :class do on_supported_os.each do |os, os_facts| os_facts[:os]['hardware'] = 'x86_64' context "on #{os}" do let(:facts) do - os_facts.merge({ - :ipaddress => '192.168.1.1', - }) + os_facts.merge(ipaddress: '192.168.1.1') end include_examples 'zookeeper', os_facts end end end diff --git a/spec/classes/install_spec.rb b/spec/classes/install_spec.rb index 3ac6d37..49cf1da 100644 --- a/spec/classes/install_spec.rb +++ b/spec/classes/install_spec.rb @@ -1,387 +1,346 @@ require 'spec_helper' shared_examples 'zookeeper install' do |os_facts| # load class, handle custom params let :pre_condition do 'class {"zookeeper": snap_retain_count => 1, }' end - it { should contain_package('zookeeper') } + it { is_expected.to contain_package('zookeeper') } os_info = get_os_info(os_facts) should_install_cron = os_info[:should_install_cron] should_install_zookeeperd = os_info[:should_install_zookeeperd] zookeeper_shell = os_info[:zookeeper_shell] - it { should contain_class('zookeeper::post_install') } - it { should compile.with_all_deps } + it { is_expected.to contain_class('zookeeper::post_install') } + it { is_expected.to compile.with_all_deps } if should_install_zookeeperd - it { should contain_package('zookeeperd') } + it { is_expected.to contain_package('zookeeperd') } else - it { should_not contain_package('zookeeperd') } + it { is_expected.not_to contain_package('zookeeperd') } end if should_install_cron - it { should contain_package('cron') } + it { is_expected.to contain_package('cron') } else - it { should_not contain_package('cron') } + it { is_expected.not_to contain_package('cron') } end it 'installs cron script' do - cron_exists = contain_cron__job('zookeeper-cleanup').with({ - 'ensure' => 'present', - 'command' => '/usr/share/zookeeper/bin/zkCleanup.sh /var/lib/zookeeper 1', - 'user' => 'zookeeper', - 'hour' => '2', - 'minute' => '42', - }) + cron_exists = contain_cron__job('zookeeper-cleanup').with('ensure' => 'present', + 'command' => '/usr/share/zookeeper/bin/zkCleanup.sh /var/lib/zookeeper 1', + 'user' => 'zookeeper', + 'hour' => '2', + 'minute' => '42') if should_install_cron is_expected.to cron_exists else is_expected.not_to cron_exists end end - it 'installs cron script' do - cron_exists = contain_cron__job('zookeeper-cleanup').with({ - 'ensure' => 'present', - 'command' => '/usr/share/zookeeper/bin/zkCleanup.sh /var/lib/zookeeper 1', - 'user' => 'zookeeper', - 'hour' => '2', - 'minute' => '42', - }) + cron_exists = contain_cron__job('zookeeper-cleanup').with('ensure' => 'present', + 'command' => '/usr/share/zookeeper/bin/zkCleanup.sh /var/lib/zookeeper 1', + 'user' => 'zookeeper', + 'hour' => '2', + 'minute' => '42') if should_install_cron is_expected.to cron_exists else is_expected.not_to cron_exists end end context 'without cron' do let :pre_condition do 'class {"zookeeper": snap_retain_count => 0, }' end - it { should contain_package('zookeeper') } - it { should_not contain_package('cron') } + it { is_expected.to contain_package('zookeeper') } + it { is_expected.not_to contain_package('cron') } if should_install_zookeeperd - it { should contain_package('zookeeperd') } + it { is_expected.to contain_package('zookeeperd') } else - it { should_not contain_package('zookeeperd') } + it { is_expected.not_to contain_package('zookeeperd') } end end context 'with cron' do let :pre_condition do 'class {"zookeeper": snap_retain_count => 5, manual_clean => true, }' end - it { should contain_package('zookeeper') } - it { should contain_package('cron') } + it { is_expected.to contain_package('zookeeper') } + it { is_expected.to contain_package('cron') } it 'installs cron script' do - should contain_cron__job('zookeeper-cleanup').with({ - 'ensure' => 'present', - 'command' => '/usr/share/zookeeper/bin/zkCleanup.sh /var/lib/zookeeper 5', - 'user' => 'zookeeper', - 'hour' => '2', - 'minute' => '42', - }) + is_expected.to contain_cron__job('zookeeper-cleanup').with('ensure' => 'present', + 'command' => '/usr/share/zookeeper/bin/zkCleanup.sh /var/lib/zookeeper 5', + 'user' => 'zookeeper', + 'hour' => '2', + 'minute' => '42') end end context 'allow changing package names' do let :pre_condition do 'class {"zookeeper": packages => [ "zookeeper", "zookeeper-server" ], }' end - it { should contain_package('zookeeper') } - it { should contain_package('zookeeper-server') } - it { should_not contain_package('zookeeperd') } + it { is_expected.to contain_package('zookeeper') } + it { is_expected.to contain_package('zookeeper-server') } + it { is_expected.not_to contain_package('zookeeperd') } end context 'allow installing multiple packages' do let :pre_condition do 'class {"zookeeper": packages => [ "zookeeper", "zookeeper-devel" ], }' end - it { should contain_package('zookeeper') } - it { should contain_package('zookeeper-devel') } + it { is_expected.to contain_package('zookeeper') } + it { is_expected.to contain_package('zookeeper-devel') } end context 'with java installation' do let(:user) { 'zookeeper' } let(:group) { 'zookeeper' } let :pre_condition do 'class {"zookeeper": install_java => true, java_package => "java-1.7.0-openjdk", }' end it do - should contain_package('java-1.7.0-openjdk').with({ - 'ensure' => 'present', - }) + is_expected.to contain_package('java-1.7.0-openjdk').with('ensure' => 'present') end it do - should contain_package('zookeeper').with({ - 'ensure' => 'present', - }) + is_expected.to contain_package('zookeeper').with('ensure' => 'present') end end context 'with java installation fail when no packge provided' do let :pre_condition do 'class {"zookeeper": install_java => true, }' end it do expect do - should compile - end.to raise_error(/Java installation is required/) end + is_expected.to compile + end.to raise_error(%r{Java installation is required}) end end context 'removing package' do let :pre_condition do 'class {"zookeeper": ensure => absent, }' end it do - should contain_package('zookeeper').with({ - 'ensure' => 'absent', - }) + is_expected.to contain_package('zookeeper').with('ensure' => 'absent') end if should_install_zookeeperd it do - should contain_package('zookeeperd').with({ - 'ensure' => 'absent', - }) + is_expected.to contain_package('zookeeperd').with('ensure' => 'absent') end else it do - should_not contain_package('zookeeperd').with({ - 'ensure' => 'present', - }) + is_expected.not_to contain_package('zookeeperd').with('ensure' => 'present') end end - it { should_not contain_package('cron') } + it { is_expected.not_to contain_package('cron') } end # create user with proper shell #50 (https://github.com/deric/puppet-zookeeper/issues/50) context 'ensure user resource exists' do it do - should contain_user('zookeeper').with({ - 'ensure' => 'present', - 'shell' => zookeeper_shell, - }) + is_expected.to contain_user('zookeeper').with('ensure' => 'present', + 'shell' => zookeeper_shell) end end context 'user account' do let :pre_condition do 'class {"zookeeper": ensure_account => "present", }' end it do - should contain_user('zookeeper').with({ - :ensure => 'present' - }) + is_expected.to contain_user('zookeeper').with(ensure: 'present') end context 'remove user accounts' do let :pre_condition do 'class {"zookeeper": ensure_account => "absent", }' end it do - should contain_user('zookeeper').with({ - :ensure => 'absent' - }) + is_expected.to contain_user('zookeeper').with(ensure: 'absent') end end context 'do not manage user accounts' do let :pre_condition do 'class {"zookeeper": ensure_account => false, }' end - it { should_not contain_user('zookeeper') } + it { is_expected.not_to contain_user('zookeeper') } end end context 'installing 3.4.8 from tar archive' do let(:install_dir) { '/opt' } let(:zoo_dir) { '/opt/zookeeper' } let(:vers) { '3.4.8' } let(:mirror_url) { 'http://archive.apache.org/dist' } let(:basefilename) { "zookeeper-#{vers}.tar.gz" } let(:package_url) { "#{mirror_url}/zookeeper/zookeeper-#{vers}/zookeeper-#{vers}.tar.gz" } let(:extract_path) { "#{zoo_dir}-#{vers}" } let :pre_condition do 'class {"zookeeper": install_method => "archive", archive_version => "3.4.8", archive_install_dir => "/opt", zoo_dir => "/opt/zookeeper", }' end it do - is_expected.to contain_file(zoo_dir).with({ - :ensure => 'link', - :target => extract_path, - }) + is_expected.to contain_file(zoo_dir).with(ensure: 'link', + target: extract_path) end it do - should contain_archive("#{install_dir}/#{basefilename}").with({ - :extract_path => install_dir, - :source => package_url, - :creates => extract_path, - :user => 'root', - :group => 'root', - }) + is_expected.to contain_archive("#{install_dir}/#{basefilename}").with(extract_path: install_dir, + source: package_url, + creates: extract_path, + user: 'root', + group: 'root') end it do - is_expected.to contain_file('/etc/zookeeper').with({ - :ensure => 'directory', - :owner => 'zookeeper', - :group => 'zookeeper', - }) + is_expected.to contain_file('/etc/zookeeper').with(ensure: 'directory', + owner: 'zookeeper', + group: 'zookeeper') end end context 'installing 3.5.5 from tar archive' do let(:install_dir) { '/opt' } let(:zoo_dir) { '/opt/zookeeper' } let(:vers) { '3.5.5' } let(:mirror_url) { 'http://apache.org/dist/zookeeper' } let(:basefilename) { "apache-zookeeper-#{vers}-bin.tar.gz" } let(:package_url) { "#{mirror_url}/zookeeper-#{vers}/apache-zookeeper-#{vers}-bin.tar.gz" } let(:extract_path) { "/opt/apache-zookeeper-#{vers}-bin" } let :pre_condition do 'class {"zookeeper": install_method => "archive", archive_version => "3.5.5", archive_install_dir => "/opt", zoo_dir => "/opt/zookeeper", }' end it do - is_expected.to contain_file(zoo_dir).with({ - :ensure => 'link', - :target => extract_path, - }) + is_expected.to contain_file(zoo_dir).with(ensure: 'link', + target: extract_path) end it do - should contain_archive("#{install_dir}/#{basefilename}").with({ - :extract_path => install_dir, - :source => package_url, - :creates => extract_path, - :user => 'root', - :group => 'root', - }) + is_expected.to contain_archive("#{install_dir}/#{basefilename}").with(extract_path: install_dir, + source: package_url, + creates: extract_path, + user: 'root', + group: 'root') end it do - is_expected.to contain_file('/etc/zookeeper').with({ - :ensure => 'directory', - :owner => 'zookeeper', - :group => 'zookeeper', - }) + is_expected.to contain_file('/etc/zookeeper').with(ensure: 'directory', + owner: 'zookeeper', + group: 'zookeeper') end end context 'installing 3.4.8 from tar archive over proxy server' do let(:install_dir) { '/opt' } let(:zoo_dir) { '/opt/zookeeper' } let(:vers) { '3.4.8' } let(:mirror_url) { 'http://archive.apache.org/dist' } let(:basefilename) { "zookeeper-#{vers}.tar.gz" } let(:package_url) { "#{mirror_url}/zookeeper/zookeeper-#{vers}/zookeeper-#{vers}.tar.gz" } let(:extract_path) { "#{zoo_dir}-#{vers}" } let :pre_condition do 'class {"zookeeper": install_method => "archive", proxy_server => "http://10.0.0.1:8080", archive_version => "3.4.8", archive_install_dir => "/opt", zoo_dir => "/opt/zookeeper", }' end it do - is_expected.to contain_file(zoo_dir).with({ - :ensure => 'link', - :target => extract_path, - }) + is_expected.to contain_file(zoo_dir).with(ensure: 'link', + target: extract_path) end it do - should contain_archive("#{install_dir}/#{basefilename}").with({ - extract_path: install_dir, - source: package_url, - creates: extract_path, - proxy_server: 'http://10.0.0.1:8080', - user: 'root', - group: 'root', - }) + is_expected.to contain_archive("#{install_dir}/#{basefilename}").with(extract_path: install_dir, + source: package_url, + creates: extract_path, + proxy_server: 'http://10.0.0.1:8080', + user: 'root', + group: 'root') end it do - is_expected.to contain_file('/etc/zookeeper').with({ - :ensure => 'directory', - :owner => 'zookeeper', - :group => 'zookeeper', - }) + is_expected.to contain_file('/etc/zookeeper').with(ensure: 'directory', + owner: 'zookeeper', + group: 'zookeeper') end end end describe 'zookeeper::install' do let(:user) { 'zookeeper' } let(:group) { 'zookeeper' } on_supported_os.each do |os, os_facts| context "on #{os}" do let(:facts) do os_facts end include_examples 'zookeeper install', os_facts end end end diff --git a/spec/classes/repo_spec.rb b/spec/classes/repo_spec.rb index afa0eff..3770c50 100644 --- a/spec/classes/repo_spec.rb +++ b/spec/classes/repo_spec.rb @@ -1,146 +1,140 @@ require 'spec_helper' -shared_examples 'zookeeper repo release support' do |os_facts| +shared_examples 'zookeeper repo release support' do |_os_facts| context 'fail when release not supported' do let :pre_condition do 'class {"zookeeper": repo => "cloudera", cdhver => "5", }' end it do expect do is_expected.to compile - end.to raise_error(/is not supported for redhat version/) end + end.to raise_error(%r{is not supported for redhat version}) end end end -shared_examples 'zookeeper repo arch support' do |os_facts| +shared_examples 'zookeeper repo arch support' do |_os_facts| context 'fail when architecture not supported' do let :pre_condition do 'class {"zookeeper": repo => "cloudera", cdhver => "5", }' end it do expect do is_expected.to compile - end.to raise_error(/is not supported for architecture/) end + end.to raise_error(%r{is not supported for architecture}) end end end shared_examples 'zookeeper repo' do |os_facts| let(:user) { 'zookeeper' } let(:group) { 'zookeeper' } os_release = os_facts[:os]['release']['major'] os_hardware = os_facts[:os]['hardware'] if os_facts[:osfamily] == 'RedHat' context 'Cloudera repo' do let :pre_condition do 'class {"zookeeper": repo => "cloudera", cdhver => "5", }' end - it { is_expected.to contain_yumrepo('cloudera-cdh5').with({ - baseurl: "http://archive.cloudera.com/cdh5/redhat/#{os_release}/#{os_hardware}/cdh/5/" - }) } + it { + is_expected.to contain_yumrepo('cloudera-cdh5').with(baseurl: "http://archive.cloudera.com/cdh5/redhat/#{os_release}/#{os_hardware}/cdh/5/") + } end end context 'fail when CDH version not supported' do let :pre_condition do 'class {"zookeeper": repo => "cloudera", cdhver => "6", }' end it do expect do - should compile - end.to raise_error(/is not a supported cloudera repo./) end + is_expected.to compile + end.to raise_error(%r{is not a supported cloudera repo.}) end end context 'fail when repository source not supported' do let :pre_condition do 'class {"zookeeper": repo => "another-repo", }' end it do expect do - should compile - end.to raise_error(/provides no repository information for yum repository/) end + is_expected.to compile + end.to raise_error(%r{provides no repository information for yum repository}) end end end describe 'zookeeper::install::repo' do on_supported_os.each do |os, os_facts| os_facts[:os]['hardware'] = 'x86_64' context "on #{os}" do let(:facts) do - os_facts.merge({ - :ipaddress => '192.168.1.1', - }) + os_facts.merge(ipaddress: '192.168.1.1') end include_examples 'zookeeper repo', os_facts end end context 'test unsupported repo arch' do test_on = { - :hardwaremodels => ['arc'], - :supported_os => [ + hardwaremodels: ['arc'], + supported_os: [ { 'operatingsystem' => 'RedHat', - 'operatingsystemrelease' => ['7'], - }, - ], + 'operatingsystemrelease' => ['7'] + } + ] } on_supported_os(test_on).each do |os, os_facts| context "on #{os}" do let(:facts) do - os_facts.merge({ - :ipaddress => '192.168.1.1', - }) + os_facts.merge(ipaddress: '192.168.1.1') end include_examples 'zookeeper repo arch support', os_facts end end end context 'test unsupported repo release' do test_on = { - :supported_os => [ + supported_os: [ { 'operatingsystem' => 'RedHat', - 'operatingsystemrelease' => ['8'], - }, - ], + 'operatingsystemrelease' => ['8'] + } + ] } on_supported_os(test_on).each do |os, os_facts| os_facts[:os]['hardware'] = 'x86_64' context "on #{os}" do let(:facts) do - os_facts.merge({ - :ipaddress => '192.168.1.1', - }) + os_facts.merge(ipaddress: '192.168.1.1') end include_examples 'zookeeper repo release support', os_facts end end end end diff --git a/spec/classes/sasl_spec.rb b/spec/classes/sasl_spec.rb index 52780b3..ec17433 100644 --- a/spec/classes/sasl_spec.rb +++ b/spec/classes/sasl_spec.rb @@ -1,71 +1,69 @@ require 'spec_helper' shared_examples 'zookeeper::sasl' do |os_facts| os_info = get_os_info(os_facts) environment_file = os_info[:environment_file] context 'sasl config' do let :pre_condition do 'class {"zookeeper": use_sasl_auth => true, }' end it { is_expected.to compile.with_all_deps } it { is_expected.to contain_class('zookeeper::sasl') } it do is_expected.to contain_file( '/etc/zookeeper/conf/jaas.conf' - ).with_content(/storeKey=true/) + ).with_content(%r{storeKey=true}) end it do is_expected.to contain_file( environment_file - ).with_content(/JAVA_OPTS=".* -Djava.security.auth.login.config=\/etc\/zookeeper\/conf\/jaas.conf"/) + ).with_content(%r{JAVA_OPTS=".* -Djava.security.auth.login.config=/etc/zookeeper/conf/jaas.conf"}) end end context 'remove host and realm from principal' do let :pre_condition do 'class {"zookeeper": use_sasl_auth => true, remove_host_principal => true, remove_realm_principal => true, }' end it { is_expected.to compile.with_all_deps } it { is_expected.to contain_class('zookeeper::sasl') } it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/kerberos.removeHostFromPrincipal=true/) + ).with_content(%r{kerberos.removeHostFromPrincipal=true}) end it do - should contain_file( + is_expected.to contain_file( '/etc/zookeeper/conf/zoo.cfg' - ).with_content(/kerberos.removeRealmFromPrincipal=true/) + ).with_content(%r{kerberos.removeRealmFromPrincipal=true}) end end end describe 'zookeeper::sasl' do on_supported_os.each do |os, os_facts| os_facts[:os]['hardware'] = 'x86_64' context "on #{os}" do let(:facts) do - os_facts.merge({ - :ipaddress => '192.168.1.1', - }) + os_facts.merge(ipaddress: '192.168.1.1') end include_examples 'zookeeper::sasl', os_facts end end end diff --git a/spec/classes/service_spec.rb b/spec/classes/service_spec.rb index 90776df..d061a18 100644 --- a/spec/classes/service_spec.rb +++ b/spec/classes/service_spec.rb @@ -1,173 +1,187 @@ require 'spec_helper' shared_examples 'zookeeper::service' do |os_facts| let(:user) { 'zookeeper' } let(:group) { 'zookeeper' } os_info = get_os_info(os_facts) should_install_zookeeperd = os_info[:should_install_zookeeperd] service_name = os_info[:service_name] init_dir = os_info[:init_dir] init_provider = os_info[:init_provider] service_file = os_info[:service_file] case init_provider when 'systemd' context 'systemd' do let :pre_condition do 'class {"zookeeper": manage_service_file => true, service_provider => "systemd", systemd_path => "/usr/lib/systemd/system", zoo_dir => "/usr/lib/zookeeper", log_dir => "/var/log/zookeeper", }' end - it { should contain_package('zookeeper') } + it { is_expected.to contain_package('zookeeper') } if should_install_zookeeperd - it { should contain_package('zookeeperd') } + it { is_expected.to contain_package('zookeeperd') } else - it { should_not contain_package('zookeeperd') } + it { is_expected.not_to contain_package('zookeeperd') } end it do is_expected.to contain_file( "/usr/lib/systemd/system/#{service_name}.service" - ).with({ - 'ensure' => 'present', - }) + ).with('ensure' => 'present') end it do is_expected.to contain_file( "/usr/lib/systemd/system/#{service_name}.service" - ).with_content(/CLASSPATH="\/usr\/lib\/zookeeper\/zookeeper.jar/) + ).with_content(%r{CLASSPATH="/usr/lib/zookeeper/zookeeper.jar}) end it do is_expected.to contain_service(service_name).with( - :ensure => 'running', - :enable => true + ensure: 'running', + enable: true ) end context 'install from archive' do let :pre_condition do 'class {"zookeeper": manage_service_file => true, install_method => "archive", archive_version => "3.4.9" }' end it do is_expected.to contain_file(service_file).with_content( - /zookeeper-3\.4\.9\.jar/ + %r{zookeeper-3\.4\.9\.jar} ) end end context 'do not manage systemd' do let :pre_condition do 'class {"zookeeper": manage_service_file => false, zoo_dir => "/usr/lib/zookeeper", log_dir => "/var/log/zookeeper", }' end it do is_expected.not_to contain_file( '/usr/lib/systemd/system/zookeeper.service' - ).with({ - 'ensure' => 'present', - }) + ).with('ensure' => 'present') end it do - is_expected.not_to contain_file(service_file).with({ - 'ensure' => 'present', - }) + is_expected.not_to contain_file(service_file).with('ensure' => 'present') end end context 'systemd dependencies' do let :pre_condition do 'class {"zookeeper": service_provider => "systemd", manage_service_file => true, manage_service => true, systemd_unit_after => "network-online.target openvpn-client@.service", systemd_unit_want => "network-online.target openvpn-client@.service", }' end it do - is_expected.to contain_file(service_file).with({ - 'ensure' => 'present', - }) + is_expected.to contain_file(service_file).with('ensure' => 'present') end it do is_expected.to contain_file(service_file).with_content( - /Wants=network-online.target openvpn-client@.service/ + %r{Wants=network-online.target openvpn-client@.service} ) end it do is_expected.to contain_service(service_name).with( - :ensure => 'running', - :enable => true + ensure: 'running', + enable: true ) end end end + when 'init' + context 'init' do + let :pre_condition do + 'class {"zookeeper": + zoo_dir => "/usr/lib/zookeeper", + log_dir => "/var/log/zookeeper", + manage_service_file => true, + service_provider => "init", + }' + end + + it do + is_expected.to contain_file( + '/etc/init.d/zookeeper' + ).with('ensure' => 'present') + end + + it do + is_expected.to contain_service('zookeeper').with( + ensure: 'running', + enable: true, + provider: 'init' + ) + end + end + context 'custom service name' do let :pre_condition do 'class {"zookeeper": manage_service_file => true, service_name => "my-zookeeper", }' end - if init_provider == 'systemd' - custom_service_file = "#{init_dir}/my-zookeeper.service" - else - custom_service_file = "#{init_dir}/my-zookeeper" - end + custom_service_file = if init_provider == 'systemd' + "#{init_dir}/my-zookeeper.service" + else + "#{init_dir}/my-zookeeper" + end it do - is_expected.to contain_file(custom_service_file).with({ - 'ensure' => 'present', - }) + is_expected.to contain_file(custom_service_file).with('ensure' => 'present') end it do is_expected.to contain_service('my-zookeeper').with( - :ensure => 'running', - :enable => true + ensure: 'running', + enable: true ) end end end end describe 'zookeeper::service' do on_supported_os.each do |os, os_facts| os_facts[:os]['hardware'] = 'x86_64' context "on #{os}" do let(:facts) do - os_facts.merge({ - :ipaddress => '192.168.1.1', - }) + os_facts.merge(ipaddress: '192.168.1.1') end include_examples 'zookeeper::service', os_facts end end end diff --git a/spec/fixtures/hiera/hiera.yaml b/spec/fixtures/hiera/hiera.yaml deleted file mode 100644 index 58f410e..0000000 --- a/spec/fixtures/hiera/hiera.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -:backends: - - yaml -:hierarchy: - - test -:yaml: - :datadir: 'spec/fixtures/hiera' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c7ccad6..1fc67f2 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,48 +1,67 @@ -require 'puppet' -require 'rspec' -require 'rubygems' +# This file is managed via modulesync +# https://github.com/voxpupuli/modulesync +# https://github.com/voxpupuli/modulesync_config +RSpec.configure do |c| + c.mock_with :rspec +end + require 'puppetlabs_spec_helper/module_spec_helper' -require 'rspec-puppet/coverage' require 'rspec-puppet-facts' - -require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb')) - -#fixture_path = File.expand_path(File.join(__FILE__, '..', 'fixtures')) - +require 'bundler' include RspecPuppetFacts -RSpec.configure do |c| - c.include PuppetlabsSpec::Files - c.hiera_config = 'spec/fixtures/hiera/hiera.yaml' - - c.before :each do - # Ensure that we don't accidentally cache facts and environment - # between test cases. - Facter::Util::Loader.any_instance.stubs(:load_all) - Facter.clear - Facter.clear_messages - - # Store any environment variables away to be restored later - @old_env = {} - ENV.each_key {|k| @old_env[k] = ENV[k]} +if ENV['DEBUG'] + Puppet::Util::Log.level = :debug + Puppet::Util::Log.newdestination(:console) +end - if ENV['STRICT_VARIABLES'] == 'yes' - Puppet.settings[:strict_variables]=true +if File.exist?(File.join(__dir__, 'default_module_facts.yml')) + facts = YAML.load(File.read(File.join(__dir__, 'default_module_facts.yml'))) + if facts + facts.each do |name, value| + add_custom_fact name.to_sym, value end end - c.after :each do - PuppetlabsSpec::Files.cleanup +end + +if Dir.exist?(File.expand_path('../../lib', __FILE__)) + require 'coveralls' + require 'simplecov' + require 'simplecov-console' + SimpleCov.formatters = [ + SimpleCov::Formatter::HTMLFormatter, + SimpleCov::Formatter::Console + ] + SimpleCov.start do + track_files 'lib/**/*.rb' + add_filter '/spec' + add_filter '/vendor' + add_filter '/.vendor' + add_filter Bundler.configured_bundle_path.path end - # we don't want to run tests from submodules in fixtures/cron/.. - c.pattern = "spec/*/*_spec.rb" - c.default_facts = { - :kernel => 'Linux', - :concat_basedir => '/var/lib/puppet/concat', - } - c.default_facter_version = '3.14.0' end -Puppet::Util::Log.level = :warning -Puppet::Util::Log.newdestination(:console) +RSpec.configure do |c| + # getting the correct facter version is tricky. We use facterdb as a source to mock facts + # see https://github.com/camptocamp/facterdb + # people might provide a specific facter version. In that case we use it. + # Otherwise we need to match the correct facter version to the used puppet version. + # as of 2019-10-31, puppet 5 ships facter 3.11 and puppet 6 ships facter 3.14 + # https://puppet.com/docs/puppet/5.5/about_agent.html + # + # The environment variable `PUPPET_VERSION` is available in our travis environment, but we cannot rely on it + # if somebody runs the tests locally. For that case we should fallback the the puppet gem version. + c.default_facter_version = if ENV['FACTERDB_FACTS_VERSION'] + ENV['FACTERDB_FACTS_VERSION'] + else + puppet_version = ENV['PUPPET_VERSION'] ? ENV['PUPPET_VERSION'] : Gem.loaded_specs['puppet'].version.to_s + Gem::Dependency.new('', puppet_version).match?('', '5') ? '3.11.0' : '3.14.0' + end -at_exit { RSpec::Puppet::Coverage.report! } + # Coverage generation + c.after(:suite) do + RSpec::Puppet::Coverage.report! + end +end + +require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb')) diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index 9148d9f..1a81793 100644 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -1,43 +1,32 @@ -require 'beaker-rspec/spec_helper' -require 'beaker-rspec/helpers/serverspec' +require 'beaker-rspec' +require 'beaker-puppet' require 'beaker/puppet_install_helper' +require 'beaker/module_install_helper' -UNSUPPORTED_PLATFORMS = ['windows','AIX','Solaris'].freeze - -HIERA_PATH = '/etc/puppetlabs/code/environments/production' +run_puppet_install_helper unless ENV['BEAKER_provision'] == 'no' +install_ca_certs unless ENV['PUPPET_INSTALL_TYPE'] =~ %r{pe}i +install_module_on(hosts) +install_module_dependencies_on(hosts) RSpec.configure do |c| - proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) - + # Readable test descriptions c.formatter = :documentation - hiera_config = '/etc/puppetlabs/puppet/hiera.yaml' - - # Configure all nodes in nodeset - c.before :suite do - #install_puppet - hosts.each do |host| - if ['RedHat'].include?(fact('osfamily')) - on host, 'yum install -y tar' - end - if ['Debian'].include?(fact('osfamily')) - on host, 'apt-get update -q && apt-get install -y net-tools netcat' + hosts.each do |host| + if fact_on(host, 'osfamily') == 'Debian' + on host, puppet('resource', 'package', 'net-tools', 'ensure=installed') + on host, puppet('resource', 'package', 'netcat', 'ensure=installed') + end + if fact_on(host, 'osfamily') == 'RedHat' + case fact('os.release.major') + when '6' + on host, puppet('resource', 'package', 'nc', 'ensure=installed') + when '7' + on host, puppet('resource', 'package', 'net-tools', 'ensure=installed') + on host, puppet('resource', 'package', 'nmap-ncat', 'ensure=installed') end - #on host, 'gem install bundler' - #on host, 'cd /etc/puppet && bundle install --without development' - on host, puppet('module','install','puppetlabs-stdlib'), { :acceptable_exit_codes => [0,1] } - on host, puppet('module', 'install', 'puppet-archive'), { :acceptable_exit_codes => [0,1] } - #binding.pry - on host, "mkdir -p /etc/puppetlabs/puppet /etc/puppet/modules", { :acceptable_exit_codes => [0] } - on host, "mkdir -p #{HIERA_PATH}", { :acceptable_exit_codes => [0] } - scp_to host, File.expand_path('./spec/acceptance/hiera.yaml'), hiera_config - # compatibility with puppet 3.x - on host, "ln -s #{hiera_config} /etc/puppet/hiera.yaml", { :acceptable_exit_codes => [0] } - on host, "ln -s #{HIERA_PATH}/hieradata /etc/puppetlabs/puppet/hieradata", { :acceptable_exit_codes => [0] } - scp_to host, File.expand_path('./spec/acceptance/hieradata'), HIERA_PATH - # assume puppet is on $PATH - on host, "puppet --version" - on host, "puppet module list" end - puppet_module_install(:source => proj_root, :module_name => 'zookeeper') + if host[:platform] =~ %r{el-7-x86_64} && host[:hypervisor] =~ %r{docker} + on(host, "sed -i '/nodocs/d' /etc/yum.conf") + end end end diff --git a/spec/spec_helper_local.rb b/spec/spec_helper_local.rb index d5c1d20..56db83a 100644 --- a/spec/spec_helper_local.rb +++ b/spec/spec_helper_local.rb @@ -1,32 +1,48 @@ def get_os_info(facts) info = { - :service_name => nil, - :environment_file => nil, - :should_install_zookeeperd => nil, - :init_provider => nil, - :init_dir => nil, - :service_file => nil, - :should_install_cron => false, - :zookeeper_shell => nil, + service_name: nil, + environment_file: nil, + should_install_zookeeperd: nil, + init_provider: nil, + init_dir: nil, + service_file: nil, + should_install_cron: false, + zookeeper_shell: nil } case facts[:osfamily] when 'Debian' info[:service_name] = 'zookeeper' info[:environment_file] = '/etc/zookeeper/conf/environment' info[:should_install_zookeeperd] = true info[:zookeeper_shell] = '/bin/false' info[:init_provider] = 'systemd' when 'RedHat' info[:service_name] = 'zookeeper-server' info[:environment_file] = '/etc/zookeeper/conf/java.env' info[:should_install_zookeeperd] = false info[:zookeeper_shell] = '/sbin/nologin' - info[:init_provider] = 'systemd' + info[:init_provider] = if Puppet::Util::Package.versioncmp(facts[:os]['release']['major'], '7') < 0 + 'redhat' + else + 'systemd' + end + end + + case info[:init_provider] + when 'init' + info[:init_dir] = '/etc/init.d' + when 'systemd' + info[:init_dir] = '/etc/systemd/system' + when 'redhat' + info[:init_dir] = '/etc/init.d' end - info[:init_dir] = '/etc/systemd/system' - info[:service_file] = "#{info[:init_dir]}/#{info[:service_name]}.service" + info[:service_file] = if info[:init_provider] == 'systemd' + "#{info[:init_dir]}/#{info[:service_name]}.service" + else + "#{info[:init_dir]}/#{info[:service_name]}" + end - return info + info end diff --git a/spec/spec_helper_system.rb b/spec/spec_helper_system.rb deleted file mode 100644 index 75a2aac..0000000 --- a/spec/spec_helper_system.rb +++ /dev/null @@ -1,17 +0,0 @@ -require 'rspec-system/spec_helper' -require 'rspec-system-puppet/helpers' -require 'rspec-system-serverspec/helpers' -include Serverspec::Helper::RSpecSystem -include Serverspec::Helper::DetectOS -include RSpecSystemPuppet::Helpers - -RSpec.configure do |c| - # Project root - proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) - - # Enable colour - c.tty = true - - c.include RSpecSystemPuppet::Helpers - -end diff --git a/templates/zookeeper.Debian.init.erb b/templates/zookeeper.Debian.init.erb new file mode 100644 index 0000000..00cfe98 --- /dev/null +++ b/templates/zookeeper.Debian.init.erb @@ -0,0 +1,187 @@ +#! /bin/sh +### BEGIN INIT INFO +# Provides: zookeeper +# Required-Start: $remote_fs +# Required-Stop: $remote_fs +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: centralized coordination service +# Description: ZooKeeper is a centralized service for maintaining +# configuration information, naming, providing distributed +# synchronization, and providing group services. +### END INIT INFO + +# Author: Foo Bar +# +# Please remove the "Author" lines above and replace them +# with your own name if you copy and modify this script. + +# Do NOT "set -e" + +ZOOBINDIR="<%= scope.lookupvar("zookeeper::service::_zoo_dir") %>/bin" +ZOOCFGDIR=<%= scope.lookupvar("zookeeper::cfg_dir") %> +ZOOCFG="$ZOOCFGDIR/zoo.cfg" +ZOO_LOG_DIR=<%= scope.lookupvar("zookeeper::log_dir") %> + +[ -r "$ZOOCFGDIR/<%= scope.lookupvar("zookeeper::environment_file") %>" ] || exit 0 +. "$ZOOCFGDIR/<%= scope.lookupvar("zookeeper::environment_file") %>" + +[ -e "$ZOOCFGDIR/java.env" ] && . "$ZOOCFGDIR/java.env" + +[ "x$ZOO_LOG4J_PROP" = "x" ] && ZOO_LOG4J_PROP="<%= scope.lookupvar("zookeeper::log4j_prop") %>" + +# PATH should only include /usr/* if it runs after the mountnfs.sh script +# +PATH=/sbin:/usr/sbin:/bin:/usr/bin +DESC="centralized coordination service" +SCRIPTNAME=/etc/init.d/$NAME + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +for f in ${ZOOBINDIR}/../zookeeper-*.jar +do + CLASSPATH="$CLASSPATH:$f" +done + +ZOOLIBDIR=${ZOOLIBDIR:-$ZOOBINDIR/../lib} +for i in "$ZOOLIBDIR"/*.jar +do + CLASSPATH="$CLASSPATH:$i" +done + +#add the zoocfg dir to classpath +CLASSPATH=$ZOOCFGDIR:$CLASSPATH + +# Load the VERBOSE setting and other rcS variables +. /lib/init/vars.sh + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. +. /lib/lsb/init-functions + +is_running() +{ + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $JAVA --user $USER --test > /dev/null \ + || return 1 + return 0 +} + +# +# Function that starts the daemon/service +# +do_start() +{ + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + is_running || return 1 + + if [ ! -d $PIDDIR ] + then + mkdir -p $PIDDIR + fi + chown $USER:$GROUP $PIDDIR + + if [ ! -d $ZOO_LOG_DIR ] + then + mkdir -p $ZOO_LOG_DIR + fi + chown $USER:$GROUP $ZOO_LOG_DIR + + start-stop-daemon --start --quiet \ + --pidfile $PIDFILE \ + --make-pidfile \ + --chuid $USER:$GROUP \ + --background \ + --exec $JAVA -- \ + -cp $CLASSPATH \ + $JAVA_OPTS \ + $JVM_FLAGS \ + -Dzookeeper.log.dir=${ZOO_LOG_DIR} \ + -Dzookeeper.root.logger=${ZOO_LOG4J_PROP} \ + $ZOOMAIN $ZOOCFG \ + || return 2 +} + +# +# Function that stops the daemon/service +# +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + is_running && return 1 + + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE + RETVAL="$?" + [ "$RETVAL" = 2 ] && return 2 + # Many daemons don't delete their pidfiles when they exit. + [ "$RETVAL" = 0 ] && rm -f $PIDFILE + return "$RETVAL" +} + +case "$1" in + start) + if [ "x$JMXDISABLE" = "x" ] + then + [ "$VERBOSE" != no ] && log_action_msg "$NAME: JMX enabled by default" + # for some reason these two options are necessary on jdk6 on Ubuntu + # accord to the docs they are not necessary, but otw jconsole cannot + # do a local attach + JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=$JMXLOCALONLY" + else + [ "$VERBOSE" != no ] && log_action_msg "$NAME: JMX disabled by user request" + fi + + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" + do_start + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" + do_stop + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + status) + status_of_proc -p $PIDFILE "$NAME" "$NAME" && exit 0 || exit $? + ;; + restart|force-reload) + # + # If the "reload" option is implemented then remove the + # 'force-reload' alias + # + log_daemon_msg "Restarting $DESC" "$NAME" + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + *) + echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 + exit 3 + ;; +esac + +: diff --git a/templates/zookeeper.RedHat.init.erb b/templates/zookeeper.RedHat.init.erb new file mode 100644 index 0000000..c62f717 --- /dev/null +++ b/templates/zookeeper.RedHat.init.erb @@ -0,0 +1,141 @@ +#!/bin/sh +# +# zookeeper ZooKeeper Server +# +# chkconfig: - 80 05 +# description: Enable ZooKeeper Server +# + +### BEGIN INIT INFO +# Provides: zookeeper +# Default-Start: +# Default-Stop: +# Required-Start: $remote_fs $network +# Required-Stop: $remote_fs $network +# Description: zookeeper Server +# Short-Description: Enable zookeeper Server +### END INIT INFO + +# Source function library. +. /etc/rc.d/init.d/functions + +prog=<%= scope.lookupvar("zookeeper::service_name") %> +desc="Zookeeper Service" + +[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog + +lockfile="/var/lock/subsys/$prog" +pidfile=<%= scope.lookupvar("zookeeper::pid_path") %> + +[ "x$JMXLOCALONLY" = "x" ] && JMXLOCALONLY=false + +if [ "x$JMXDISABLE" = "x" ] +then + # for some reason these two options are necessary on jdk6 on Ubuntu + # accord to the docs they are not necessary, but otw jconsole cannot + # do a local attach + ZOOMAIN="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=$JMXLOCALONLY <%= scope.lookupvar("zookeeper::zoo_main") %>" +else + ZOOMAIN=<%= scope.lookupvar("zookeeper::zoo_main") %> +fi + +ZOOBINDIR="<%= scope.lookupvar("zookeeper::service::_zoo_dir") %>/bin" +ZOOCFGDIR=<%= scope.lookupvar("zookeeper::cfg_dir") %> +ZOOCFG="$ZOOCFGDIR/zoo.cfg" +ZOO_LOG_DIR=<%= scope.lookupvar("zookeeper::log_dir") %> + +[ -e "$ZOOCFGDIR/java.env" ] && . "$ZOOCFGDIR/java.env" +[ -e "$ZOOCFGDIR/<%= scope.lookupvar("zookeeper::environment_file") %>" ] && . "$ZOOCFGDIR/<%= scope.lookupvar("zookeeper::environment_file") %>" + +[ "x$ZOO_LOG4J_PROP" = "x" ] && ZOO_LOG4J_PROP="<%= scope.lookupvar("zookeeper::log4j_prop") %>" + +for f in ${ZOOBINDIR}/../zookeeper-*.jar +do + CLASSPATH="$CLASSPATH:$f" +done + +ZOOLIBDIR=${ZOOLIBDIR:-$ZOOBINDIR/../lib} +for i in "$ZOOLIBDIR"/*.jar +do + CLASSPATH="$CLASSPATH:$i" +done + +#add the zoocfg dir to classpath +CLASSPATH=$ZOOCFGDIR:$CLASSPATH + +cmd="java \"-Dzookeeper.log.dir=${ZOO_LOG_DIR}\" \"-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}\" -cp ${CLASSPATH} ${JAVA_OPTS} ${JVMFLAGS} ${ZOOMAIN} ${ZOOCFG} & echo \$! > ${pidfile}" + + +start() { + echo $pidfile + echo -n "Starting $desc $prog: " + touch $pidfile && chown <%= scope.lookupvar("zookeeper::user") %> $pidfile + daemon --user <%= scope.lookupvar("zookeeper::user") %> --pidfile $pidfile "$cmd" + retval=$? + echo + [ $retval -eq 0 ] && touch $lockfile + return $retval +} + +stop() { + echo -n $"Stopping $prog: " + killproc -p $pidfile $prog + retval=$? + echo + [ $retval -eq 0 ] && rm -f $lockfile + return $retval +} + +restart() { + stop + start +} + +reload() { + restart +} + +get_status() { + if [ -f $pidfile ] + then + PID=`cat $pidfile` + if [ -z "`ps -ef | awk '{print $2}' | grep "^$PID$"`" ] + then + echo "$prog stopped but pid file exists" + exit 1 + else + echo "$prog running with pid $PID" + exit 0 + fi + else + echo "$prog stopped" + exit 1 + fi +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + restart + ;; + reload) + reload + ;; + condrestart) + [ -e /var/lock/subsys/$prog ] && restart + RETVAL=$? + ;; + status) + get_status + ;; + *) + echo $"Usage: $0 {start|stop|restart|reload|condrestart|status}" + RETVAL=1 +esac + +exit $RETVAL