Compare commits

...

11 Commits

Author SHA1 Message Date
Greg Karékinian
d7bc5e6f08 Update Chef on these servers 2023-06-28 18:55:13 +02:00
Greg Karékinian
b7d17c1ad7 Replace application cookbook with git resource 2023-06-28 18:55:05 +02:00
Greg Karékinian
54098a450c Replace application cookbook with git resource 2023-06-28 18:54:38 +02:00
Greg Karékinian
3a5a038f7e Replace application cookbook with git resource 2023-06-28 18:53:59 +02:00
Greg Karékinian
3cf9c3868b Deploy mastodon without the application cookbooks 2023-06-28 17:23:05 +02:00
Greg Karékinian
57fdf0723f Deploy RTL without the deprecated application cookbook 2023-06-28 16:35:57 +02:00
Greg Karékinian
9378df23db Remove unused lndhub recipe 2023-06-28 16:35:56 +02:00
Greg Karékinian
88caae26e4 Install the latest backup gem
It added a few dev dependencies, install them
2023-06-28 16:35:56 +02:00
Greg Karékinian
0564165e81 Override the attributes in attributes, not the default recipe 2023-06-28 16:35:56 +02:00
Greg Karékinian
ddeebc739d Update chef-sugar to fix a conflict in Chef 16+ 2023-06-28 16:35:56 +02:00
Greg Karékinian
b9cf396d42 Deploy akkounts without the application_git cookbook
Use the built-in git resource from Chef instead. poise/application does
not work on modern Chef.
2023-06-28 16:35:56 +02:00
103 changed files with 6234 additions and 799 deletions

View File

@ -40,7 +40,7 @@ cookbook 'logrotate', '= 2.2.0'
cookbook 'openssl', '~> 8.5.5'
cookbook 'ntp', '= 3.4.0'
cookbook 'apache2', '= 3.3.0'
cookbook 'chef-sugar', '= 3.3.0'
cookbook 'chef-sugar', '= 5.1.12'
cookbook 'compat_resource', '= 12.19.0'
cookbook 'homebrew', '= 3.0.0'
cookbook 'mariadb', '= 0.3.1'
@ -52,3 +52,4 @@ cookbook 'java', '~> 4.3.0'
cookbook 'ulimit', '~> 1.0.0'
cookbook 'golang', '~> 5.3.1'
cookbook 'zerotier', '~> 1.0.7'
cookbook 'ruby_build', '~> 2.5.0'

View File

@ -6,7 +6,7 @@ DEPENDENCIES
apt (~> 7.3.0)
ark (>= 5.0.0)
build-essential (~> 8.2.1)
chef-sugar (= 3.3.0)
chef-sugar (= 5.1.12)
compat_resource (= 12.19.0)
composer (~> 2.7.0)
elasticsearch (= 4.3.0)
@ -46,6 +46,7 @@ DEPENDENCIES
poise-service (~> 1.5.2)
postfix (= 5.0.2)
redisio (~> 6.4.1)
ruby_build (~> 2.5.0)
timezone_iii (= 1.0.4)
ulimit (~> 1.0.0)
users (~> 5.3.1)
@ -71,7 +72,7 @@ GRAPH
build-essential (8.2.1)
mingw (>= 1.1)
seven_zip (>= 0.0.0)
chef-sugar (3.3.0)
chef-sugar (5.1.12)
chocolatey (3.0.0)
compat_resource (12.19.0)
composer (2.7.0)
@ -150,6 +151,9 @@ GRAPH
postfix (5.0.2)
redisio (6.4.1)
selinux (>= 0.0.0)
ruby_build (2.5.0)
homebrew (>= 0.0.0)
yum-epel (>= 0.0.0)
selinux (6.1.12)
seven_zip (4.2.2)
timezone_iii (1.0.4)

26
cookbooks/chef-sugar/.gitignore vendored Normal file
View File

@ -0,0 +1,26 @@
*~
*#
.#*
\#*#
.*.sw[a-z]
*.un~
*.tmp
*.bk
*.bkup
.kitchen.local.yml
Berksfile.lock
Gemfile.lock
.bundle/
.cache/
.kitchen/
.vagrant/
.vagrant.d/
.yardoc/
bin/
coverage/
doc/
pkg/
tmp/
vendor/
.rspec

View File

@ -0,0 +1,16 @@
driver:
name: vagrant
provisioner:
name: chef_zero
deprecations_as_errors: true
platforms:
- name: centos-6
- name: centos-7
- name: ubuntu-16.04
- name: ubuntu-18.04
suites:
- name: default
run_list: chef-sugar::default

View File

@ -1,16 +1,117 @@
Chef Sugar Changelog
=========================
# Chef Sugar Changelog
This file is used to list changes made in each version of the chef-sugar cookbook and gem.
v3.3.0 (2016-01-11)
-------------------
<!-- latest_release -->
<!-- latest_release -->
<!-- release_rollup -->
<!-- release_rollup -->
<!-- latest_stable_release -->
## [v5.1.12](https://github.com/chef/chef-sugar/tree/v5.1.12) (2020-11-11)
#### Merged Pull Requests
- Don&#39;t define which helper on Chef 16+ to avoid conflicts [#21](https://github.com/chef/chef-sugar/pull/21) ([tas50](https://github.com/tas50))
<!-- latest_stable_release -->
## [v5.1.11](https://github.com/chef/chef-sugar/tree/v5.1.11) (2020-08-14)
#### Merged Pull Requests
- Fix Ruby 2.3 tests [#19](https://github.com/chef/chef-sugar/pull/19) ([tas50](https://github.com/tas50))
- Only require libs if we haven&#39;t already loaded them [#20](https://github.com/chef/chef-sugar/pull/20) ([tas50](https://github.com/tas50))
## [v5.1.9](https://github.com/chef/chef-sugar/tree/v5.1.9) (2019-11-13)
#### Merged Pull Requests
- Don&#39;t fail if Chef::VERSION isn&#39;t defined [#18](https://github.com/chef/chef-sugar/pull/18) ([lamont-granquist](https://github.com/lamont-granquist))
## [v5.1.8](https://github.com/chef/chef-sugar/tree/v5.1.8) (2019-11-13)
#### Merged Pull Requests
- Wire up Expeditor and support both chef-sugar and chef-sugar-ng [#8](https://github.com/chef/chef-sugar/pull/8) ([tas50](https://github.com/tas50))
- Add github templates and a code of conduct [#9](https://github.com/chef/chef-sugar/pull/9) ([tas50](https://github.com/tas50))
- Beginning of chef-sugar deprecation [#10](https://github.com/chef/chef-sugar/pull/10) ([lamont-granquist](https://github.com/lamont-granquist))
- Use Expeditor to set the version in the metadata.rb file [#11](https://github.com/chef/chef-sugar/pull/11) ([tas50](https://github.com/tas50))
- Switch gemfile back to chef-sugar [#12](https://github.com/chef/chef-sugar/pull/12) ([tas50](https://github.com/tas50))
- Fix metadata.rb version updatig logic and use SPDX compliant license strings [#14](https://github.com/chef/chef-sugar/pull/14) ([tas50](https://github.com/tas50))
- Additional Chef-15 greenification [#13](https://github.com/chef/chef-sugar/pull/13) ([lamont-granquist](https://github.com/lamont-granquist))
- Move test deps to the Gemfile [#15](https://github.com/chef/chef-sugar/pull/15) ([tas50](https://github.com/tas50))
- Get the tests green [#17](https://github.com/chef/chef-sugar/pull/17) ([tas50](https://github.com/tas50))
- Deprecate chef-sugar node API [#16](https://github.com/chef/chef-sugar/pull/16) ([lamont-granquist](https://github.com/lamont-granquist))
## v5.0.1 (2019-03-13)
- Modifies the behavior of `systemd?` so that it works equally well on physical/virtual
machines as well as within containers.
## v5.0.0 (2018-12-26)
- BREAKING CHANGE: Require Chef 13 or later
- Trim out test files and the cookbook from the gem artifact to slim install size
## v4.2.1 (2018-12-06)
- Repackaged with an older stove to remove the metadata.rb on the Supermarket for older chef-client releases
## v4.2.0 (2018-12-05)
- Added a new parallels? helper
- Added support for the Raspberry Pi 1 and Zero to armhf? helper
- Added a centos_final? helper
## v4.1.0 (2018-08-16)
- Improve the detection of linux hosts with the linux? helper. Amazon Linux and obscure distros will now be properly detected.
## v4.0.1 (2018-08-09)
- Add new Debian, Mint, macOS codenames
- Add new Ubuntu codenames: artful, bionic, cosmic
## v4.0.0 (2018-01-26)
- Require Ruby 2.2 or later and Chef 12.10 or later
- Cookbook now installs the chef-sugar gem via a metadata installation so chef-sugar::default on your runlist is no longer needed
- Added additional metadata to the cookbook: supports, issue_url, source_url, chef_version.
- Requirements improved in the readme
## v3.6.0 (2017-10-26)
- Add Ubuntu zesty and debian stretch detection
- Add softlayer? helper
- Add aarch64? helper
## v3.5.0 (2016-07-12)
- Improve the systemd check to not fail on older kernels or Windows hosts
- Add detection of macOS 10.11 and 10.12
## v3.4.0 (2016-07-18)
### Improvements
- Add `virtual?` and `physical?` methods
- Add Scaleway C1 server (arm arch) support
- Add IMB s390x support
- Add missing Ubuntu release names
### Bug Fixes
- Drop Ruby 2.0.0 support from Travis test matrix
- Pin to Rack 1.6 (dev dep)
## v3.3.0 (2016-01-11)
### Improvements
- Break up `Chef::Sugar::Constraints` into a class and a dsl file
- Add `platform_version` method with full constraints comparison support
v3.2.0 (2015-12-10)
-------------------
## v3.2.0 (2015-12-10)
### Improvements
- Add platform matchers for `debian` and `fedora`
- Add `openvz` support under virtualization
- Add init system detection support
@ -18,41 +119,47 @@ v3.2.0 (2015-12-10)
- Add additional `aix` helpers
### Bug Fixes
- Properly expose `Architecture#i386?` in the DSL
v3.1.1 (2015-06-23)
-------------------
## v3.1.1 (2015-06-23)
### Improvements
- Update Intel CPU types based on existing Fauxhai data
- Update SPARC logic and 32/64-bit logic for x86 and i386
### Bug Fixes
- Fix 32-bit logic
- Fix default behavior to include chef-sugar at compile time
- Fix Chef 12.1.0 warnings for chef_gem compile time install
- Fix `redhat_enterprise_linux?` matcher
v3.0.2 (2015-03-26)
-------------------
## v3.0.2 (2015-03-26)
### Improvements
- Add helpers for `ppc64` and `ppc64le` architecture
### Bug Fixes
- Adjustments to error message
v3.0.1 (2015-03-20)
-------------------
### Breaking Changes
- Rename `compile_time` `to at_compile_time` - if your recipes are affected by
this breaking change, your Chef Client run will produce a verbose error
message with details on how to fix the error.
## v3.0.1 (2015-03-20)
v3.0.0 (2015-03-17)
-------------------
### Breaking Changes
- Rename `compile_time` `to at_compile_time` - if your recipes are affected by this breaking change, your Chef Client run will produce a verbose error message with details on how to fix the error.
## v3.0.0 (2015-03-17)
### Breaking Changes
- Drop support for Ruby 1.9 (it might still work, but it is no longer officially supported)
### Improvements
- Remove accidentially committed gem source
- Bump development dependencies
- Add `digitalocean?` matcher
@ -63,74 +170,87 @@ v3.0.0 (2015-03-17)
- Add dynamic platform/version matchers for Solaris
### Bug Fixes
- Reset namespace_options when reaching top-level resources
v2.5.0 (2015-01-05)
-------------------
## v2.5.0 (2015-01-05)
### Improvements
- Add `data_bag_item_for_environment` function
- Add `kvm?` matcher
- Add `virtualbox?` matcher
### Bug Fixes
- Use `.key?` to check for hash key presence, raising an `AttributeDoesNotExist`
error sooner
v2.4.1 (2014-10-12)
-------------------
- Use `.key?` to check for hash key presence, raising an `AttributeDoesNotExist` error sooner
## v2.4.1 (2014-10-12)
- No changes from v2.4.0 - forced a new version upload to the Chef Supermarket
v2.4.0 (2014-10-12)
-------------------
## v2.4.0 (2014-10-12)
### Improvements
- Add `docker?` matcher
v2.3.2 (2014-10-07)
-------------------
## v2.3.2 (2014-10-07)
### Big Fixues
- Include `amd64` in `_64_bit?` check
v2.3.1 (2014-10-07)
-------------------
## v2.3.1 (2014-10-07)
### Improvements
- Check all 64-bit architectures that may be reported by Ohai
### Bug Fixes
- Be more tolerant of `nil` values return from sub functions
- Check to make sure `node['domain']` is not `nil` before calling `#include?`
v2.3.0 (2014-09-24)
-------------------
## v2.3.0 (2014-09-24)
### Improvements
- Add `vmware?` matcher
- Allow the attribute DSL to access parent attributes
### Bug Fixes
- Return `true` or `false` from all Boolean methods (instead of `nil` or truthy values)
v2.2.0 (2014-08-20)
-------------------
## v2.2.0 (2014-08-20)
### Improvements
- Add `smartos?` matcher
- Add `omnios?` matcher
v2.1.0 (2014-06-26)
-------------------
## v2.1.0 (2014-06-26)
### Improvements
- Add `solaris2?` matcher
- Add `aix?` matcher
- Add 'lxc?' matcher
### Bug Fixes
- Fix a bug in namespace memoization during attribute initialization
v2.0.0 (2014-06-16)
-------------------
## v2.0.0 (2014-06-16)
### Breaking
- Remove `not_linux?` method
- Remove `not_windows?` method
### Improvements
- Miscellaneous spelling fixes
- Update a failing unit test for `installed?`
- Add Mac OS X to the list of platforms (Yosemite)
@ -138,8 +258,8 @@ v2.0.0 (2014-06-16)
- Fix `which` (and `installed?` and `installed_at_version?`) when given an absolute path
- Fix `linux?` check to only return true on real linuxes
v1.3.0 (2014-05-05)
-------------------
## v1.3.0 (2014-05-05)
- Check both `$stdout` and `$stderr` in `version_for`
- Add additional platform versions
- Make `includes_recipe?` a top-level API (instead of just Node)
@ -148,21 +268,21 @@ v1.3.0 (2014-05-05)
- Define `String#flush` as a core extension
- Remove Stove
v1.2.6 (2014-03-16)
-------------------
## v1.2.6 (2014-03-16)
- Fix a bug in `vagrant?` returning false on newer Vagrant versions
- Remove Coveralls
v1.2.4 (2014-03-13)
-------------------
## v1.2.4 (2014-03-13)
- See (1.2.2), but I botched the release
v1.2.2 (2014-03-13)
-------------------
## v1.2.2 (2014-03-13)
- Fix a critical bug with `encrypted_data_bag_item` using the wrong key
v1.2.0 (2014-03-09)
-------------------
## v1.2.0 (2014-03-09)
- Add `namespace` functionality for specifying attributes in a DSL
- Add constraints helpers for comparing version strings
- Add `require_chef_gem` to safely require and degrade if a gem is not installed
@ -171,19 +291,19 @@ v1.2.0 (2014-03-09)
- Add Stove for releasing
- Updated copyrights for 2014
v1.1.0 (2013-12-10)
-------------------
## v1.1.0 (2013-12-10)
- Add `cloudstack?` helper
- Add data bag helpers
- Remove foodcritic checks
- Upgrade development gem versions
- Randomize spec order
v1.0.1 (2013-10-15)
-------------------
## v1.0.1 (2013-10-15)
- Add development recipe
- Add `compile_time`, `before`, and `after` filters
v1.0.0 (2013-10-15)
-------------------
- First public release
## v1.0.0 (2013-10-15)
- First public release

View File

@ -0,0 +1 @@
Please refer to the Chef Community Code of Conduct at https://www.chef.io/code-of-conduct/

View File

@ -0,0 +1,84 @@
### Chef Sugar is being deprecated, this is the internal list of the TODO tasks
TASKS in order:
* ~~pull cloud.rb into core-chef~~
* pull data_bag.rb into core-chef
* ~~pull run_context.rb into core-chef~~
* ~~pull vagrant.rb into core-chef~~
* ~~pull virtualization.rb into core-chef~~
* deprecate ip.rb with no replacement (although maybe a new ohai attribute?)
* deprecate kernel.rb with no replacement
* ~~deprecate node.rb with no replacement~~
* deprecate ruby.rb with no replacement
* determine what to do about filters.rb
* determine what to do about remaining platform.rb
* determine what to do about shell.rb
* determine what to do about core_extensions
NOTES on files:
architecture.rb is COMPLETED
cloud.rb is COMPLETED
constraint.rb / constraint_dsl.rb tasks:
* replace with Chef::VersionString objects
core_extensions
* pile of monkeypatches that makes my eyes twitch a little bit. how much do we want to become activerecord? counter-argument is
that some activerecord-ish helpers are SUUUPER useful. but we should probably copy them from activerecord since those are more
likely to get pulled directly into core-chef.
data_bag
* we should pull this into core-chef or something comparable (TBD)
docker.rb is COMPLETED
filters.rb tasks
* incorporate the before/after syntax into the find_resource/edit_resource API (probably renamed, with deprecation done here)
* deprecate the at_compile_time helper in favor of moving the `compile_time true` property into Chef::Resource directly
init.rb is COMPLETED
* unless we get user complaints, runit is dead to us and this is done
ip.rb
* needs to be deprecated with no replacement (could push this into another ohai attribute -- or have we done it already?)
kernel.rb (the require_chef_gem trivial helper)
* needs to be deprecated with no replacement.
kitchen.rb is COMPLETED
node.rb (the method_missing syntax)
* needs to be deprecated with no replacement.
platform.rb tasks:
* decide what to do about the `debian_before_squeeze` platform version helpers.
* decide what to do about the `platform_version` helper (can we wire this up to a Chef::VersionString object instead?)
platform_family.rb is COMPLETED
ruby.rb tasks:
* needs to be deprecated with no replacement (nobody has used it since ruby 2.0, so its clearly not being used)
run_context.rb is COMPLETED
shell.rb: (collection of helpers including `which`)
* TBD
vagrant.rb is COMPLETED
virtualization.rb is COMPLETED

View File

@ -0,0 +1,34 @@
source "https://rubygems.org"
gemspec name: "chef-sugar"
group :debug do
gem "pry"
gem "pry-byebug" unless Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.4")
gem "pry-stack_explorer", "~> 0.4.0" # pin until we drop ruby < 2.6
end
group :test do
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.5")
gem "chefspec", "~> 7.4.0" # supports Chef 13+ aka ruby 2.3+
gem "chef", "~> 13" # also needed to support Ruby 2.3
elsif Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.6")
gem "chefspec"
gem "chef-zero", "~> 14"
gem "chef", "~> 15" # also needed to support Ruby 2.3
else
gem "chefspec"
end
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.4")
gem "rubyzip", "< 2"
else
gem "rubyzip"
end
gem "rake"
gem "rspec"
end
group :kitchen do
gem "kitchen-vagrant"
gem "license-acceptance", "~> 1.0" if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.4")
gem "test-kitchen"
end

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2013-2015 Seth Vargo
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,17 +1,34 @@
Chef Sugar
==========
# Chef Sugar
[![Gem Version](http://img.shields.io/gem/v/chef-sugar.svg?style=flat-square)][gem]
[![Build Status](http://img.shields.io/travis/sethvargo/chef-sugar.svg?style=flat-square)][travis]
[![Build status](https://badge.buildkite.com/f44140e4898b4935bfc3bba523efc2a7592d7c9a1bae3faf5c.svg?branch=master)](https://buildkite.com/chef-oss/chef-chef-sugar-master-verify)
[gem]: https://rubygems.org/gems/chef-sugar
[travis]: http://travis-ci.org/sethvargo/chef-sugar
# CHEF SUGAR DEPRECATION WARNING
Chef Sugar is a Gem & Chef Recipe that includes series of helpful sugar of the Chef core and other resources to make a cleaner, more lean recipe DSL, enforce DRY principles, and make writing Chef recipes an awesome experience!
Chef Sugar is in the process of being migrated into Chef Infra Client 15 and Chef Infra Client 16. The bulk of that work has already
been completed. After it is completed there will be no need for this cookbook and gem, and it will no longer be supported. No
issues or patches are being accepted at this time.
The final major version release of Chef Sugar will raise and will not be functional. Users on Chef Infra Client <= 14 or old versions of 15
will need to have a pessimistic pin on chef-sugar, or simply upgrade.
Installation
------------
If you want to develop/hack on chef-sugar, please see the Contributing.md.
## Requirements
### Platforms
- any platform
### Chef
- Chef 13.0+
### Cookbooks
- none
## Installation
If you want to develop/hack on chef-sugar, please see the CONTRIBUTING.md.
If you are using Berkshelf, add `chef-sugar` to your `Berksfile`:
@ -25,20 +42,14 @@ Otherwise, you can use `knife` or download the tarball directly from the communi
knife cookbook site install chef-sugar
```
## Usage
Usage
-----
In order to use Chef Sugar in your Chef Recipes, you'll first need to include it:
```ruby
include_recipe 'chef-sugar::default'
```
Alternatively you can put it in a base role or recipe and it will be included subsequently.
Simply depend on this cookbook in the metadata of your cookbook and the gem will be installed and required..
Requiring the Chef Sugar Gem will automatically extend the Recipe DSL, `Chef::Resource`, and `Chef::Provider` with helpful convenience methods.
### Module Method
If you are working outside of the Recipe DSL, you can use the module methods instead of the Recipe DSL. In general, the module methods have the same name as their Recipe-DSL counterparts, but require the node object as a parameter. For example:
In a Recipe:
@ -68,12 +79,12 @@ def only_on_windows(&block)
end
```
## API
API
---
**Note:** For the most extensive API documentation, please see the YARD documentation.
### Architecture
**Note:** Some of the architecture commands begin with an underscore (`_`) because Ruby does not permit methods to start with a numeric.
- `_64_bit?`
@ -85,6 +96,7 @@ API
- `powerpc?`
#### Examples
```ruby
execute 'build[my binary]' do
command '...'
@ -93,6 +105,7 @@ end
```
### Cloud
- `azure?`
- `cloud?`
- `digitalocean?`
@ -103,8 +116,10 @@ end
- `openstack?`
- `cloudstack?`
- `rackspace?`
- `softlayer?`
#### Examples
```ruby
template '/tmp/config' do
variables(
@ -115,6 +130,7 @@ end
```
### Core Extensions
**Note:** Core extensions are **not** included by default. You must require the `chef/sugar/core_extensions` module manually to gain access to these APIs:
```ruby
@ -127,6 +143,7 @@ require 'chef/sugar/core_extensions'
- `Object#blank?`
#### Examples
```ruby
# Checking version constraints
'1.0.0'.satisfies?('~> 1.0') #=> true
@ -140,11 +157,13 @@ require 'chef/sugar/core_extensions'
```
### Data Bag
- `encrypted_data_bag_item` - a handy DSL method for loading encrypted data bag items the same way you load a regular data bag item; this requires `Chef::Config[:encrypted_data_bag_secret]` is set!
- `encrypted_data_bag_item_for_environment` - find the encrypted data bag entry for the current node's Chef environment.
- `data_bag_item_for_environment` - find the data bag entry for the current node's Chef environment.
#### Examples
```ruby
encrypted_data_bag_item('accounts', 'hipchat')
```
@ -158,11 +177,13 @@ data_bag_item_for_environment('accounts', 'github')
```
### Docker
Chef Sugar looks for hints to see if the node being converged is a Docker container. When [Ohai supports checking other nodes](https://github.com/opscode/ohai/pull/428), Chef Sugar will automatically pick up the information.
- `docker?`
#### Examples
```ruby
template '/runme' do
only_if { docker?(node) }
@ -170,6 +191,7 @@ end
```
### Attributes
Chef Sugar adds more Chef-like DSL to attribute definitions. Instead of using the Ruby hash syntax, you can define attributes using nested namespaces. This DSL may be more friendly to non-Ruby developers. It can safely be mixed-and-matched with the standard syntax.
```ruby
@ -198,11 +220,13 @@ end
```
### Constraints
- `constraints` - create a new constraint (or requirement) that can be used to test version validations.
- `chef_version` - (DSL only) a wrapper for `version(Chef::VERSION)`
- `version` - create a new version that can be used to test constraint validation.
#### Examples
```ruby
# Check if a version is satisfied by a constraint
version('1.2.3').satisfies?('~> 1.2.0')
@ -227,14 +251,18 @@ end
```
### Kernel
- `require_chef_gem` - "safely" require a gem. Loading a gem with Chef is sometimes difficult and confusing. The errors that Chef produces are also sometimes not very intuitive. In the event you require a gem to exist on the system, you can use `require_chef_gem`, which will attempt to require the gem and then produce helpful output if the gem is not installed:
Chef could not load the gem `#{name}'! You may need to install the gem
manually with `gem install #{name}', or include a recipe before you can
use this resource. Please consult the documentation for this cookbook
for proper usage.
```
Chef could not load the gem `#{name}'! You may need to install the gem
manually with `gem install #{name}', or include a recipe before you can
use this resource. Please consult the documentation for this cookbook
for proper usage.
```
#### Examples
```ruby
# LWRP
require_chef_gem 'pry'
@ -251,11 +279,13 @@ end
```
### Init
- `systemd?` - detect if init system is systemd
- `upstart?` - detect if init system is upstart
- `runit?` - detect if init system is runit
#### Examples
```ruby
systemd_service 'my-service' do
description 'My Service'
@ -276,9 +306,11 @@ end
```
### IP
- `best_ip_for` - determine the best IP address for the given "other" node, preferring local IP addresses over public ones.
#### Examples
```ruby
redis = search('node', 'role:redis').first
@ -298,6 +330,7 @@ Additional methods for the `node` object
- `in?` - determine if the node is in the given Chef environment.
#### Examples
```ruby
credentials = if node.in?('production')
Chef::EncryptedDataBag.new('...')
@ -311,6 +344,7 @@ node.deep_fetch('apache2', 'config', 'root') => node['apache2']['config']['root'
```
### Platform
- `amazon_linux?`
- `centos?`
- `linux_mint?`
@ -326,11 +360,12 @@ node.deep_fetch('apache2', 'config', 'root') => node['apache2']['config']['root'
- `nexus?`
- `ios_xr?`
There are also a series of dynamically defined matchers that map named operating system release versions and comparison operators in the form "#{platform}\_#{operator}\_#{name}?". For example:
There are also a series of dynamically defined matchers that map named operating system release versions and comparison operators in the form "#{platform}_#{operator}_#{name}?". For example:
- `debian_after_squeeze?`
- `linuxmint_after_or_at_olivia?`
- `mac_os_x_lion?`
- `centos_final?`
- `ubuntu_before_lucid?`
- `ubuntu_before_or_at_maverick?`
- `solaris_10?`
@ -344,6 +379,7 @@ puts Chef::Sugar::Platform.instance_methods
```
#### Examples
```ruby
if ubuntu?
execute 'apt-get update'
@ -351,6 +387,7 @@ end
```
### Platform Family
- `arch_linux?`
- `debian?`
- `fedora?`
@ -366,6 +403,7 @@ end
- `wrlinux?`
#### Examples
```ruby
node['attribute'] = if windows?
'C:\Foo\BarDrive'
@ -375,17 +413,20 @@ node['attribute'] = if windows?
```
### Ruby
**Note:** The applies to the Ruby found at `node['languages']['ruby']`.
- `ruby_20?`
- `ruby_19?`
#### Examples
```ruby
log 'This has been known to fail on Ruby 2.0' if ruby_20?
```
### Run Context
- `includes_recipe?` - determines if the current run context includes the recipe
```ruby
@ -397,6 +438,7 @@ end
```
### Shell
- `which`
- `dev_null`
- `installed?`
@ -404,6 +446,7 @@ end
- `version_for`
#### Examples
```ruby
log "Using `mongo` at `#{which('mongo')}`"
@ -420,9 +463,11 @@ log "Skipping git install, version is at #{version_for('mongo', '-v')}"
```
### Vagrant
- `vagrant?`
#### Examples
```ruby
http_request 'http://...' do
not_if { vagrant? }
@ -430,13 +475,16 @@ end
```
### Virtualization
- `kvm?`
- `lxc?`
- `parallels?`
- `virtualbox?`
- `vmware?`
- `openvz?`
#### Examples
```ruby
service 'ntpd' do
action [:enable, :start]
@ -445,11 +493,13 @@ end
```
### Filters
- `at_compile_time` - accepts a block of resources to run at compile time
- `before` - insert resource in the collection before the given resource
- `after` - insert resource in the collection after the given resource
#### Examples
```ruby
at_compile_time do
package 'apache2'
@ -473,9 +523,8 @@ after 'service[apache2]' do
end
```
## License & Authors
License & Authors
-----------------
- Author: Seth Vargo (sethvargo@gmail.com)
```text
@ -493,3 +542,5 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
[gem]: https://rubygems.org/gems/chef-sugar

View File

@ -0,0 +1,9 @@
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new do |t|
t.rspec_opts = [
'--color',
'--format progress',
].join(' ')
end
task default: :spec

View File

@ -0,0 +1 @@
5.1.12

View File

@ -0,0 +1,24 @@
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'chef/sugar/version'
Gem::Specification.new do |spec|
spec.name = 'chef-sugar-ng'
spec.version = Chef::Sugar::VERSION
spec.authors = ['Seth Vargo']
spec.email = ['sethvargo@gmail.com']
spec.description = 'A series of helpful sugar of the Chef core and ' \
'other resources to make a cleaner, more lean recipe ' \
'DSL, enforce DRY principles, and make writing Chef ' \
'recipes an awesome experience!'
spec.summary = 'A collection of helper methods and modules that ' \
'make working with Chef recipes awesome.'
spec.homepage = 'https://github.com/chef/chef-sugar'
spec.license = 'Apache-2.0'
spec.required_ruby_version = '>= 2.3'
spec.files = %w{LICENSE} + Dir.glob("lib/**/*", File::FNM_DOTMATCH).reject { |f| File.directory?(f) }
spec.require_paths = ['lib']
end

View File

@ -0,0 +1,24 @@
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'chef/sugar/version'
Gem::Specification.new do |spec|
spec.name = 'chef-sugar'
spec.version = Chef::Sugar::VERSION
spec.authors = ['Seth Vargo']
spec.email = ['sethvargo@gmail.com']
spec.description = 'A series of helpful sugar of the Chef core and ' \
'other resources to make a cleaner, more lean recipe ' \
'DSL, enforce DRY principles, and make writing Chef ' \
'recipes an awesome experience!'
spec.summary = 'A collection of helper methods and modules that ' \
'make working with Chef recipes awesome.'
spec.homepage = 'https://github.com/chef/chef-sugar'
spec.license = 'Apache-2.0'
spec.required_ruby_version = '>= 2.3'
spec.files = %w{LICENSE} + Dir.glob("lib/**/*", File::FNM_DOTMATCH).reject { |f| File.directory?(f) }
spec.require_paths = ['lib']
end

View File

@ -0,0 +1,51 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require 'chef/recipe'
require 'chef/resource'
require 'chef/provider'
class Chef
module Sugar
require_relative 'sugar/architecture'
require_relative 'sugar/cloud'
require_relative 'sugar/constraints'
require_relative 'sugar/constraints_dsl'
require_relative 'sugar/data_bag'
require_relative 'sugar/docker'
require_relative 'sugar/filters'
require_relative 'sugar/init'
require_relative 'sugar/ip'
require_relative 'sugar/kernel'
require_relative 'sugar/kitchen'
require_relative 'sugar/node'
require_relative 'sugar/platform'
require_relative 'sugar/platform_family'
require_relative 'sugar/ruby'
require_relative 'sugar/run_context'
require_relative 'sugar/shell'
require_relative 'sugar/vagrant'
require_relative 'sugar/version'
require_relative 'sugar/virtualization'
end
end
Chef::Recipe.send(:include, Chef::Sugar::DSL)
Chef::Recipe.send(:include, Chef::Sugar::RecipeDSL) # TODO: this is a hack
Chef::Resource.send(:include, Chef::Sugar::DSL)
Chef::Provider.send(:include, Chef::Sugar::DSL)
Object.send(:include, Chef::Sugar::Kernel)

View File

@ -0,0 +1,176 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Chef
module Sugar
module Architecture
extend self
# these helpers have been moved to core-chef
if !defined?(Chef::VERSION) || Gem::Requirement.new("< 15.4.70").satisfied_by?(Gem::Version.new(Chef::VERSION))
#
# Determine if the current architecture is 64-bit
#
# @return [Boolean]
#
def _64_bit?(node)
%w(amd64 x86_64 ppc64 ppc64le s390x ia64 sparc64 aarch64 arch64 arm64 sun4v sun4u s390x)
.include?(node['kernel']['machine']) || ( node['kernel']['bits'] == '64' )
end
#
# Determine if the current architecture is 32-bit
#
# @todo Make this more than "not 64-bit"
#
# @return [Boolean]
#
def _32_bit?(node)
!_64_bit?(node)
end
#
# Determine if the current architecture is i386
#
# @return [Boolean]
#
def i386?(node)
_32_bit?(node) && intel?(node)
end
#
# Determine if the current architecture is Intel.
#
# @return [Boolean]
#
def intel?(node)
%w(i86pc i386 x86_64 amd64 i686)
.include?(node['kernel']['machine'])
end
#
# Determine if the current architecture is SPARC.
#
# @return [Boolean]
#
def sparc?(node)
%w(sun4u sun4v)
.include?(node['kernel']['machine'])
end
#
# Determine if the current architecture is Powerpc64 Big Endian
#
# @return [Boolean]
#
def ppc64?(node)
%w(ppc64)
.include?(node['kernel']['machine'])
end
#
# Determine if the current architecture is Powerpc64 Little Endian
#
# @return [Boolean]
#
def ppc64le?(node)
%w(ppc64le)
.include?(node['kernel']['machine'])
end
#
# Determine if the current architecture is PowerPC
#
# @return [Boolean]
#
def powerpc?(node)
%w(powerpc)
.include?(node['kernel']['machine'])
end
#
# Determine if the current architecture is ARM with Hard Float
#
# @return [Boolean]
#
def armhf?(node)
# Add more arm variants as needed here
%w(armv6l armv7l)
.include?(node['kernel']['machine'])
end
#
# Determine if the current architecture is AArch64
#
# @return [Boolean]
#
def aarch64?(node)
# Add more arm variants as needed here
%w(aarch64)
.include?(node['kernel']['machine'])
end
#
# Determine if the current architecture is s390x
#
# @return [Boolean]
#
def s390x?(node)
%w(s390x)
.include?(node['kernel']['machine'])
end
end
end
module DSL
if !defined?(Chef::VERSION) || Gem::Requirement.new("< 15.4.70").satisfied_by?(Gem::Version.new(Chef::VERSION))
# @see Chef::Sugar::Architecture#_64_bit?
def _64_bit?; Chef::Sugar::Architecture._64_bit?(node); end
# @see Chef::Sugar::Architecture#_32_bit?
def _32_bit?; Chef::Sugar::Architecture._32_bit?(node); end
# @see Chef::Sugar::Architecture#intel?
def i386?; Chef::Sugar::Architecture.i386?(node); end
# @see Chef::Sugar::Architecture#intel?
def intel?; Chef::Sugar::Architecture.intel?(node); end
# @see Chef::Sugar::Architecture#sparc?
def sparc?; Chef::Sugar::Architecture.sparc?(node); end
# @see Chef::Sugar::Architecture#ppc64?
def ppc64?; Chef::Sugar::Architecture.ppc64?(node); end
# @see Chef::Sugar::Architecture#ppc64le?
def ppc64le?; Chef::Sugar::Architecture.ppc64le?(node); end
# @see Chef::Sugar::Architecture#powerpc?
def powerpc?; Chef::Sugar::Architecture.powerpc?(node); end
# @see Chef::Sugar::Architecture#arm?
def armhf?; Chef::Sugar::Architecture.armhf?(node); end
# @see Chef::Sugar::Architecture#aarch64?
def aarch64?; Chef::Sugar::Architecture.aarch64?(node); end
# @see Chef::Sugar::Architecture#s390x?
def s390x?; Chef::Sugar::Architecture.s390x?(node); end
end
end
end
end

View File

@ -0,0 +1,192 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Chef
module Sugar
module Cloud
extend self
#
# Return true if the current current node is in "the cloud".
#
# @param [Chef::Node] node
# the node to check
#
# @return [Boolean]
#
def cloud?(node)
node.key?('cloud')
end
#
# Return true if the current current node is in EC2
#
# @param [Chef::Node] node
# the node to check
#
# @return [Boolean]
#
def ec2?(node)
node.key?('ec2')
end
#
# Return true if the current current node is in GCE
#
# @param [Chef::Node] node
# the node to check
#
# @return [Boolean]
#
def gce?(node)
node.key?('gce')
end
#
# Return true if the current current node is in Rackspace
#
# @param [Chef::Node] node
# the node to check
#
# @return [Boolean]
#
def rackspace?(node)
node.key?('rackspace')
end
#
# Return true if the current current node is in Eucalyptus
#
# @param [Chef::Node] node
# the node to check
#
# @return [Boolean]
#
def eucalyptus?(node)
node.key?('eucalyptus')
end
alias_method :euca?, :eucalyptus?
#
# Return true if the current current node is in Linode
#
# @param [Chef::Node] node
# the node to check
#
# @return [Boolean]
#
def linode?(node)
node.key?('linode')
end
#
# Return true if the current current node is in Openstack
#
# @param [Chef::Node] node
# the node to check
#
# @return [Boolean]
#
def openstack?(node)
node.key?('openstack')
end
#
# Return true if the current current node is in Cloudstack
#
# @param [Chef::Node] node
# the node to check
#
# @return [Boolean]
#
def cloudstack?(node)
node.key?('cloudstack')
end
#
# Return true if the current current node is in Azure
#
# @param [Chef::Node] node
# the node to check
#
# @return [Boolean]
#
def azure?(node)
node.key?('azure')
end
#
# Return true if the current current node is in DigitalOcean
#
# @param [Chef::Node] node
# the node to check
#
# @return [Boolean]
#
def digitalocean?(node)
node.key?('digital_ocean')
end
#
# Return true if the current current node is in SoftLayer
#
# @param [Chef::Node] node
# the node to check
#
# @return [Boolean]
#
def softlayer?(node)
node.key?('softlayer')
end
end
module DSL
# @see Chef::Sugar::Cloud#cloud?
def cloud?; Chef::Sugar::Cloud.cloud?(node); end
# @see Chef::Sugar::Cloud#ec2?
def ec2?; Chef::Sugar::Cloud.ec2?(node); end
# @see Chef::Sugar::Cloud#gce?
def gce?; Chef::Sugar::Cloud.gce?(node); end
# @see Chef::Sugar::Cloud#rackspace?
def rackspace?; Chef::Sugar::Cloud.rackspace?(node); end
# @see Chef::Sugar::Cloud#eucalyptus?
def eucalyptus?; Chef::Sugar::Cloud.eucalyptus?(node); end
alias_method :euca?, :eucalyptus?
# @see Chef::Sugar::Cloud#linode?
def linode?; Chef::Sugar::Cloud.linode?(node); end
# @see Chef::Sugar::Cloud#openstack?
def openstack?; Chef::Sugar::Cloud.openstack?(node); end
# @see Chef::Sugar::Cloud#cloudstack?
def cloudstack?; Chef::Sugar::Cloud.cloudstack?(node); end
# @see Chef::Sugar::Cloud#azure?
def azure?; Chef::Sugar::Cloud.azure?(node); end
# @see Chef::Sugar::Cloud#digitalocean?
def digitalocean?; Chef::Sugar::Cloud.digitalocean?(node); end
# @see Chef::Sugar::Cloud#softlayer?
def softlayer?; Chef::Sugar::Cloud.softlayer?(node); end
end
end
end

View File

@ -0,0 +1,108 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Chef
module Sugar
module Constraints
#
# This class is a wrapper around a version requirement that adds a nice
# DSL for comparing constraints:
#
# @example Comparing a single constraint
# Constraint.new('~> 1.2.3').satisfied_by?('1.2.7')
#
# @example Comparing multiple constraints
# Constraint.new('> 1.2.3', '< 2.0.0').satisfied_by?('1.2.7')
#
class Constraint
#
# Create a new constraint object.
#
# @param [String, Array<String>] constraints
# the list of constraints
#
def initialize(*constraints)
@requirement = Gem::Requirement.new(*constraints)
end
#
# Determine if the given version string is satisfied by this constraint
# or group of constraints.
#
# @example Given a satisified constraint
# Constraint.new('~> 1.2.0').satisfied_by?('1.2.5') #=> true
#
# @example Given an unsatisfied constraint
# Constraint.new('~> 1.2.0').satisfied_by?('2.0.0') #=> false
#
#
# @param [String] version
# the version to compare
#
# @return [Boolean]
# true if the constraint is satisfied, false otherwise
#
def satisfied_by?(version)
@requirement.satisfied_by?(Gem::Version.new(version))
end
end
#
# This class exposes a single version constraint object that wraps the
# string representation of a version string and proved helpful comparator
# methods.
#
# @example Create a new version
# Chef::Sugar::Version('1.2.3')
#
# @example Compare a version with constraints
# Chef::Sugar::Version('1.2.3').satisfies?('~> 1.3.4', '< 2.0.5')
#
class Version < String
#
# Create a new version object.
#
# @param [String] version
# the version to create
#
def initialize(version)
super
@version = Gem::Version.new(version)
end
#
# Determine if the given constraint is satisfied by this version.
#
# @example Given a satisified version
# Version.new('1.2.5').satisfies?('~> 1.2.0') #=> true
#
# @example Given an unsatisfied version
# Version.new('2.0.0').satisfies?('~> 1.2.0') #=> false
#
#
# @param [String, Array<String>] constraints
# the constraints to satisfy
#
# @return [Boolean]
# true if the version satisfies the constraints, false otherwise
#
def satisfies?(*constraints)
Gem::Requirement.new(*constraints).satisfied_by?(@version)
end
end
end
end
end

View File

@ -0,0 +1,83 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require_relative 'constraints'
class Chef
module Sugar
#
# The Constraints DSL methods were broken out into this separate
# file to allow projects (such as Omnibus) to consume the
# Chef::Sugar::Constraints classes without the DSL methods
# stepping on existing methods of the same name.
#
module Constraints
extend self
#
# Shortcut method for creating a new {Version} object.
#
# @param [String] version
# the version (as a string) to create
#
# @return [Chef::Sugar::Constraints::Version]
# the new version object
#
def version(version)
Chef::Sugar::Constraints::Version.new(version)
end
#
# Shortcut method for creating a new {Constraint} object.
#
# @param [String, Array<String>] constraints
# the list of constraints to use
#
# @return [Chef::Sugar::Constraints::Constraint]
# the new constraint object
#
def constraint(*constraints)
Chef::Sugar::Constraints::Constraint.new(*constraints)
end
end
module DSL
# @see Chef::Sugar::Constraints#version
def version(version)
Chef::Sugar::Constraints::Version.new(version)
end
# @see Chef::Sugar::Constraints#constraint
def constraint(*constraints)
Chef::Sugar::Constraints.constraint(*constraints)
end
#
# This wrapper/convenience method is only available in the recipe DSL. It
# creates a new version object from the {Chef::VERSION}.
#
# @example Check if Chef 11+
# chef_version.satisfies?('>= 11.0.0')
#
# @return [Chef::Sugar::Constraints::Version]
# a version object, wrapping the current {Chef::VERSION}
#
def chef_version
version(Chef::VERSION)
end
end
end
end

View File

@ -0,0 +1,19 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require_relative 'core_extensions/array'
require_relative 'core_extensions/string'
require_relative 'core_extensions/object'

View File

@ -0,0 +1,34 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require_relative '../constraints'
class Array
#
# Treat an array of objects as version constraints.
#
# @see Chef::Sugar::Constraints::Constraint
#
# @example Using pure Array<String> objects like constraints
# ['> 2.0.0', '< 3.0.0'].satisfied_by?('2.1.0')
#
# @param [String] version
# the version to check if it is satisfied
#
def satisfied_by?(version)
Chef::Sugar::Constraints::Constraint.new(*dup).satisfied_by?(version)
end unless method_defined?(:satisfied_by?)
end

View File

@ -0,0 +1,27 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Object
# An object is blank if it's false, empty, or a whitespace string.
# This is implemented in rails.
#
# @example foo.nil? || foo.empty? can be replaced by foo.blank?
#
# @return [true, false]
def blank?
respond_to?(:empty?) ? empty? : !self
end unless method_defined?(:blank?)
end

View File

@ -0,0 +1,66 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# require_relative '../constraints'
class String
#
# Treat strings as version objects.
#
# @see Chef::Sugar::Constraints::Version
#
# @example Using pure string objects like versions
# '1.2.3'.satisfies?('~> 1.2.0')
#
# @param [String, Array<String>] constraints
# the list of constraints to satisfy
#
def satisfies?(*constraints)
Chef::Sugar::Constraints::Version.new(dup).satisfies?(*constraints)
end unless method_defined?(:satisfies?)
#
# Treat strings as version constraints.
#
# @see Chef::Sugar::Constraints::Constraint
#
# @example Using pure string objects like constraints
# '~> 1.2.0'.satisfied_by?('1.2.3')
#
# @param [String] version
# the version to check if it is satisfied
#
def satisfied_by?(version)
Chef::Sugar::Constraints::Constraint.new(dup).satisfied_by?(version)
end unless method_defined?(:satisfied_by?)
#
# Left-flush a string based off of the number of whitespace characters on the
# first line. This is especially useful for heredocs when whitespace matters.
#
# @example Remove leading whitespace and flush
# <<-EOH.flush
# def method
# 'This is a string!'
# end
# EOH #=>"def method\n 'This is a string!'\nend"
#
# @return [String]
#
def flush
gsub(/^#{self[/\A\s*/]}/, '').chomp
end unless method_defined?(:flush)
end

View File

@ -0,0 +1,146 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Chef
module Sugar
module DataBag
class EncryptedDataBagSecretNotGiven < StandardError
def initialize
super <<-EOH
You did not set your `encrypted_data_bag_secret'! In order to use the
`encrypted_data_bag_item' helper, you must load your encrypted data bag secret
into the `Chef::Config'.
Alternatively, you can pass the secret key as the last parameter to the method
call. For more information, please see
http://docs.opscode.com/chef/essentials_data_bags.html#access-from-recipe.
EOH
end
end
extend self
#
# Helper method for loading an encrypted data bag item in a similar
# syntax/recipe DSL method.
#
# @param [String] bag
# the name of the encrypted data bag
# @param [String] id
# the id of the encrypted data bag
# @param [String] secret
# the encrypted data bag secret raw value
#
# @return [Hash]
#
def encrypted_data_bag_item(bag, id, secret = nil)
Chef::Log.debug "Loading encrypted data bag item #{bag}/#{id}"
if secret.nil? && Chef::Config[:encrypted_data_bag_secret].nil?
raise EncryptedDataBagSecretNotGiven.new
end
secret ||= File.read(Chef::Config[:encrypted_data_bag_secret]).strip
Chef::EncryptedDataBagItem.load(bag, id, secret)
end
#
# This algorithm attempts to find the data bag entry for the current
# node's Chef environment. If there are no environment-specific
# values, the "default" bucket is used. The data bag must follow the
# schema:
#
# {
# "default": {...},
# "environment_name": {...},
# "other_environment": {...},
# }
#
# @param [Node] node
# the current Chef node
# @param [String] bag
# the name of the encrypted data bag
# @param [String] id
# the id of the encrypted data bag
# @param [String] secret
# the encrypted data bag secret (default's to the +Chef::Config+ value)
#
# @return [Hash]
#
def encrypted_data_bag_item_for_environment(node, bag, id, secret = nil)
data = encrypted_data_bag_item(bag, id, secret)
if data[node.chef_environment]
Chef::Log.debug "Using #{node.chef_environment} as the key"
data[node.chef_environment]
else
Chef::Log.debug "#{node.chef_environment} key does not exist, using `default`"
data['default']
end
end
#
# This algorithm attempts to find the data bag entry for the current
# node's Chef environment. If there are no environment-specific
# values, the "default" bucket is used. The data bag must follow the
# schema:
#
# {
# "default": {...},
# "environment_name": {...},
# "other_environment": {...},
# }
#
# @param [Node] node
# the current Chef node
# @param [String] bag
# the name of the data bag
# @param [String] id
# the id of the data bag
#
# @return [Hash]
#
def data_bag_item_for_environment(node, bag, id)
data = Chef::DataBagItem.load(bag, id)
if data[node.chef_environment]
Chef::Log.debug "Using #{node.chef_environment} as the key"
data[node.chef_environment]
else
Chef::Log.debug "#{node.chef_environment} key does not exist, using `default`"
data['default']
end
end
end
module DSL
# @see Chef::Sugar::DataBag#encrypted_data_bag_item
def encrypted_data_bag_item(bag, id, secret = nil)
Chef::Sugar::DataBag.encrypted_data_bag_item(bag, id, secret)
end
# @see Chef::Sugar::DataBag#encrypted_data_bag_item_for_environment
def encrypted_data_bag_item_for_environment(bag, id, secret = nil)
Chef::Sugar::DataBag.encrypted_data_bag_item_for_environment(node, bag, id, secret)
end
# @see Chef::Sugar::DataBag#data_bag_item_for_environment
def data_bag_item_for_environment(bag, id)
Chef::Sugar::DataBag.data_bag_item_for_environment(node, bag, id)
end
end
end
end

View File

@ -0,0 +1,45 @@
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
if defined?(Chef::Deprecated::Base)
class Chef
class Deprecated
class ChefSugar < Base
def id
28
end
def target
"chef_sugar.html"
end
end
end
end
end
class Chef
module Sugar
module Deprecation
if defined?(Chef::Deprecated::Base)
def deprecated(message)
Chef.deprecated(:chef_sugar, message)
end
else
def deprecated(message)
Chef::Log.warn(message)
end
end
extend self
end
end
end

View File

@ -0,0 +1,45 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Chef
module Sugar
module Docker
extend self
# these helpers have been moved to core chef
if !defined?(Chef::VERSION) || Gem::Requirement.new("< 15.4.70").satisfied_by?(Gem::Version.new(Chef::VERSION))
#
# Returns true if the current node is a docker container.
#
# @param [Chef::Node] node
# the node to check
#
# @return [Boolean]
#
def docker?(node)
File.exist?('/.dockerinit') || File.exist?('/.dockerenv')
end
end
end
module DSL
if !defined?(Chef::VERSION) || Gem::Requirement.new("< 15.4.70").satisfied_by?(Gem::Version.new(Chef::VERSION))
# @see Chef::Sugar::Docker#docker?
def docker?; Chef::Sugar::Docker.docker?(node); end
end
end
end
end

View File

@ -0,0 +1,227 @@
class Chef
module Sugar
module Filters
#
# Evaluate resources at compile time instead of converge time.
#
class AtCompileTime
def initialize(recipe)
@recipe = recipe
end
def evaluate(&block)
instance_eval(&block)
end
def method_missing(m, *args, &block)
resource = @recipe.send(m, *args, &block)
if resource.is_a?(Chef::Resource)
actions = Array(resource.action)
resource.action(:nothing)
actions.each do |action|
resource.run_action(action)
end
end
resource
end
end
#
# A top-level class for manipulation the resource collection.
#
class Injector
def initialize(recipe, identifier, placement)
@recipe = recipe
@resource_collection = @recipe.run_context.resource_collection
@resource = @resource_collection.lookup(identifier)
@placement = placement
end
def evaluate(&block)
instance_eval(&block)
end
def insert_before(resource, new_resource)
@resource_collection.instance_eval do
# Remove the resource because it's automatically created
@resources.delete_at(@resources_by_name[new_resource.to_s])
@resources_by_name.delete(new_resource.to_s)
index = @resources_by_name[resource.to_s]
@resources.insert(index, new_resource)
@resources_by_name[new_resource.to_s] = index
end
end
def insert_after(resource, new_resource)
@resource_collection.instance_eval do
# Remove the resource because it's automatically created
@resources.delete_at(@resources_by_name[new_resource.to_s])
@resources_by_name.delete(new_resource.to_s)
index = @resources_by_name[resource.to_s] + 2
@resources.insert(index, new_resource)
@resources_by_name[new_resource.to_s] = index
end
end
def method_missing(m, *args, &block)
new_resource = @recipe.send(m, *args, &block)
case @placement
when :before
insert_before(@resource, new_resource)
when :after
insert_after(@resource, new_resource)
else
super
end
end
end
end
module DSL
#
# Dynamically run resources specified in the block during the compilation
# phase, instead of the convergence phase.
#
# @example The old way
# package('apache2') do
# action :nothing
# end.run_action(:install)
#
# @example The new way
# at_compile_time do
# package('apache2')
# end
#
# @example Resource actions are run in order
# at_compile_time do
# service 'apache2' do
# action [:enable, :start] # run_action(:enable), run_action(:start)
# end
# end
#
def at_compile_time(&block)
Chef::Sugar::Filters::AtCompileTime.new(self).evaluate(&block)
end
#
# Dynamically insert resources before an existing resource in the
# resource_collection.
#
# @example Write a custom template before the apache2 service actions
# are run
# before 'service[apache2]' do
# template '/etc/apache2/thing.conf' do
# source '...'
# end
# end
#
#
# @param [String] identifier
# the +resource[name]+ identifier string
#
def before(identifier, &block)
Chef::Sugar::Filters::Injector.new(self, identifier, :before).evaluate(&block)
end
#
# Dynamically insert resources after an existing resource in the
# resource_collection.
#
# @example Write a custom template after the apache2 service actions
# are run
# after 'service[apache2]' do
# template '/etc/apache2/thing.conf' do
# source '...'
# end
# end
#
#
# @param [String] identifier
# the +resource[name]+ identifier string
#
def after(identifier, &block)
Chef::Sugar::Filters::Injector.new(self, identifier, :after).evaluate(&block)
end
end
module RecipeDSL
#
# @deprecated The description is in the method body pretty accurately...
#
def compile_time(&block)
message = <<-EOH
The Chef Sugar recipe DSL method `compile_time' has been renamed to
`at_compile_time'! This is a breaking change that was released in a patch
version, so please continue reading to understand the necessary semantic
versioning violation.
Chef Software implemented a version of `compile_time' in Chef 12.1, breaking any
cookbook that uses or depends on Chef Sugar on Chef 12.1:
https://www.chef.io/blog/2015/03/03/chef-12-1-0-released
In order to progress Chef Sugar forward, the DSL method has been renamed to
avoid the namespace collision.
In short, you should change this:
compile_time do
# ...
end
to this:
at_compile_time do
# ...
end
EOH
if Chef::Resource::ChefGem.instance_methods(false).include?(:compile_time)
message << <<-EOH
You are running a version of Chef Client that includes the `compile_time'
attribute on core Chef resources (most likely Chef 12.1+). Instead of continuing
and having Chef provide you with an obscure error message, I am going to error
here. There is no way for the Chef Recipe to successfully continue unless you
change the Chef Sugar `compile_time' method to `at_compile_time' in your Chef
recipes.
You should NOT change resource-level `compile_time' attributes:
package "foo" do
compile_time true # Do NOT change these
end
I truly apologize for the inconvienence and hope the reason for introducing this
breaking change is clear. I am sorry if it causes extra work, but I promise this
error message is much more informative than "wrong number of arguments".
If you have any questions, please feel free to open an issue on GitHub at:
https://github.com/sethvargo/chef-sugar
Thank you, and have a great day!
EOH
raise RuntimeError, message
else
message << <<-EOH
You are running a version of Chef Client that does not include the
`compile_time' attribute on core Chef resources (most likely less than
Chef 12.1), so this is just a warning. Please consider changing the Chef Sugar
`compile_time' method to `at_compile_time' in your Chef recipes. If you upgrade
Chef, your recipes WILL break.
EOH
Chef::Log.warn(message)
at_compile_time(&block)
end
end
end
end
end

View File

@ -0,0 +1,61 @@
#
# Copyright 2015, Nathan Williams <nath.e.will@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Chef
module Sugar
module Init
extend self
#
# Determine if the current init system is systemd.
#
# @return [Boolean]
#
def systemd?(node)
File.exist?('/bin/systemctl')
end
#
# Determine if the current init system is upstart.
#
# @return [Boolean]
#
def upstart?(node)
File.executable?('/sbin/initctl')
end
#
# Determine if the current init system is runit.
#
# @return [Boolean]
#
def runit?(node)
File.executable?('/sbin/runit-init')
end
end
module DSL
# @see Chef::Sugar::Init#systemd?
def systemd?; Chef::Sugar::Init.systemd?(node); end
# @see Chef::Sugar::Init#upstart?
def upstart?; Chef::Sugar::Init.upstart?(node); end
# @see Chef::Sugar::Init#runit?
def runit?; Chef::Sugar::Init.runit?(node); end
end
end
end

View File

@ -0,0 +1,48 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Chef
module Sugar
module IP
extend self
#
# The best IP address for the given node, in the context of
# the current node. Useful for choosing a local IP address
# over a public one to limit bandwidth on cloud providers.
#
# @param [Chef::Node] other
# the node to calculate the best IP address for
#
def best_ip_for(node, other)
if other['cloud']
if node['cloud'] && other['cloud']['provider'] == node['cloud']['provider']
other['cloud']['local_ipv4']
else
other['cloud']['public_ipv4']
end
else
other['ipaddress']
end
end
end
module DSL
# @see Chef::Sugar::IP#best_ip_for
def best_ip_for(other); Chef::Sugar::IP.best_ip_for(node, other); end
end
end
end

View File

@ -0,0 +1,49 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Chef
module Sugar
module Kernel
class ChefGemLoadError < StandardError
def initialize(name)
super <<-EOH
Chef could not load the gem `#{name}'! You may need to install the gem manually
with `gem install #{name}', or include a recipe before you can use this
resource. Please consult the documentation for this cookbook for proper usage.
EOH
end
end
#
# Require a gem that should have been installed by Chef, such as in a
# recipes as a +chef_gem+. This method will gracefully degrade if the
# gem cannot be loaded.
#
# @param [String] name
# the name of the gem to install
#
# @return [Boolean]
# true if the require is successful and false if the gem is already
# loaded
#
def require_chef_gem(name)
require(name)
rescue LoadError
raise ChefGemLoadError.new(name)
end
end
end
end

View File

@ -0,0 +1,45 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Chef
module Sugar
module Kitchen
extend self
# these helpers have been moved to core-chef
if !defined?(Chef::VERSION) || Gem::Requirement.new("< 15.4.70").satisfied_by?(Gem::Version.new(Chef::VERSION))
#
# Returns true if the current node is provisioned by Test Kitchen.
#
# @param [Chef::Node] node
# the node to check
#
# @return [Boolean]
#
def kitchen?(node)
!ENV['TEST_KITCHEN'].nil?
end
end
end
module DSL
if !defined?(Chef::VERSION) || Gem::Requirement.new("< 15.4.70").satisfied_by?(Gem::Version.new(Chef::VERSION))
# @see Chef::Sugar::Kitchen#kitchen?
def kitchen?; Chef::Sugar::Kitchen.kitchen?(node); end
end
end
end
end

View File

@ -0,0 +1,219 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require_relative "deprecation"
class Chef
class Node
class AttributeDoesNotExistError < StandardError
def initialize(keys, key)
hash = keys.map { |key| "['#{key}']" }
super <<-EOH
No attribute `node#{hash.join}' exists on
the current node. Specifically the `#{key}' attribute is not
defined. Please make sure you have spelled everything correctly.
EOH
end
end
#
# Determine if the current node is in the given Chef environment
# (or matches the given regular expression).
#
# @param [String, Regex] environment
#
# @return [Boolean]
#
def in?(environment)
Chef::Sugar::Deprecation.deprecated "the chef-sugar node.in? method is deprecated"
environment === chef_environment
end
#
# Safely fetch a deeply nested attribute by specifying a list of keys,
# bypassing Ruby's Hash notation. This method swallows +NoMethodError+
# exceptions, avoiding the most common error in Chef-land.
#
# This method will return +nil+ if any deeply nested key does not exist.
#
# @see [Node#deep_fetch!]
#
def deep_fetch(*keys)
Chef::Sugar::Deprecation.deprecated "the chef-sugar deep_fetch method is deprecated and should be replaced by node.read"
deep_fetch!(*keys)
rescue NoMethodError, AttributeDoesNotExistError
nil
end
#
# Deeply fetch a node attribute by specifying a list of keys, bypassing
# Ruby's Hash notation.
#
# This method will raise any exceptions, such as
# +undefined method `[]' for nil:NilClass+, just as if you used the native
# attribute notation. If you want a safely vivified hash, see {deep_fetch}.
#
# @example Fetch a deeply nested key
# node.deep_fetch(:foo, :bar, :zip) #=> node['foo']['bar']['zip']
#
# @param [Array<String, Symbol>] keys
# the list of keys to kdeep fetch
#
# @return [Object]
#
def deep_fetch!(*keys)
Chef::Sugar::Deprecation.deprecated "the chef-sugar deep_fetch method is deprecated and should be replaced by node.read!"
keys.map!(&:to_s)
keys.inject(attributes.to_hash) do |hash, key|
if hash.key?(key)
hash[key]
else
raise AttributeDoesNotExistError.new(keys, key)
end
end
end
#
# Dynamically define the current namespace. Multiple namespaces may be
# nested.
#
# @example Define a simple namespace
#
# namespace 'apache2' do
# # ...
# end
#
# @example Define a nested namespace
#
# namespace 'apache2', 'config' do
# # ...
# end
#
# @example Define a complex nested namespace
#
# namespace 'apache2' do
# namespace 'config' do
# # ...
# end
# end
#
# @example Define a namespace with a custom precedence level
#
# namespace 'apache2', precedence: normal do
# # Attributes here will use the "normal" level
# end
#
# @example Define different nested precedence levels
#
# namespace 'apache2', precedence: normal do
# # Attributes defined here will use the "normal" level
#
# namespace 'config', precedence: override do
# # Attributes defined here will use the "override" level
# end
# end
#
#
# @param [Array] args
# the list of arguments (such as the namespace and precedence levels)
# the user gave
# @param [Proc] block
# the nested evaluation context
#
# @return [nil]
# to prevent accidential method chaining if the block isn't closed
#
def namespace(*args, &block)
Chef::Sugar::Deprecation.deprecated "the chef-sugar attribute namespace setting is deprecated, please use traditional chef attribute notation"
@namespace_options = namespace_options.merge(args.last.is_a?(Hash) ? args.pop : {})
keys = args.map(&:to_s)
@current_namespace = current_namespace + keys
instance_eval(&block)
@current_namespace = current_namespace - keys
if @current_namespace.empty?
@namespace_options = nil
end
nil
end
alias_method :old_method_missing, :method_missing
#
# Provide a nice DSL for defining attributes. +method_missing+ is called
# on all the attribute names. For more information on how to use the DSL,
# see the class-level documentation.
#
# @return [nil]
# to prevent accidential method chaining if the block isn't closed
# @return [Object]
# If no argument is passed in, method becomes an attribute accessor
#
def method_missing(m, *args, &block)
old_method_missing(m, *args, &block)
rescue NoMethodError
# The Node Attribute's key is the method name
key = m.to_s
# If arguments are passed in, set node attribute with args as the value
if args.size > 0
vivified[key] = args.size == 1 ? args.first : args
return nil
# If no arguments are passed in, attempt to access corresponding attribute
else
deep_key = current_namespace.dup << key
return deep_fetch!(*deep_key)
end
end
private
#
# The namespace options.
#
# @return [Hash]
#
def namespace_options
@namespace_options ||= {
precedence: default
}
end
#
# The current namespace. This is actually a reverse-ordered array that
# vivifies the correct hash.#
#
# @return [Array<String>]
#
def current_namespace
@current_namespace ||= []
end
#
# The vivified (fake-filled) hash. It is assumed that the default value
# for non-existent keys in the hash is a new, empty hash.
#
# @return [Hash<String, Hash>]
#
def vivified
current_namespace.inject(namespace_options[:precedence]) do |hash, item|
hash[item] ||= {}
hash[item]
end
end
end
end

View File

@ -0,0 +1,331 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require_relative 'constraints'
class Chef
module Sugar
module Platform
extend self
PLATFORM_VERSIONS = {
'debian' => {
'squeeze' => '6',
'wheezy' => '7',
'jessie' => '8',
'stretch' => '9',
'buster' => '10',
},
'linuxmint' => {
'tara' => '19',
'sarah' => '18',
'qiana' => '17',
'petra' => '16',
'olivia' => '15',
'nadia' => '14',
'maya' => '13',
'lisa' => '12',
},
'mac_os_x' => {
'lion' => '10.7',
'mountain_lion' => '10.8',
'mavericks' => '10.9',
'yosemite' => '10.10',
'el_capitan' => '10.11',
'sierra' => '10.12',
'high_sierra' => '10.13',
'mojave' => '10.14',
},
'redhat' => {
'santiago' => '6',
'6' => '6',
'maipo' => '7',
'7' => '7',
'oompa' => '8',
'8' => '8'
},
'centos' => {
'final' => '6',
'6' => '6',
'core' => '7',
'7' => '7'
},
'solaris' => {
'7' => '5.7',
'8' => '5.8',
'9' => '5.9',
'10' => '5.10',
'11' => '5.11',
},
'ubuntu' => {
'lucid' => '10.04',
'maverick' => '10.10',
'natty' => '11.04',
'oneiric' => '11.10',
'precise' => '12.04',
'quantal' => '12.10',
'raring' => '13.04',
'saucy' => '13.10',
'trusty' => '14.04',
'utopic' => '14.10',
'vivid' => '15.04',
'wily' => '15.10',
'xenial' => '16.04',
'zesty' => '17.04',
'artful' => '17.10',
'bionic' => '18.04',
'cosmic' => '18.10',
},
}
COMPARISON_OPERATORS = {
'after' => ->(a, b) { a > b },
'after_or_at' => ->(a, b) { a >= b },
'' => ->(a, b) { a == b },
'before' => ->(a, b) { a < b },
'before_or_at' => ->(a, b) { a <= b },
}
# Dynamically define custom matchers at runtime in a matrix. For each
# Platform, we create a map of named versions to their numerical
# equivalents (e.g. debian_before_squeeze?).
PLATFORM_VERSIONS.each do |platform, versions|
versions.each do |name, version|
COMPARISON_OPERATORS.each do |operator, block|
method_name = "#{platform}_#{operator}_#{name}?".squeeze('_').to_sym
define_method(method_name) do |node|
# Find the highest precedence that we actually care about based
# off of what was given to us in the list.
length = version.split('.').size
check = node['platform_version'].split('.')[0...length].join('.')
# Calling #to_f will ensure we only check major versions since
# '10.04.4'.to_f #=> 10.04. We also use a regex to match on
# platform so things like `solaris2` match on `solaris`.
node['platform'] =~ %r(^#{platform}) && block.call(check.to_f, version.to_f)
end
end
end
end
# these helpers have been moved to core chef
if !defined?(Chef::VERSION) || Gem::Requirement.new("< 15.4.70").satisfied_by?(Gem::Version.new(Chef::VERSION))
#
# Determine if the current node is linux mint.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def linux_mint?(node)
node['platform'] == 'linuxmint'
end
alias_method :mint?, :linux_mint?
#
# Determine if the current node is ubuntu.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def ubuntu?(node)
node['platform'] == 'ubuntu'
end
#
# Determine if the current node is debian (platform, not platform_family).
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def debian_platform?(node)
node['platform'] == 'debian'
end
#
# Determine if the current node is amazon linux.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def amazon_linux?(node)
node['platform'] == 'amazon'
end
alias_method :amazon?, :amazon_linux?
#
# Determine if the current node is centos.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def centos?(node)
node['platform'] == 'centos'
end
#
# Determine if the current node is oracle linux.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def oracle_linux?(node)
node['platform'] == 'oracle'
end
alias_method :oracle?, :oracle_linux?
#
# Determine if the current node is scientific linux.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def scientific_linux?(node)
node['platform'] == 'scientific'
end
alias_method :scientific?, :scientific_linux?
#
# Determine if the current node is redhat enterprise.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def redhat_enterprise_linux?(node)
node['platform'] == 'redhat'
end
alias_method :redhat_enterprise?, :redhat_enterprise_linux?
#
# Determine if the current node is fedora (platform, not platform_family).
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def fedora_platform?(node)
node['platform'] == 'fedora'
end
#
# Determine if the current node is solaris2
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def solaris2?(node)
node['platform'] == 'solaris2'
end
alias_method :solaris?, :solaris2?
#
# Determine if the current node is aix
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def aix?(node)
node['platform'] == 'aix'
end
#
# Determine if the current node is smartos
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def smartos?(node)
node['platform'] == 'smartos'
end
#
# Determine if the current node is omnios
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def omnios?(node)
node['platform'] == 'omnios'
end
#
# Determine if the current node is raspbian
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def raspbian?(node)
node['platform'] == 'raspbian'
end
#
# Determine if the current node is a Cisco nexus device
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def nexus?(node)
node['platform'] == 'nexus'
end
#
# Determine if the current node is a Cisco IOS-XR device
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def ios_xr?(node)
node['platform'] == 'ios_xr'
end
end
#
# Return the platform_version for the node. Acts like a String
# but also provides a mechanism for checking version constraints.
#
# @param [Chef::Node] node
#
# @return [Chef::Sugar::Constraints::Version]
#
def platform_version(node)
Chef::Sugar::Constraints::Version.new(node['platform_version'])
end
end
module DSL
Chef::Sugar::Platform.instance_methods.each do |name|
define_method(name) do
Chef::Sugar::Platform.send(name, node)
end
end
end
end
end

View File

@ -0,0 +1,184 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Chef
module Sugar
module PlatformFamily
extend self
# these helpers have been moved to core chef
if !defined?(Chef::VERSION) || Gem::Requirement.new("< 15.4.70").satisfied_by?(Gem::Version.new(Chef::VERSION))
#
# Determine if the current node is a member of the arch family.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def arch_linux?(node)
node['platform_family'] == 'arch'
end
alias_method :arch?, :arch_linux?
#
# Determine if the current node is a member of the debian family.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def debian?(node)
node['platform_family'] == 'debian'
end
#
# Determine if the current node is a member of the fedora family.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def fedora?(node)
node['platform_family'] == 'fedora'
end
#
# Determine if the current node is a member of the freebsd family.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def freebsd?(node)
node['platform_family'] == 'freebsd'
end
#
# Determine if the current node is a member of the arch family.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def gentoo?(node)
node['platform_family'] == 'gentoo'
end
#
# Determine if the current node is a member of the OSX family.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def mac_os_x?(node)
node['platform_family'] == 'mac_os_x'
end
alias_method :osx?, :mac_os_x?
alias_method :mac?, :mac_os_x?
#
# Determine if the current node is a member of the openbsd family.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def openbsd?(node)
node['platform_family'] == 'openbsd'
end
#
# Determine if the current node is a member of the redhat family.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def rhel?(node)
node['platform_family'] == 'rhel'
end
alias_method :redhat?, :rhel?
alias_method :el?, :rhel?
#
# Determine if the current node is a member of the slackware family.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def slackware?(node)
node['platform_family'] == 'slackware'
end
#
# Determine if the current node is a member of the suse family.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def suse?(node)
node['platform_family'] == 'suse'
end
#
# Determine if the current node is a member of the windows family.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def windows?(node)
node['platform_family'] == 'windows'
end
#
# Determine if the current node is a member of the wrlinux family.
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def wrlinux?(node)
node['platform_family'] == 'wrlinux'
end
#
# Determine if the current system is a linux derivative
#
# @param [Chef::Node] node
#
# @return [Boolean]
#
def linux?(node)
node['os'] == 'linux'
end
end
end
module DSL
Chef::Sugar::PlatformFamily.instance_methods.each do |name|
define_method(name) do
Chef::Sugar::PlatformFamily.send(name, node)
end
end
end
end
end

View File

@ -0,0 +1,51 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Chef
module Sugar
module Ruby
extend self
#
# Determine if the current Ruby version is 2.0.
#
# @return [Boolean]
#
def ruby_20?(node)
version = Gem::Version.new(node['languages']['ruby']['version'])
Gem::Requirement.new('~> 2.0.0').satisfied_by?(version)
end
#
# Determine if the current Ruby version is 1.9.
#
# @return [Boolean]
#
def ruby_19?(node)
version = Gem::Version.new(node['languages']['ruby']['version'])
Gem::Requirement.new('~> 1.9.0').satisfied_by?(version)
end
end
module DSL
# @see Chef::Sugar::Ruby#ruby_20?
def ruby_20?; Chef::Sugar::Ruby.ruby_20?(node); end
# @see Chef::Sugar::Ruby#ruby_19?
def ruby_19?; Chef::Sugar::Ruby.ruby_19?(node); end
end
end
end

View File

@ -0,0 +1,41 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Chef
module Sugar
module RunContext
extend self
#
# Determine if the current node includes the given recipe name.
#
# @param [String] recipe_name
#
def includes_recipe?(node, recipe_name)
node.recipe?(recipe_name)
end
alias_method :include_recipe?, :includes_recipe?
end
module DSL
# @see Chef::Sugar::IP#best_ip_for
def includes_recipe?(recipe_name)
Chef::Sugar::RunContext.includes_recipe?(node, recipe_name)
end
alias_method :include_recipe?, :includes_recipe?
end
end
end

View File

@ -0,0 +1,157 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require 'mixlib/shellout' unless defined?(Mixlib::ShellOut)
require 'pathname' unless defined?(Pathname)
class Chef
module Sugar
module Shell
extend self
# this helper has been moved to core chef
if !defined?(Chef::VERSION) || Gem::Requirement.new("< 16.0.257").satisfied_by?(Gem::Version.new(Chef::VERSION))
#
# Finds a command in $PATH
#
# @param [String] cmd
# the command to find
#
# @return [String, nil]
#
def which(cmd)
if Pathname.new(cmd).absolute?
File.executable?(cmd) ? cmd : nil
else
paths = ENV['PATH'].split(::File::PATH_SEPARATOR) + %w(/bin /usr/bin /sbin /usr/sbin)
paths.each do |path|
possible = File.join(path, cmd)
return possible if File.executable?(possible)
end
nil
end
end
end
#
# The platform-specific output path to +/dev/null+.
#
# @return [String]
#
def dev_null(node)
if defined?(ChefUtils)
ChefUtils.windows?(node) ? 'NUL' : '/dev/null'
else
Chef::Sugar::PlatformFamily.windows?(node) ? 'NUL' : '/dev/null'
end
end
#
# Boolean method to check if a command line utility is installed.
#
# @param [String] cmd
# the command to find
#
# @return [Boolean]
# true if the command is found in the path, false otherwise
#
def installed?(cmd)
!which(cmd).nil?
end
#
# Checks if the given binary is installed and exists at the given
# version. Also see {version_for}.
#
# @param [String] cmd
# the command to check
# @param [String] expected_version
# the version to check
# @param [String] flag
# the flag to use to check the version of the binary
#
# @return [Boolean]
# true if the command exists and is at the given version, false
# otherwise
#
def installed_at_version?(cmd, expected_version, flag = '--version')
return false if !installed?(cmd)
version = version_for(cmd, flag)
return false if version.nil?
if expected_version.is_a?(Regexp)
!version.match(expected_version).nil?
else
version.include?(expected_version)
end
end
#
# The version for a given command. This method does NOT check if the
# command exists! It is assumed the command existence has been
# checked with +which+ or similar. To simply check if an installed
# version is acceptable, please see {installed_at_version}.
#
# Assumptions:
# 1. The command exists.
# 2. The command outputs version information to +$stdout+ or +$stderr+.
# Did you know that java outputs its version to $stderr?
#
#
# @param [String] cmd
# the command to find the version for
# @param [String] flag
# the flag to use to get the version
#
# @return [String]
# the entire output of the version command (stderr and stdout)
#
def version_for(cmd, flag = '--version')
cmd = Mixlib::ShellOut.new("#{cmd} #{flag}")
cmd.run_command
cmd.error!
[cmd.stdout.strip, cmd.stderr.strip].join("\n")
end
end
module DSL
# this helper has been moved to core chef
if !defined?(Chef::VERSION) || Gem::Requirement.new("< 16.0.257").satisfied_by?(Gem::Version.new(Chef::VERSION))
# @see Chef::Sugar::Shell#which
def which(cmd); Chef::Sugar::Shell.which(cmd); end
end
# @see Chef::Sugar::Shell#dev_null
def dev_null; Chef::Sugar::Shell.dev_null(node); end
# @see Chef::Sugar::Shell#installed?
def installed?(cmd); Chef::Sugar::Shell.installed?(cmd); end
# @see Chef::Sugar::Shell#installed_at_version?
def installed_at_version?(cmd, version, flag = '--version')
Chef::Sugar::Shell.installed_at_version?(cmd, version, flag)
end
# @see Chef::Sugar::Shell#version_for
def version_for(cmd, flag = '--version')
Chef::Sugar::Shell.version_for(cmd, flag)
end
end
end
end

View File

@ -0,0 +1,77 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Chef
module Sugar
module Vagrant
extend self
#
# Determine if the current node is running in vagrant mode.
#
# @param [Chef::Node] node
#
# @return [Boolean]
# true if the machine is currently running vagrant, false
# otherwise
#
def vagrant?(node)
vagrant_key?(node) || vagrant_domain?(node) || vagrant_user?(node)
end
private
#
# Check if the +vagrant+ key exists on the +node+ object. This key is no
# longer populated by vagrant, but it is kept around for legacy purposes.
#
# @param (see vagrant?)
# @return (see vagrant?)
#
def vagrant_key?(node)
node.key?('vagrant')
end
#
# Check if "vagrantup.com" is included in the node's domain. Technically,
# this would make Chef Sugar falsely detect +vagrant?+ on any of
# Hashicorp's servers. But if that edge case becomes a serious problem,
# @mitchellh has my phone number.
#
# @param (see vagrant?)
# @return (see vagrant?)
#
def vagrant_domain?(node)
node.key?('domain') && !node['domain'].nil? && node['domain'].include?('vagrantup.com')
end
#
# Check if the system contains a +vagrant+ user.
#
# @param (see vagrant?)
# @return (see vagrant?)
#
def vagrant_user?(node)
node.key?('etc') && node['etc'].key?('passwd') && node['etc']['passwd'].key?('vagrant')
end
end
module DSL
# @see Chef::Sugar::Vagrant#vagrant?
def vagrant?; Chef::Sugar::Vagrant.vagrant?(node); end
end
end
end

View File

@ -0,0 +1,21 @@
#
# Copyright 2013-2015, Seth Vargo <sethvargo@gmail.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Chef
module Sugar
VERSION = "5.1.12"
end
end

View File

@ -0,0 +1,151 @@
#
# Copyright 2014, Joseph J. Nuspl Jr. <nuspl@nvwls.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Chef
module Sugar
module Virtualization
extend self
#
# Determine if the current node is running under KVM.
#
# @param [Chef::Node] node
#
# @return [Boolean]
# true if the machine is currently running under KVM, false
# otherwise
#
def kvm?(node)
node.key?('virtualization') && node['virtualization']['system'] == 'kvm'
end
#
# Determine if the current node is running in a linux container.
#
# @param [Chef::Node] node
#
# @return [Boolean]
# true if the machine is currently running in a container, false
# otherwise
#
def lxc?(node)
node.key?('virtualization') && node['virtualization']['system'] == 'lxc'
end
#
# Determine if the current node is running under Parallels Desktop.
#
# @param [Chef::Node] node
#
# @return [Boolean]
# true if the machine is currently running under Parallels Desktop, false
# otherwise
#
def parallels?(node)
node.key?('virtualization') && node['virtualization']['system'] == 'parallels'
end
#
# Determine if the current node is running under VirtualBox.
#
# @param [Chef::Node] node
#
# @return [Boolean]
# true if the machine is currently running under VirtualBox, false
# otherwise
#
def virtualbox?(node)
node.key?('virtualization') && node['virtualization']['system'] == 'vbox'
end
#
# Determine if the current node is running under VMware.
#
# @param [Chef::Node] node
#
# @return [Boolean]
# true if the machine is currently running under VMware, false
# otherwise
#
def vmware?(node)
node.key?('virtualization') && node['virtualization']['system'] == 'vmware'
end
#
# Determine if the current node is running under openvz.
#
# @param [Chef::Node] node
#
# @return [Boolean]
# true if the machine is currently running under openvz, false
# otherwise
#
def openvz?(node)
node.key?('virtualization') && node['virtualization']['system'] == 'openvz'
end
def virtual?(node)
openvz?(node) || vmware?(node) || virtualbox?(node) || parallels?(node) || lxc?(node) || kvm?(node)
end
def physical?(node)
!virtual?(node)
end
end
module DSL
# @see Chef::Sugar::Virtualization#kvm?
def kvm?
Chef::Sugar::Virtualization.kvm?(node)
end
# @see Chef::Sugar::Virtualization#lxc?
def lxc?
Chef::Sugar::Virtualization.lxc?(node)
end
# @see Chef::Sugar::Virtualization#parallels?
def parallels?
Chef::Sugar::Virtualization.parallels?(node)
end
# @see Chef::Sugar::Virtualization#virtualbox?
def virtualbox?
Chef::Sugar::Virtualization.virtualbox?(node)
end
# @see Chef::Sugar::Virtualization#vmware?
def vmware?
Chef::Sugar::Virtualization.vmware?(node)
end
# @see Chef::Sugar::Virtualization#openvz?
def openvz?
Chef::Sugar::Virtualization.openvz?(node)
end
# @see Chef::Sugar::Virtualization#virtual?
def virtual?
Chef::Sugar::Virtualization.virtual?(node)
end
# @see Chef::Sugar::Virtualization#physical?
def physical?
Chef::Sugar::Virtualization.physical?(node)
end
end
end
end

View File

@ -0,0 +1 @@
require "chef/sugar"

View File

@ -1 +1,38 @@
{"name":"chef-sugar","version":"3.3.0","description":"Installs chef-sugar. Please see the chef-sugar Ruby gem for more information.","long_description":"Chef Sugar is a Gem & Chef Recipe that includes series of helpful syntactic\nsugars on top of the Chef core and other resources to make a cleaner, more lean\nrecipe DSL, enforce DRY principles, and make writing Chef recipes an awesome and\nfun experience!\n\nFor the most up-to-date information and documentation, please visit the [Chef\nSugar project page on GitHub](https://github.com/sethvargo/chef-sugar).\n","maintainer":"Seth Vargo","maintainer_email":"sethvargo@gmail.com","license":"Apache 2.0","platforms":{},"dependencies":{},"recommendations":{},"suggestions":{},"conflicting":{},"providing":{},"replacing":{},"attributes":{},"groupings":{},"recipes":{}}
{
"name": "chef-sugar",
"description": "Installs chef-sugar. Please see the chef-sugar Ruby gem for more information.",
"long_description": "Chef Sugar is a Gem & Chef Recipe that includes series of helpful syntactic\nsugars on top of the Chef core and other resources to make a cleaner, more lean\nrecipe DSL, enforce DRY principles, and make writing Chef recipes an awesome and\nfun experience!\n\nFor the most up-to-date information and documentation, please visit the [Chef\nSugar project page on GitHub](https://github.com/chef/chef-sugar).\n",
"maintainer": "Chef Software, Inc",
"maintainer_email": "cookbooks@chef.io",
"license": "Apache-2.0",
"platforms": {
"any": ">= 0.0.0"
},
"dependencies": {
},
"providing": {
},
"recipes": {
},
"version": "5.1.12",
"source_url": "https://github.com/chef/chef-sugar",
"issues_url": "https://github.com/chef/chef-sugar/issues",
"privacy": false,
"chef_versions": [
[
">= 13.0"
]
],
"ohai_versions": [
],
"gems": [
[
"chef-sugar"
]
],
"eager_load_libraries": true
}

View File

@ -0,0 +1,22 @@
name 'chef-sugar'
maintainer 'Chef Software, Inc'
maintainer_email 'cookbooks@chef.io'
license 'Apache-2.0'
description 'Installs chef-sugar. Please see the chef-sugar Ruby gem for more information.'
long_description <<-EOH
Chef Sugar is a Gem & Chef Recipe that includes series of helpful syntactic
sugars on top of the Chef core and other resources to make a cleaner, more lean
recipe DSL, enforce DRY principles, and make writing Chef recipes an awesome and
fun experience!
For the most up-to-date information and documentation, please visit the [Chef
Sugar project page on GitHub](https://github.com/chef/chef-sugar).
EOH
version '5.1.12'
supports 'any'
issues_url 'https://github.com/chef/chef-sugar/issues'
source_url 'https://github.com/chef/chef-sugar'
chef_version '>= 13.0'
gem 'chef-sugar'

View File

@ -17,18 +17,4 @@
# limitations under the License.
#
gem_version = run_context.cookbook_collection[cookbook_name].metadata.version
if Chef::Resource::ChefGem.instance_methods(false).include?(:compile_time)
chef_gem 'chef-sugar' do
version gem_version
compile_time true
end
else
chef_gem 'chef-sugar' do
version gem_version
action :nothing
end.run_action(:install)
end
require 'chef/sugar'
Chef::Log.warn('chef-sugar::default no longer needs to be included in your runlist. Instead simply depend on the chef-sugar cookbook and the gem will be installed and loaded automatically.')

View File

@ -0,0 +1,28 @@
require 'rspec'
require 'chefspec'
require 'chef/sugar'
require 'chef/version'
require_relative 'support/shared_examples'
RSpec.configure do |config|
# Prohibit using the should syntax
config.expect_with :rspec do |spec|
spec.syntax = :expect
end
# Focus groups
config.filter_run(focus: true)
config.run_all_when_everything_filtered = true
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = 'random'
# ChefSpec configuration
config.log_level = :fatal
config.filter_run_excluding pre_chef16_only: Gem::Requirement.new(">= 16.0.257").satisfied_by?(Gem::Version.new(Chef::VERSION))
end

View File

@ -0,0 +1,20 @@
module RSpec
shared_examples 'a chef sugar' do
it 'acts as a singleton' do
described_class.module_eval("def foo; 'result'; end")
klass = Class.new.tap { |k| k.send(:include, described_class) }
expect(described_class.foo).to eq(klass.new.foo)
end
described_class.instance_methods.each do |name|
it "defines a `#{name}` DSL method" do
expect(Chef::Sugar::DSL).to be_method_defined(name)
end
it 'has n-1 arity from the parent method' do
method = Chef::Sugar::DSL.instance_method(name)
expect(method.arity).to eq(described_class.method(name).arity - 1)
end
end
end
end

View File

@ -0,0 +1,149 @@
require 'spec_helper'
describe Chef::Sugar::Cloud do
it_behaves_like 'a chef sugar'
describe '#cloud?' do
it 'is true when the node is on cloud' do
node = { 'cloud' => nil }
expect(described_class.cloud?(node)).to be true
end
it 'is false when the node is not on cloud' do
node = {}
expect(described_class.cloud?(node)).to be false
end
end
describe '#ec2?' do
it 'is true when the node is on ec2' do
node = { 'ec2' => nil }
expect(described_class.ec2?(node)).to be true
end
it 'is false when the node is not on ec2' do
node = {}
expect(described_class.ec2?(node)).to be false
end
end
describe '#gce?' do
it 'is true when the node is on gce' do
node = { 'gce' => nil }
expect(described_class.gce?(node)).to be true
end
it 'is false when the node is not on gce' do
node = {}
expect(described_class.gce?(node)).to be false
end
end
describe '#rackspace?' do
it 'is true when the node is on rackspace' do
node = { 'rackspace' => nil }
expect(described_class.rackspace?(node)).to be true
end
it 'is false when the node is not on rackspace' do
node = {}
expect(described_class.rackspace?(node)).to be false
end
end
describe '#eucalyptus?' do
it 'is true when the node is on eucalyptus' do
node = { 'eucalyptus' => nil }
expect(described_class.eucalyptus?(node)).to be true
end
it 'is false when the node is not on eucalyptus' do
node = {}
expect(described_class.eucalyptus?(node)).to be false
end
end
describe '#euca?' do
it 'is true when the node is on eucalyptus' do
node = { 'eucalyptus' => nil }
expect(described_class.euca?(node)).to be true
end
it 'is false when the node is not on eucalyptus' do
node = {}
expect(described_class.euca?(node)).to be false
end
end
describe '#linode?' do
it 'is true when the node is on linode' do
node = { 'linode' => nil }
expect(described_class.linode?(node)).to be true
end
it 'is false when the node is not on linode' do
node = {}
expect(described_class.linode?(node)).to be false
end
end
describe '#openstack?' do
it 'is true when the node is on openstack' do
node = { 'openstack' => nil }
expect(described_class.openstack?(node)).to be true
end
it 'is false when the node is not on openstack' do
node = {}
expect(described_class.openstack?(node)).to be false
end
end
describe '#cloudstack?' do
it 'is true when the node is on cloudstack' do
node = { 'cloudstack' => nil }
expect(described_class.cloudstack?(node)).to be true
end
it 'is false when the node is not on cloudstack' do
node = {}
expect(described_class.cloudstack?(node)).to be false
end
end
describe '#azure?' do
it 'is true when the node is on azure' do
node = { 'azure' => nil }
expect(described_class.azure?(node)).to be true
end
it 'is false when the node is not on azure' do
node = {}
expect(described_class.azure?(node)).to be false
end
end
describe '#digitalocean?' do
it 'is true when the node is on digitalocean' do
node = { 'digital_ocean' => nil }
expect(described_class.digitalocean?(node)).to be true
end
it 'is false when the node is not on digitalocean' do
node = {}
expect(described_class.digitalocean?(node)).to be false
end
end
describe '#softlayer?' do
it 'is true when the node is on softlayer' do
node = { 'softlayer' => nil }
expect(described_class.softlayer?(node)).to be true
end
it 'is false when the node is not on softlayer' do
node = {}
expect(described_class.softlayer?(node)).to be false
end
end
end

View File

@ -0,0 +1,45 @@
require 'spec_helper'
describe Chef::Sugar::Constraints do
describe '#version' do
let(:version) { described_class.version('1.2.3') }
it 'returns a new version object' do
expect(version).to be_a(Chef::Sugar::Constraints::Version)
end
it 'behaves like a String' do
expect(version).to be_a(String)
end
it 'returns true with the version is satisifed' do
expect(version).to be_satisfies('~> 1.2.0')
end
it 'returns false when the version is not satisfed' do
expect(version).to_not be_satisfies('~> 2.0.0')
end
end
describe '#constraint' do
let(:constraint) { described_class.constraint('~> 1.2.0') }
it 'returns a new constraint object' do
expect(constraint).to be_a(Chef::Sugar::Constraints::Constraint)
end
it 'returns true when the constraint is satisfied' do
expect(constraint).to be_satisfied_by('1.2.3')
end
it 'returns false when the constraint is not satisfied' do
expect(constraint).to_not be_satisfied_by('2.0.0')
end
end
describe '#chef_version' do
it 'is a DSL method' do
expect(Chef::Sugar::DSL).to be_method_defined(:chef_version)
end
end
end

View File

@ -0,0 +1,10 @@
require 'spec_helper'
require 'chef/sugar/core_extensions'
describe Array do
describe '#satisfied_by?' do
it 'includes the method' do
expect(described_class).to be_method_defined(:satisfied_by?)
end
end
end

View File

@ -0,0 +1,62 @@
require 'spec_helper'
require 'chef/sugar/core_extensions'
describe Object do
describe '#blank?' do
it 'includes the method' do
expect(described_class).to be_method_defined(:blank?)
end
it 'returns true for nil' do
expect(nil).to be_blank
end
it 'returns true for false' do
expect(false).to be_blank
end
it 'returns true for the empty string' do
expect('').to be_blank
end
it 'returns true for the empty array' do
expect([]).to be_blank
end
it 'returns true for the empty hash' do
expect({}).to be_blank
end
it 'returns false for a non-empty string' do
expect(' ').to_not be_blank
end
it 'returns false for a non-empty string with unicode' do
expect("\u00a0").to_not be_blank
end
it 'returns false for a non-empty string with special characters' do
expect("\n\t").to_not be_blank
end
it 'returns false for any object' do
expect(Object.new).to_not be_blank
end
it 'returns false for true' do
expect(true).to_not be_blank
end
it 'returns false for a fixnum' do
expect(1).to_not be_blank
end
it 'returns false for an array with items' do
expect(['foo']).to_not be_blank
end
it 'returns false for an array with items' do
expect({'foo' => 'bar'}).to_not be_blank
end
end
end

View File

@ -0,0 +1,48 @@
require 'spec_helper'
require 'chef/sugar/core_extensions'
describe String do
describe '#satisfies?' do
it 'includes the method' do
expect(described_class).to be_method_defined(:satisfies?)
end
end
describe '#satisfied_by?' do
it 'includes the method' do
expect(described_class).to be_method_defined(:satisfied_by?)
end
end
describe '#flush' do
context 'when given a single-line string' do
it 'strips trailing whitespace' do
string = <<-EOH
This is a string
EOH
expect(string.flush).to eq('This is a string')
end
end
context 'when given a multi-line string' do
it 'removes the leading number of whitespaces' do
string = <<-EOH
def method
"This is a string!"
end
EOH
expect(string.flush).to eq(%Q(def method\n "This is a string!"\nend))
end
it 'leaves a newline when given' do
string = <<-EOH
def method
"This is a string!"
end
EOH
expect(string.flush).to eq(%Q(def method\n "This is a string!"\nend\n))
end
end
end
end

View File

@ -0,0 +1,118 @@
require 'spec_helper'
describe Chef::Sugar::DataBag do
describe '#encrypted_data_bag_item' do
before { allow(Chef::EncryptedDataBagItem).to receive(:load) }
it 'loads the encrypted data bag item' do
expect(Chef::EncryptedDataBagItem).to receive(:load)
.with('accounts', 'github', 'secret_key')
described_class.encrypted_data_bag_item('accounts', 'github', 'secret_key')
end
context 'when Chef::Config is set' do
it 'loads the secret key from the Chef::Config' do
allow(Chef::Config).to receive(:[]).with(:encrypted_data_bag_secret).and_return('/data/path')
allow(File).to receive(:read).with('/data/path').and_return('B@c0n')
expect(Chef::EncryptedDataBagItem).to receive(:load)
.with('accounts', 'github', 'B@c0n')
described_class.encrypted_data_bag_item('accounts', 'github')
end
end
context 'when Chef::Config is not set and no value is given' do
it 'raises an exception' do
expect {
described_class.encrypted_data_bag_item('accounts', 'github')
}.to raise_error(Chef::Sugar::DataBag::EncryptedDataBagSecretNotGiven)
end
end
end
describe '#encrypted_data_bag_item_for_environment' do
let(:node) { double(:node, chef_environment: 'production') }
context 'when the environment exists' do
it 'loads the data from the environment' do
allow(Chef::EncryptedDataBagItem).to receive(:load).and_return(
'production' => {
'username' => 'sethvargo',
'password' => 'bacon',
}
)
expect(described_class.encrypted_data_bag_item_for_environment(node, 'accounts', 'github', 'secret_key')).to eq(
'password' => 'bacon',
'username' => 'sethvargo',
)
end
end
context 'when the environment does not exist' do
it 'loads the data from the default bucket' do
allow(Chef::EncryptedDataBagItem).to receive(:load).and_return(
'staging' => {
'username' => 'sethvargo',
'password' => 'bacon',
},
'default' => {
'username' => 'schisamo',
'password' => 'ham',
}
)
expect(described_class.encrypted_data_bag_item_for_environment(node, 'accounts', 'github', 'secret_key')).to eq(
'password' => 'ham',
'username' => 'schisamo',
)
end
end
end
describe '#data_bag_item_for_environment' do
let(:node) { double(:node, chef_environment: 'production') }
context 'when the environment exists' do
it 'loads the data from the environment' do
allow(Chef::DataBagItem).to receive(:load).and_return(
'production' => {
'username' => 'sethvargo',
'comment' => 'loves bacon',
},
'default' => {
'username' => 'schisamo',
'comment' => 'more of a ham guy',
}
)
expect(described_class.data_bag_item_for_environment(node, 'accounts', 'github')).to eq(
'comment' => 'loves bacon',
'username' => 'sethvargo',
)
end
end
context 'when the environment does not exist' do
it 'loads the data from the default bucket' do
allow(Chef::DataBagItem).to receive(:load).and_return(
'staging' => {
'username' => 'sethvargo',
'comment' => 'loves bacon',
},
'default' => {
'username' => 'schisamo',
'comment' => 'more of a ham guy',
}
)
expect(described_class.data_bag_item_for_environment(node, 'accounts', 'github')).to eq(
'comment' => 'more of a ham guy',
'username' => 'schisamo',
)
end
end
end
end

View File

@ -0,0 +1,70 @@
require 'spec_helper'
describe Chef::Sugar::Init do
it_behaves_like 'a chef sugar'
before(:each) do
allow(IO).to receive(:read)
.with("/proc/1/comm")
.and_return("init")
allow(File).to receive(:executable?)
.with("/sbin/initctl")
.and_return(false)
allow(File).to receive(:executable?)
.with("/sbin/runit-init")
.and_return(false)
end
describe '#systemd?' do
systemctl_path = '/bin/systemctl'
it "is true when #{systemctl_path} exists" do
allow(File).to receive(:exist?)
.with(systemctl_path)
.and_return(true)
node = {}
expect(described_class.systemd?(node)).to be true
end
it "is false when #{systemctl_path} does not exist" do
allow(File).to receive(:exist?)
.with(systemctl_path)
.and_return(false)
node = {}
expect(described_class.systemd?(node)).to be false
end
end
describe '#upstart?' do
it 'is true when /sbin/initctl is executable' do
allow(File).to receive(:executable?)
.with("/sbin/initctl")
.and_return(true)
node = {}
expect(described_class.upstart?(node)).to be true
end
it 'is false when /sbin/initctl is not executable' do
node = {}
expect(described_class.upstart?(node)).to be false
end
end
describe '#runit?' do
it 'is true when /sbin/runit-init is executable' do
allow(File).to receive(:executable?)
.with("/sbin/runit-init")
.and_return(true)
node = {}
expect(described_class.runit?(node)).to be true
end
it 'is false when /sbin/runit-init is not executable' do
node = {}
expect(described_class.runit?(node)).to be false
end
end
end

View File

@ -0,0 +1,53 @@
require 'spec_helper'
describe Chef::Sugar::IP do
it_behaves_like 'a chef sugar'
let(:node) { { 'ipaddress' => '1.2.3.4' } }
let(:other) { { 'ipaddress' => '5.6.7.8' } }
context 'when not on a cloud' do
it 'returns the default IP address' do
expect(described_class.best_ip_for(node, other)).to eq(other['ipaddress'])
end
end
context 'when the target is on the cloud' do
before do
other['cloud'] = {}
other['cloud']['provider'] = 'ec2'
other['cloud']['local_ipv4'] = '9.10.11.12'
other['cloud']['public_ipv4'] = '13.14.15.16'
node['cloud'] = nil
end
context 'when the current node is not on the cloud' do
it 'uses the public ipv4' do
expect(described_class.best_ip_for(node, other)).to eq('13.14.15.16')
end
end
context 'when the current node is on a different cloud' do
before do
node['cloud'] = {}
node['cloud']['provider'] = 'rackspace'
end
it 'uses the public ipv4' do
expect(described_class.best_ip_for(node, other)).to eq('13.14.15.16')
end
end
context 'when the current node is on the same cloud' do
before do
node['cloud'] = {}
node['cloud']['provider'] = 'ec2'
end
it 'uses the local ipv4' do
expect(described_class.best_ip_for(node, other)).to eq('9.10.11.12')
end
end
end
end

View File

@ -0,0 +1,16 @@
require 'spec_helper'
describe Chef::Sugar::Kernel do
describe '.require_chef_gem' do
it 'raises an exception when the gem is not installed' do
expect {
described_class.require_chef_gem('bacon')
}.to raise_error(Chef::Sugar::Kernel::ChefGemLoadError)
end
it 'loads the gem' do
allow(Chef::Sugar::Kernel).to receive(:require).and_return(true)
expect(described_class.require_chef_gem('bacon')).to be true
end
end
end

View File

@ -0,0 +1,172 @@
require 'spec_helper'
describe Chef::Node do
describe '#in?' do
it 'returns true when the node is in the environment' do
allow(subject).to receive(:chef_environment).and_return('production')
expect(subject.in?('production')).to be true
expect(subject.in?(/production$/)).to be true
end
it 'returns false when the node is not in the environment' do
allow(subject).to receive(:chef_environment).and_return('staging')
expect(subject.in?('production')).to be false
expect(subject.in?(/production$/)).to be false
end
end
describe '#deep_fetch' do
let(:node) { described_class.new }
before { node.default['apache2']['config']['root'] = '/var/www' }
it 'fetches a deeply nested attribute' do
expect(node.deep_fetch('apache2', 'config', 'root')).to eq('/var/www')
end
it 'ignores symbols, strings, etc' do
expect(node.deep_fetch(:apache2, :config, :root)).to eq('/var/www')
end
it 'safely returns nil if a key does not exist' do
expect(node.deep_fetch(:apache2, :not_real, :nested, :yup)).to be_nil
end
end
describe '#deep_fetch!' do
let(:node) { described_class.new }
before { node.default['apache2']['config']['root'] = '/var/www' }
it 'fetches a deeply nested attribute' do
expect(node.deep_fetch!('apache2', 'config', 'root')).to eq('/var/www')
end
it 'ignores symbols, strings, etc' do
expect(node.deep_fetch!(:apache2, :config, :root)).to eq('/var/www')
end
it 'raises an error if a key does not exist' do
expect {
node.deep_fetch!(:apache2, :not_real)
}.to raise_error(Chef::Node::AttributeDoesNotExistError) { |e|
expect(e.message).to eq(<<-EOH.gsub(/^ {10}/, ''))
No attribute `node['apache2']['not_real']' exists on
the current node. Specifically the `not_real' attribute is not
defined. Please make sure you have spelled everything correctly.
EOH
}
end
end
describe '#namespace' do
let(:node) { described_class.new }
it 'defines the attributes' do
node.instance_eval do
namespace 'apache2' do
namespace 'config' do
root '/var/www'
end
end
end
expect(node.default).to eq({
'apache2' => {
'config' => { 'root' => '/var/www' }
}
})
end
it 'accepts multiple attributes' do
node.instance_eval do
namespace 'apache2', 'config' do
root '/var/www'
end
end
expect(node.default).to eq({
'apache2' => {
'config' => { 'root' => '/var/www' }
}
})
end
it 'accepts attribute precedence levels' do
node.instance_eval do
namespace 'apache2', precedence: normal do
namespace 'config', precedence: override do
root '/var/www'
end
end
end
expect(node.override).to eq({
'apache2' => {
'config' => { 'root' => '/var/www' }
}
})
end
it 'maintains precedence level into nested calls' do
node.instance_eval do
namespace 'apache2', precedence: override do
namespace 'config' do
root '/var/www'
end
end
end
expect(node.override).to eq({
'apache2' => {
'config' => { 'root' => '/var/www' }
}
})
end
it 'resets precedence to default in subsequent non-nested calls' do
node.instance_eval do
namespace 'apache2', precedence: override do
namespace 'config' do
root '/var/www'
end
end
namespace 'php' do
version '5.3'
end
end
expect(node.override).to eq({
'apache2' => {
'config' => { 'root' => '/var/www' }
}
})
expect(node.default).to eq({
'php' => {
'version' => '5.3'
}
})
end
it 'can access attributes within itself' do
node.instance_eval do
namespace 'apache2' do
namespace 'config' do
root '/var/www'
ssl File.join(root, 'ssl')
end
end
end
expect(node.default).to eq({
'apache2' => {
'config' => {
'root' => '/var/www',
'ssl' => '/var/www/ssl',
}
}
})
end
end
end

View File

@ -0,0 +1,174 @@
require 'spec_helper'
describe Chef::Sugar::Platform do
it_behaves_like 'a chef sugar'
describe '#platform_version' do
it 'returns the platform version' do
node = { 'platform_version' => '1.2.3' }
expect(described_class.platform_version(node)).to eq('1.2.3')
end
end
context 'dynamic matchers' do
describe '#ubuntu_after_lucid?' do
it 'returns true when the version is later than 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '10.10' }
expect(described_class.ubuntu_after_lucid?(node)).to be true
end
it 'returns false when the version is 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '10.04' }
expect(described_class.ubuntu_after_lucid?(node)).to be false
end
it 'returns false when the version is a patch release higher than 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '10.04.4' }
expect(described_class.ubuntu_after_lucid?(node)).to be false
end
it 'returns false when the version is less than 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '9.10' }
expect(described_class.ubuntu_after_lucid?(node)).to be false
end
end
describe '#ubuntu_after_or_at_lucid?' do
it 'returns true when the version is later than 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '10.10' }
expect(described_class.ubuntu_after_or_at_lucid?(node)).to be true
end
it 'returns true when the version is 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '10.04' }
expect(described_class.ubuntu_after_or_at_lucid?(node)).to be true
end
it 'returns true when the version is a patch release higher than 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '10.04.4' }
expect(described_class.ubuntu_after_or_at_lucid?(node)).to be true
end
it 'returns false when the version is less than 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '9.10' }
expect(described_class.ubuntu_after_or_at_lucid?(node)).to be false
end
end
describe '#ubuntu_lucid?' do
it 'returns false when the version is later than 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '10.10' }
expect(described_class.ubuntu_lucid?(node)).to be false
end
it 'returns true when the version is 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '10.04' }
expect(described_class.ubuntu_lucid?(node)).to be true
end
it 'returns true when the version is a patch release higher than 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '10.04.4' }
expect(described_class.ubuntu_lucid?(node)).to be true
end
it 'returns false when the version is less than 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '9.10' }
expect(described_class.ubuntu_lucid?(node)).to be false
end
end
describe '#ubuntu_before_lucid?' do
it 'returns false when the version is later than 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '10.10' }
expect(described_class.ubuntu_before_lucid?(node)).to be false
end
it 'returns false when the version is 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '10.04' }
expect(described_class.ubuntu_before_lucid?(node)).to be false
end
it 'returns false when the version is a patch release higher than 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '10.04.4' }
expect(described_class.ubuntu_before_lucid?(node)).to be false
end
it 'returns true when the version is less than 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '9.10' }
expect(described_class.ubuntu_before_lucid?(node)).to be true
end
end
describe '#ubuntu_before_or_at_lucid?' do
it 'returns false when the version is later than 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '10.10' }
expect(described_class.ubuntu_before_or_at_lucid?(node)).to be false
end
it 'returns true when the version is 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '10.04' }
expect(described_class.ubuntu_before_or_at_lucid?(node)).to be true
end
it 'returns true when the version is a patch release higher than 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '10.04.4' }
expect(described_class.ubuntu_before_or_at_lucid?(node)).to be true
end
it 'returns true when the version is less than 10.04' do
node = { 'platform' => 'ubuntu', 'platform_version' => '9.10' }
expect(described_class.ubuntu_before_or_at_lucid?(node)).to be true
end
end
describe '#centos_final?' do
it 'returns true when the version is a subset of the major' do
node = { 'platform' => 'centos', 'platform_version' => '6.8' }
expect(described_class.centos_final?(node)).to be true
end
it 'returns false when the version is not the major' do
node = { 'platform' => 'centos', 'platform_version' => '7.4' }
expect(described_class.centos_final?(node)).to be false
end
end
describe '#debian_wheezy?' do
it 'returns true when the version is a subset of the major' do
node = { 'platform' => 'debian', 'platform_version' => '7.1' }
expect(described_class.debian_wheezy?(node)).to be true
end
it 'returns false when the version is not the major' do
node = { 'platform' => 'debian', 'platform_version' => '6.1' }
expect(described_class.debian_wheezy?(node)).to be false
end
end
describe '#debian_before_wheezy?' do
it 'returns true when the version is a less than the major' do
node = { 'platform' => 'debian', 'platform_version' => '6.5' }
expect(described_class.debian_before_wheezy?(node)).to be true
end
it 'returns false when the version is not less than the major' do
node = { 'platform' => 'debian', 'platform_version' => '8.0' }
expect(described_class.debian_before_wheezy?(node)).to be false
end
end
describe '#solaris_10?' do
it 'returns true when the version is 5.10' do
node = { 'platform' => 'solaris2', 'platform_version' => '5.10' }
expect(described_class.solaris_10?(node)).to be true
end
end
describe '#solaris_11?' do
it 'returns true when the version is 5.11' do
node = { 'platform' => 'solaris2', 'platform_version' => '5.11' }
expect(described_class.solaris_11?(node)).to be true
end
end
end
end

View File

@ -0,0 +1,39 @@
require 'spec_helper'
describe Chef::Sugar::Ruby do
it_behaves_like 'a chef sugar'
describe '#ruby_20?' do
it 'returns true when the ruby version is 2.0' do
node = { 'languages' => { 'ruby' => { 'version' => '2.0.0' } } }
expect(described_class.ruby_20?(node)).to be true
end
it 'returns true when the ruby version is less than 2.0' do
node = { 'languages' => { 'ruby' => { 'version' => '1.9.3' } } }
expect(described_class.ruby_20?(node)).to be false
end
it 'returns false when the ruby version is higher than 2.0' do
node = { 'languages' => { 'ruby' => { 'version' => '3.0.0' } } }
expect(described_class.ruby_20?(node)).to be false
end
end
describe '#ruby_19?' do
it 'returns true when the ruby version is 1.9' do
node = { 'languages' => { 'ruby' => { 'version' => '1.9.1' } } }
expect(described_class.ruby_19?(node)).to be true
end
it 'returns true when the ruby version is less than 1.9' do
node = { 'languages' => { 'ruby' => { 'version' => '1.8.7' } } }
expect(described_class.ruby_19?(node)).to be false
end
it 'returns false when the ruby version is higher than 1.9' do
node = { 'languages' => { 'ruby' => { 'version' => '2.0.0' } } }
expect(described_class.ruby_19?(node)).to be false
end
end
end

View File

@ -0,0 +1,19 @@
require 'spec_helper'
describe Chef::Sugar::RunContext do
it_behaves_like 'a chef sugar'
describe '#includes_recipe?' do
let(:node) { double(Chef::Node) }
it 'returns true when the recipe exists' do
allow(node).to receive(:recipe?).and_return(true)
expect(described_class.includes_recipe?(node, 'foo')).to be true
end
it 'returns false when the recipe does not exist' do
allow(node).to receive(:recipe?).and_return(false)
expect(described_class.includes_recipe?(node, 'bar')).to be false
end
end
end

View File

@ -0,0 +1,104 @@
require 'spec_helper'
describe Chef::Sugar::Shell do
describe '#which', :pre_chef16_only do
it 'returns the first executable matching the command' do
allow(File).to receive(:executable?).and_return(false)
allow(File).to receive(:executable?).with('/usr/bin/mongo').and_return(true)
expect(described_class.which('mongo')).to eq('/usr/bin/mongo')
end
it 'returns nil when no command is found' do
allow(File).to receive(:executable?).and_return(false)
expect(described_class.which('node')).to be_nil
end
context 'with an absolute path' do
it 'returns the executable if it exists' do
allow(File).to receive(:executable?).with('/usr/local/bin/bash').and_return(true)
expect(described_class.which('/usr/local/bin/bash')).to eq('/usr/local/bin/bash')
end
it 'returns nil when the file is not executable' do
allow(File).to receive(:executable?).with('/usr/local/bin/bash').and_return(false)
expect(described_class.which('/usr/local/bin/bash')).to be_nil
end
end
end
describe '#dev_null' do
it 'returns NUL on Windows' do
node = { 'platform_family' => 'windows' }
expect(described_class.dev_null(node)).to eq('NUL')
end
it 'returns /dev/null on Linux' do
node = { 'platform_family' => 'debian' }
expect(described_class.dev_null(node)).to eq('/dev/null')
end
end
describe '#installed?' do
it 'returns true if the given binary exists' do
allow(described_class).to receive(:which).and_return(nil)
allow(described_class).to receive(:which).with('mongo').and_return(true)
expect(described_class.installed?('mongo')).to be true
end
it 'returns false if the given binary does not exist' do
allow(described_class).to receive(:which).with('node').and_return(nil)
expect(described_class.installed?('node')).to be false
end
end
describe '#installed_at_version?' do
it 'returns true if the command is installed at the correct version' do
allow(described_class).to receive(:which).and_return(true)
allow(described_class).to receive(:version_for).and_return('1.2.3')
expect(described_class.installed_at_version?('mongo', '1.2.3')).to be true
end
it 'returns true if the command is installed at the correct version and has additional output' do
allow(described_class).to receive(:which).and_return(true)
allow(described_class).to receive(:version_for).and_return('Mongo DB version 1.2.3. Some other text.')
expect(described_class.installed_at_version?('mongo', '1.2.3')).to be true
end
it 'returns true if the command is installed at the correct version with a regex' do
allow(described_class).to receive(:which).and_return(true)
allow(described_class).to receive(:version_for).and_return('1.2.3')
expect(described_class.installed_at_version?('mongo', /1\.2/)).to be true
end
it 'returns false if the command is installed at the wrong version' do
allow(described_class).to receive(:which).and_return(true)
allow(described_class).to receive(:version_for).and_return('1.2.3')
expect(described_class.installed_at_version?('mongo', '4.5.6')).to be false
end
it 'returns false if #version_for is nil' do
allow(described_class).to receive(:which).and_return(true)
allow(described_class).to receive(:version_for).and_return(nil)
expect(described_class.installed_at_version?('mongo', '4.5.6')).to be false
end
it 'returns false if the command is not installed' do
allow(described_class).to receive(:which).and_return(nil)
expect(described_class.installed_at_version?('mongo', '1.0.0')).to be false
end
end
describe '#version_for' do
let(:shell_out) { double('shell_out', run_command: nil, error!: nil, stdout: '1.2.3', stderr: 'Oh no!') }
before { allow(Mixlib::ShellOut).to receive(:new).and_return(shell_out) }
it 'runs the thing in shellout' do
expect(Mixlib::ShellOut).to receive(:new).with('mongo --version')
described_class.version_for('mongo')
end
it 'returns the combined stdout and stderr' do
expect(described_class.version_for('mongo')).to eq("1.2.3\nOh no!")
end
end
end

View File

@ -0,0 +1,37 @@
require 'spec_helper'
describe Chef::Sugar::Vagrant do
it_behaves_like 'a chef sugar'
describe '#vagrant?' do
it 'returns true when the machine is on vagrant' do
node = { 'vagrant' => {} }
expect(described_class.vagrant?(node)).to be true
end
it 'returns true when the domain is vagrantup.com' do
node = { 'domain' => 'bacon.vagrantup.com' }
expect(described_class.vagrant?(node)).to be true
end
it 'returns false when the domain is nil' do
node = { 'domain' => nil }
expect(described_class.vagrant?(node)).to be false
end
it 'returns false when the domain is not vagrantup.com' do
node = { 'domain' => 'sethvargo.com' }
expect(described_class.vagrant?(node)).to be false
end
it 'returns true when the vagrant user exists on the system' do
node = { 'etc' => { 'passwd' => { 'vagrant' => {} } } }
expect(described_class.vagrant?(node)).to be true
end
it 'returns false when the machine is not on vagrant' do
node = {}
expect(described_class.vagrant?(node)).to be false
end
end
end

View File

@ -0,0 +1,135 @@
require 'spec_helper'
describe Chef::Sugar::Virtualization do
it_behaves_like 'a chef sugar'
describe '#kvm?' do
it 'returns true when the machine is under kvm' do
node = { 'virtualization' => { 'system' => 'kvm' } }
expect(described_class.kvm?(node)).to be true
end
it 'returns false when the virtual machine is not under kvm' do
node = { 'virtualization' => { 'system' => 'vbox' } }
expect(described_class.kvm?(node)).to be false
end
it 'returns false when the machine is not virtual' do
node = {}
expect(described_class.kvm?(node)).to be false
end
end
describe '#lxc?' do
it 'returns true when the machine is a linux contianer' do
node = { 'virtualization' => { 'system' => 'lxc' } }
expect(described_class.lxc?(node)).to be true
end
it 'returns false when the virtual machine is not lxc' do
node = { 'virtualization' => { 'system' => 'vbox' } }
expect(described_class.lxc?(node)).to be false
end
it 'returns false when the machine is not virtual' do
node = {}
expect(described_class.lxc?(node)).to be false
end
end
describe '#parallels?' do
it 'returns true when the machine is under parallels' do
node = { 'virtualization' => { 'system' => 'parallels' } }
expect(described_class.parallels?(node)).to be true
end
it 'returns false when the virtual machine is not under parallels' do
node = { 'virtualization' => { 'system' => 'kvm' } }
expect(described_class.parallels?(node)).to be false
end
it 'returns false when the machine is not virtual' do
node = {}
expect(described_class.parallels?(node)).to be false
end
end
describe '#virtualbox?' do
it 'returns true when the machine is under virtualbox' do
node = { 'virtualization' => { 'system' => 'vbox' } }
expect(described_class.virtualbox?(node)).to be true
end
it 'returns false when the virtual machine is not under virtualbox' do
node = { 'virtualization' => { 'system' => 'kvm' } }
expect(described_class.virtualbox?(node)).to be false
end
it 'returns false when the machine is not virtual' do
node = {}
expect(described_class.virtualbox?(node)).to be false
end
end
describe '#vmware?' do
it 'returns true when the machine is under vmware' do
node = { 'virtualization' => { 'system' => 'vmware' } }
expect(described_class.vmware?(node)).to be true
end
it 'returns false when the virtual machine is not under vmware' do
node = { 'virtualization' => { 'system' => 'vbox' } }
expect(described_class.vmware?(node)).to be false
end
it 'returns false when the machine is not virtual' do
node = {}
expect(described_class.vmware?(node)).to be false
end
end
describe '#openvz?' do
it 'returns true when the machine is under openvz' do
node = { 'virtualization' => { 'system' => 'openvz' } }
expect(described_class.openvz?(node)).to be true
end
it 'returns false when the virtual machine is not under openvz' do
node = { 'virtualization' => { 'system' => 'kvm' } }
expect(described_class.openvz?(node)).to be false
end
it 'returns false when the machine is not virtual' do
node = {}
expect(described_class.openvz?(node)).to be false
end
end
describe '#virtual?' do
it 'returns true when the machine is under a supported virtualization provider' do
%w(openvz vmware vbox lxc kvm).each do |host|
node = { 'virtualization' => { 'system' => host } }
expect(described_class.virtual?(node)).to be true
end
end
it 'returns false when the machine is not virtual' do
node = {}
expect(described_class.virtual?(node)).to be false
end
end
describe '#physical?' do
it 'returns false when the machine is under a supported virtualization provider' do
%w(openvz vmware vbox lxc kvm).each do |host|
node = { 'virtualization' => { 'system' => host } }
expect(described_class.physical?(node)).to be false
end
end
it 'returns true when the machine is not virtual' do
node = {}
expect(described_class.physical?(node)).to be true
end
end
end

View File

@ -0,0 +1,9 @@
require 'spec_helper'
describe 'chef-sugar::default' do
let(:chef_run) { ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '16.04').converge(described_recipe) }
it 'converges successfully' do
expect { :chef_run }.to_not raise_error
end
end

View File

@ -0,0 +1,5 @@
config:
ul-indent: false # MD007
line-length: false # MD013
no-duplicate-heading: false # MD024
reference-links-images: false # MD052

View File

@ -0,0 +1,235 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 2.5.0 - *2023-05-16*
- Allow ruby-build to recognize when it needs to be upgraded.
- Allow ruby-build to reinstall Ruby if the version changes.
## 2.4.1 - *2023-05-16*
## 2.4.0 - *2023-05-16*
- Ubuntu 18 now uses 'libssl-dev' instead of 'libssl1.0-dev'
## 2.3.15 - *2023-05-15*
## 2.3.14 - *2023-04-17*
## 2.3.13 - *2023-04-07*
Standardise files with files in sous-chefs/repo-management
## 2.3.12 - *2023-04-01*
## 2.3.11 - *2023-04-01*
## 2.3.10 - *2023-04-01*
Standardise files with files in sous-chefs/repo-management
## 2.3.9 - *2023-03-20*
Standardise files with files in sous-chefs/repo-management
## 2.3.8 - *2023-03-15*
Standardise files with files in sous-chefs/repo-management
Standardise files with files in sous-chefs/repo-management
## 2.3.7 - *2023-02-27*
Standardise files with files in sous-chefs/repo-management
## 2.3.6 - *2023-02-16*
Standardise files with files in sous-chefs/repo-management
## 2.3.5 - *2023-02-14*
Standardise files with files in sous-chefs/repo-management
## 2.3.4 - *2023-02-13*
## 2.3.3 - *2023-02-13*
## 2.3.2 - *2023-02-13*
## 2.3.1 - *2022-12-06*
Standardise files with files in sous-chefs/repo-management
## 2.3.0 - *2022-08-08*
- Add `verbose` option
- Remove Delivery and move to calling RSpec directly via a reusable workflow
- Use reusable workflows
- Update test build to use Ruby 3.0.4
- Add Alma Linux & Rocky Linux / Replace CentOS 8 with CentOS Stream 8
- Standardize kitchen.dokken.yml
- Add support for Ubuntu 22.04
- Remove use of yum-centos and replace with use of yum-config-manager to make it easier to work with Alma/Rocky
- Install openssl@1.1 on MacOS
## 2.2.3 - *2022-05-16*
- Standardise files with files in sous-chefs/repo-management
## 2.2.2 - *2022-02-10*
- Standardise files with files in sous-chefs/repo-management
## 2.2.1 - *2022-02-08*
- Remove delivery folder
## 2.2.0 - *2021-12-27*
- support Chef temporary directory being located on a volume mounted `noexec`
- support Ruby installation directory being created ahead of time
## 2.1.5 - *2021-11-22*
- Retry when cloning the ruby-build code repository
## 2.1.4 - *2021-08-30*
- Standardise files with files in sous-chefs/repo-management
## 2.1.3 - *2021-06-01*
- Standardise files with files in sous-chefs/repo-management
## 2.1.2 - *2020-12-02*
- resolved cookstyle error: libraries/package_deps.rb:8:5 convention: `Layout/EmptyLineBetweenDefs`
## 2.1.1 (2020-09-16)
- resolved cookstyle error: spec/libraries/cruby_spec.rb:6:7 refactor: `ChefCorrectness/IncorrectLibraryInjection`
- Cookstyle Bot Auto Corrections with Cookstyle 6.16.8
## 2.1.0 (2020-06-17)
- Fix package_deps being passed too many arguments
- Fix switching to master when we're already on master
- Add MacOS testing
- fix broken environment property (needs a Hash, was set to String)
- update documentation pages with new custom resource name ruby_build_definition
- make the automatic addition of the Ruby version to the prefix an option
- allow users to use the old ruby_build_ruby resource name, for compatibility
- do not assume that users are running Chef 15.3.x and can use unified_mode
- add requested feature: patch
## 2.0.0 (2020-04-21)
- Remove support for JRuby, it requires an out of support Java version
- Convert to a custom resource
- Move test from bats to Inspec
- Add support for Amazon Linux
- Add support for Ubuntu 18.04
## 1.3.0 (2020-03-05)
- Add debian-10 platform to test kitchen configurations
- Migrate to github actions
- Fix CircleCI testing, bring it up to Sous-Chefs standards
- Fix Markdown
- Fix YAML
- Use platform? helper in the attributes file
- Remove the unnecessary long_description field in metadata.rb
- Fix libgdbm package name in attributes for debian 10
- Fix libgdbm package name in attributes for Ubuntu 19.04
## 1.2.0 (2019-01-23)
- Add debian-10 platform to test kitchen configurations
- Migrate to github actions
- Remove recipes
- Add ruby_build_install resource
- Add ruby_build_definition resource
- Add unit testing
## 1.1.0 (2017-04-07)
- Maintenance of this cookbook has been moved to the Sous Chefs organization - <http://sous-chefs.org/>
- Switched git installation to the git cookbook
- Sped up converge times by using multi-package installs when available
- Added Chefspec matchers
- Removed a duplicate package that was causing warnings on Chef 12 / failures on Chef 13
- Ensured that multi-package installs would continue on Amazon Linux with Chef 13
- Removed some fragile and unnecessary code that checked to see if we were on Chef 12+
- Switched testing to Delivery local mode and removed all test gems from the Gemfile.
- Added a skeleton Chefspec test suite
- Updated to more modern Ruby versions to test with
## 1.0.0 (2016-07-18)
- This cookbook has been moved under the chef-rbenv Github organization to allow for additional committers and further maintenance
- The cookbook now requires Chef 12 due to the use of multi-package installations
- Existing lists of package dependencies have been updated to match those on the ruby-build wiki. This removes several runtime dependencies such as readline, zlib, and subversion
- Added support for installing Rubinius dependencies when installing Rubinius
- Added dependency installation on OS X machines
- Added support for FreeBSD
- Added a dependency on yum-epel when on RHEL
- Added Travis CI integration testing using kitchen-dokken and inspec
- Added cookstyle for Ruby linting and resolved all warnings
- Updated the ruby-build Github URL to the new location
- Switched package dependency logic to use platform_family which supports additional derivative distros
- Add source_url, issues_url, and chef_version metadata to metadata.rb
- Updated the LWRP to use use_inline_resources for proper update notifications
- Added a Chef 11+ style default_action to the LWRP
- Updated attribute file to use default instead of node.set which avoids deprecation warnings
- Updated the Berksfile to use Supermarket
- Updated the Gemfile with the latest testing dependencies
- Added the Apache 2.0 license file
- Updated readme to remove HTML tables that don't render in Supermarket
- Swapped the Rakefile for the standard Chef Rakefile
## 0.8.0 (2013-05-22)
- Pull request [#8]: Remove libyaml-devel pkg dependency for Red Hat family platforms. ([@fnichol])
- Pull request [#9]: Use the HTTPS clone URL. ([@adammck])
- Pull request [#10]: Use old-form notifies to support AWS OpsWorks. ([@tsabat])
- Issue [#7]: Install Git package(s) only if Git is not previously installed. ([@fnichol], [@ChrisLundquist])
- Convert project from Jamie to Test Kitchen. ([@fnichol])
## 0.7.2 (2012-12-31)
- Fix missing package dependencies for C Ruby versions on RHEL family. ([@fnichol])
- Print Ruby build time to :info logger (formerly :debug). ([@fnichol])
- Add integration tests for commonly installed Ruby versions. ([@fnichol])
## 0.7.0 (2012-11-21)
- Add environment attr to ruby_build_ruby. This allows for adding custom compilation flags, as well as newer ruby-build environment variables, such as RUBY_BUILD_MIRROR_URL. ([@fnichol])
- Update foodcritic configuration and update .travis.yml. ([@fnichol])
- Update Installation section of README (welcome Berkshelf). ([@fnichol])
## 0.6.2 (2012-05-03)
- Fix ruby_build_ruby LWRP now notifies when updated (FC017). ([@fnichol])
- Fix Add plaform equivalents in default attrs (FC024). ([@fnichol])
- Fix JRuby requires make package on Ubuntu/Debian. ([@fnichol])
- Ensure `Chef::Config[:file_cache_path]` exists in solo mode. ([@fnichol])
- Add TravisCI to run Foodcritic linter. ([@fnichol])
- Reorganize README with section links. ([@fnichol])
## 0.6.0 (2011-12-10)
The initial release.
[#10]: https://github.com/fnichol/chef-ruby_build/issues/10
[#7]: https://github.com/fnichol/chef-ruby_build/issues/7
[#8]: https://github.com/fnichol/chef-ruby_build/issues/8
[#9]: https://github.com/fnichol/chef-ruby_build/issues/9
[@adammck]: https://github.com/adammck
[@chrislundquist]: https://github.com/ChrisLundquist
[@fnichol]: https://github.com/fnichol
[@tsabat]: https://github.com/tsabat

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,79 @@
# ruby-build Chef Cookbook
[![Cookbook Version](https://img.shields.io/cookbook/v/ruby_build.svg)](https://supermarket.chef.io/cookbooks/ruby_build)
[![OpenCollective](https://opencollective.com/sous-chefs/sponsors/badge.svg)](#sponsors)
[![License](https://img.shields.io/badge/License-Apache%202.0-green.svg)](https://opensource.org/licenses/Apache-2.0)
## Description
Manages the [ruby-build][rb_site] framework and its installed Rubies, through custom resources.
## Maintainers
This cookbook is maintained by the Sous Chefs. The Sous Chefs are a community of Chef cookbook maintainers working together to maintain important cookbooks. If youd like to know more please visit [sous-chefs.org](https://sous-chefs.org/) or come chat with us on the Chef Community Slack in [#sous-chefs](https://chefcommunity.slack.com/messages/C2V7B88SF).
## Usage
It is for use in standalone mode. If you wish to use ruby-build with rbenv, please use the [rbenv cookbook][rbenv-cookbook].
## Requirements
### Chef
- Chef 15+
### Supported Platforms
- Ubuntu 16.04+
- MacOS
- debian 8+
- FreeBSD 9+
- RedHat 6+
## Usage
```ruby
# metadata.rb
depends 'ruby_build'
```
```ruby
# default.rb
ruby_build_install ''
ruby_build_definition '2.6.0'
# build 2.6.0 with a patch that lives in your cookbook's files/default dir
ruby_build_definition '2.6.0' do
patch 'foobar.patch'
end
```
## Resources
- [ruby_build_install](https://github.com/sous-chefs/ruby_build/blob/master/documentation/resources/install.md)
- [ruby_build_definition](https://github.com/sous-chefs/ruby_build/blob/master/documentation/resources/definition.md)
## License and Author
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
```text
http://www.apache.org/licenses/LICENSE-2.0
```
### Sponsors
[rb_site]: https://github.com/rbenv/ruby-build
[rbenv-cookbook]: https://github.com/sous-chefs/ruby_rbenv
![https://opencollective.com/sous-chefs/sponsor/0/website](https://opencollective.com/sous-chefs/sponsor/0/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/1/website](https://opencollective.com/sous-chefs/sponsor/1/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/2/website](https://opencollective.com/sous-chefs/sponsor/2/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/3/website](https://opencollective.com/sous-chefs/sponsor/3/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/4/website](https://opencollective.com/sous-chefs/sponsor/4/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/5/website](https://opencollective.com/sous-chefs/sponsor/5/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/6/website](https://opencollective.com/sous-chefs/sponsor/6/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/7/website](https://opencollective.com/sous-chefs/sponsor/7/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/8/website](https://opencollective.com/sous-chefs/sponsor/8/avatar.svg?avatarHeight=100)
![https://opencollective.com/sous-chefs/sponsor/9/website](https://opencollective.com/sous-chefs/sponsor/9/avatar.svg?avatarHeight=100)

View File

@ -0,0 +1,115 @@
# Put files/directories that should be ignored in this file when uploading
# to a Chef Infra Server or Supermarket.
# Lines that start with '# ' are comments.
# OS generated files #
######################
.DS_Store
ehthumbs.db
Icon?
nohup.out
Thumbs.db
.envrc
# EDITORS #
###########
.#*
.project
.settings
*_flymake
*_flymake.*
*.bak
*.sw[a-z]
*.tmproj
*~
\#*
REVISION
TAGS*
tmtags
.vscode
.editorconfig
## COMPILED ##
##############
*.class
*.com
*.dll
*.exe
*.o
*.pyc
*.so
*/rdoc/
a.out
mkmf.log
# Testing #
###########
.circleci/*
.codeclimate.yml
.delivery/*
.foodcritic
.kitchen*
.mdlrc
.overcommit.yml
.rspec
.rubocop.yml
.travis.yml
.watchr
.yamllint
azure-pipelines.yml
Dangerfile
examples/*
features/*
Guardfile
kitchen*.yml
mlc_config.json
Procfile
Rakefile
spec/*
test/*
# SCM #
#######
.git
.gitattributes
.gitconfig
.github/*
.gitignore
.gitkeep
.gitmodules
.svn
*/.bzr/*
*/.git
*/.hg/*
*/.svn/*
# Berkshelf #
#############
Berksfile
Berksfile.lock
cookbooks/*
tmp
# Bundler #
###########
vendor/*
Gemfile
Gemfile.lock
# Policyfile #
##############
Policyfile.rb
Policyfile.lock.json
# Documentation #
#############
CODE_OF_CONDUCT*
CONTRIBUTING*
documentation/*
TESTING*
UPGRADING*
# Vagrant #
###########
.vagrant
Vagrantfile

View File

@ -0,0 +1,43 @@
class Chef
module Rbenv
module MacOs
def openssl_prefix
`/usr/local/bin/brew --prefix openssl@1.1`.strip!
end
end
module PackageDeps
def cruby_package_deps
case node['platform_family']
when 'rhel', 'fedora', 'amazon'
%w( gcc bzip2 openssl-devel libyaml-devel libffi-devel readline-devel zlib-devel gdbm-devel ncurses-devel make patch )
when 'debian'
case node['platform']
when 'debian'
if node['platform_version'].to_i >= 10
%w( gcc autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm6 libgdbm-dev make patch )
else
%w( gcc autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev make patch )
end
when 'ubuntu'
if node['platform_version'].to_i >= 20
%w( gcc autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm6 libgdbm-dev make patch )
elsif node['platform_version'].to_i == 18
%w( gcc autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm5 libgdbm-dev make patch )
else
%w( gcc autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev make patch )
end
end
when 'suse'
%w( gcc make automake gdbm-devel libyaml-devel ncurses-devel readline-devel zlib-devel libopenssl-devel patch )
when 'mac_os_x'
%w( openssl@1.1 readline )
end
end
def package_deps
cruby_package_deps
end
end
end
end

View File

@ -0,0 +1,48 @@
{
"name": "ruby_build",
"description": "Manages the ruby-build framework and its installed rubies. A LWRP is also defined.",
"long_description": "",
"maintainer": "Sous Chefs",
"maintainer_email": "help@sous-chefs.org",
"license": "Apache-2.0",
"platforms": {
"ubuntu": ">= 0.0.0",
"debian": ">= 0.0.0",
"freebsd": ">= 0.0.0",
"redhat": ">= 0.0.0",
"centos": ">= 0.0.0",
"fedora": ">= 0.0.0",
"amazon": ">= 0.0.0",
"scientific": ">= 0.0.0",
"suse": ">= 0.0.0",
"opensuse": ">= 0.0.0",
"opensuseleap": ">= 0.0.0",
"mac_os_x": ">= 0.0.0"
},
"dependencies": {
"yum-epel": ">= 0.0.0",
"homebrew": ">= 0.0.0"
},
"providing": {
},
"recipes": {
},
"version": "2.5.0",
"source_url": "https://github.com/sous-chefs/ruby_build",
"issues_url": "https://github.com/sous-chefs/ruby_build/issues",
"privacy": false,
"chef_versions": [
[
">= 15.0"
]
],
"ohai_versions": [
],
"gems": [
],
"eager_load_libraries": true
}

View File

@ -0,0 +1,25 @@
name 'ruby_build'
maintainer 'Sous Chefs'
maintainer_email 'help@sous-chefs.org'
license 'Apache-2.0'
description 'Manages the ruby-build framework and its installed rubies. A LWRP is also defined.'
source_url 'https://github.com/sous-chefs/ruby_build'
issues_url 'https://github.com/sous-chefs/ruby_build/issues'
chef_version '>= 15.0'
version '2.5.0'
supports 'ubuntu'
supports 'debian'
supports 'freebsd'
supports 'redhat'
supports 'centos'
supports 'fedora'
supports 'amazon'
supports 'scientific'
supports 'suse'
supports 'opensuse'
supports 'opensuseleap'
supports 'mac_os_x'
depends 'yum-epel'
depends 'homebrew'

View File

@ -0,0 +1,17 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:base"],
"packageRules": [{
"groupName": "Actions",
"matchUpdateTypes": ["patch", "pin", "digest"],
"automerge": true,
"addLabels": ["Release: Patch", "Skip: Announcements"]
},
{
"groupName": "Actions",
"matchUpdateTypes": ["major"],
"automerge": false,
"addLabels": ["Release: Patch", "Skip: Announcements"]
}
]
}

View File

@ -0,0 +1,102 @@
include Chef::Rbenv::MacOs
# for compatibility with earlier incarnations
# of this resource
#
provides :ruby_build_ruby
property :definition, String,
name_property: true,
description: 'Version of Ruby to install'
property :prefix_path, String,
default: '/usr/local/ruby',
description: 'Location to install Ruby'
property :verbose, [true, false],
default: false,
description: 'print compilation status to stdout'
# NOTE: adding the Ruby version to the installation prefix
# by default is unexpected and will likely lead to user
# problems. Now defaults to false.
#
property :version_prefix, [true, false],
default: false,
description: 'add Ruby version to the installation prefix'
property :patch, [String, nil],
description: 'path to a Ruby patch file for ruby-build to use'
property :environment, Hash,
default: {},
description: 'Environment hash to pass to the ruby-build install process'
property :user, String,
description: 'User to install as'
property :group, String,
description: 'Group to install as'
unified_mode true if respond_to? :unified_mode
action :install do
Chef::Log.fatal('JRuby is not a supported definition') \
if new_resource.definition.include? 'jruby'
if platform_family?('mac_os_x') && Chef::VERSION < '16'
Array(package_deps).each do |pkg|
package pkg
end
else
package package_deps
end
installation_path = if new_resource.version_prefix
::File.join(new_resource.prefix_path, new_resource.definition)
else
new_resource.prefix_path
end
env = if platform_family?('mac_os_x')
extra_env = { 'RUBY_CONFIGURE_OPTS' => "--with-openssl-dir=#{openssl_prefix}" }
new_resource.environment.merge extra_env
else
new_resource.environment
end
ruby_build_cmd = [
'/usr/local/bin/ruby-build',
new_resource.definition,
installation_path,
].join(' ')
ruby_build_cmd += ' --verbose' if new_resource.verbose
if new_resource.patch
patch_path = "#{Chef::Config[:file_cache_path]}/#{new_resource.patch}"
ruby_build_cmd += %( --patch < "#{patch_path}" )
cookbook_file patch_path do
source new_resource.patch
end
end
bash "ruby-build #{new_resource.definition}" do
code ruby_build_cmd
environment env
user new_resource.user
group new_resource.group
not_if do
::Dir.exist?("#{installation_path}/bin") &&
new_resource.definition == `#{installation_path}/bin/ruby -e 'print RUBY_VERSION'`
end
live_stream true
action :run
end
end
action_class do
include Chef::Rbenv::PackageDeps
include Chef::Rbenv::MacOs
end

View File

@ -0,0 +1,77 @@
unified_mode true if respond_to? :unified_mode
provides :homebrew_update
description 'Use the **homebrew_update** resource to manage Homebrew repository updates on MacOS.'
introduced '16.2'
examples <<~DOC
**Update the hombrew repository data at a specified interval**:
```ruby
homebrew_update 'all platforms' do
frequency 86400
action :periodic
end
```
**Update the Homebrew repository at the start of a Chef Infra Client run**:
```ruby
homebrew_update 'update'
```
DOC
# allow bare homebrew_update with no name
property :name, String, default: ''
property :frequency, Integer,
description: 'Determines how frequently (in seconds) Homebrew updates are made. Use this property when the `:periodic` action is specified.',
default: 86_400
default_action :periodic
action_class do
BREW_STAMP_DIR = '/var/lib/homebrew/periodic'.freeze
BREW_STAMP = "#{BREW_STAMP_DIR}/update-success-stamp".freeze
# Determines whether we need to run `homebrew update`
#
# @return [Boolean]
def brew_up_to_date?
::File.exist?(BREW_STAMP) &&
::File.mtime(BREW_STAMP) > Time.now - new_resource.frequency
end
def do_update
directory BREW_STAMP_DIR do
recursive true
end
file BREW_STAMP do
content "BREW::Update::Post-Invoke-Success\n"
action :create_if_missing
end
execute 'brew update' do
command %w(brew update)
default_env true
user Homebrew.owner
notifies :touch, "file[#{BREW_STAMP}]", :immediately
end
end
end
action :periodic do
return unless mac_os_x?
unless brew_up_to_date?
converge_by 'update new lists of packages' do
do_update
end
end
end
action :update do
return unless mac_os_x?
converge_by 'force update new lists of packages' do
do_update
end
end

View File

@ -0,0 +1,41 @@
property :name, String, default: ''
property :git_ref, String,
default: 'master',
description: 'Git reference to download, set to a tag to get a specific version'
unified_mode true if respond_to? :unified_mode
action :install do
src_path = "#{Chef::Config['file_cache_path']}/ruby-build"
if platform_family?('rhel')
if node['platform_version'].to_i >= 8
package 'yum-utils'
execute 'yum-config-manager --enable powertools' do
not_if 'yum-config-manager --dump powertools | grep -q "enabled = 1"'
end
end
include_recipe 'yum-epel'
end
package %w(tar bash curl git) unless platform_family?('mac_os_x', 'freebsd')
git src_path do
repository 'https://github.com/rbenv/ruby-build.git'
revision new_resource.git_ref unless new_resource.git_ref == 'master'
retries 5
retry_delay 5
end
execute 'Install ruby-build' do
cwd src_path
command %(sh ./install.sh)
not_if do
::File.exist?('/usr/local/bin/ruby-build') &&
`#{src_path}/bin/ruby-build --version` == `/usr/local/bin/ruby-build --version`
end
end
end

View File

@ -46,7 +46,7 @@
"redisio::default",
"redisio::_install_prereqs",
"redisio::install",
"ulimit::default",
"redisio::ulimit",
"redisio::disable_os_default",
"redisio::configure",
"redisio::enable",
@ -54,21 +54,20 @@
"nodejs::nodejs_from_package",
"nodejs::repo",
"nodejs::npm",
"nodejs::install",
"git::default",
"git::package"
"nodejs::install"
],
"platform": "ubuntu",
"platform_version": "20.04",
"cloud": null,
"chef_packages": {
"chef": {
"version": "15.14.0",
"chef_root": "/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.14.0/lib"
"version": "18.2.7",
"chef_root": "/opt/chef/embedded/lib/ruby/gems/3.1.0/gems/chef-18.2.7/lib",
"chef_effortless": null
},
"ohai": {
"version": "15.12.0",
"ohai_root": "/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/ohai-15.12.0/lib/ohai"
"version": "18.1.4",
"ohai_root": "/opt/chef/embedded/lib/ruby/gems/3.1.0/gems/ohai-18.1.4/lib/ohai"
}
}
},

View File

@ -37,7 +37,6 @@
"kosmos-bitcoin::rtl",
"kosmos-bitcoin::peerswap-lnd",
"kosmos_postgresql::hostsfile",
"kosmos-bitcoin::lndhub",
"kosmos-bitcoin::lndhub-go",
"kosmos-bitcoin::dotnet",
"kosmos-bitcoin::nbxplorer",
@ -71,14 +70,6 @@
"nodejs::nodejs_from_package",
"nodejs::repo",
"firewall::default",
"chef-sugar::default",
"redisio::default",
"redisio::_install_prereqs",
"redisio::install",
"ulimit::default",
"redisio::disable_os_default",
"redisio::configure",
"redisio::enable",
"kosmos-nginx::default",
"nginx::default",
"nginx::package",
@ -95,13 +86,14 @@
"platform_version": "20.04",
"cloud": null,
"chef_packages": {
"ohai": {
"version": "15.12.0",
"ohai_root": "/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/ohai-15.12.0/lib/ohai"
},
"chef": {
"version": "15.13.8",
"chef_root": "/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.13.8/lib"
"version": "18.2.7",
"chef_root": "/opt/chef/embedded/lib/ruby/gems/3.1.0/gems/chef-18.2.7/lib",
"chef_effortless": null
},
"ohai": {
"version": "18.1.4",
"ohai_root": "/opt/chef/embedded/lib/ruby/gems/3.1.0/gems/ohai-18.1.4/lib/ohai"
}
}
},

View File

@ -8,7 +8,7 @@
"automatic": {
"fqdn": "ipfs-1",
"os": "linux",
"os_version": "5.4.0-131-generic",
"os_version": "5.4.0-152-generic",
"hostname": "ipfs-1",
"ipaddress": "192.168.122.195",
"roles": [
@ -39,7 +39,6 @@
"ipfs::default",
"ipfs::_user",
"firewall::default",
"chef-sugar::default",
"kosmos-nodejs::default",
"nodejs::nodejs_from_package",
"nodejs::repo",
@ -50,12 +49,13 @@
"cloud": null,
"chef_packages": {
"chef": {
"version": "15.14.0",
"chef_root": "/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.14.0/lib"
"version": "18.2.7",
"chef_root": "/opt/chef/embedded/lib/ruby/gems/3.1.0/gems/chef-18.2.7/lib",
"chef_effortless": null
},
"ohai": {
"version": "15.12.0",
"ohai_root": "/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/ohai-15.12.0/lib/ohai"
"version": "18.1.4",
"ohai_root": "/opt/chef/embedded/lib/ruby/gems/3.1.0/gems/ohai-18.1.4/lib/ohai"
}
}
},

View File

@ -45,9 +45,6 @@
"postfix::sasl_auth",
"hostname::default",
"firewall::default",
"chef-sugar::default",
"git::default",
"git::package",
"kosmos-nodejs::default",
"nodejs::nodejs_from_package",
"nodejs::repo",
@ -60,7 +57,7 @@
"redisio::default",
"redisio::_install_prereqs",
"redisio::install",
"ulimit::default",
"redisio::ulimit",
"redisio::disable_os_default",
"redisio::configure",
"redisio::enable",
@ -73,13 +70,14 @@
"platform_version": "20.04",
"cloud": null,
"chef_packages": {
"ohai": {
"version": "15.12.0",
"ohai_root": "/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/ohai-15.12.0/lib/ohai"
},
"chef": {
"version": "15.17.4",
"chef_root": "/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.17.4/lib"
"version": "18.2.7",
"chef_root": "/opt/chef/embedded/lib/ruby/gems/3.1.0/gems/chef-18.2.7/lib",
"chef_effortless": null
},
"ohai": {
"version": "18.1.4",
"ohai_root": "/opt/chef/embedded/lib/ruby/gems/3.1.0/gems/ohai-18.1.4/lib/ohai"
}
}
},

View File

@ -8,7 +8,7 @@
"automatic": {
"fqdn": "nodejs-4",
"os": "linux",
"os_version": "5.4.0-1058-kvm",
"os_version": "5.4.0-1089-kvm",
"hostname": "nodejs-4",
"ipaddress": "192.168.122.106",
"roles": [
@ -47,7 +47,7 @@
"redisio::default",
"redisio::_install_prereqs",
"redisio::install",
"ulimit::default",
"redisio::ulimit",
"redisio::disable_os_default",
"redisio::configure",
"redisio::enable",
@ -75,13 +75,14 @@
"platform_version": "20.04",
"cloud": null,
"chef_packages": {
"ohai": {
"version": "15.12.0",
"ohai_root": "/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/ohai-15.12.0/lib/ohai"
},
"chef": {
"version": "15.17.4",
"chef_root": "/opt/chef/embedded/lib/ruby/gems/2.6.0/gems/chef-15.17.4/lib"
"version": "18.2.7",
"chef_root": "/opt/chef/embedded/lib/ruby/gems/3.1.0/gems/chef-18.2.7/lib",
"chef_effortless": null
},
"ohai": {
"version": "18.1.4",
"ohai_root": "/opt/chef/embedded/lib/ruby/gems/3.1.0/gems/ohai-18.1.4/lib/ohai"
}
}
},

View File

@ -2,6 +2,5 @@ name "lndhub"
run_list %w(
role[postgresql_client]
kosmos-bitcoin::lndhub
kosmos-bitcoin::lndhub-go
)

View File

@ -5,12 +5,13 @@
apt_package 'postgresql-client-12'
build_essential 'backup gem'
package ['libxml2-dev', 'libcurl4-gnutls-dev']
# Don't try to install packages on older Ubuntu, the repositories are 404
package ["ruby", "ruby-dev", "zlib1g-dev"] if node[:platform_version].to_f >= 16.04
gem_package 'backup' do
version '5.0.0.beta.2'
version '5.0.0.beta.3'
end
smtp_credentials = Chef::EncryptedDataBagItem.load('credentials', 'smtp')

View File

@ -5,15 +5,13 @@ license 'MIT'
description 'Installs/configures kosmos-akkounts'
long_description 'Installs/configures kosmos-akkounts'
version '0.2.0'
chef_version '>= 14.0'
chef_version '>= 18.0'
depends 'kosmos-nginx'
depends "kosmos-nodejs"
depends "redisio"
depends "poise-ruby-build"
depends "application"
depends 'application_git'
depends "postgresql"
depends "kosmos_postgresql"
depends "backup"
depends "kosmos-dirsrv"
depends "ruby_build"

View File

@ -30,9 +30,15 @@ npm_package "yarn" do
end
ruby_version = "2.7.5"
bundle_path = "/opt/ruby_build/builds/#{ruby_version}/bin/bundle"
ruby_path = "/opt/ruby_build/builds/#{ruby_version}"
bundle_path = "#{ruby_path}/bin/bundle"
rails_env = node.chef_environment == "development" ? "development" : "production"
ruby_build_install 'v20230615'
ruby_build_definition ruby_version do
prefix_path ruby_path
end
postgres_readonly_host = search(:node, "role:postgresql_replica").first["knife_zero"]["host"] rescue nil
btcpay_host = search(:node, "role:btcpay").first["knife_zero"]["host"] rescue nil
lndhub_host = search(:node, "role:lndhub").first["knife_zero"]["host"] rescue nil
@ -152,7 +158,7 @@ systemd_unit "akkounts-sidekiq.service" do
User: deploy_user,
WorkingDirectory: deploy_path,
Environment: "MALLOC_ARENA_MAX=2",
ExecStart: "#{bundle_path} exec sidekiq -C #{deploy_path}/config/sidekiq.yml -e production",
ExecStart: "#{bundle_path} exec sidekiq -C #{deploy_path}/config/sidekiq.yml -e #{rails_env}",
WatchdogSec: "10",
Restart: "on-failure",
RestartSec: "1",
@ -169,84 +175,83 @@ systemd_unit "akkounts-sidekiq.service" do
action [:create, :enable]
end
application deploy_path do
deploy_env = {
"HOME" => deploy_path,
"PATH" => "#{ruby_path}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin",
"RAILS_ENV" => rails_env,
"NODE_ENV" => rails_env
}
git deploy_path do
repository node[app_name]["repo"]
revision node[app_name]["revision"]
user deploy_user
group deploy_group
# Restart services on deployments
notifies :run, "execute[restart #{app_name} services]", :delayed
end
execute "restart #{app_name} services" do
command "true"
action :nothing
notifies :restart, "service[#{app_name}]", :delayed
notifies :restart, "service[#{app_name}-sidekiq]", :delayed
end
file "#{deploy_path}/config/master.key" do
content credentials['rails_master_key']
mode '0400'
owner deploy_user
group deploy_group
notifies :run, "execute[restart #{app_name} services]", :delayed
end
# Take care of application restarts manually, in the git resource
action_on_update false
template "#{deploy_path}/.env.#{rails_env}" do
source 'env.erb'
owner deploy_user
group deploy_group
mode 0600
sensitive true
variables config: env
notifies :run, "execute[restart #{app_name} services]", :delayed
end
environment "HOME" => deploy_path,
"PATH" => "/opt/ruby_build/builds/#{ruby_version}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
execute "bundle install" do
environment deploy_env
user deploy_user
cwd deploy_path
command "bundle install --without development,test --deployment"
end
ruby_runtime ruby_version do
provider :ruby_build
version ruby_version
end
execute "yarn install" do
environment deploy_env
user deploy_user
cwd deploy_path
command "yarn install --pure-lockfile"
end
git do
user deploy_user
group deploy_group
repository node[app_name]["repo"]
revision node[app_name]["revision"]
# Restart services on deployments
notifies :restart, "application[#{deploy_path}]", :delayed
end
execute 'rake db:migrate' do
environment deploy_env
user deploy_user
group deploy_group
cwd deploy_path
command "bundle exec rake db:migrate"
end
file "#{deploy_path}/config/master.key" do
content credentials['rails_master_key']
mode '0400'
owner deploy_user
group deploy_group
end
execute 'rake assets:precompile' do
environment deploy_env
user deploy_user
group deploy_group
cwd deploy_path
command "bundle exec rake assets:precompile"
end
template "#{deploy_path}/.env.production" do
source 'env.production.erb'
owner deploy_user
group deploy_group
mode 0600
sensitive true
variables config: env
notifies :restart, "application[#{deploy_path}]", :delayed
end
service "akkounts" do
action [:enable, :start]
end
execute "bundle install" do
environment "HOME" => deploy_path
user deploy_user
cwd deploy_path
command "/opt/ruby_build/builds/#{ruby_version}/bin/bundle install --without development,test --deployment"
end
execute "yarn install" do
environment "HOME" => deploy_path, "NODE_ENV" => "production"
user deploy_user
cwd deploy_path
command "yarn install --pure-lockfile"
end
execute 'rake db:migrate' do
environment "RAILS_ENV" => rails_env, "HOME" => deploy_path
user deploy_user
group deploy_group
cwd deploy_path
command "PATH=\"/opt/ruby_build/builds/#{ruby_version}/bin:$PATH\" bundle exec rake db:migrate"
end
execute 'rake assets:precompile' do
environment "RAILS_ENV" => rails_env, "HOME" => deploy_path
user deploy_user
group deploy_group
cwd deploy_path
command "PATH=\"/opt/ruby_build/builds/#{ruby_version}/bin:$PATH\" bundle exec rake assets:precompile"
end
service "akkounts" do
action [:enable, :start]
end
service "akkounts-sidekiq" do
action [:enable, :start]
end
service "akkounts-sidekiq" do
action [:enable, :start]
end
firewall_rule "akkounts_zerotier" do

View File

@ -74,13 +74,8 @@ node.default['rtl']['revision'] = 'v0.12.1'
node.default['rtl']['host'] = '10.1.1.163'
node.default['rtl']['port'] = '3000'
node.default['lndhub']['repo'] = 'https://gitea.kosmos.org/kosmos/lndhub.git'
node.default['lndhub']['revision'] = 'master'
node.default['lndhub']['port'] = '3023'
node.default['lndhub']['domain'] = 'lndhub.kosmos.org'
node.default['lndhub-go']['repo'] = 'https://github.com/getAlby/lndhub.go.git'
node.default['lndhub-go']['revision'] = '0.12.0'
node.default['lndhub-go']['revision'] = '0.14.0'
node.default['lndhub-go']['source_dir'] = '/opt/lndhub-go'
node.default['lndhub-go']['port'] = 3026
node.default['lndhub-go']['domain'] = 'lndhub.kosmos.org'

View File

@ -7,7 +7,6 @@ long_description 'Installs/configures bitcoin-related software'
version '0.1.0'
chef_version '>= 14.0'
depends 'application_javascript'
depends 'ark'
depends 'backup'
depends 'firewall'

View File

@ -1,96 +0,0 @@
#
# Cookbook:: kosmos-bitcoin
# Recipe:: lndhub
#
include_recipe 'redisio::default'
include_recipe 'redisio::enable'
app_name = "lndhub"
app_dir = "/opt/#{app_name}"
lnd_dir = node['lnd']['lnd_dir']
bitcoin_user = node['bitcoin']['username']
bitcoin_group = node['bitcoin']['usergroup']
application app_dir do
owner bitcoin_user
group bitcoin_group
git do
user bitcoin_user
group bitcoin_group
repository node['lndhub']['repo']
revision node['lndhub']['revision']
notifies :restart, "systemd_unit[lndhub.service]", :delayed
end
npm_install do
user bitcoin_user
end
link "#{app_dir}/admin.macaroon" do
to "#{lnd_dir}/data/chain/bitcoin/mainnet/admin.macaroon"
owner bitcoin_user
group bitcoin_group
end
link "#{app_dir}/tls.cert" do
to "#{lnd_dir}/tls.cert"
owner bitcoin_user
group bitcoin_group
end
template "#{app_dir}/config.js" do
source "lndhub.config.js.erb"
owner bitcoin_user
group bitcoin_group
mode '0600'
variables lnd_rpc_host: '127.0.0.1:10009'
notifies :restart, "systemd_unit[lndhub.service]", :delayed
end
systemd_unit 'lndhub.service' do
content({
Unit: {
Description: 'LND Hub',
Documentation: ['https://github.com/BlueWallet/LndHub'],
Requires: 'lnd.service',
After: 'lnd.service'
},
Service: {
User: bitcoin_user,
Group: bitcoin_group,
Type: 'simple',
Environment: "PORT=#{node['lndhub']['port']}",
WorkingDirectory: app_dir,
ExecStart: "/usr/bin/npm start",
Restart: 'always',
RestartSec: '30',
TimeoutSec: '120',
PrivateTmp: true,
ProtectSystem: 'full',
NoNewPrivileges: true,
PrivateDevices: true,
},
Install: {
WantedBy: 'multi-user.target'
}
})
verify false
triggers_reload true
action [:create, :enable, :start]
end
end
include_recipe 'firewall'
firewall_rule 'lndhub_private' do
port node['lndhub']['port'].to_i
source "10.1.1.0/24"
protocol :tcp
command :allow
end
return if node.chef_environment == "development"
node.override["backup"]["archives"]["lndhub"] = ["/var/lib/redis/dump-6379.rdb"]
include_recipe "backup"

View File

@ -51,60 +51,57 @@ if node['boltz']
rtl_config[:nodes][0][:Settings][:boltzServerUrl] = "https://#{node['boltz']['rest_host']}:#{node['boltz']['rest_port']}"
end
application rtl_dir do
git rtl_dir do
user bitcoin_user
group bitcoin_group
repository node['rtl']['repo']
revision node['rtl']['revision']
notifies :restart, "systemd_unit[#{app_name}.service]", :delayed
end
execute "npm install" do
cwd rtl_dir
environment "HOME" => rtl_dir
user bitcoin_user
end
file "#{rtl_dir}/RTL-Config.json" do
owner bitcoin_user
group bitcoin_group
mode '0640'
content rtl_config.to_json
notifies :restart, "systemd_unit[#{app_name}.service]", :delayed
end
git do
user bitcoin_user
group bitcoin_group
repository node['rtl']['repo']
revision node['rtl']['revision']
notifies :restart, "systemd_unit[rtl.service]", :delayed
end
npm_install do
user bitcoin_user
end
file "#{rtl_dir}/RTL-Config.json" do
owner bitcoin_user
group bitcoin_group
mode '0640'
content rtl_config.to_json
notifies :restart, "systemd_unit[rtl.service]", :delayed
end
systemd_unit 'rtl.service' do
content({
Unit: {
Description: 'Ride The Lightning',
Documentation: ['https://github.com/Ride-The-Lightning/RTL'],
Requires: 'lnd.service',
After: 'lnd.service'
},
Service: {
User: bitcoin_user,
Group: bitcoin_group,
Type: 'simple',
# ExecStartPre: '/bin/sleep 120',
ExecStart: "/usr/bin/node #{rtl_dir}/rtl.js",
Restart: 'always',
RestartSec: '30',
TimeoutSec: '120',
PrivateTmp: true,
ProtectSystem: 'full',
NoNewPrivileges: true,
PrivateDevices: true,
},
Install: {
WantedBy: 'multi-user.target'
}
})
verify false
triggers_reload true
action [:create, :enable, :start]
end
systemd_unit "#{app_name}.service" do
content({
Unit: {
Description: 'Ride The Lightning',
Documentation: ['https://github.com/Ride-The-Lightning/RTL'],
Requires: 'lnd.service',
After: 'lnd.service'
},
Service: {
User: bitcoin_user,
Group: bitcoin_group,
Type: 'simple',
# ExecStartPre: '/bin/sleep 120',
ExecStart: "/usr/bin/node #{rtl_dir}/rtl.js",
Restart: 'always',
RestartSec: '30',
TimeoutSec: '120',
PrivateTmp: true,
ProtectSystem: 'full',
NoNewPrivileges: true,
PrivateDevices: true,
},
Install: {
WantedBy: 'multi-user.target'
}
})
verify false
triggers_reload true
action [:create, :enable, :start]
end
include_recipe 'firewall'

View File

@ -10,6 +10,5 @@ depends 'kosmos-base'
depends 'kosmos-nodejs'
depends 'kosmos-ipfs'
depends 'firewall'
depends 'application_javascript'
depends 'git'
depends 'redisio'

View File

@ -18,85 +18,86 @@ include_recipe "kosmos-hubot::_user"
include_recipe "kosmos-hubot::_nodejs"
include_recipe "kosmos-base::firewall"
application app_path do
credentials = Chef::EncryptedDataBagItem.load('credentials', app_name)
credentials = Chef::EncryptedDataBagItem.load('credentials', app_name)
git app_path do
user app_user
group app_group
repository "https://gitea.kosmos.org/kosmos/botka.git"
revision "master"
notifies :restart, "systemd_unit[#{app_name}.service]", :delayed
end
file "#{app_path}/external-scripts.json" do
mode "0640"
owner app_user
group app_group
content [
"hubot-help",
"hubot-redis-brain",
"hubot-remotestorage-logger",
"hubot-web-push-notifications",
].to_json
end
git do
user app_user
group app_group
repository "https://gitea.kosmos.org/kosmos/botka.git"
revision "master"
end
execute "npm install" do
cwd app_path
environment "HOME" => app_path
user app_user
end
file "#{app_path}/external-scripts.json" do
mode "0640"
owner app_user
group app_group
content [
"hubot-help",
"hubot-redis-brain",
"hubot-remotestorage-logger",
"hubot-web-push-notifications",
].to_json
end
service_env = {
"HUBOT_LOG_LEVEL" => node.chef_environment == "development" ? "debug" : "info",
"HUBOT_IRC_USESSL" => "true",
"HUBOT_IRC_SERVER" => credentials["znc_host"],
"HUBOT_IRC_PORT" => credentials["znc_port"],
"HUBOT_IRC_NICK" => "botka",
"HUBOT_IRC_USERNAME" => credentials['znc_user'],
"HUBOT_IRC_PASSWORD" => credentials['znc_password'],
"HUBOT_IRC_REALNAME" => "botka (kosmos)",
"HUBOT_IRC_ROOMS" => "#kosmos,#kosmos-dev,#kosmos-random,#remotestorage,#hackerbeach,#unhosted,#sockethub,#mastodon",
"HUBOT_IRC_UNFLOOD" => "100",
"HUBOT_RSS_PRINTSUMMARY" => "false",
"HUBOT_RSS_PRINTERROR" => "false",
"HUBOT_RSS_IRCCOLORS" => "true",
"REDIS_URL" => "redis://localhost:6379/botka",
"EXPRESS_PORT" => node[app_name]['http_port'],
"HUBOT_AUTH_ADMIN" => "bkero,raucao",
"HUBOT_HELP_REPLY_IN_PRIVATE" => "true",
"RS_LOGGER_USER" => "kosmos@5apps.com",
"RS_LOGGER_TOKEN" => credentials['rs_logger_token'],
"RS_LOGGER_SERVER_NAME" => "irc.libera.chat",
"RS_LOGGER_PUBLIC" => "true",
"GCM_API_KEY" => credentials['gcm_api_key'],
"VAPID_SUBJECT" => "https://kosmos.org",
"VAPID_PUBLIC_KEY" => credentials['vapid_public_key'],
"VAPID_PRIVATE_KEY" => credentials['vapid_private_key']
}
npm_install do
user app_user
end
systemd_unit "#{app_name}.service" do
content({
Unit: {
Description: app_name,
Requires: "redis@6379.service",
After: "redis@6379.service"
},
execute "systemctl daemon-reload" do
command "systemctl daemon-reload"
action :nothing
end
Service: {
ExecStart: "#{app_path}/bin/hubot -a irc",
WorkingDirectory: app_path,
User: app_user,
Group: app_group,
Environment: service_env.map { |k, v| "'#{k}=#{v}'" },
Restart: 'always'
},
template "/lib/systemd/system/#{app_name}.service" do
source 'nodejs.systemd.service.erb'
owner 'root'
group 'root'
mode '0644'
variables(
user: app_user,
group: app_group,
app_dir: app_path,
entry: "#{app_path}/bin/hubot -a irc",
environment: {
"HUBOT_LOG_LEVEL" => node.chef_environment == "development" ? "debug" : "info",
"HUBOT_IRC_USESSL" => "true",
"HUBOT_IRC_SERVER" => credentials["znc_host"],
"HUBOT_IRC_PORT" => credentials["znc_port"],
"HUBOT_IRC_NICK" => "botka",
"HUBOT_IRC_USERNAME" => credentials['znc_user'],
"HUBOT_IRC_PASSWORD" => credentials['znc_password'],
"HUBOT_IRC_REALNAME" => "botka (kosmos)",
"HUBOT_IRC_ROOMS" => "#kosmos,#kosmos-dev,#kosmos-random,#remotestorage,#hackerbeach,#unhosted,#sockethub,#mastodon",
"HUBOT_IRC_UNFLOOD" => "100",
"HUBOT_RSS_PRINTSUMMARY" => "false",
"HUBOT_RSS_PRINTERROR" => "false",
"HUBOT_RSS_IRCCOLORS" => "true",
"REDIS_URL" => "redis://localhost:6379/botka",
"EXPRESS_PORT" => node[app_name]['http_port'],
"HUBOT_AUTH_ADMIN" => "bkero,raucao",
"HUBOT_HELP_REPLY_IN_PRIVATE" => "true",
"RS_LOGGER_USER" => "kosmos@5apps.com",
"RS_LOGGER_TOKEN" => credentials['rs_logger_token'],
"RS_LOGGER_SERVER_NAME" => "irc.libera.chat",
"RS_LOGGER_PUBLIC" => "true",
"GCM_API_KEY" => credentials['gcm_api_key'],
"VAPID_SUBJECT" => "https://kosmos.org",
"VAPID_PUBLIC_KEY" => credentials['vapid_public_key'],
"VAPID_PRIVATE_KEY" => credentials['vapid_private_key']
}
)
notifies :run, "execute[systemctl daemon-reload]", :delayed
notifies :restart, "service[#{app_name}]", :delayed
end
service app_name do
action [:enable, :start]
end
Install: {
WantedBy: 'multi-user.target'
}
})
verify false
triggers_reload true
action [:create, :enable, :start]
end
firewall_rule app_name do

View File

@ -18,41 +18,40 @@ include_recipe "kosmos-hubot::_user"
include_recipe "kosmos-hubot::_nodejs"
include_recipe "kosmos-base::firewall"
application app_path do
data_bag = Chef::EncryptedDataBagItem.load('credentials', app_name)
data_bag = Chef::EncryptedDataBagItem.load('credentials', app_name)
git app_path do
user app_user
group app_group
repository "https://gitea.kosmos.org/kosmos/hal8000.git"
revision "master"
notifies :restart, "systemd_unit[#{app_name}.service]", :delayed
end
file "#{app_path}/external-scripts.json" do
mode "0640"
owner app_user
group app_group
content node[app_name]['hubot_scripts'].to_json
end
git do
user app_user
group app_group
repository "https://gitea.kosmos.org/kosmos/hal8000.git"
revision "master"
end
execute "npm install" do
cwd app_path
environment "HOME" => app_path
user app_user
end
file "#{app_path}/external-scripts.json" do
mode "0640"
owner app_user
group app_group
content node[app_name]['hubot_scripts'].to_json
end
ipfs_host = search(:node, "role:ipfs_gateway").first["knife_zero"]["host"]
node.override[app_name]['kredits']['ipfs_host'] = ipfs_host
npm_install do
user app_user
end
rsk_node_ip = search(:node, "role:rskj_testnet").first["knife_zero"]["host"]
node.override[app_name]['kredits']['provider_url'] = "http://#{rsk_node_ip}:4444"
ipfs_host = search(:node, "role:ipfs_gateway").first["knife_zero"]["host"]
node.override[app_name]['kredits']['ipfs_host'] = ipfs_host
rsk_node_ip = search(:node, "role:rskj_testnet").first["knife_zero"]["host"]
node.override[app_name]['kredits']['provider_url'] = "http://#{rsk_node_ip}:4444"
file "#{app_path}/node_modules/@kredits/hubot-kredits/.env" do
mode "0600"
owner app_user
group app_group
content <<-EOF
file "#{app_path}/node_modules/@kredits/hubot-kredits/.env" do
mode "0600"
owner app_user
group app_group
content <<-EOF
GITEA_TOKEN=#{data_bag['gitea_token']}
GITHUB_TOKEN=#{data_bag['github_token']}
KREDITS_PROVIDER_URL=#{node[app_name]['kredits']['provider_url']}
@ -61,72 +60,74 @@ IPFS_API_PORT=#{node[app_name]['kredits']['ipfs_port']}
IPFS_API_PROTOCOL=#{node[app_name]['kredits']['ipfs_protocol']}
KREDITS_WALLET_PATH=../../#{node[app_name]['kredits']['wallet_path']}
KREDITS_WALLET_PASSWORD=#{data_bag['kredits_wallet_password']}
EOF
end
EOF
end
execute "systemctl daemon-reload" do
command "systemctl daemon-reload"
action :nothing
end
cookbook_file "#{app_path}/wallet.json" do
source "wallet.json"
end
template "/lib/systemd/system/#{app_name}.service" do
source 'nodejs.systemd.service.erb'
owner 'root'
group 'root'
mode '0644'
variables(
user: app_user,
group: app_user,
app_dir: app_path,
entry: "#{app_path}/bin/hubot -a xmpp --name hal8000",
environment: {
"HUBOT_LOG_LEVEL" => node.chef_environment == "development" ? "debug" : "info",
"HUBOT_XMPP_USERNAME" => "hal8000@kosmos.org/hubot",
"HUBOT_XMPP_PASSWORD" => data_bag['xmpp_password'],
"HUBOT_XMPP_HOST" => "xmpp.kosmos.org",
"HUBOT_XMPP_ROOMS" => node[app_name]['rooms'].join(','),
"HUBOT_AUTH_ADMIN" => node[app_name]['auth_admins'].join(','),
"HUBOT_RSS_PRINTSUMMARY" => "false",
"HUBOT_RSS_PRINTERROR" => "false",
"HUBOT_RSS_IRCCOLORS" => "true",
"HUBOT_PLUSPLUS_POINTS_TERM" => "karma,karma",
"HUBOT_RSS_HEADER" => "Update:",
"HUBOT_HELP_REPLY_IN_PRIVATE" => "true",
"REDIS_URL" => "redis://localhost:6379/#{app_name}",
"EXPRESS_PORT" => node[app_name]['http_port'],
"WEBHOOK_TOKEN" => data_bag['webhook_token'],
"IPFS_API_HOST" => node[app_name]['kredits']['ipfs_host'],
"IPFS_API_PORT" => node[app_name]['kredits']['ipfs_port'],
"IPFS_API_PROTOCOL" => node[app_name]['kredits']['ipfs_protocol'],
"KREDITS_WEB_URL" => node[app_name]['kredits']['web_url'],
"KREDITS_ROOM" => node[app_name]['kredits']['room'],
"KREDITS_WEBHOOK_TOKEN" => data_bag['kredits_webhook_token'],
"KREDITS_PROVIDER_URL" => node[app_name]['kredits']['provider_url'],
"KREDITS_WALLET_PATH" => node[app_name]['kredits']['wallet_path'],
"KREDITS_WALLET_PASSWORD" => data_bag['kredits_wallet_password'],
"KREDITS_MEDIAWIKI_URL" => node[app_name]['kredits']['mediawiki_url'],
"KREDITS_GITHUB_REPO_BLACKLIST" => node[app_name]['kredits']['github_repo_blacklist'],
"KREDITS_GITEA_REPO_BLACKLIST" => node[app_name]['kredits']['gitea_repo_blacklist'],
"KREDITS_GRANT_HOST" => node[app_name]['domain'],
"KREDITS_GRANT_PROTOCOL" => "https",
"KREDITS_SESSION_SECRET" => data_bag['kredits_session_secret'],
"KREDITS_GITHUB_KEY" => data_bag['kredits_github_key'],
"KREDITS_GITHUB_SECRET" => data_bag['kredits_github_secret'],
"KREDITS_ZOOM_JWT" => data_bag['kredits_zoom_jwt'],
"KREDITS_ZOOM_MEETING_WHITELIST" => "414901303,82557072771"
}
)
notifies :run, "execute[systemctl daemon-reload]", :delayed
notifies :restart, "service[#{app_name}]", :delayed
end
service_env = {
"HUBOT_LOG_LEVEL" => node.chef_environment == "development" ? "debug" : "info",
"HUBOT_XMPP_USERNAME" => "hal8000@kosmos.org/hubot",
"HUBOT_XMPP_PASSWORD" => data_bag['xmpp_password'],
"HUBOT_XMPP_HOST" => "xmpp.kosmos.org",
"HUBOT_XMPP_ROOMS" => node[app_name]['rooms'].join(','),
"HUBOT_AUTH_ADMIN" => node[app_name]['auth_admins'].join(','),
"HUBOT_RSS_PRINTSUMMARY" => "false",
"HUBOT_RSS_PRINTERROR" => "false",
"HUBOT_RSS_IRCCOLORS" => "true",
"HUBOT_PLUSPLUS_POINTS_TERM" => "karma,karma",
"HUBOT_RSS_HEADER" => "Update:",
"HUBOT_HELP_REPLY_IN_PRIVATE" => "true",
"REDIS_URL" => "redis://localhost:6379/#{app_name}",
"EXPRESS_PORT" => node[app_name]['http_port'],
"WEBHOOK_TOKEN" => data_bag['webhook_token'],
"IPFS_API_HOST" => node[app_name]['kredits']['ipfs_host'],
"IPFS_API_PORT" => node[app_name]['kredits']['ipfs_port'],
"IPFS_API_PROTOCOL" => node[app_name]['kredits']['ipfs_protocol'],
"KREDITS_WEB_URL" => node[app_name]['kredits']['web_url'],
"KREDITS_ROOM" => node[app_name]['kredits']['room'],
"KREDITS_WEBHOOK_TOKEN" => data_bag['kredits_webhook_token'],
"KREDITS_PROVIDER_URL" => node[app_name]['kredits']['provider_url'],
"KREDITS_WALLET_PATH" => node[app_name]['kredits']['wallet_path'],
"KREDITS_WALLET_PASSWORD" => data_bag['kredits_wallet_password'],
"KREDITS_MEDIAWIKI_URL" => node[app_name]['kredits']['mediawiki_url'],
"KREDITS_GITHUB_REPO_BLACKLIST" => node[app_name]['kredits']['github_repo_blacklist'],
"KREDITS_GITEA_REPO_BLACKLIST" => node[app_name]['kredits']['gitea_repo_blacklist'],
"KREDITS_GRANT_HOST" => node[app_name]['domain'],
"KREDITS_GRANT_PROTOCOL" => "https",
"KREDITS_SESSION_SECRET" => data_bag['kredits_session_secret'],
"KREDITS_GITHUB_KEY" => data_bag['kredits_github_key'],
"KREDITS_GITHUB_SECRET" => data_bag['kredits_github_secret'],
"KREDITS_ZOOM_JWT" => data_bag['kredits_zoom_jwt'],
"KREDITS_ZOOM_MEETING_WHITELIST" => "414901303,82557072771"
}
cookbook_file "#{app_path}/wallet.json" do
source "wallet.json"
end
systemd_unit "#{app_name}.service" do
content({
Unit: {
Description: app_name,
Requires: "redis@6379.service",
After: "redis@6379.service"
},
service app_name do
action [:enable, :start]
end
Service: {
ExecStart: "#{app_path}/bin/hubot -a xmpp --name hal8000",
WorkingDirectory: app_path,
User: app_user,
Group: app_group,
Environment: service_env.map { |k, v| "'#{k}=#{v}'" },
Restart: 'always'
},
Install: {
WantedBy: 'multi-user.target'
}
})
verify false
triggers_reload true
action [:create, :enable, :start]
end
firewall_rule app_name do

View File

@ -1,19 +0,0 @@
[Unit]
Description=Start nodejs app
<% unless @without_redis %>
Requires=redis@6379.service
After=redis@6379.service
<% end %>
[Service]
ExecStart=<%= @entry %>
WorkingDirectory=<%= @app_dir %>
User=<%= @user %>
Group=<%= @group %>
<% unless @environment.empty? -%>
Environment=<% @environment.each do |key, value| -%>'<%= key %>=<%= value %>' <% end %>
<% end -%>
Restart=always
[Install]
WantedBy=multi-user.target

View File

@ -12,4 +12,3 @@ depends 'kosmos-base'
depends 'kosmos-nginx'
depends 'kosmos-nodejs'
depends 'firewall'
depends 'application_javascript'

View File

@ -13,50 +13,51 @@ deploy_group = "ipfs"
group deploy_group
path_to_deploy = "/opt/#{app_name}"
app_path = "/opt/#{app_name}"
rsk_node_ip = search(:node, "role:rskj_testnet").first["knife_zero"]["host"]
rsk_rpc_url = "http://#{rsk_node_ip}:4444"
application path_to_deploy do
owner deploy_user
git app_path do
user deploy_user
group deploy_group
git do
user deploy_user
group deploy_group
repository "https://gitea.kosmos.org/kredits/#{app_name}.git"
revision node['kosmos-ipfs']['kredits-pinner']['revision']
end
npm_install do
user deploy_user
end
execute "systemctl daemon-reload" do
command "systemctl daemon-reload"
action :nothing
end
template "/lib/systemd/system/#{app_name}.service" do
source 'nodejs.systemd.service.erb'
owner 'root'
group 'root'
mode '0640'
variables(
user: deploy_user,
group: deploy_group,
app_dir: path_to_deploy,
entry: "/usr/bin/node /usr/bin/npm start -- --watch --rpc-url #{rsk_rpc_url}",
environment: {
'DEBUG' => 'ipfs-pinner'
}
)
notifies :run, "execute[systemctl daemon-reload]", :delayed
notifies :restart, "service[#{app_name}]", :delayed
end
service app_name do
action [:enable, :start]
end
repository "https://gitea.kosmos.org/kredits/#{app_name}.git"
revision node['kosmos-ipfs']['kredits-pinner']['revision']
notifies :restart, "systemd_unit[#{app_name}.service]", :delayed
end
execute "npm install" do
cwd app_path
environment "HOME" => app_path
user deploy_user
end
service_env = {
'DEBUG' => 'ipfs-pinner'
}
systemd_unit "#{app_name}.service" do
content({
Unit: {
Description: app_name,
After: "ipfs.service"
},
Service: {
ExecStartPre: '/bin/sleep 5',
ExecStart: "/usr/bin/npm start -- --watch --rpc-url #{rsk_rpc_url}",
WorkingDirectory: app_path,
User: deploy_user,
Group: deploy_group,
Environment: service_env.map { |k, v| "'#{k}=#{v}'" },
Restart: 'always'
},
Install: {
WantedBy: 'multi-user.target'
}
})
verify false
triggers_reload true
action [:create, :enable, :start]
end

View File

@ -6,16 +6,14 @@ description 'Installs/Configures Mastodon'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version '0.2.1'
depends 'application'
depends 'application_git'
depends 'backup'
depends 'elasticsearch'
depends 'java'
depends 'firewall'
depends 'redisio'
depends 'tor-full'
depends 'poise-ruby-build'
depends 'postgresql'
depends 'kosmos-nginx'
depends 'kosmos-nodejs'
depends 'kosmos_postgresql'
depends 'ruby_build'

View File

@ -71,6 +71,15 @@ npm_package "yarn" do
end
ruby_version = "3.0.4"
# ruby_version = "3.2.2"
ruby_path = "/opt/ruby_build/builds/#{ruby_version}"
bundle_path = "#{ruby_path}/bin/bundle"
ruby_build_install 'v20230615'
ruby_build_definition ruby_version do
prefix_path ruby_path
end
execute "systemctl daemon-reload" do
command "systemctl daemon-reload"
@ -85,7 +94,7 @@ template "/lib/systemd/system/mastodon-web.service" do
app_dir: mastodon_path,
bind: bind_ip,
port: node["kosmos-mastodon"]["app_port"],
bundle_path: "/opt/ruby_build/builds/#{ruby_version}/bin/bundle"
bundle_path: bundle_path
notifies :run, "execute[systemctl daemon-reload]", :immediately
notifies :restart, "service[mastodon-web]", :delayed
end
@ -96,7 +105,7 @@ template "/lib/systemd/system/mastodon-sidekiq.service" do
source "mastodon-sidekiq.systemd.service.erb"
variables user: mastodon_user,
app_dir: mastodon_path,
bundle_path: "/opt/ruby_build/builds/#{ruby_version}/bin/bundle",
bundle_path: bundle_path,
sidekiq_threads: node["kosmos-mastodon"]["sidekiq_threads"]
notifies :run, "execute[systemctl daemon-reload]", :immediately
notifies :restart, "service[mastodon-sidekiq]", :delayed
@ -108,7 +117,7 @@ template "/lib/systemd/system/mastodon-sidekiq-scheduler.service" do
source "mastodon-sidekiq-scheduler.systemd.service.erb"
variables user: mastodon_user,
app_dir: mastodon_path,
bundle_path: "/opt/ruby_build/builds/#{ruby_version}/bin/bundle",
bundle_path: bundle_path,
sidekiq_threads: 1
notifies :run, "execute[systemctl daemon-reload]", :immediately
notifies :restart, "service[mastodon-sidekiq-scheduler]", :delayed
@ -126,110 +135,114 @@ template "/lib/systemd/system/mastodon-streaming.service" do
notifies :restart, "service[mastodon-streaming]", :delayed
end
application mastodon_path do
owner "mastodon"
group "mastodon"
rails_env = node.chef_environment == "development" ? "development" : "production"
deploy_env = {
# FIXME: /usr/bin was missing from PATH when running `yarn install`
"PATH" => "#{ruby_path}/bin:/usr/bin:$PATH",
"HOME" => mastodon_path,
"RAILS_ENV" => rails_env,
"NODE_ENV" => rails_env,
"SKIP_POST_DEPLOYMENT_MIGRATIONS" => "true"
}
# Take care of application restarts manually, in the git resource
action_on_update false
git mastodon_path do
user mastodon_user
group mastodon_user
environment "HOME" => mastodon_path,
"PATH" => "/opt/ruby_build/builds/#{ruby_version}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
ruby_runtime ruby_version do
provider :ruby_build
version ruby_version
end
git do
user mastodon_user
group mastodon_user
repository node["kosmos-mastodon"]["repo"]
revision node["kosmos-mastodon"]["revision"]
# Restart services on deployments
notifies :restart, "application[#{mastodon_path}]", :delayed
end
mastodon_credentials = data_bag_item('credentials', 'mastodon')
template ".env.production" do
source "env.production.erb"
mode "0640"
owner mastodon_user
group mastodon_user
variables redis_url: node["kosmos-mastodon"]["redis_url"],
domain: node["kosmos-mastodon"]["domain"],
alternate_domains: node["kosmos-mastodon"]["alternate_domains"],
paperclip_secret: mastodon_credentials['paperclip_secret'],
secret_key_base: mastodon_credentials['secret_key_base'],
otp_secret: mastodon_credentials['otp_secret'],
smtp_login: mastodon_credentials['smtp_user_name'],
smtp_password: mastodon_credentials['smtp_password'],
smtp_from_address: "mail@#{node['kosmos-mastodon']['domain']}",
s3_endpoint: node["kosmos-mastodon"]["s3_endpoint"],
s3_region: node["kosmos-mastodon"]["s3_region"],
s3_bucket: node["kosmos-mastodon"]["s3_bucket"],
s3_alias_host: node["kosmos-mastodon"]["s3_alias_host"],
aws_access_key_id: mastodon_credentials['s3_key_id'],
aws_secret_access_key: mastodon_credentials['s3_secret_key'],
vapid_private_key: mastodon_credentials['vapid_private_key'],
vapid_public_key: mastodon_credentials['vapid_public_key'],
db_pass: postgresql_data_bag_item['mastodon_user_password'],
db_host: "pg.kosmos.local",
default_locale: node["kosmos-mastodon"]["default_locale"],
allowed_private_addresses: node["kosmos-mastodon"]["allowed_private_addresses"],
libre_translate_endpoint: node["kosmos-mastodon"]["libre_translate_endpoint"]
notifies :restart, "application[#{mastodon_path}]", :delayed
end
execute "bundle install" do
environment "HOME" => mastodon_path
user mastodon_user
cwd mastodon_path
command "/opt/ruby_build/builds/#{ruby_version}/bin/bundle install --without development,test --deployment"
end
execute "yarn install" do
environment "HOME" => mastodon_path, "NODE_ENV" => "production"
user mastodon_user
cwd mastodon_path
command "yarn install --pure-lockfile"
end
execute 'rake db:migrate' do
environment "RAILS_ENV" => "production", "HOME" => mastodon_path, "SKIP_POST_DEPLOYMENT_MIGRATIONS" => "true"
user mastodon_user
group mastodon_user
cwd mastodon_path
command "PATH=\"/opt/ruby_build/builds/#{ruby_version}/bin:$PATH\" bundle exec rake db:migrate"
end
execute 'rake assets:precompile' do
environment "RAILS_ENV" => "production", "HOME" => mastodon_path
user mastodon_user
group mastodon_user
cwd mastodon_path
command "PATH=\"/opt/ruby_build/builds/#{ruby_version}/bin:$PATH\" bundle exec rake assets:precompile"
end
service "mastodon-web" do
action [:enable, :start]
end
service "mastodon-sidekiq" do
action [:enable, :start]
end
service "mastodon-sidekiq-scheduler" do
action [:enable, :start]
end
service "mastodon-streaming" do
action [:enable, :start]
end
repository node["kosmos-mastodon"]["repo"]
revision node["kosmos-mastodon"]["revision"]
# Restart services on deployments
notifies :run, "execute[restart mastodon services]", :delayed
end
firewall_rule 'mastodon_app' do
execute "restart mastodon services" do
command "true"
action :nothing
notifies :restart, "service[mastodon-web]", :delayed
notifies :restart, "service[mastodon-sidekiq]", :delayed
notifies :restart, "service[mastodon-sidekiq-scheduler]", :delayed
notifies :restart, "service[mastodon-streaming]", :delayed
end
mastodon_credentials = data_bag_item('credentials', 'mastodon')
template "#{mastodon_path}/.env.#{rails_env}" do
source "env.erb"
mode "0640"
owner mastodon_user
group mastodon_user
variables redis_url: node["kosmos-mastodon"]["redis_url"],
domain: node["kosmos-mastodon"]["domain"],
alternate_domains: node["kosmos-mastodon"]["alternate_domains"],
paperclip_secret: mastodon_credentials['paperclip_secret'],
secret_key_base: mastodon_credentials['secret_key_base'],
otp_secret: mastodon_credentials['otp_secret'],
smtp_login: mastodon_credentials['smtp_user_name'],
smtp_password: mastodon_credentials['smtp_password'],
smtp_from_address: "mail@#{node['kosmos-mastodon']['domain']}",
s3_endpoint: node["kosmos-mastodon"]["s3_endpoint"],
s3_region: node["kosmos-mastodon"]["s3_region"],
s3_bucket: node["kosmos-mastodon"]["s3_bucket"],
s3_alias_host: node["kosmos-mastodon"]["s3_alias_host"],
aws_access_key_id: mastodon_credentials['s3_key_id'],
aws_secret_access_key: mastodon_credentials['s3_secret_key'],
vapid_private_key: mastodon_credentials['vapid_private_key'],
vapid_public_key: mastodon_credentials['vapid_public_key'],
db_pass: postgresql_data_bag_item['mastodon_user_password'],
db_host: "pg.kosmos.local",
default_locale: node["kosmos-mastodon"]["default_locale"],
allowed_private_addresses: node["kosmos-mastodon"]["allowed_private_addresses"],
libre_translate_endpoint: node["kosmos-mastodon"]["libre_translate_endpoint"]
notifies :run, "execute[restart mastodon services]", :delayed
end
execute "bundle install" do
environment deploy_env
user mastodon_user
cwd mastodon_path
command "bundle install --without development,test --deployment"
end
execute "yarn install" do
environment deploy_env
user mastodon_user
cwd mastodon_path
command "yarn install --pure-lockfile"
end
execute "rake db:migrate" do
environment deploy_env
user mastodon_user
group mastodon_user
cwd mastodon_path
command "bundle exec rake db:migrate"
end
execute "rake assets:precompile" do
environment deploy_env
user mastodon_user
group mastodon_user
cwd mastodon_path
command "bundle exec rake assets:precompile"
end
service "mastodon-web" do
action [:enable, :start]
end
service "mastodon-sidekiq" do
action [:enable, :start]
end
service "mastodon-sidekiq-scheduler" do
action [:enable, :start]
end
service "mastodon-streaming" do
action [:enable, :start]
end
firewall_rule "mastodon_app" do
port node['kosmos-mastodon']['app_port']
source "10.1.1.0/24"
protocol :tcp

View File

@ -0,0 +1,3 @@
node.override["nodejs"]["repo"] = "https://deb.nodesource.com/node_14.x"
# Allows upgrading
node.override["nodejs"]["package_action"]["nodejs"] = :upgrade

View File

@ -3,7 +3,4 @@
# Recipe:: default
#
node.normal["nodejs"]["repo"] = "https://deb.nodesource.com/node_14.x"
# Allows upgrading
node.normal["nodejs"]["package_action"]["nodejs"] = :upgrade
include_recipe "nodejs::nodejs_from_package"

Some files were not shown because too many files have changed in this diff Show More