├── documentation └── .gitkeep ├── .envrc ├── .gitattributes ├── .github ├── CODEOWNERS └── workflows │ ├── conventional-commits.yml │ ├── prevent-file-change.yml │ ├── release.yml │ ├── copilot-setup-steps.yml │ ├── stale.yml │ └── ci.yml ├── .mdlrc ├── .release-please-manifest.json ├── test ├── fixtures │ └── cookbooks │ │ └── test │ │ ├── metadata.rb │ │ └── recipes │ │ ├── simple.rb │ │ ├── read_only.rb │ │ └── networking.rb └── integration │ ├── default │ ├── inspec.yml │ └── controls │ │ └── default_spec.rb │ ├── simple │ ├── inspec.yml │ └── controls │ │ └── default_spec.rb │ ├── networking │ ├── inspec.yml │ └── controls │ │ └── default_spec.rb │ └── read-only │ ├── inspec.yml │ └── controls │ └── default_spec.rb ├── CODE_OF_CONDUCT.md ├── kitchen.exec.yml ├── templates └── default │ ├── rsync-defaults.erb │ └── rsyncd.conf.erb ├── Berksfile ├── TESTING.md ├── .vscode └── extensions.json ├── CONTRIBUTING.md ├── .markdownlint-cli2.yaml ├── spec ├── spec_helper.rb ├── default_spec.rb └── server_spec.rb ├── .yamllint ├── release-please-config.json ├── .editorconfig ├── metadata.rb ├── renovate.json ├── libraries └── helpers.rb ├── .overcommit.yml ├── .gitignore ├── recipes ├── default.rb └── server.rb ├── attributes └── default.rb ├── kitchen.global.yml ├── kitchen.yml ├── Dangerfile ├── chefignore ├── kitchen.dokken.yml ├── resources └── serve.rb ├── CHANGELOG.md ├── README.md └── LICENSE /documentation/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | use chefworkstation 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @sous-chefs/maintainers 2 | -------------------------------------------------------------------------------- /.mdlrc: -------------------------------------------------------------------------------- 1 | rules "~MD013", "~MD024", "~MD025" 2 | -------------------------------------------------------------------------------- /.release-please-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | ".": "4.0.11" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/metadata.rb: -------------------------------------------------------------------------------- 1 | name 'test' 2 | version '1.0.0' 3 | depends 'rsync' 4 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Community Guidelines 2 | 3 | This project follows the Chef Community Guidelines 4 | -------------------------------------------------------------------------------- /kitchen.exec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: { name: exec } 3 | transport: { name: exec } 4 | 5 | platforms: 6 | - name: macos-latest 7 | - name: windows-latest 8 | -------------------------------------------------------------------------------- /templates/default/rsync-defaults.erb: -------------------------------------------------------------------------------- 1 | # File generated by chef 2 | # 3 | # defaults file for rsync daemon mode 4 | OPTIONS="<%= node['rsyncd']['options'] %>" 5 | -------------------------------------------------------------------------------- /Berksfile: -------------------------------------------------------------------------------- 1 | source 'https://supermarket.chef.io' 2 | 3 | metadata 4 | 5 | group :integration do 6 | cookbook 'apt' 7 | cookbook 'test', path: 'test/fixtures/cookbooks/test' 8 | end 9 | -------------------------------------------------------------------------------- /TESTING.md: -------------------------------------------------------------------------------- 1 | # Testing 2 | 3 | Please refer to [the community cookbook documentation on testing](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/TESTING.MD). 4 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "chef-software.chef", 4 | "rebornix.ruby", 5 | "editorconfig.editorconfig", 6 | "DavidAnson.vscode-markdownlint" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /test/integration/default/inspec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: rsync-default-integration-tests 3 | title: Integration tests for rsync cookbook 4 | summary: This InSpec profile contains integration tests for rsync cookbook 5 | supports: 6 | - os-family: linux 7 | -------------------------------------------------------------------------------- /test/integration/simple/inspec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: rsync-simple-integration-tests 3 | title: Integration tests for rsync cookbook 4 | summary: This InSpec profile contains integration tests for rsync cookbook 5 | supports: 6 | - os-family: linux 7 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Please refer to 4 | [https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD](https://github.com/chef-cookbooks/community_cookbook_documentation/blob/master/CONTRIBUTING.MD) 5 | -------------------------------------------------------------------------------- /test/integration/networking/inspec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: rsync-networking-integration-tests 3 | title: Integration tests for rsync cookbook 4 | summary: This InSpec profile contains integration tests for rsync cookbook 5 | supports: 6 | - os-family: linux 7 | -------------------------------------------------------------------------------- /test/integration/read-only/inspec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: rsync-read-only-integration-tests 3 | title: Integration tests for rsync cookbook 4 | summary: This InSpec profile contains integration tests for rsync cookbook 5 | supports: 6 | - os-family: linux 7 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/simple.rb: -------------------------------------------------------------------------------- 1 | apt_update 'update' if platform_family?('debian') 2 | 3 | include_recipe 'rsync::server' 4 | 5 | rsync_serve 'foo' do 6 | path '/foo' 7 | end 8 | 9 | rsync_serve 'tmp' do 10 | path '/tmp' 11 | end 12 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/read_only.rb: -------------------------------------------------------------------------------- 1 | apt_update 'update' if platform_family?('debian') 2 | 3 | include_recipe 'rsync::server' 4 | 5 | rsync_serve 'tmp' do 6 | path '/tmp' 7 | uid 'nobody' 8 | gid 'nobody' 9 | read_only true 10 | end 11 | -------------------------------------------------------------------------------- /.markdownlint-cli2.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | ul-indent: false # MD007 3 | line-length: false # MD013 4 | no-duplicate-heading: false # MD024 5 | reference-links-images: false # MD052 6 | no-multiple-blanks: 7 | maximum: 2 8 | ignores: 9 | - .github/copilot-instructions.md 10 | -------------------------------------------------------------------------------- /test/integration/simple/controls/default_spec.rb: -------------------------------------------------------------------------------- 1 | control 'simple' do 2 | # rsync is serving /foo and /tmp alphabetically 3 | describe command 'rsync rsync://127.0.0.1' do 4 | its('stdout') { should match /foo\s*\ntmp/ } 5 | its('exit_status') { should eq 0 } 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'chefspec' 2 | require 'chefspec/berkshelf' 3 | 4 | RSpec.configure do |config| 5 | config.color = true # Use color in STDOUT 6 | config.formatter = :documentation # Use the specified formatter 7 | config.log_level = :error # Avoid deprecation notice SPAM 8 | end 9 | -------------------------------------------------------------------------------- /spec/default_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'rsync::default' do 4 | let(:chef_run) do 5 | ChefSpec::ServerRunner.new(platform: 'ubuntu', version: '16.04').converge('rsync::default') 6 | end 7 | 8 | it 'installs the rsync package' do 9 | expect(chef_run).to install_package('rsync') 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /.github/workflows/conventional-commits.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: conventional-commits 3 | 4 | "on": 5 | pull_request: 6 | types: 7 | - opened 8 | - reopened 9 | - edited 10 | - synchronize 11 | 12 | jobs: 13 | conventional-commits: 14 | uses: sous-chefs/.github/.github/workflows/conventional-commits.yml@5.0.3 15 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | rules: 4 | line-length: 5 | max: 256 6 | level: warning 7 | document-start: disable 8 | braces: 9 | forbid: false 10 | min-spaces-inside: 0 11 | max-spaces-inside: 1 12 | min-spaces-inside-empty: -1 13 | max-spaces-inside-empty: -1 14 | comments: 15 | min-spaces-from-content: 1 16 | -------------------------------------------------------------------------------- /templates/default/rsyncd.conf.erb: -------------------------------------------------------------------------------- 1 | # Rsync Config file written by chef 2 | # 3 | 4 | <% @globals.each do |key, value| -%> 5 | <%= key %> = <%= value %> 6 | <% end -%> 7 | 8 | # Modules 9 | <% @modules.keys.sort.each do |mod| -%> 10 | [<%= mod %>] 11 | <% @modules[mod].each do |key,value| -%> 12 | <%= key %> = <%= value %> 13 | <% end %> 14 | 15 | <% end %> 16 | -------------------------------------------------------------------------------- /release-please-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": { 3 | ".": { 4 | "package-name": "rsync", 5 | "changelog-path": "CHANGELOG.md", 6 | "release-type": "ruby", 7 | "include-component-in-tag": false, 8 | "version-file": "metadata.rb" 9 | } 10 | }, 11 | "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json" 12 | } 13 | -------------------------------------------------------------------------------- /.github/workflows/prevent-file-change.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: prevent-file-change 3 | 4 | "on": 5 | pull_request: 6 | types: 7 | - opened 8 | - reopened 9 | - edited 10 | - synchronize 11 | 12 | jobs: 13 | prevent-file-change: 14 | uses: sous-chefs/.github/.github/workflows/prevent-file-change.yml@5.0.3 15 | secrets: 16 | token: ${{ secrets.GITHUB_TOKEN }} 17 | -------------------------------------------------------------------------------- /test/integration/default/controls/default_spec.rb: -------------------------------------------------------------------------------- 1 | control 'default' do 2 | service_name = os.family == 'debian' ? 'rsync' : 'rsyncd' 3 | describe package 'rsync' do 4 | it { should be_installed } 5 | end 6 | 7 | describe service service_name do 8 | it { should be_enabled } 9 | it { should be_running } 10 | end 11 | 12 | describe port 873 do 13 | it { should be_listening } 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root=true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | # 2 space indentation 12 | indent_style = space 13 | indent_size = 2 14 | 15 | # Avoid issues parsing cookbook files later 16 | charset = utf-8 17 | 18 | # Avoid cookstyle warnings 19 | trim_trailing_whitespace = true 20 | -------------------------------------------------------------------------------- /metadata.rb: -------------------------------------------------------------------------------- 1 | name 'rsync' 2 | maintainer 'Sous Chefs' 3 | maintainer_email 'help@sous-chefs.org' 4 | license 'Apache-2.0' 5 | description 'Installs rsync' 6 | version '4.0.11' 7 | source_url 'https://github.com/sous-chefs/rsync' 8 | issues_url 'https://github.com/sous-chefs/rsync/issues' 9 | chef_version '>= 15.3' 10 | 11 | supports 'amazon' 12 | supports 'centos' 13 | supports 'fedora' 14 | supports 'oracle' 15 | supports 'redhat' 16 | supports 'scientific' 17 | supports 'ubuntu' 18 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["config:base"], 4 | "packageRules": [ 5 | { 6 | "groupName": "Actions", 7 | "matchUpdateTypes": ["minor", "patch", "pin"], 8 | "automerge": true, 9 | "addLabels": ["Release: Patch", "Skip: Announcements"] 10 | }, 11 | { 12 | "groupName": "Actions", 13 | "matchUpdateTypes": ["major"], 14 | "automerge": false, 15 | "addLabels": ["Release: Patch", "Skip: Announcements"] 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /test/integration/read-only/controls/default_spec.rb: -------------------------------------------------------------------------------- 1 | control 'read-only' do 2 | # rsync is serving /tmp 3 | describe command('rsync rsync://127.0.0.1') do 4 | its('stdout') { should match /tmp/ } 5 | its('exit_status') { should eq 0 } 6 | end 7 | 8 | describe ini '/etc/rsyncd.conf' do 9 | its('tmp.read only') { should cmp 'true' } # rsync is readonly 10 | its('tmp.uid') { should cmp 'nobody' } # rsync is using nobody:nobody 11 | its('tmp.gid') { should cmp 'nobody' } # rsync is using nobody:nobodyend 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: release 3 | 4 | "on": 5 | push: 6 | branches: 7 | - main 8 | 9 | permissions: 10 | contents: write 11 | issues: write 12 | pull-requests: write 13 | packages: write 14 | attestations: write 15 | id-token: write 16 | 17 | jobs: 18 | release: 19 | uses: sous-chefs/.github/.github/workflows/release-cookbook.yml@5.0.3 20 | secrets: 21 | token: ${{ secrets.PORTER_GITHUB_TOKEN }} 22 | supermarket_user: ${{ secrets.CHEF_SUPERMARKET_USER }} 23 | supermarket_key: ${{ secrets.CHEF_SUPERMARKET_KEY }} 24 | -------------------------------------------------------------------------------- /libraries/helpers.rb: -------------------------------------------------------------------------------- 1 | module Rsync 2 | module Cookbook 3 | module Helpers 4 | def rsync_service_name 5 | if platform_family?('debian') 6 | 'rsync' 7 | else 8 | 'rsyncd' 9 | end 10 | end 11 | 12 | def rsync_defaults_file 13 | if platform_family?('debian') 14 | '/etc/default/rsync' 15 | else 16 | '/etc/sysconfig/rsyncd' 17 | end 18 | end 19 | end 20 | end 21 | end 22 | Chef::DSL::Recipe.include ::Rsync::Cookbook::Helpers 23 | Chef::Resource.include ::Rsync::Cookbook::Helpers 24 | -------------------------------------------------------------------------------- /.overcommit.yml: -------------------------------------------------------------------------------- 1 | --- 2 | PreCommit: 3 | TrailingWhitespace: 4 | enabled: true 5 | YamlLint: 6 | enabled: true 7 | required_executable: "yamllint" 8 | ChefSpec: 9 | enabled: true 10 | required_executable: "chef" 11 | command: ["chef", "exec", "rspec"] 12 | Cookstyle: 13 | enabled: true 14 | required_executable: "cookstyle" 15 | command: ["cookstyle"] 16 | MarkdownLint: 17 | enabled: false 18 | required_executable: "npx" 19 | command: ["npx", "markdownlint-cli2", "'**/*.md'"] 20 | include: ["**/*.md"] 21 | 22 | CommitMsg: 23 | HardTabs: 24 | enabled: true 25 | -------------------------------------------------------------------------------- /.github/workflows/copilot-setup-steps.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: 'Copilot Setup Steps' 3 | 4 | "on": 5 | workflow_dispatch: 6 | push: 7 | paths: 8 | - .github/workflows/copilot-setup-steps.yml 9 | pull_request: 10 | paths: 11 | - .github/workflows/copilot-setup-steps.yml 12 | 13 | jobs: 14 | copilot-setup-steps: 15 | runs-on: ubuntu-latest 16 | permissions: 17 | contents: read 18 | steps: 19 | - name: Check out code 20 | uses: actions/checkout@v5 21 | - name: Install Chef 22 | uses: actionshub/chef-install@main 23 | - name: Install cookbooks 24 | run: berks install 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.rbc 2 | .config 3 | InstalledFiles 4 | pkg 5 | test/tmp 6 | test/version_tmp 7 | tmp 8 | _Store 9 | *~ 10 | *# 11 | .#* 12 | \#*# 13 | *.un~ 14 | *.tmp 15 | *.bk 16 | *.bkup 17 | 18 | # editor files 19 | .idea 20 | .*.sw[a-z] 21 | 22 | # ruby/bundler/rspec files 23 | .ruby-version 24 | .ruby-gemset 25 | .rvmrc 26 | Gemfile.lock 27 | .bundle 28 | *.gem 29 | coverage 30 | spec/reports 31 | 32 | # YARD / rdoc artifacts 33 | .yardoc 34 | _yardoc 35 | doc/ 36 | rdoc 37 | 38 | # chef infra stuff 39 | Berksfile.lock 40 | .kitchen 41 | kitchen.local.yml 42 | vendor/ 43 | .coverage/ 44 | .zero-knife.rb 45 | Policyfile.lock.json 46 | 47 | # vagrant stuff 48 | .vagrant/ 49 | .vagrant.d/ 50 | -------------------------------------------------------------------------------- /recipes/default.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: rsync 3 | # Recipe:: default 4 | # 5 | # Copyright:: 2008-2019, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | package 'rsync' 21 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/networking.rb: -------------------------------------------------------------------------------- 1 | apt_update 'update' if platform_family?('debian') 2 | 3 | include_recipe 'rsync::server' 4 | 5 | rsync_serve 'centos-prod' do 6 | path '/data/repos/prod/centos' 7 | comment 'CentOS prod mirror' 8 | read_only true 9 | use_chroot true 10 | list true 11 | uid 'nobody' 12 | gid 'nobody' 13 | hosts_allow '127.0.0.1, 10.4.1.0/24, 192.168.4.0/24' 14 | hosts_deny '0.0.0.0/0' 15 | max_connections 10 16 | transfer_logging true 17 | log_file '/tmp/centos-sync' 18 | prexfer_exec '/bin/true' 19 | postxfer_exec '/bin/true' 20 | incoming_chmod 'a=r,u+w,D+x' 21 | outgoing_chmod 'a=r,u+w,D+x' 22 | end 23 | -------------------------------------------------------------------------------- /attributes/default.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: rsync 3 | # Attribute:: default 4 | # 5 | # Copyright:: 2012-2019, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # 18 | default['rsyncd']['config'] = '/etc/rsyncd.conf' 19 | default['rsyncd']['globals'] = {} 20 | default['rsyncd']['options'] = '' 21 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Mark stale issues and pull requests 3 | 4 | "on": 5 | schedule: [cron: "0 0 * * *"] 6 | 7 | jobs: 8 | stale: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/stale@v10 12 | with: 13 | repo-token: ${{ secrets.GITHUB_TOKEN }} 14 | close-issue-message: > 15 | Closing due to inactivity. 16 | If this is still an issue please reopen or open another issue. 17 | Alternatively drop by the #sous-chefs channel on the [Chef Community Slack](http://community-slack.chef.io/) and we'll be happy to help! 18 | Thanks, Sous-Chefs. 19 | days-before-close: 7 20 | days-before-stale: 365 21 | stale-issue-message: > 22 | Marking stale due to inactivity. 23 | Remove stale label or comment or this will be closed in 7 days. 24 | Alternatively drop by the #sous-chefs channel on the [Chef Community Slack](http://community-slack.chef.io/) and we'll be happy to help! 25 | Thanks, Sous-Chefs. 26 | -------------------------------------------------------------------------------- /kitchen.global.yml: -------------------------------------------------------------------------------- 1 | --- 2 | provisioner: 3 | name: chef_infra 4 | product_name: chef 5 | product_version: <%= ENV['CHEF_VERSION'] || 'latest' %> 6 | channel: stable 7 | install_strategy: once 8 | chef_license: accept 9 | enforce_idempotency: <%= ENV['ENFORCE_IDEMPOTENCY'] || true %> 10 | multiple_converge: <%= ENV['MULTIPLE_CONVERGE'] || 2 %> 11 | deprecations_as_errors: true 12 | log_level: <%= ENV['CHEF_LOG_LEVEL'] || 'auto' %> 13 | 14 | verifier: 15 | name: inspec 16 | 17 | platforms: 18 | - name: almalinux-8 19 | - name: almalinux-9 20 | - name: amazonlinux-2023 21 | - name: centos-7 22 | - name: centos-stream-8 23 | - name: centos-stream-9 24 | - name: debian-9 25 | - name: debian-10 26 | - name: debian-11 27 | - name: debian-12 28 | - name: fedora-latest 29 | - name: opensuse-leap-15 30 | - name: oraclelinux-7 31 | - name: oraclelinux-8 32 | - name: oraclelinux-9 33 | - name: rockylinux-8 34 | - name: rockylinux-9 35 | - name: ubuntu-18.04 36 | - name: ubuntu-20.04 37 | - name: ubuntu-22.04 38 | - name: ubuntu-23.04 39 | -------------------------------------------------------------------------------- /kitchen.yml: -------------------------------------------------------------------------------- 1 | driver: 2 | name: vagrant 3 | 4 | provisioner: 5 | name: chef_infra 6 | product_name: chef 7 | enforce_idempotency: true 8 | multiple_converge: 2 9 | deprecations_as_errors: true 10 | 11 | verifier: 12 | name: inspec 13 | 14 | platforms: 15 | - name: almalinux-8 16 | - name: amazonlinux-2023 17 | - name: centos-7 18 | - name: centos-stream-8 19 | - name: debian-10 20 | - name: debian-11 21 | - name: debian-12 22 | - name: fedora-latest 23 | - name: opensuse-leap-15 24 | - name: rockylinux-8 25 | - name: ubuntu-18.04 26 | - name: ubuntu-20.04 27 | - name: ubuntu-22.04 28 | 29 | suites: 30 | - name: simple 31 | run_list: 32 | - recipe[test::simple] 33 | verifier: 34 | inspec_tests: 35 | - name: rsync-integration-tests 36 | path: test/integration/default 37 | - name: read-only 38 | run_list: 39 | - recipe[test::read_only] 40 | verifier: 41 | inspec_tests: 42 | - name: rsync-integration-tests 43 | path: test/integration/default 44 | - name: networking 45 | run_list: 46 | - recipe[test::networking] 47 | verifier: 48 | inspec_tests: 49 | - name: rsync-integration-tests 50 | path: test/integration/default 51 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: ci 3 | 4 | "on": 5 | pull_request: 6 | push: 7 | branches: 8 | - main 9 | 10 | jobs: 11 | lint-unit: 12 | uses: sous-chefs/.github/.github/workflows/lint-unit.yml@5.0.3 13 | permissions: 14 | actions: write 15 | checks: write 16 | pull-requests: write 17 | statuses: write 18 | issues: write 19 | 20 | integration: 21 | needs: "lint-unit" 22 | 23 | runs-on: ubuntu-latest 24 | strategy: 25 | matrix: 26 | os: 27 | - almalinux-8 28 | - amazonlinux-2023 29 | - centos-stream-8 30 | - debian-10 31 | - debian-11 32 | - debian-12 33 | - fedora-latest 34 | - opensuse-leap-15 35 | - rockylinux-8 36 | - ubuntu-1804 37 | - ubuntu-2004 38 | - ubuntu-2204 39 | suite: 40 | - simple 41 | - read-only 42 | - networking 43 | fail-fast: false 44 | 45 | steps: 46 | - name: Check out code 47 | uses: actions/checkout@v5 48 | - name: Install Chef 49 | uses: actionshub/chef-install@3.0.1 50 | - name: Dokken 51 | uses: actionshub/test-kitchen@3.0.0 52 | env: 53 | CHEF_LICENSE: accept-no-persist 54 | KITCHEN_LOCAL_YAML: kitchen.dokken.yml 55 | with: 56 | suite: ${{ matrix.suite }} 57 | os: ${{ matrix.os }} 58 | -------------------------------------------------------------------------------- /recipes/server.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: rsync 3 | # Recipe:: server 4 | # 5 | # Copyright:: 2012-2019, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # 18 | 19 | include_recipe 'rsync::default' 20 | 21 | systemd_unit 'rsync' do 22 | content <<~EOU 23 | [Unit] 24 | Description=fast remote file copy program daemon 25 | ConditionPathExists=#{node['rsyncd']['config']} 26 | 27 | [Service] 28 | EnvironmentFile=#{rsync_defaults_file} 29 | ExecStart=/usr/bin/rsync --daemon --no-detach --config #{node['rsyncd']['config']} "$OPTIONS" 30 | 31 | [Install] 32 | WantedBy=multi-user.target 33 | EOU 34 | unit_name "#{rsync_service_name}.service" 35 | notifies :restart, 'service[rsync]' 36 | action :create 37 | end 38 | 39 | template rsync_defaults_file do 40 | source 'rsync-defaults.erb' 41 | notifies :restart, 'service[rsync]' 42 | end 43 | 44 | service 'rsync' do 45 | service_name rsync_service_name 46 | action [:enable, :start] 47 | end 48 | -------------------------------------------------------------------------------- /test/integration/networking/controls/default_spec.rb: -------------------------------------------------------------------------------- 1 | control 'networking' do 2 | # rsync is serving /data/repos/prod/centos 3 | describe command 'rsync rsync://127.0.0.1' do 4 | its('stdout') { should match /centos-prod\s+CentOS prod mirror/ } 5 | its('exit_status') { should eq 0 } 6 | end 7 | 8 | describe ini '/etc/rsyncd.conf' do 9 | its('centos-prod.path') { should cmp '/data/repos/prod/centos' } # rsync added path 10 | its('centos-prod.comment') { should cmp 'CentOS prod mirror' } # rsync added comment 11 | its('centos-prod.read only') { should cmp 'true' } # rsync is readonly 12 | its('centos-prod.list') { should cmp 'true' } # rsync has list true 13 | its('centos-prod.uid') { should cmp 'nobody' } # rsync is using nobody:nobody 14 | its('centos-prod.gid') { should cmp 'nobody' } # rsync is using nobody:nobody 15 | its('centos-prod.hosts allow') { should cmp '127.0.0.1, 10.4.1.0/24, 192.168.4.0/24' } 16 | its('centos-prod.hosts deny') { should cmp '0.0.0.0/0' } 17 | its('centos-prod.max connections') { should cmp '10' } 18 | its('centos-prod.transfer logging') { should cmp 'true' } 19 | its('centos-prod.log file') { should cmp '/tmp/centos-sync' } 20 | its('centos-prod.pre-xfer exec') { should cmp '/bin/true' } 21 | its('centos-prod.post-xfer exec') { should cmp '/bin/true' } 22 | its('centos-prod.incoming chmod') { should cmp 'a=r,u+w,D+x' } 23 | its('centos-prod.outgoing chmod') { should cmp 'a=r,u+w,D+x' } 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /Dangerfile: -------------------------------------------------------------------------------- 1 | # Reference: http://danger.systems/reference.html 2 | 3 | # A pull request summary is required. Add a description of the pull request purpose. 4 | # Changelog must be updated for each pull request that changes code. 5 | # Warnings will be issued for: 6 | # Pull request with more than 400 lines of code changed 7 | # Pull reqest that change more than 5 lines without test changes 8 | # Failures will be issued for: 9 | # Pull request without summary 10 | # Pull requests with code changes without changelog entry 11 | 12 | def code_changes? 13 | code = %w(libraries attributes recipes resources files templates) 14 | code.each do |location| 15 | return true unless git.modified_files.grep(/#{location}/).empty? 16 | end 17 | false 18 | end 19 | 20 | def test_changes? 21 | tests = %w(spec test kitchen.yml kitchen.dokken.yml) 22 | tests.each do |location| 23 | return true unless git.modified_files.grep(/#{location}/).empty? 24 | end 25 | false 26 | end 27 | 28 | failure 'Please provide a summary of your Pull Request.' if github.pr_body.length < 10 29 | 30 | warn 'This is a big Pull Request.' if git.lines_of_code > 400 31 | 32 | warn 'This is a Table Flip.' if git.lines_of_code > 2000 33 | 34 | # Require a CHANGELOG entry for non-test changes. 35 | if !git.modified_files.include?('CHANGELOG.md') && code_changes? 36 | failure 'Please include a CHANGELOG entry.' 37 | end 38 | 39 | # Require Major Minor Patch version labels 40 | unless github.pr_labels.grep /minor|major|patch/i 41 | warn 'Please add a release label to this pull request' 42 | end 43 | 44 | # A sanity check for tests. 45 | if git.lines_of_code > 5 && code_changes? && !test_changes? 46 | warn 'This Pull Request is probably missing tests.' 47 | end 48 | -------------------------------------------------------------------------------- /spec/server_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'rsync::server' do 4 | before :each do 5 | allow(File).to receive(:exist?).and_call_original 6 | allow(File).to receive(:exist?).with('/etc/rsyncd.conf').and_return(true) 7 | end 8 | 9 | context 'on rhel' do 10 | cached(:chef_run) do 11 | ChefSpec::SoloRunner.new(platform: 'centos', version: '8').converge('rsync::server') 12 | end 13 | 14 | it 'includes the default recipe' do 15 | expect(chef_run).to include_recipe('rsync::default') 16 | end 17 | 18 | it 'starts and enables the rsync service' do 19 | expect(chef_run).to enable_service('rsyncd') 20 | end 21 | end 22 | 23 | context 'on debian' do 24 | cached(:chef_run) do 25 | ChefSpec::SoloRunner.new(platform: 'ubuntu', version: '20.04').converge('rsync::server') 26 | end 27 | 28 | it 'includes the default recipe' do 29 | expect(chef_run).to include_recipe('rsync::default') 30 | end 31 | 32 | context '/etc/default/rsync template' do 33 | let(:template) { chef_run.template('/etc/default/rsync') } 34 | 35 | it 'writes the template' do 36 | expect(chef_run).to render_file('/etc/default/rsync').with_content('defaults file for rsync daemon mode') 37 | end 38 | end 39 | 40 | it 'starts and enables the rsync service' do 41 | expect(chef_run).to enable_service('rsync') 42 | end 43 | end 44 | context 'on amazon' do 45 | cached(:chef_run) do 46 | ChefSpec::SoloRunner.new(platform: 'amazon', version: '2').converge('rsync::server') 47 | end 48 | 49 | it 'includes the default recipe' do 50 | expect(chef_run).to include_recipe('rsync::default') 51 | end 52 | 53 | it 'starts and enables the rsync service' do 54 | expect(chef_run).to enable_service('rsyncd') 55 | end 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /chefignore: -------------------------------------------------------------------------------- 1 | # Put files/directories that should be ignored in this file when uploading 2 | # to a Chef Infra Server or Supermarket. 3 | # Lines that start with '# ' are comments. 4 | 5 | # OS generated files # 6 | ###################### 7 | .DS_Store 8 | ehthumbs.db 9 | Icon? 10 | nohup.out 11 | Thumbs.db 12 | .envrc 13 | 14 | # EDITORS # 15 | ########### 16 | .#* 17 | .project 18 | .settings 19 | *_flymake 20 | *_flymake.* 21 | *.bak 22 | *.sw[a-z] 23 | *.tmproj 24 | *~ 25 | \#* 26 | REVISION 27 | TAGS* 28 | tmtags 29 | .vscode 30 | .editorconfig 31 | 32 | ## COMPILED ## 33 | ############## 34 | *.class 35 | *.com 36 | *.dll 37 | *.exe 38 | *.o 39 | *.pyc 40 | *.so 41 | */rdoc/ 42 | a.out 43 | mkmf.log 44 | 45 | # Testing # 46 | ########### 47 | .circleci/* 48 | .codeclimate.yml 49 | .delivery/* 50 | .foodcritic 51 | .kitchen* 52 | .mdlrc 53 | .overcommit.yml 54 | .rspec 55 | .rubocop.yml 56 | .travis.yml 57 | .watchr 58 | .yamllint 59 | azure-pipelines.yml 60 | Dangerfile 61 | examples/* 62 | features/* 63 | Guardfile 64 | kitchen*.yml 65 | mlc_config.json 66 | Procfile 67 | Rakefile 68 | spec/* 69 | test/* 70 | 71 | # SCM # 72 | ####### 73 | .git 74 | .gitattributes 75 | .gitconfig 76 | .github/* 77 | .gitignore 78 | .gitkeep 79 | .gitmodules 80 | .svn 81 | */.bzr/* 82 | */.git 83 | */.hg/* 84 | */.svn/* 85 | 86 | # Berkshelf # 87 | ############# 88 | Berksfile 89 | Berksfile.lock 90 | cookbooks/* 91 | tmp 92 | 93 | # Bundler # 94 | ########### 95 | vendor/* 96 | Gemfile 97 | Gemfile.lock 98 | 99 | # Policyfile # 100 | ############## 101 | Policyfile.rb 102 | Policyfile.lock.json 103 | 104 | # Documentation # 105 | ############# 106 | CODE_OF_CONDUCT* 107 | CONTRIBUTING* 108 | documentation/* 109 | TESTING* 110 | UPGRADING* 111 | 112 | # Vagrant # 113 | ########### 114 | .vagrant 115 | Vagrantfile 116 | -------------------------------------------------------------------------------- /kitchen.dokken.yml: -------------------------------------------------------------------------------- 1 | driver: 2 | name: dokken 3 | privileged: true 4 | chef_version: <%= ENV['CHEF_VERSION'] || 'current' %> 5 | 6 | transport: { name: dokken } 7 | provisioner: { name: dokken } 8 | 9 | platforms: 10 | - name: almalinux-8 11 | driver: 12 | image: dokken/almalinux-8 13 | pid_one_command: /usr/lib/systemd/systemd 14 | 15 | - name: almalinux-9 16 | driver: 17 | image: dokken/almalinux-9 18 | pid_one_command: /usr/lib/systemd/systemd 19 | 20 | - name: amazonlinux-2023 21 | driver: 22 | image: dokken/amazonlinux-2023 23 | pid_one_command: /usr/lib/systemd/systemd 24 | 25 | - name: centos-7 26 | driver: 27 | image: dokken/centos-7 28 | pid_one_command: /usr/lib/systemd/systemd 29 | 30 | - name: centos-stream-8 31 | driver: 32 | image: dokken/centos-stream-8 33 | pid_one_command: /usr/lib/systemd/systemd 34 | 35 | - name: centos-stream-9 36 | driver: 37 | image: dokken/centos-stream-9 38 | pid_one_command: /usr/lib/systemd/systemd 39 | 40 | - name: debian-9 41 | driver: 42 | image: dokken/debian-9 43 | pid_one_command: /bin/systemd 44 | 45 | - name: debian-10 46 | driver: 47 | image: dokken/debian-10 48 | pid_one_command: /bin/systemd 49 | 50 | - name: debian-11 51 | driver: 52 | image: dokken/debian-11 53 | pid_one_command: /bin/systemd 54 | 55 | - name: debian-12 56 | driver: 57 | image: dokken/debian-12 58 | pid_one_command: /bin/systemd 59 | 60 | - name: fedora-latest 61 | driver: 62 | image: dokken/fedora-latest 63 | pid_one_command: /usr/lib/systemd/systemd 64 | 65 | - name: opensuse-leap-15 66 | driver: 67 | image: dokken/opensuse-leap-15 68 | pid_one_command: /usr/lib/systemd/systemd 69 | 70 | - name: oraclelinux-7 71 | driver: 72 | image: dokken/oraclelinux-7 73 | pid_one_command: /usr/lib/systemd/systemd 74 | 75 | - name: oraclelinux-8 76 | driver: 77 | image: dokken/oraclelinux-8 78 | pid_one_command: /usr/lib/systemd/systemd 79 | 80 | - name: oraclelinux-9 81 | driver: 82 | image: dokken/oraclelinux-9 83 | pid_one_command: /usr/lib/systemd/systemd 84 | 85 | - name: rockylinux-8 86 | driver: 87 | image: dokken/rockylinux-8 88 | pid_one_command: /usr/lib/systemd/systemd 89 | 90 | - name: rockylinux-9 91 | driver: 92 | image: dokken/rockylinux-9 93 | pid_one_command: /usr/lib/systemd/systemd 94 | 95 | - name: ubuntu-18.04 96 | driver: 97 | image: dokken/ubuntu-18.04 98 | pid_one_command: /bin/systemd 99 | 100 | - name: ubuntu-20.04 101 | driver: 102 | image: dokken/ubuntu-20.04 103 | pid_one_command: /bin/systemd 104 | 105 | - name: ubuntu-22.04 106 | driver: 107 | image: dokken/ubuntu-22.04 108 | pid_one_command: /bin/systemd 109 | 110 | - name: ubuntu-23.04 111 | driver: 112 | image: dokken/ubuntu-23.04 113 | pid_one_command: /bin/systemd 114 | -------------------------------------------------------------------------------- /resources/serve.rb: -------------------------------------------------------------------------------- 1 | unified_mode true 2 | 3 | # man rsyncd.conf for more info on each property 4 | property :config_path, String, default: '/etc/rsyncd.conf' 5 | property :path, String, required: true 6 | property :comment, String 7 | property :read_only, [true, false] 8 | property :write_only, [true, false] 9 | property :list, [true, false] 10 | property :uid, String 11 | property :gid, String 12 | property :auth_users, String 13 | property :secrets_file, String 14 | property :hosts_allow, String 15 | property :hosts_deny, String 16 | property :max_connections, Integer, default: 0 17 | property :munge_symlinks, [true, false], default: true 18 | property :use_chroot, [true, false] 19 | property :numeric_ids, [true, false], default: true 20 | property :fake_super, [true, false] 21 | property :exclude_from, String 22 | property :exclude, String 23 | property :include_from, String 24 | property :include, String 25 | property :strict_modes, [true, false] 26 | property :log_file, String 27 | property :log_format, String 28 | property :transfer_logging, [true, false] 29 | # by default rsync sets no client timeout (lets client choose, but this is a trivial DOS) so we make a 10 minute one 30 | property :timeout, Integer, default: 600 31 | property :dont_compress, String 32 | property :lock_file, String 33 | property :refuse_options, String 34 | property :prexfer_exec, String 35 | property :postxfer_exec, String 36 | property :incoming_chmod, String 37 | property :outgoing_chmod, String 38 | 39 | action :add do 40 | write_conf 41 | end 42 | 43 | action :remove do 44 | write_conf 45 | end 46 | 47 | action_class do 48 | # 49 | # Walk collection for :add rsync_serve resources 50 | # Build and write the config template 51 | # 52 | def write_conf 53 | template(new_resource.config_path) do 54 | source 'rsyncd.conf.erb' 55 | cookbook 'rsync' 56 | owner 'root' 57 | group 'root' 58 | mode '0640' 59 | variables( 60 | globals: global_modules, 61 | modules: rsync_modules 62 | ) 63 | notifies :restart, "service[#{rsync_service_name}]", :delayed 64 | end 65 | 66 | service rsync_service_name do 67 | action :nothing 68 | end 69 | end 70 | 71 | # The list of attributes for this resource. 72 | # 73 | # @todo find a better way to do this 74 | # 75 | # @return [Array] 76 | def resource_attributes 77 | %w( 78 | auth_users 79 | comment 80 | dont_compress 81 | exclude 82 | exclude_from 83 | fake_super 84 | gid 85 | hosts_allow 86 | hosts_deny 87 | include 88 | include_from 89 | incoming_chmod 90 | list 91 | lock_file 92 | log_file 93 | log_format 94 | max_connections 95 | munge_symlinks 96 | numeric_ids 97 | outgoing_chmod 98 | path 99 | postxfer_exec 100 | prexfer_exec 101 | read_only 102 | refuse_options 103 | secrets_file 104 | strict_modes 105 | timeout 106 | transfer_logging 107 | uid 108 | use_chroot 109 | write_only 110 | ) 111 | end 112 | 113 | # The list of rsync server resources in the resource collection 114 | # 115 | # @return [Array] 116 | def rsync_resources 117 | ::ObjectSpace.each_object(::Chef::Resource).select do |resource| 118 | resource.resource_name == :rsync_serve 119 | end 120 | end 121 | 122 | # Perform replacement on specific (un)hyphenated config directives. 123 | # 124 | # @param [String] string 125 | # 126 | # @return [String] 127 | def unhyphenate(string) 128 | string.to_s.gsub(/(pre|post)xfer/, '\1-xfer') 129 | end 130 | 131 | # Expand "snake_case_things" to "snake case things". 132 | # 133 | # @param [String] string 134 | # 135 | # @return [String] 136 | def snake_to_space(string) 137 | string.to_s.tr('_', ' ') 138 | end 139 | 140 | # Converts a provider attribute to an rsync config directive. 141 | # 142 | # @param [String] string 143 | # 144 | # @return [String] 145 | def attribute_to_directive(string) 146 | unhyphenate(snake_to_space(string)) 147 | end 148 | 149 | # The list of rsync modules defined in the resource collection. 150 | # 151 | # @return [Hash] 152 | def rsync_modules 153 | rsync_resources.each_with_object({}) do |resource, hash| 154 | next unless resource.config_path == new_resource.config_path && ( 155 | resource.action == :add || 156 | resource.action.include?(:add) 157 | ) 158 | hash[resource.name] ||= {} 159 | resource_attributes.each do |key| 160 | value = resource.send(key) 161 | next if value.nil? 162 | hash[resource.name][attribute_to_directive(key)] = value 163 | end 164 | end 165 | end 166 | 167 | # The global rsync configuration 168 | # 169 | # @return [Hash] 170 | def global_modules 171 | node['rsyncd']['globals'].each_with_object({}) do |(key, value), hash| 172 | hash[attribute_to_directive(key)] = value unless value.nil? 173 | end 174 | end 175 | end 176 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # rsync Cookbook CHANGELOG 2 | 3 | This file is used to list changes made in each version of the rsync cookbook. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## [4.0.11](https://github.com/sous-chefs/rsync/compare/4.0.10...v4.0.11) (2025-10-16) 9 | 10 | 11 | ### Bug Fixes 12 | 13 | * **ci:** Update workflows to use release pipeline ([#74](https://github.com/sous-chefs/rsync/issues/74)) ([70f90c7](https://github.com/sous-chefs/rsync/commit/70f90c7ae26ea546659314d07ccedc30fec0ac91)) 14 | 15 | ## 4.0.0 - *2023-05-04* 16 | 17 | * Enable `unified_mode` and require Chef >= 15.3 18 | * Update and fix CI, tests and platforms 19 | * Update sous-chefs/.github action to v2 20 | * Update actions/checkout action to v3 21 | 22 | ## 3.1.5 - *2023-02-14* 23 | 24 | * Add renovate.json 25 | 26 | ## 3.1.4 - *2023-02-14* 27 | 28 | * Standardise files with files in sous-chefs/repo-management 29 | 30 | ## 3.1.3 - *2022-02-08* 31 | 32 | * Remove delivery folder 33 | 34 | ## 3.1.2 - *2021-08-30* 35 | 36 | * Standardise files with files in sous-chefs/repo-management 37 | 38 | ## 3.1.1 - *2021-06-01* 39 | 40 | * Standardise files with files in sous-chefs/repo-management 41 | 42 | ## 3.1.0 - *2020-11-20* 43 | 44 | * Fixed issue with auto release system 45 | 46 | ## 3.0.0 - *2020-11-20* 47 | 48 | ### Changed 49 | 50 | * Sous Chefs Adoption 51 | * Update Changelog to Sous Chefs 52 | * Update to use Sous Chefs GH workflow 53 | * Update README to sous-chefs 54 | * Update metadata.rb to Sous Chefs 55 | * Update test-kitchen to Sous Chefs 56 | * Improve InSpec tests 57 | 58 | ### Fixed 59 | 60 | * Yamllint fixes 61 | * MDL fixes 62 | 63 | ### Added 64 | 65 | * Management of systemd unit file 66 | * Add library helpers 67 | * Add `node['rsyncd']['options']` attribute for additional daemon arguments 68 | 69 | ### Removed 70 | 71 | * Remove testing for Amazon Linux 1 & CentOS 6 72 | * Remove support for init.d based systems 73 | * Remove the following attributes: `node['rsyncd']['service']`, `node['rsyncd']['nice']`, `node['rsyncd']['ionice']` 74 | 75 | ## 2.0.2 (2020-07-27) 76 | 77 | * Do not use kind_of in resource properties to fix failures - [@infertux](https://github.com/infertux) 78 | * Convert to a custom resource to resolve missing :remove action - [@tas50](https://github.com/tas50) 79 | * Test on Chef Infra Client 15 and 16 as well - [@tas50](https://github.com/tas50) 80 | 81 | ## 2.0.1 (2020-07-26) 82 | 83 | * Sort modules alphabetically to preserve idempotency - [@infertux](https://github.com/infertux) 84 | * Cookstyle fixes - [@tas50](https://github.com/tas50) 85 | * Standardise files with files in chef-cookbooks/repo-management - [@xorimabot](https://github.com/xorimabot) 86 | 87 | ## 3.0.0 - *2020-11-20* 88 | 89 | * resolved cookstyle error: spec/server_spec.rb:11:7 warning: `ChefDeprecations/DeprecatedChefSpecPlatform` 90 | * resolved cookstyle error: resources/serve.rb:12:1 refactor: `ChefRedundantCode/UnnecessaryNameProperty` 91 | 92 | ## 2.0.0 (2019-10-07) 93 | 94 | * Update specs to the latest platform versions - [@tas50](https://github.com/tas50) 95 | * Update the platforms we test - [@tas50](https://github.com/tas50) 96 | * Require Chef 13+ and resolve cookstyle warnings - [@tas50](https://github.com/tas50) 97 | 98 | ## 1.1.0 (2018-03-11) 99 | 100 | * Add Amazon linux compatibility for init script. 101 | * Remove the ChefSpec matchers. These are auto generated by modern ChefSpec/ChefDK 102 | 103 | ## 1.0.3 (2017-10-17) 104 | 105 | * Fix chef 13 compatibility 106 | 107 | ## 1.0.2 (2017-04-26) 108 | 109 | * Cookstyle fixes 110 | * Test with Local Delivery instead of Rake 111 | * Update apache2 license string 112 | 113 | ## 1.0.1 (2016-09-18) 114 | 115 | * Clarify in readme we require Chef 12.1+ 116 | * Update maintainer text 117 | * Disable use_inline_resources as it breaks the provider 118 | * Convert tests to use inspec 119 | * Moved all testing to the test recipe and removed the need for the apt cookbook in testing 120 | 121 | ## 1.0.0 (2016-09-07) 122 | 123 | * Run integration tests in Travis CI with kitchen-dokken 124 | * Run chefspec and cookstyle in Travis 125 | * Add use_inline_resources to the provider 126 | * Require chef 12 127 | 128 | ## v0.8.9 (2015-10-05) 129 | 130 | * Fixed support for Chef 12.4.X and later 131 | * Added Chefspec matchers 132 | * Added additional platforms to Test Kitchen 133 | * Updated rubocop rules to our standard set and resolved all warnings 134 | * Updated Travis CI to test on additional Ruby versions 135 | * Updated contributing and testing docs 136 | * Added maintainers.toml and maintainers.md files 137 | * Added additional testing depedendencies to the Gemfile with version pinning 138 | * Added cookbook version and Travis CI badges to the readme 139 | * Clarified that Chef 11.0 is the minimum required Chef version for this cookbook 140 | * Removed outdated development information from the readme 141 | * Added a Rakefile for simplified testing 142 | * Added a chefignore file to limit what files are uploaded to the Chef server 143 | * Added Amazon Linux, Oracle, and Scientific Linux to the metadata Added source_url and issues_url to metadata.rb for Supermarket 144 | * Removed all pre-Ruby 1.9 hash rockets 145 | 146 | ## v0.8.8 (2015-05-07) 147 | 148 | * [#15] Add incoming/outgoing chmod options 149 | * [#16] Add prexfer/postxfer exec commands 150 | * [#14,#17] Support Chef 12 151 | 152 | ## v0.8.6 (2014-09-30) 153 | 154 | * [#11] Fixes to allow rsync daemon to be started if not up. 155 | 156 | ## v0.8.4 157 | 158 | ### Improvement 159 | 160 | * Add Test Kitchen, Specs, and Travis CI 161 | 162 | ## v0.8.2 163 | 164 | ### Improvement 165 | 166 | * Add `refuse_options` parameter to `rsync_serve` 167 | 168 | ### Bug 169 | 170 | * Support chkconfig 171 | * Allow setting value to false in `rsyncd.conf` 172 | 173 | ## v0.8.0 174 | 175 | * [COOK-878] - Add LWRP for rsyncd.conf and server recipe 176 | 177 | ## v0.7.0 178 | 179 | * Initial released version 180 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rsync Cookbook 2 | 3 | [![Cookbook Version](https://img.shields.io/cookbook/v/rsync.svg)](https://supermarket.chef.io/cookbooks/rsync) 4 | [![CI State](https://github.com/sous-chefs/rsync/workflows/ci/badge.svg)](https://github.com/sous-chefs/rsync/actions?query=workflow%3Aci) 5 | [![OpenCollective](https://opencollective.com/sous-chefs/backers/badge.svg)](#backers) 6 | [![OpenCollective](https://opencollective.com/sous-chefs/sponsors/badge.svg)](#sponsors) 7 | [![License](https://img.shields.io/badge/License-Apache%202.0-green.svg)](https://opensource.org/licenses/Apache-2.0) 8 | 9 | Rsync cookbook with rsyncd LWRP. More info on ryncd options can be found in the [Docs](http://www.samba.org/ftp/rsync/rsyncd.conf.html). 10 | 11 | ## Requirements 12 | 13 | ### Platforms 14 | 15 | - Debian/Ubuntu 16 | - RHEL/CentOS/Scientific/Amazon/Oracle 17 | 18 | ### Chef 19 | 20 | - Chef >= 15.3 21 | 22 | ### Cookbooks 23 | 24 | - none 25 | 26 | ## Attributes 27 | 28 | `node['rsyncd']['config']` _(Hash) default: "/etc/rsyncd.conf"_ 29 | 30 | Path to the rsyncd config file. This is the default, but the serve resource can write config files to arbitrary paths independant of this. 31 | 32 | `node['rsyncd']['globals']` _(Hash) default: {}_ 33 | 34 | This is where you can store key-value pairs that coincide with rsyncd globals. 35 | 36 | `node['rsyncd']['options']` _(String) default: ''_ 37 | 38 | Additional daemon arguments. 39 | 40 | - **motd file:** This parameter allows you to specify a "message of the day" to display to clients on each connect. This usually contains site information and any legal notices. The default is no motd file. 41 | - **pid file:** This parameter tells the rsync daemon to write its process ID to that file. If the file already exists, the rsync daemon will abort rather than overwrite the file. 42 | - **port:** You can override the default port the daemon will listen on by specifying this value (defaults to 873). This is ignored if the daemon is being run by inetd, and is superseded by the --port command-line option. 43 | - **address:** You can override the default IP address the daemon will listen on by specifying this value. This is ignored if the daemon is being run by inetd, and is superseded by the --address command-line option. 44 | - **socket options:** This parameter can provide endless fun for people who like to tune their systems to the utmost degree. You can set all sorts of socket options which may make transfers faster (or slower!). Read the man page for the setsockopt() system call for details on some of the options you may be able to set. By default no special socket options are set. These settings can also be specified via the --sockopts command-line option. 45 | 46 | Refer to the documentation for rsyncd for more info. 47 | 48 | ## Recipes 49 | 50 | ### default 51 | 52 | This recipe simply installs the rsync package, nothing more. 53 | 54 | ## Resources/Providers 55 | 56 | ### serve 57 | 58 | This LWRP implements a rsync server module. The folowing params are chef-only, the rest implement the feature as described in the [rsyncd docs][1] 59 | 60 | #### Parameters 61 | 62 | ##### Required 63 | 64 | - `path` - Path which this module should server 65 | 66 | ##### Optional 67 | 68 | Unless specified these paramaters use the rsyncd default values as refed in the [Rsyncd docs][1]. Params are _Strings_ unless specified otherwise. 69 | 70 | - `name` - The name of this module that will be refrenced by rsync://foo/NAME. Defaults to the resource name. 71 | - `config_path` - Path to write the rsyncd config Defaults to `node['rsyncd']['config'] 72 | - `comment` - Comment when rsync gets the list of modules from the server. 73 | - `read_only` - _Boolean_ - Serve this as a read-only module. 74 | - `write_only`- _Boolean_ - Serve this as a write-only module. 75 | - `list` - _Boolean_ - Add this module the the rsync modules list 76 | - `uid` - _String_ - This parameter specifies the user name or user ID that file transfers to and from that module should take place as when the daemon was run as root. 77 | - `gid` - _String_ - This parameter specifies the group name or group ID that file transfers to and from that module should take place as when the daemon was run as root. 78 | - `auth_users` - This parameter specifies a comma and space-separated list of usernames that will be allowed to connect to this module. [more info][1] 79 | - `secrets_file` - This parameter specifies the name of a file that contains the username:password pairs used for authenticating this module. [more info][1] 80 | - `hosts_allow` - This parameter allows you to specify a list of patterns that are matched against a connecting clients hostname and IP address. If none of the patterns match then the connection is rejected. [more info][1] 81 | - `hosts_deny` - This parameter allows you to specify a list of patterns that are matched against a connecting clients hostname and IP address. If the pattern matches then the connection is rejected. [more info][1] 82 | - `max_connections` - _Fixnum_ - *Default: `0` - The maximum number of simultaneous connections you will allow. 83 | - `munge_symlinks` - _Boolean_ - *Default: `true` - This parameter tells rsync to modify all incoming symlinks in a way that makes them unusable but recoverable. [more info][1] 84 | - `use_chroot` - _Boolean_ - the rsync daemon will chroot to the "path" before starting the file transfer with the client. 85 | - `nemeric_ids` - _Boolean_ - *Default: `true` - Enabling this parameter disables the mapping of users and groups by name for the current daemon module. 86 | - `fake_super` - _Boolean_ - This allows the full attributes of a file to be stored without having to have the daemon actually running as root. 87 | - `exclude_from` - This parameter specifies the name of a file on the daemon that contains daemon exclude patterns. [more info][1] 88 | - `exclude` - This parameter specifies the name of a file on the daemon that contains daemon exclude patterns. [more info][1] 89 | - `include_from` - Analogue of `exclude_from` 90 | - `include` - Analogue of `exclude` 91 | - `strict_modes` - _Boolean_ - If true, then the secrets file must not be readable by any user ID other than the one that the rsync daemon is running under. 92 | - `log_file` - Path where you should store this modules log file. 93 | - `log_format` - The format is a text string containing embedded single-character escape sequences prefixed with a percent (%) character. An optional numeric field width may also be specified between the percent and the escape letter (e.g. "%-50n %8l %07p"). [more info][1] 94 | - `transfer_logging` - This parameter enables per-file logging of downloads and uploads in a format somewhat similar to that used by ftp daemons. The daemon always logs the transfer at the end, so if a transfer is aborted, no mention will be made in the log file. 95 | - `timeout` - _Fixnum_ - Default: `600` - Using this parameter you can ensure that rsync won't wait on a dead client forever. The timeout is specified in seconds. A value of zero means no timeout. 96 | - `dont_compress` - This parameter allows you to select filenames based on wildcard patterns that should not be compressed when pulling files from the daemon 97 | - `lock_file` - This parameter specifies the file to use to support the "max connections" parameter. The rsync daemon uses record locking on this file to ensure that the max connections limit is not exceeded for the modules sharing the lock file. The default is /var/run/rsyncd.lock 98 | - `refuse_options` - This parameter allows you to specify a space-separated list of rsync command line options that will be refused by your rsync daemon. 99 | - `prexfer_exec` - A command to run before each transfer to or from this module. If this command fails, the transfer will be aborted. 100 | - `postxfer_exec` - A command to run after each transfer to or from this module. 101 | 102 | ## Usage 103 | 104 | After loading the rsync cookbook you have access to the `rsync_serve` resource for serving up a generic rsyncd module with many options. 105 | 106 | **You must include the `rsync::server` recipe before you can use the LWRP** as shown in the examples below. 107 | 108 | ### Examples 109 | 110 | Serve a directory: 111 | 112 | ```ruby 113 | include_recipe 'rsync::server' 114 | 115 | rsync_serve 'tmp' do 116 | path '/tmp' 117 | end 118 | ``` 119 | 120 | Serve a directory with read only and specify uids: 121 | 122 | ```ruby 123 | include_recipe 'rsync::server' 124 | 125 | rsync_serve 'tmp' do 126 | path '/tmp' 127 | uid 'nobody' 128 | gid 'nobody' 129 | read_only true 130 | end 131 | ``` 132 | 133 | A more complex example with networking: 134 | 135 | ```ruby 136 | include_recipe 'rsync::server' 137 | 138 | rsync_serve 'centos-prod' do 139 | path '/data/repos/prod/centos' 140 | comment 'CentOS prod mirror' 141 | read_only true 142 | use_chroot true 143 | list true 144 | uid 'nobody' 145 | gid 'nobody' 146 | hosts_allow '127.0.0.1, 10.4.1.0/24, 192.168.4.0/24' 147 | hosts_deny '0.0.0.0/0' 148 | max_connections 10 149 | transfer_logging true 150 | log_file '/tmp/centos-sync' 151 | postxfer_exec '/usr/local/bin/collect_things.sh' 152 | end 153 | ``` 154 | 155 | ## Contributors 156 | 157 | This project exists thanks to all the people who [contribute.](https://opencollective.com/sous-chefs/contributors.svg?width=890&button=false) 158 | 159 | ### Backers 160 | 161 | Thank you to all our backers! 162 | 163 | ![https://opencollective.com/sous-chefs#backers](https://opencollective.com/sous-chefs/backers.svg?width=600&avatarHeight=40) 164 | 165 | ### Sponsors 166 | 167 | Support this project by becoming a sponsor. Your logo will show up here with a link to your website. 168 | 169 | ![https://opencollective.com/sous-chefs/sponsor/0/website](https://opencollective.com/sous-chefs/sponsor/0/avatar.svg?avatarHeight=100) 170 | ![https://opencollective.com/sous-chefs/sponsor/1/website](https://opencollective.com/sous-chefs/sponsor/1/avatar.svg?avatarHeight=100) 171 | ![https://opencollective.com/sous-chefs/sponsor/2/website](https://opencollective.com/sous-chefs/sponsor/2/avatar.svg?avatarHeight=100) 172 | ![https://opencollective.com/sous-chefs/sponsor/3/website](https://opencollective.com/sous-chefs/sponsor/3/avatar.svg?avatarHeight=100) 173 | ![https://opencollective.com/sous-chefs/sponsor/4/website](https://opencollective.com/sous-chefs/sponsor/4/avatar.svg?avatarHeight=100) 174 | ![https://opencollective.com/sous-chefs/sponsor/5/website](https://opencollective.com/sous-chefs/sponsor/5/avatar.svg?avatarHeight=100) 175 | ![https://opencollective.com/sous-chefs/sponsor/6/website](https://opencollective.com/sous-chefs/sponsor/6/avatar.svg?avatarHeight=100) 176 | ![https://opencollective.com/sous-chefs/sponsor/7/website](https://opencollective.com/sous-chefs/sponsor/7/avatar.svg?avatarHeight=100) 177 | ![https://opencollective.com/sous-chefs/sponsor/8/website](https://opencollective.com/sous-chefs/sponsor/8/avatar.svg?avatarHeight=100) 178 | ![https://opencollective.com/sous-chefs/sponsor/9/website](https://opencollective.com/sous-chefs/sponsor/9/avatar.svg?avatarHeight=100) 179 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | --------------------------------------------------------------------------------