Commit ec6c0fc78ba325b3ae505719382b9b15b1b6d4ba
1 parent
36b9f84a
First version of cookbook backup-file2s3
Showing
14 changed files
with
560 additions
and
0 deletions
.gitignore
0 → 100644
.kitchen.yml
0 → 100644
1 | +--- | |
2 | +driver: | |
3 | + name: ec2 | |
4 | + aws_ssh_key_id: cfe_stg_20160222 | |
5 | + security_group_ids: ["sg-7f6fda18"] | |
6 | + region: us-west-2 | |
7 | + availability_zone: b | |
8 | + subnet_id: subnet-d530d8b1 | |
9 | + instance_type: t2.micro | |
10 | + associate_public_ip: true | |
11 | + require_chef_omnibus: true | |
12 | + shared_credentials_profile: earth | |
13 | + | |
14 | +provisioner: | |
15 | + name: chef_solo | |
16 | + | |
17 | +platforms: | |
18 | + - name: ubuntu-14.04 | |
19 | + driver: | |
20 | + image_id: ami-50946030 | |
21 | + transport: | |
22 | + username: ubuntu | |
23 | + ssh_key: ~/.ssh/cfe_stg_20160222.pem | |
24 | + | |
25 | +suites: | |
26 | + - name: default | |
27 | + run_list: | |
28 | + - recipe[backup-file2s3::default] | |
29 | + attributes: | ... | ... |
CHANGELOG.md
0 → 100644
Gemfile
0 → 100644
README.md
0 → 100644
1 | +# backup-file2s3-cookbook | |
2 | + | |
3 | +Installs a script that backs up one or more directories into an S3 bucket. Also sets up the cronjob to regularly run said script. | |
4 | + | |
5 | +## Supported Platforms | |
6 | + | |
7 | +Ubuntu 14.04 | |
8 | + | |
9 | +## Attributes | |
10 | + | |
11 | +<table> | |
12 | + <tr> | |
13 | + <th>Key</th> | |
14 | + <th>Type</th> | |
15 | + <th>Description</th> | |
16 | + <th>Default</th> | |
17 | + </tr> | |
18 | + <tr> | |
19 | + <td><tt>['backup-file2s3']['bucket']</tt></td> | |
20 | + <td>String</td> | |
21 | + <td>The S3 bucket where backup tarballs will be stored.</td> | |
22 | + <td><tt>nil</tt></td> | |
23 | + </tr> | |
24 | + <tr> | |
25 | + <td><tt>['backup-file2s3']['region']</tt></td> | |
26 | + <td>String</td> | |
27 | + <td>AWS region of the bucket.</td> | |
28 | + <td><tt>'us-east-1'</tt></td> | |
29 | + </tr> | |
30 | + <tr> | |
31 | + <td><tt>['backup-file2s3']['max_backups']</tt></td> | |
32 | + <td>Integer</td> | |
33 | + <td>Number of old backup tarballs to retain in S3.</td> | |
34 | + <td><tt>30</tt></td> | |
35 | + </tr> | |
36 | + <tr> | |
37 | + <td><tt>['backup-file2s3']['dirs']</tt></td> | |
38 | + <td>Array</td> | |
39 | + <td>An array of directories to be backed up.</td> | |
40 | + <td><tt>[]</tt></td> | |
41 | + </tr> | |
42 | + <tr> | |
43 | + <td><tt>['backup-file2s3']['cron']['min']</tt></td> | |
44 | + <td>String</td> | |
45 | + <td>Related cron attributes are: `hour`, `day`, `mon`, `wday`, each specifying a corresponding crontab value. This cron job will determine how often the backup script is run.</td> | |
46 | + <td><tt>nil</tt></td> | |
47 | + </tr> | |
48 | +</table> | |
49 | + | |
50 | +## Usage | |
51 | + | |
52 | +### backup-file2s3::default | |
53 | + | |
54 | +Include `backup-file2s3` in your node's `run_list`: | |
55 | + | |
56 | +```json | |
57 | +{ | |
58 | + "run_list": [ | |
59 | + "recipe[backup-file2s3::default]" | |
60 | + ] | |
61 | +} | |
62 | +``` | |
63 | + | |
64 | +## License and Authors | |
65 | + | |
66 | +Author:: Earth U. (<sysadmin@chromedia.com>) | ... | ... |
Thorfile
0 → 100644
Vagrantfile
0 → 100644
1 | +# -*- mode: ruby -*- | |
2 | +# vi: set ft=ruby : | |
3 | + | |
4 | +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! | |
5 | +VAGRANTFILE_API_VERSION = '2' | |
6 | + | |
7 | +Vagrant.require_version '>= 1.5.0' | |
8 | + | |
9 | +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| | |
10 | + # All Vagrant configuration is done here. The most common configuration | |
11 | + # options are documented and commented below. For a complete reference, | |
12 | + # please see the online documentation at vagrantup.com. | |
13 | + | |
14 | + config.vm.hostname = 'backup-file2s3-berkshelf' | |
15 | + | |
16 | + # Set the version of chef to install using the vagrant-omnibus plugin | |
17 | + # NOTE: You will need to install the vagrant-omnibus plugin: | |
18 | + # | |
19 | + # $ vagrant plugin install vagrant-omnibus | |
20 | + # | |
21 | + if Vagrant.has_plugin?("vagrant-omnibus") | |
22 | + config.omnibus.chef_version = 'latest' | |
23 | + end | |
24 | + | |
25 | + # Every Vagrant virtual environment requires a box to build off of. | |
26 | + # If this value is a shorthand to a box in Vagrant Cloud then | |
27 | + # config.vm.box_url doesn't need to be specified. | |
28 | + config.vm.box = 'chef/ubuntu-14.04' | |
29 | + | |
30 | + | |
31 | + # Assign this VM to a host-only network IP, allowing you to access it | |
32 | + # via the IP. Host-only networks can talk to the host machine as well as | |
33 | + # any other machines on the same network, but cannot be accessed (through this | |
34 | + # network interface) by any external networks. | |
35 | + config.vm.network :private_network, type: 'dhcp' | |
36 | + | |
37 | + # Create a forwarded port mapping which allows access to a specific port | |
38 | + # within the machine from a port on the host machine. In the example below, | |
39 | + # accessing "localhost:8080" will access port 80 on the guest machine. | |
40 | + | |
41 | + # Share an additional folder to the guest VM. The first argument is | |
42 | + # the path on the host to the actual folder. The second argument is | |
43 | + # the path on the guest to mount the folder. And the optional third | |
44 | + # argument is a set of non-required options. | |
45 | + # config.vm.synced_folder "../data", "/vagrant_data" | |
46 | + | |
47 | + # Provider-specific configuration so you can fine-tune various | |
48 | + # backing providers for Vagrant. These expose provider-specific options. | |
49 | + # Example for VirtualBox: | |
50 | + # | |
51 | + # config.vm.provider :virtualbox do |vb| | |
52 | + # # Don't boot with headless mode | |
53 | + # vb.gui = true | |
54 | + # | |
55 | + # # Use VBoxManage to customize the VM. For example to change memory: | |
56 | + # vb.customize ["modifyvm", :id, "--memory", "1024"] | |
57 | + # end | |
58 | + # | |
59 | + # View the documentation for the provider you're using for more | |
60 | + # information on available options. | |
61 | + | |
62 | + # The path to the Berksfile to use with Vagrant Berkshelf | |
63 | + # config.berkshelf.berksfile_path = "./Berksfile" | |
64 | + | |
65 | + # Enabling the Berkshelf plugin. To enable this globally, add this configuration | |
66 | + # option to your ~/.vagrant.d/Vagrantfile file | |
67 | + config.berkshelf.enabled = true | |
68 | + | |
69 | + # An array of symbols representing groups of cookbook described in the Vagrantfile | |
70 | + # to exclusively install and copy to Vagrant's shelf. | |
71 | + # config.berkshelf.only = [] | |
72 | + | |
73 | + # An array of symbols representing groups of cookbook described in the Vagrantfile | |
74 | + # to skip installing and copying to Vagrant's shelf. | |
75 | + # config.berkshelf.except = [] | |
76 | + | |
77 | + config.vm.provision :chef_solo do |chef| | |
78 | + chef.json = { | |
79 | + mysql: { | |
80 | + server_root_password: 'rootpass', | |
81 | + server_debian_password: 'debpass', | |
82 | + server_repl_password: 'replpass' | |
83 | + } | |
84 | + } | |
85 | + | |
86 | + chef.run_list = [ | |
87 | + 'recipe[backup-file2s3::default]' | |
88 | + ] | |
89 | + end | |
90 | +end | ... | ... |
attributes/default.rb
0 → 100644
1 | +# | |
2 | +# Author:: Earth U (<sysadmin@chromedia.com>) | |
3 | +# Cookbook Name:: backup-file2s3 | |
4 | +# Attributes:: default | |
5 | +# | |
6 | +# Copyright 2016, Chromedia Far East, Inc. | |
7 | +# | |
8 | +# Licensed under the Apache License, Version 2.0 (the "License"); | |
9 | +# you may not use this file except in compliance with the License. | |
10 | +# You may obtain a copy of the License at | |
11 | +# | |
12 | +# http://www.apache.org/licenses/LICENSE-2.0 | |
13 | +# | |
14 | +# Unless required by applicable law or agreed to in writing, software | |
15 | +# distributed under the License is distributed on an "AS IS" BASIS, | |
16 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
17 | +# See the License for the specific language governing permissions and | |
18 | +# limitations under the License. | |
19 | +# | |
20 | + | |
21 | +default['backup-file2s3']['bucket'] = 'bucketname' | |
22 | +default['backup-file2s3']['region'] = 'us-east-1' | |
23 | +default['backup-file2s3']['max_backups'] = 30 | |
24 | + | |
25 | +# The array of file directories to be backed up to S3 | |
26 | +default['backup-file2s3']['dirs'] = [] | |
27 | + | |
28 | +default['backup-file2s3']['script_dir'] = '/etc/backup_file_to_s3' | |
29 | +default['backup-file2s3']['log_dir'] = '/var/log/backup_file_to_s3' | |
30 | +default['backup-file2s3']['tmp_dir'] = '/tmp/backup_files' | |
31 | + | |
32 | +default['backup-file2s3']['aws_bin'] = value_for_platform( | |
33 | + 'ubuntu' => { 'default' => '/usr/local/bin/aws' }, | |
34 | + 'default' => '/usr/local/bin/aws' # haven't tested on other platforms yet | |
35 | +) | |
36 | + | |
37 | +# Basic options for cron | |
38 | +default['backup-file2s3']['cron']['min'] = '0' | |
39 | +default['backup-file2s3']['cron']['hour'] = '0' | |
40 | +default['backup-file2s3']['cron']['day'] = '*' | |
41 | +default['backup-file2s3']['cron']['mon'] = '*' | |
42 | +default['backup-file2s3']['cron']['wday'] = '*' | |
43 | +default['backup-file2s3']['cron']['mailto'] = "''" | |
44 | + | |
45 | +# Basic options for logrotate | |
46 | +default['backup-file2s3']['logrotate']['conf_dir'] = '/etc/logrotate.d' | |
47 | +default['backup-file2s3']['logrotate']['options'] = %w{ | |
48 | + weekly | |
49 | + rotate\ 12 | |
50 | + missingok | |
51 | + compress | |
52 | + notifempty | |
53 | +} | ... | ... |
chefignore
0 → 100644
1 | +# Put files/directories that should be ignored in this file when uploading | |
2 | +# or sharing to the community site. | |
3 | +# Lines that start with '# ' are comments. | |
4 | + | |
5 | +# OS generated files # | |
6 | +###################### | |
7 | +.DS_Store | |
8 | +Icon? | |
9 | +nohup.out | |
10 | +ehthumbs.db | |
11 | +Thumbs.db | |
12 | + | |
13 | +# SASS # | |
14 | +######## | |
15 | +.sass-cache | |
16 | + | |
17 | +# EDITORS # | |
18 | +########### | |
19 | +\#* | |
20 | +.#* | |
21 | +*~ | |
22 | +*.sw[a-z] | |
23 | +*.bak | |
24 | +REVISION | |
25 | +TAGS* | |
26 | +tmtags | |
27 | +*_flymake.* | |
28 | +*_flymake | |
29 | +*.tmproj | |
30 | +.project | |
31 | +.settings | |
32 | +mkmf.log | |
33 | + | |
34 | +## COMPILED ## | |
35 | +############## | |
36 | +a.out | |
37 | +*.o | |
38 | +*.pyc | |
39 | +*.so | |
40 | +*.com | |
41 | +*.class | |
42 | +*.dll | |
43 | +*.exe | |
44 | +*/rdoc/ | |
45 | + | |
46 | +# Testing # | |
47 | +########### | |
48 | +.watchr | |
49 | +.rspec | |
50 | +spec/* | |
51 | +spec/fixtures/* | |
52 | +test/* | |
53 | +features/* | |
54 | +Guardfile | |
55 | +Procfile | |
56 | + | |
57 | +# SCM # | |
58 | +####### | |
59 | +.git | |
60 | +*/.git | |
61 | +.gitignore | |
62 | +.gitmodules | |
63 | +.gitconfig | |
64 | +.gitattributes | |
65 | +.svn | |
66 | +*/.bzr/* | |
67 | +*/.hg/* | |
68 | +*/.svn/* | |
69 | + | |
70 | +# Berkshelf # | |
71 | +############# | |
72 | +cookbooks/* | |
73 | +tmp | |
74 | + | |
75 | +# Cookbooks # | |
76 | +############# | |
77 | +CONTRIBUTING | |
78 | +CHANGELOG* | |
79 | + | |
80 | +# Strainer # | |
81 | +############ | |
82 | +Colanderfile | |
83 | +Strainerfile | |
84 | +.colander | |
85 | +.strainer | |
86 | + | |
87 | +# Vagrant # | |
88 | +########### | |
89 | +.vagrant | |
90 | +Vagrantfile | |
91 | + | |
92 | +# Travis # | |
93 | +########## | |
94 | +.travis.yml | ... | ... |
metadata.rb
0 → 100644
1 | +name 'backup-file2s3' | |
2 | +maintainer 'Chromedia Far East, Inc.' | |
3 | +maintainer_email 'sysadmin@chromedia.com' | |
4 | +license 'Apache License' | |
5 | +description 'Creates a script to backup directories into an S3 bucket.' | |
6 | +long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) | |
7 | +version '0.1.0' | |
8 | + | |
9 | +depends 'awscli', '~> 1.0.1' | |
10 | +depends 'cron', '~> 1.7.4' | |
11 | + | |
12 | +supports 'ubuntu', '>= 14.04' | ... | ... |
recipes/default.rb
0 → 100644
1 | +# | |
2 | +# Author:: Earth U (<sysadmin@chromedia.com>) | |
3 | +# Cookbook Name:: backup-file2s3 | |
4 | +# Recipe:: default | |
5 | +# | |
6 | +# Copyright 2016, Chromedia Far East, Inc. | |
7 | +# | |
8 | +# Licensed under the Apache License, Version 2.0 (the "License"); | |
9 | +# you may not use this file except in compliance with the License. | |
10 | +# You may obtain a copy of the License at | |
11 | +# | |
12 | +# http://www.apache.org/licenses/LICENSE-2.0 | |
13 | +# | |
14 | +# Unless required by applicable law or agreed to in writing, software | |
15 | +# distributed under the License is distributed on an "AS IS" BASIS, | |
16 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
17 | +# See the License for the specific language governing permissions and | |
18 | +# limitations under the License. | |
19 | +# | |
20 | + | |
21 | +include_recipe 'awscli' | |
22 | + | |
23 | +attribs = node['backup-file2s3'] | |
24 | +scr_dir = attribs['script_dir'] | |
25 | +sname = 'backup_file_to_s3' | |
26 | + | |
27 | +template "#{scr_dir}/#{sname}" do | |
28 | + mode 0644 | |
29 | + only_if "test -d #{scr_dir} || mkdir -p #{scr_dir}" | |
30 | + variables( | |
31 | + :aws_bin => attribs['aws_bin'], | |
32 | + :log_dir => attribs['log_dir'], | |
33 | + :tmp_dir => attribs['tmp_dir'], | |
34 | + :bucket => attribs['bucket'], | |
35 | + :region => attribs['region'] || 'us-east-1', | |
36 | + :max_backups => attribs['max_backups'] || 30, | |
37 | + :dirs => attribs['dirs'] | |
38 | + ) | |
39 | +end | |
40 | + | |
41 | +cra = attribs['cron'] | |
42 | +cron_d sname do | |
43 | + command "bash #{scr_dir}/#{sname}" | |
44 | + minute cra['min'] | |
45 | + hour cra['hour'] | |
46 | + day cra['day'] | |
47 | + month cra['mon'] | |
48 | + weekday cra['wday'] | |
49 | + mailto cra['mailto'] | |
50 | + path '/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin' | |
51 | +end | |
52 | + | |
53 | +package 'logrotate' | |
54 | + | |
55 | +loa = attribs['logrotate'] | |
56 | +template "#{loa['conf_dir']}/#{sname}" do | |
57 | + source "#{sname}_logrotate.erb" | |
58 | + only_if "test -d #{loa['conf_dir']} || mkdir -p #{loa['conf_dir']}" | |
59 | + variables( | |
60 | + :log_dir => attribs['log_dir'], | |
61 | + :options => loa['options'] | |
62 | + ) | |
63 | +end | ... | ... |
templates/default/backup_file_to_s3.erb
0 → 100644
1 | +#!/bin/bash | |
2 | +# | |
3 | +# Generated by Chef | |
4 | +# | |
5 | +# Back up directories into an S3 bucket | |
6 | + | |
7 | +set -e | |
8 | + | |
9 | +log_dir=<%= @log_dir %> | |
10 | +if [[ ! -d "$log_dir" ]] ; then | |
11 | + mkdir -p "$log_dir" | |
12 | +fi | |
13 | + | |
14 | +aws_cmd=<%= @aws_bin %> | |
15 | + | |
16 | +exec 3>&1 4>&2 | |
17 | +trap 'exec 2>&4 1>&3' 0 1 2 3 | |
18 | +exec 1>>"${log_dir}/backup_file_to_s3.log" 2>&1 | |
19 | + | |
20 | +bucket=<%= @bucket %> | |
21 | +region=<%= @region %> | |
22 | +max_backups=<%= @max_backups %> | |
23 | +bak_dir=<%= @tmp_dir %> | |
24 | + | |
25 | +# Array of directories to be backed up. | |
26 | +# | |
27 | +# Example: | |
28 | +# declare -a tar_dirs=( | |
29 | +# "/path/to/dira" | |
30 | +# "/another/path/to/dirb" | |
31 | +# ) | |
32 | +# | |
33 | +# Tarball names will be the basename of each path given. | |
34 | +declare -a tar_dirs=( | |
35 | +<% @dirs.each do |dirx| -%> | |
36 | + "<%= dirx %>" | |
37 | +<% end -%> | |
38 | +) | |
39 | + | |
40 | +if [[ ! -d "$bak_dir" ]] ; then | |
41 | + echo "$(date) : Missing backup directory. Creating." | |
42 | + mkdir -p "$bak_dir" | |
43 | +fi | |
44 | + | |
45 | +# Rotate the current backups in S3 | |
46 | +# $1 = directory to be tarred | |
47 | +increment_backup_names() { | |
48 | + fname=$( basename "$1" ) | |
49 | + bak_keyname="${fname}.tar.gz" | |
50 | + | |
51 | + baks=$( "$aws_cmd" --output text --region "$region" \ | |
52 | + s3api list-objects --bucket "$bucket" \ | |
53 | + | grep '^CONTENTS' | cut -f3 | grep "^${bak_keyname}" || echo "" ) | |
54 | + | |
55 | + echo "$(date) : Backup rotation for ${bak_keyname}" | |
56 | + start=$((max_backups - 1)) | |
57 | + | |
58 | + for (( x=start ; x > 0 ; x-- )) ; do | |
59 | + if echo "$baks" | grep "^${bak_keyname}\\.${x}\$" ; then | |
60 | + newx=$((x + 1)) | |
61 | + if [[ $newx -lt $max_backups ]] ; then | |
62 | + "$aws_cmd" --region "$region" \ | |
63 | + s3 cp "s3://${bucket}/${bak_keyname}.${x}" \ | |
64 | + "s3://${bucket}/${bak_keyname}.${newx}" | |
65 | + fi | |
66 | + fi | |
67 | + done | |
68 | + | |
69 | + if echo "$baks" | grep "^${bak_keyname}\$" ; then | |
70 | + "$aws_cmd" --region "$region" \ | |
71 | + s3 cp "s3://${bucket}/${bak_keyname}" \ | |
72 | + "s3://${bucket}/${bak_keyname}.1" | |
73 | + fi | |
74 | +} | |
75 | + | |
76 | +# Tar up the directory | |
77 | +# $1 = directory to be tarred | |
78 | +tar_dir() { | |
79 | + fname=$( basename "$1" ) | |
80 | + parent=$( dirname "$1" ) | |
81 | + echo "$(date) : Tar up ${1}" | |
82 | + | |
83 | + tar -C "$parent" -czf "${bak_dir}/${fname}.tar.gz" "$fname" | |
84 | +} | |
85 | + | |
86 | +# $1 = directory to be tarred | |
87 | +upload_to_s3() { | |
88 | + fname=$( basename "$1" ) | |
89 | + echo "$(date) : Upload ${fname}.tar.gz to S3 bucket ${bucket}" | |
90 | + | |
91 | + "$aws_cmd" --region "$region" \ | |
92 | + s3 mv "${bak_dir}/${fname}.tar.gz" "s3://${bucket}/${fname}.tar.gz" | |
93 | +} | |
94 | + | |
95 | +for dirx in "${tar_dirs[@]}" ; do | |
96 | + if [[ -d "$dirx" ]] ; then | |
97 | + increment_backup_names "$dirx" | |
98 | + tar_dir "$dirx" | |
99 | + upload_to_s3 "$dirx" | |
100 | + else | |
101 | + echo "$(date) : WARNING : Directory ${dirx} does not exist" | |
102 | + fi | |
103 | +done | |
104 | + | |
105 | +echo "$(date) : Done" | ... | ... |