diff --git a/Gemfile b/Gemfile index 7a5ad02..101aa69 100644 --- a/Gemfile +++ b/Gemfile @@ -4,3 +4,5 @@ gem 'chef' gem 'batali' gem 'knife-solo' gem 'knife-solo_data_bag' +gem 'cookstyle' +gem 'test-kitchen' diff --git a/Gemfile.lock b/Gemfile.lock index 7ee54ce..1f2dab4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,6 +3,8 @@ GEM specs: addressable (2.5.0) public_suffix (~> 2.0, >= 2.0.2) + artifactory (2.7.0) + ast (2.3.0) attribute_struct (0.3.4) bogo (>= 0.1.31, < 0.3.0) batali (0.4.10) @@ -75,6 +77,8 @@ GEM colored (1.2) command_line_reporter (3.3.6) colored (>= 1.2) + cookstyle (1.3.0) + rubocop (= 0.47.1) diff-lcs (1.3) domain_name (0.5.20170223) unf (>= 0.0.5, < 1.0.0) @@ -112,8 +116,14 @@ GEM mixlib-log mixlib-cli (1.7.0) mixlib-config (2.2.4) + mixlib-install (2.1.12) + artifactory + mixlib-shellout + mixlib-versioning + thor mixlib-log (1.7.1) mixlib-shellout (2.2.7) + mixlib-versioning (1.1.0) multi_json (1.12.1) multi_xml (0.6.0) net-scp (1.2.1) @@ -140,10 +150,14 @@ GEM systemu (~> 2.6.4) wmi-lite (~> 1.0) paint (2.0.0) + parser (2.4.0.0) + ast (~> 2.2) plist (3.2.0) + powerpack (0.1.1) proxifier (1.0.3) public_suffix (2.0.5) rack (2.0.1) + rainbow (2.2.1) rspec (3.5.0) rspec-core (~> 3.5.0) rspec-expectations (~> 3.5.0) @@ -163,6 +177,14 @@ GEM rspec_junit_formatter (0.2.3) builder (< 4) rspec-core (>= 2, < 4, != 2.12.0) + rubocop (0.47.1) + parser (>= 2.3.3.1, < 3.0) + powerpack (~> 0.1) + rainbow (>= 1.99.1, < 3.0) + ruby-progressbar (~> 1.7) + unicode-display_width (~> 1.0, >= 1.0.1) + ruby-progressbar (1.8.1) + safe_yaml (1.0.4) serverspec (2.38.0) multi_json rspec (~> 3.0) @@ -177,9 +199,19 @@ GEM sfl syslog-logger (1.6.8) systemu (2.6.5) + test-kitchen (1.15.0) + mixlib-install (>= 1.2, < 3.0) + mixlib-shellout (>= 1.2, < 3.0) + net-scp (~> 1.1) + net-ssh (>= 2.9, < 5.0) + net-ssh-gateway (~> 1.2) + safe_yaml (~> 1.0) + thor (~> 0.18) + thor (0.19.4) unf (0.1.4) unf_ext unf_ext (0.0.7.2) + unicode-display_width (1.1.3) uuidtools (2.1.5) wmi-lite (1.0.0) @@ -189,8 +221,10 @@ PLATFORMS DEPENDENCIES batali chef + cookstyle knife-solo knife-solo_data_bag + test-kitchen BUNDLED WITH 1.14.3 diff --git a/nodes/dev.kosmos.org.json b/nodes/dev.kosmos.org.json index fee301f..46364b4 100644 --- a/nodes/dev.kosmos.org.json +++ b/nodes/dev.kosmos.org.json @@ -8,7 +8,8 @@ "kosmos-mediawiki", "5apps-hubot::xmpp_botka", "5apps-hubot::xmpp_schlupp", - "5apps-xmpp_server" + "5apps-xmpp_server", + "kosmos-ipfs" ], "automatic": { "ipaddress": "dev.kosmos.org" diff --git a/site-cookbooks/ipfs/.gitignore b/site-cookbooks/ipfs/.gitignore new file mode 100644 index 0000000..c15fe86 --- /dev/null +++ b/site-cookbooks/ipfs/.gitignore @@ -0,0 +1 @@ +/.kitchen/ diff --git a/site-cookbooks/ipfs/.kitchen.docker.yml b/site-cookbooks/ipfs/.kitchen.docker.yml new file mode 100644 index 0000000..2eacee8 --- /dev/null +++ b/site-cookbooks/ipfs/.kitchen.docker.yml @@ -0,0 +1,44 @@ +me: dokken + privileged: true # because Docker and SystemD/Upstart + chef_image: chef/chef + chef_version: current + +transport: + name: dokken + +provisioner: + name: dokken + +platforms: +- name: debian-7 + driver: + image: debian:7 + pid_one_command: /sbin/init + intermediate_instructions: + - RUN /usr/bin/apt-get update + +- name: debian-8 + driver: + image: debian:8 + pid_one_command: /bin/systemd + intermediate_instructions: + - RUN /usr/bin/apt-get update + +- name: ubuntu-14.04 + driver: + image: ubuntu-upstart:14.04 + pid_one_command: /sbin/init + intermediate_instructions: + - RUN /usr/bin/apt-get update + +- name: ubuntu-16.04 + driver: + image: ubuntu:16.04 + pid_one_command: /bin/systemd + intermediate_instructions: + - RUN /usr/bin/apt-get update + +suites: +- name: default + run_list: + - recipe[ipfs] diff --git a/site-cookbooks/ipfs/.kitchen.yml b/site-cookbooks/ipfs/.kitchen.yml new file mode 100644 index 0000000..493932a --- /dev/null +++ b/site-cookbooks/ipfs/.kitchen.yml @@ -0,0 +1,17 @@ +--- +driver: + name: vagrant + +provisioner: + name: chef_zero + +platforms: + - name: ubuntu-14.04 + - name: ubuntu-16.04 + - name: debian-8.7 + +suites: + - name: default + run_list: + - recipe[ipfs::default] + attributes: diff --git a/site-cookbooks/ipfs/.travis.yml b/site-cookbooks/ipfs/.travis.yml new file mode 100644 index 0000000..4ec0c53 --- /dev/null +++ b/site-cookbooks/ipfs/.travis.yml @@ -0,0 +1,50 @@ +sudo: required +dist: trusty + +# install the pre-release chef-dk. Use chef-stable-trusty to install the stable release +addons: + apt: + sources: + - chef-stable-trusty + packages: + - chefdk + +# Don't `bundle install` which takes about 1.5 mins +install: echo "skip bundle install" + +branches: + only: + - master + +services: docker + +env: + matrix: + # - INSTANCE=default-centos-5 times out for no reason + - INSTANCE=default-centos-6 + - INSTANCE=default-centos-7 + - INSTANCE=default-debian-7 + - INSTANCE=default-debian-8 + - INSTANCE=default-fedora-latest + - INSTANCE=default-opensuse-132 + - INSTANCE=default-opensuse-421 + - INSTANCE=default-ubuntu-1204 + - INSTANCE=default-ubuntu-1404 + - INSTANCE=default-ubuntu-1604 + +before_script: + - sudo iptables -L DOCKER || ( echo "DOCKER iptables chain missing" ; sudo iptables -N DOCKER ) + - eval "$(/opt/chefdk/bin/chef shell-init bash)" + +script: KITCHEN_LOCAL_YAML=.kitchen.docker.yml /opt/chefdk/embedded/bin/kitchen verify ${INSTANCE} + +matrix: + include: + - before_script: + - eval "$(/opt/chefdk/bin/chef shell-init bash)" + - /opt/chefdk/embedded/bin/chef --version + - /opt/chefdk/embedded/bin/cookstyle --version + - /opt/chefdk/embedded/bin/foodcritic --version + - script: + - /opt/chefdk/bin/chef exec rake +env: UNIT_AND_LINT=1 diff --git a/site-cookbooks/ipfs/Berksfile b/site-cookbooks/ipfs/Berksfile new file mode 100644 index 0000000..2e1a070 --- /dev/null +++ b/site-cookbooks/ipfs/Berksfile @@ -0,0 +1,3 @@ +source "https://api.berkshelf.com" + +metadata diff --git a/site-cookbooks/ipfs/Berksfile.lock b/site-cookbooks/ipfs/Berksfile.lock new file mode 100644 index 0000000..b57f089 --- /dev/null +++ b/site-cookbooks/ipfs/Berksfile.lock @@ -0,0 +1,24 @@ +DEPENDENCIES + ipfs + path: . + metadata: true + +GRAPH + ark (2.2.1) + build-essential (>= 0.0.0) + seven_zip (>= 0.0.0) + windows (>= 0.0.0) + build-essential (8.0.0) + mingw (>= 1.1) + seven_zip (>= 0.0.0) + compat_resource (12.16.3) + ipfs (0.1.0) + ark (>= 0.0.0) + mingw (1.2.5) + compat_resource (>= 12.16.3) + seven_zip (>= 0.0.0) + ohai (5.0.0) + seven_zip (2.0.2) + windows (>= 1.2.2) + windows (2.1.1) + ohai (>= 4.0.0) diff --git a/site-cookbooks/ipfs/CHANGELOG.md b/site-cookbooks/ipfs/CHANGELOG.md new file mode 100644 index 0000000..4b7a448 --- /dev/null +++ b/site-cookbooks/ipfs/CHANGELOG.md @@ -0,0 +1,6 @@ +# ipfs CHANGELOG + +This file is used to list changes made in each version of the ipfs cookbook. + +## 0.1.0 +- [gregkare] - Initial release of ipfs diff --git a/site-cookbooks/ipfs/Gemfile b/site-cookbooks/ipfs/Gemfile new file mode 100644 index 0000000..01382a5 --- /dev/null +++ b/site-cookbooks/ipfs/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "rake" +gem "test-kitchen" +gem "kitchen-vagrant" +gem "berkshelf" diff --git a/site-cookbooks/ipfs/Gemfile.lock b/site-cookbooks/ipfs/Gemfile.lock new file mode 100644 index 0000000..e760d2b --- /dev/null +++ b/site-cookbooks/ipfs/Gemfile.lock @@ -0,0 +1,134 @@ +GEM + remote: https://rubygems.org/ + specs: + addressable (2.5.0) + public_suffix (~> 2.0, >= 2.0.2) + artifactory (2.7.0) + berkshelf (5.2.0) + addressable (~> 2.3, >= 2.3.4) + berkshelf-api-client (>= 2.0.2, < 4.0) + buff-config (~> 2.0) + buff-extensions (~> 2.0) + buff-shell_out (~> 1.0) + cleanroom (~> 1.0) + faraday (~> 0.9) + httpclient (~> 2.7) + minitar (~> 0.5, >= 0.5.4) + mixlib-archive (~> 0.1) + octokit (~> 4.0) + retryable (~> 2.0) + ridley (~> 5.0) + solve (> 2.0, < 4.0) + thor (~> 0.19) + berkshelf-api-client (3.0.0) + faraday (~> 0.9) + httpclient (~> 2.7) + ridley (>= 4.5, < 6.0) + buff-config (2.0.0) + buff-extensions (~> 2.0) + varia_model (~> 0.6) + buff-extensions (2.0.0) + buff-ignore (1.2.0) + buff-ruby_engine (1.0.0) + buff-shell_out (1.1.0) + buff-ruby_engine (~> 1.0) + celluloid (0.16.0) + timers (~> 4.0.0) + celluloid-io (0.16.2) + celluloid (>= 0.16.0) + nio4r (>= 1.1.0) + chef-config (12.19.36) + addressable + fuzzyurl + mixlib-config (~> 2.0) + mixlib-shellout (~> 2.0) + cleanroom (1.0.0) + erubis (2.7.0) + faraday (0.9.2) + multipart-post (>= 1.2, < 3) + fuzzyurl (0.9.0) + hashie (3.5.5) + hitimes (1.2.4) + httpclient (2.8.3) + json (2.0.3) + kitchen-vagrant (1.0.2) + test-kitchen (~> 1.4) + minitar (0.6.1) + mixlib-archive (0.4.1) + mixlib-log + mixlib-authentication (1.4.1) + mixlib-log + mixlib-config (2.2.4) + mixlib-install (2.1.12) + artifactory + mixlib-shellout + mixlib-versioning + thor + mixlib-log (1.7.1) + mixlib-shellout (2.2.7) + mixlib-versioning (1.1.0) + molinillo (0.5.6) + multipart-post (2.0.0) + net-scp (1.2.1) + net-ssh (>= 2.6.5) + net-ssh (4.1.0) + net-ssh-gateway (1.3.0) + net-ssh (>= 2.6.5) + nio4r (2.0.0) + octokit (4.6.2) + sawyer (~> 0.8.0, >= 0.5.3) + public_suffix (2.0.5) + rake (11.3.0) + retryable (2.0.4) + ridley (5.1.0) + addressable + buff-config (~> 2.0) + buff-extensions (~> 2.0) + buff-ignore (~> 1.2) + buff-shell_out (~> 1.0) + celluloid (~> 0.16.0) + celluloid-io (~> 0.16.1) + chef-config (>= 12.5.0) + erubis + faraday (~> 0.9.0) + hashie (>= 2.0.2, < 4.0.0) + httpclient (~> 2.7) + json (>= 1.7.7) + mixlib-authentication (>= 1.3.0) + retryable (~> 2.0) + semverse (~> 2.0) + varia_model (~> 0.6) + safe_yaml (1.0.4) + sawyer (0.8.1) + addressable (>= 2.3.5, < 2.6) + faraday (~> 0.8, < 1.0) + semverse (2.0.0) + solve (3.1.0) + molinillo (>= 0.5) + semverse (>= 1.1, < 3.0) + test-kitchen (1.15.0) + mixlib-install (>= 1.2, < 3.0) + mixlib-shellout (>= 1.2, < 3.0) + net-scp (~> 1.1) + net-ssh (>= 2.9, < 5.0) + net-ssh-gateway (~> 1.2) + safe_yaml (~> 1.0) + thor (~> 0.18) + thor (0.19.4) + timers (4.0.4) + hitimes + varia_model (0.6.0) + buff-extensions (~> 2.0) + hashie (>= 2.0.2, < 4.0.0) + +PLATFORMS + ruby + +DEPENDENCIES + berkshelf + kitchen-vagrant + rake + test-kitchen + +BUNDLED WITH + 1.14.3 diff --git a/site-cookbooks/ipfs/LICENSE b/site-cookbooks/ipfs/LICENSE new file mode 100644 index 0000000..41c8973 --- /dev/null +++ b/site-cookbooks/ipfs/LICENSE @@ -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 2017 Kosmos + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/site-cookbooks/ipfs/README.md b/site-cookbooks/ipfs/README.md new file mode 100644 index 0000000..778d89c --- /dev/null +++ b/site-cookbooks/ipfs/README.md @@ -0,0 +1,74 @@ +# ipfs Cookbook + +This cookbook installs ipfs and starts it as a daemon + +## Requirements + +### Platforms + +This cookbook is tested on Ubuntu 16.06, 14.04 and Debian 8 using Test Kitchen. +It currently only supports 64bit platforms + +### Chef + +- Chef 12.5 or later (we are providing a + [https://docs.chef.io/custom_resources.html](Custom Resource) to configure + IPFS + +### Cookbook dependencies + +- `ark` to download and uncompress the Go IPFS package + +## Usage + +### ipfs::default + +Just include `ipfs` in your node's `run_list`: + +```json +{ + "name":"my_node", + "run_list": [ + "recipe[ipfs]" + ] +} +``` + +## Attributes + +- `node.['ipfs']['version']` - the Go IPFS version to download from the official +site (64bit) +- `node['ipfs']['checksum']` - the SHA256 checksum for the package +- `node['ipfs']['config']['swarm']['addr_filter']` - the network ranges to not +connect to. This will stop platforms like Hetzner to block your server +(https://github.com/ipfs/go-ipfs/issues/1226) + +## Resources + +`ipfs_config` sets the config. Supports hashes, arrays, booleans and strings. +Does not change anything if the config already has that value, and restarts +the server automatically + +```ruby +ipfs_config "Gateway.Writable" do + true + end +``` + +## License and Authors + +Authors: Kosmos + +``` +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +``` diff --git a/site-cookbooks/ipfs/Rakefile b/site-cookbooks/ipfs/Rakefile new file mode 100644 index 0000000..981af6b --- /dev/null +++ b/site-cookbooks/ipfs/Rakefile @@ -0,0 +1,65 @@ +#!/usr/bin/env rake + +# Style tests. cookstyle (rubocop) and Foodcritic +namespace :style do + begin + require 'cookstyle' + require 'rubocop/rake_task' + + desc 'Run Ruby style checks' + RuboCop::RakeTask.new(:ruby) + rescue LoadError => e + puts ">>> Gem load error: #{e}, omitting #{task.name}" unless ENV['CI'] + end + + begin + require 'foodcritic' + + desc 'Run Chef style checks' + FoodCritic::Rake::LintTask.new(:chef) do |t| + t.options = { + fail_tags: ['any'], + progress: true, + } + end + rescue LoadError + puts ">>> Gem load error: #{e}, omitting #{task.name}" unless ENV['CI'] + end +end + +desc 'Run all style checks' +task style: ['style:chef', 'style:ruby'] + +# ChefSpec +begin + desc 'Run ChefSpec examples' + require 'rspec/core/rake_task' + RSpec::Core::RakeTask.new(:spec) +rescue LoadError => e + puts ">>> Gem load error: #{e}, omitting #{task.name}" unless ENV['CI'] +end + +# Integration tests. Kitchen.ci +namespace :integration do + begin + require 'kitchen/rake_tasks' + + desc 'Run kitchen integration tests' + Kitchen::RakeTasks.new + rescue StandardError => e + puts ">>> Gem load error: #{e}, omitting #{task.name}" unless ENV['CI'] + end +end + +namespace :supermarket do + begin + desc 'Publish cookbook to Supermarket with Stove' + require 'stove/rake_task' + Stove::RakeTask.new + rescue LoadError => e + puts ">>> Gem load error: #{e}, omitting #{task.name}" unless ENV['CI'] + end +end + +# Default +task default: %w(style spec) diff --git a/site-cookbooks/ipfs/attributes/default.rb b/site-cookbooks/ipfs/attributes/default.rb new file mode 100644 index 0000000..6ccba68 --- /dev/null +++ b/site-cookbooks/ipfs/attributes/default.rb @@ -0,0 +1,21 @@ +node.default['ipfs']['version'] = "0.4.7" +node.default['ipfs']['checksum'] = "f2686980f3417edd543e972a623ae3d4c0727844aa7c13bae9bfd7ffe7a28e37" +# Do not contact local network addresses. This will stop platforms like Hetzner +# to block your server (https://github.com/ipfs/go-ipfs/issues/1226) +node.default['ipfs']['config']['swarm']['addr_filter'] = [ + "/ip4/10.0.0.0/ipcidr/8", + "/ip4/100.64.0.0/ipcidr/10", + "/ip4/169.254.0.0/ipcidr/16", + "/ip4/172.16.0.0/ipcidr/12", + "/ip4/192.0.0.0/ipcidr/24", + "/ip4/192.0.0.0/ipcidr/29", + "/ip4/192.0.0.8/ipcidr/32", + "/ip4/192.0.0.170/ipcidr/32", + "/ip4/192.0.0.171/ipcidr/32", + "/ip4/192.0.2.0/ipcidr/24", + "/ip4/192.168.0.0/ipcidr/16", + "/ip4/198.18.0.0/ipcidr/15", + "/ip4/198.51.100.0/ipcidr/24", + "/ip4/203.0.113.0/ipcidr/24", + "/ip4/240.0.0.0/ipcidr/4" +] diff --git a/site-cookbooks/ipfs/chefignore b/site-cookbooks/ipfs/chefignore new file mode 100644 index 0000000..7be3c6d --- /dev/null +++ b/site-cookbooks/ipfs/chefignore @@ -0,0 +1 @@ +.kitchen diff --git a/site-cookbooks/ipfs/metadata.rb b/site-cookbooks/ipfs/metadata.rb new file mode 100644 index 0000000..c0410c6 --- /dev/null +++ b/site-cookbooks/ipfs/metadata.rb @@ -0,0 +1,11 @@ +name 'ipfs' +maintainer 'Kosmos' +maintainer_email 'mail@kosmos.org' +license 'Apache 2.0' +description 'Installs/Configures ipfs' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version '0.1.0' + +supports ['ubuntu', 'debian'] + +depends 'ark' diff --git a/site-cookbooks/ipfs/recipes/default.rb b/site-cookbooks/ipfs/recipes/default.rb new file mode 100644 index 0000000..70fb43b --- /dev/null +++ b/site-cookbooks/ipfs/recipes/default.rb @@ -0,0 +1,78 @@ +# +# Cookbook Name:: ipfs +# Recipe:: default +# +# Copyright 2017, Kosmos +# +# All rights reserved - Do Not Redistribute +# + +version = node["ipfs"]["version"] + +ark "ipfs" do + url "https://dist.ipfs.io/go-ipfs/v#{version}/go-ipfs_v#{version}_linux-amd64.tar.gz" + checksum node["ipfs"]["checksum"] + has_binaries ["ipfs"] +end + +group "ipfs" do + gid 4737 +end + +user "ipfs" do + comment "ipfs" + uid 4737 + gid 4737 + home "/home/ipfs" + manage_home true +end + +execute "ipfs init --empty-repo" do + environment "IPFS_PATH" => "/home/ipfs/.ipfs" + user "ipfs" + not_if { File.directory? "/home/ipfs/.ipfs" } +end + +if platform?('ubuntu') && node[:platform_version].to_f < 15.04 || + platform?('debian') && node['platform_version'].to_f < 8 + template "ipfs.initd.service.erb" do + path "/etc/init.d/ipfs" + source 'ipfs.initd.service.erb' + owner 'root' + group 'root' + mode '0750' + notifies :restart, "service[ipfs]", :delayed + end + + service "ipfs" do + provider Chef::Provider::Service::Init::Debian + action [:enable] + supports start: true, stop: true, restart: true, reload: false, status: true + end + +else + execute "systemctl daemon-reload" do + command "systemctl daemon-reload" + action :nothing + end + + template "ipfs.systemd.service.erb" do + path "/lib/systemd/system/ipfs.service" + source 'ipfs.systemd.service.erb' + owner 'root' + group 'root' + mode '0644' + notifies :run, "execute[systemctl daemon-reload]", :delayed + notifies :restart, "service[ipfs]", :delayed + end + + service "ipfs" do + provider Chef::Provider::Service::Systemd + action [:enable] + end +end + +# Configure ipfs to not contact local network addresses +ipfs_config "Swarm.AddrFilters" do + value node['ipfs']['config']['swarm']['addr_filter'] +end diff --git a/site-cookbooks/ipfs/resources/config.rb b/site-cookbooks/ipfs/resources/config.rb new file mode 100644 index 0000000..67df68a --- /dev/null +++ b/site-cookbooks/ipfs/resources/config.rb @@ -0,0 +1,29 @@ +property :key, String, name_property: true +property :value, [String, Hash, Array, TrueClass, FalseClass], default: nil, required: true + +load_current_value do + # some Ruby +end + +action :create do + include_recipe "ipfs" + + json_value = JSON.generate(value) + execute "ipfs config --json #{key} #{json_value}" do + environment "IPFS_PATH" => "/home/ipfs/.ipfs" + user "ipfs" + not_if do + require 'json' + require 'mixlib/shellout' + cmd = Mixlib::ShellOut.new("ipfs", "config", key, user: 'ipfs', + env: {"IPFS_PATH" => "/home/ipfs/.ipfs"}) + cmd.run_command + begin + JSON.parse(cmd.stdout) == value + rescue JSON::ParserError + cmd.stdout.include?(value) + end + end + notifies :restart, "service[ipfs]", :delayed + end +end diff --git a/site-cookbooks/ipfs/templates/default/ipfs.initd.service.erb b/site-cookbooks/ipfs/templates/default/ipfs.initd.service.erb new file mode 100644 index 0000000..38e5d74 --- /dev/null +++ b/site-cookbooks/ipfs/templates/default/ipfs.initd.service.erb @@ -0,0 +1,102 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: ipfs daemon +# Required-Start: $local_fs $remote_fs $network $syslog $named +# Required-Stop: $local_fs $remote_fs $network $syslog $named +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Starts the ipfs daemon +# Description: Starts the ipfs daemon using the start-stop-daemon +### END INIT INFO + +# Author: Dylan Powers = 3.2-14) to ensure that this file is present +# and status_of_proc is working. +. /lib/lsb/init-functions + +# +# Function that starts the daemon/service +# +do_start() { + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test >/dev/null \ + || return 1 + start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile \ + --background --chuid $IPFS_USER --no-close \ + --exec /usr/bin/env IPFS_PATH="$IPFS_PATH" $DAEMON 2>>$IPFS_PATH/daemon.log 1>/dev/null \ + -- $DAEMON_ARGS \ + || return 2 +} + +# +# Function that stops the daemon/service +# +do_stop() { + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME + RETVAL="$?" + [ "$RETVAL" = 2 ] && return 2 + + # Delete the pid + rm -f $PIDFILE + return "$RETVAL" +} + +case "$1" in + start) + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" + do_start + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" + do_stop + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + status) + status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? + ;; + restart) + do_stop + do_start + ;; + *) + echo "Usage: $SCRIPTNAME {start|stop|status|restart}" >&2 + exit 3 + ;; +esac diff --git a/site-cookbooks/ipfs/templates/default/ipfs.systemd.service.erb b/site-cookbooks/ipfs/templates/default/ipfs.systemd.service.erb new file mode 100644 index 0000000..2217b29 --- /dev/null +++ b/site-cookbooks/ipfs/templates/default/ipfs.systemd.service.erb @@ -0,0 +1,11 @@ +[Unit] +Description=Start ipfs + +[Service] +ExecStart=/usr/local/bin/ipfs daemon +User=ipfs +Group=ipfs +Restart=always + +[Install] +WantedBy=multi-user.target diff --git a/site-cookbooks/ipfs/test/integration/default/serverspec/ipfs_spec.rb b/site-cookbooks/ipfs/test/integration/default/serverspec/ipfs_spec.rb new file mode 100644 index 0000000..3bc17ee --- /dev/null +++ b/site-cookbooks/ipfs/test/integration/default/serverspec/ipfs_spec.rb @@ -0,0 +1,26 @@ +require 'serverspec' + +# Required by serverspec +set :backend, :exec + +describe "IPFS" do + + # It is in the PATH + describe command("which ipfs") do + its(:exit_status) { should eq 0 } + end + + it "is listening on port 4001" do + expect(port(4001)).to be_listening + end + + it "is listening on port 8080 (gateway)" do + expect(port(8080)).to be_listening + end + + it "has a running service of ipfs" do + expect(service("ipfs")).to be_running + expect(service("ipfs")).to be_enabled + end + +end diff --git a/site-cookbooks/kosmos-ipfs/CHANGELOG.md b/site-cookbooks/kosmos-ipfs/CHANGELOG.md new file mode 100644 index 0000000..6115db6 --- /dev/null +++ b/site-cookbooks/kosmos-ipfs/CHANGELOG.md @@ -0,0 +1,6 @@ +# kosmos-ipfs CHANGELOG + +This file is used to list changes made in each version of the kosmos-ipfs cookbook. + +## 0.1.0 +- [gregkare] - Initial release of kosmos-ipfs diff --git a/site-cookbooks/kosmos-ipfs/README.md b/site-cookbooks/kosmos-ipfs/README.md new file mode 100644 index 0000000..25b7ca9 --- /dev/null +++ b/site-cookbooks/kosmos-ipfs/README.md @@ -0,0 +1,11 @@ +# kosmos-ipfs Cookbook + +This cookbook sets up ipfs for Kosmos + +### Chef + +- Chef 12.0 or later + +### Cookbooks + +- `default` - Install ipfs and configure it for Kosmos diff --git a/site-cookbooks/kosmos-ipfs/metadata.rb b/site-cookbooks/kosmos-ipfs/metadata.rb new file mode 100644 index 0000000..1eb2e3e --- /dev/null +++ b/site-cookbooks/kosmos-ipfs/metadata.rb @@ -0,0 +1,10 @@ +name 'kosmos-ipfs' +maintainer 'Kosmos' +maintainer_email 'mail@kosmos.org' +license 'All rights reserved' +description 'Installs/Configures kosmos-ipfs' +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) +version '0.1.0' + +depends 'ipfs' +depends 'kosmos-base' diff --git a/site-cookbooks/kosmos-ipfs/recipes/default.rb b/site-cookbooks/kosmos-ipfs/recipes/default.rb new file mode 100644 index 0000000..9ea808d --- /dev/null +++ b/site-cookbooks/kosmos-ipfs/recipes/default.rb @@ -0,0 +1,24 @@ +# +# Cookbook Name:: kosmos-ipfs +# Recipe:: default +# +# Copyright 2017, Kosmos +# +# All rights reserved - Do Not Redistribute +# + +include_recipe "ipfs" + +# Configure ipfs + +# The default gateway is already used by kosmos' hubot (8080) +ipfs_config "Addresses.Gateway" do + value "/ip4/127.0.0.1/tcp/9090" +end + +# Set up the Gateway to be writable +ipfs_config "Gateway.Writable" do + value true +end + +include_recipe "kosmos-ipfs::letsencrypt" diff --git a/site-cookbooks/kosmos-ipfs/recipes/letsencrypt.rb b/site-cookbooks/kosmos-ipfs/recipes/letsencrypt.rb new file mode 100644 index 0000000..2775c60 --- /dev/null +++ b/site-cookbooks/kosmos-ipfs/recipes/letsencrypt.rb @@ -0,0 +1,56 @@ +# +# Cookbook Name:: kosmos-ipfs +# Recipe:: letsencrypt +# +# Copyright 2017, Kosmos +# +# All rights reserved - Do Not Redistribute +# +# nginx config to generate a Let's Encrypt cert + +include_recipe "kosmos-base::letsencrypt" + +root_directory = "/var/www/ipfs.kosmos.org" + +directory "#{root_directory}/.well-known" do + owner node["nginx"]["user"] + group node["nginx"]["group"] + action :create + recursive true +end + +template "#{node['nginx']['dir']}/sites-available/ipfs.kosmos.org" do + source 'nginx_conf_ipfs.kosmos.org.erb' + owner 'www-data' + mode 0640 + variables server_name: 'ipfs.kosmos.org', + root_directory: root_directory, + ssl_cert: "/etc/letsencrypt/live/ipfs.kosmos.org/fullchain.pem", + ssl_key: "/etc/letsencrypt/live/ipfs.kosmos.org/privkey.pem", + ipfs_api_port: 5001, + ipfs_external_api_port: 5444 + + notifies :reload, 'service[nginx]', :delayed +end + +nginx_site 'ipfs.kosmos.org' do + enable true +end + +firewall_rule 'ipfs_api' do + port 5444 + protocol :tcp + command :allow +end + +# Generate a Let's Encrypt cert (only if the nginx vhost exists and no cert +# has been generated before. The renew cron will take care of renewing +execute "letsencrypt cert for ipfs.kosmos.org" do + command "./certbot-auto certonly --webroot --agree-tos --email ops@5apps.com --webroot-path #{root_directory} -d ipfs.kosmos.org -n" + cwd "/usr/local/certbot" + only_if do + File.exist?("#{node['nginx']['dir']}/sites-enabled/ipfs.kosmos.org") && + ! File.exist?("/etc/letsencrypt/live/ipfs.kosmos.org/fullchain.pem") + end + notifies :create, "template[#{node['nginx']['dir']}/sites-available/ipfs.kosmos.org]", :delayed +end diff --git a/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb b/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb new file mode 100644 index 0000000..94c75a1 --- /dev/null +++ b/site-cookbooks/kosmos-ipfs/templates/default/nginx_conf_ipfs.kosmos.org.erb @@ -0,0 +1,49 @@ +upstream _ipfs { + server localhost:<%= @ipfs_api_port %>; +} + +# Used by Let's Encrypt (certbot in webroot mode) +server { + listen 80; + server_name <%= @server_name %>; + location /.well-known { + root "<%= @root_directory %>"; + } + location / { + return 301 https://$host$request_uri; + } +} + +server { + <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> + listen <%= @ipfs_external_api_port %> ssl spdy; + <% else -%> + listen 80; + <% end -%> + + server_name <%= @server_name %>; + + location / { + return 200 'Nothing to see here'; + add_header Content-Type text/plain; + } + + # Increase number of buffers. Default is 8 + proxy_buffers 1024 8k; + proxy_http_version 1.1; + # CORS headers for Kredits + add_header 'Access-Control-Allow-Origin' 'https://kredits.kosmos.org'; + + location /api/v0/cat { + proxy_pass http://_ipfs/api/v0/cat; + } + + location /api/v0/add { + proxy_pass http://_ipfs/api/v0/add; + } + + <% if File.exist?(@ssl_cert) && File.exist?(@ssl_key) -%> + ssl_certificate <%= @ssl_cert %>; + ssl_certificate_key <%= @ssl_key %>; + <% end -%> +}