martilla 0.3.1 → 0.4.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6ddec52e6ea8e2f0ae5251811b050dfbb5c514cc2d3c359cb1a744e0f24e058b
4
- data.tar.gz: e34e08990fd2055561471c3f9ee9b97ba19e15e79aa4d0ffa69211f23979a61b
3
+ metadata.gz: 52022187479500d2fe42d9bbf8153a7383811b06904be9e334a12b6379789ab5
4
+ data.tar.gz: b19c9c14f59b5bee0db4fc62ef5f1dfc9cbcc01d6ae3bd717e2c59616f6d5292
5
5
  SHA512:
6
- metadata.gz: b60213c9e11b06571ef8d081d1219073622b3f8efdc447a26b8ffc814f0ce626ed740ad41478c6d68143fb52ab4b38492ce90f30b026cb0640b361cac8dbf911
7
- data.tar.gz: 121370b1a2fd0634cdf3b5e507deac53574e1c1cd20948adb96f8569efa0f2cfcbdcfcc75a27498928004fcee6dbf72f34f177f3a4c8c25a34a0d7ec6f82a217
6
+ metadata.gz: a34c2e035a36c9069d40333b4fd98c377f27d4b0ef6ee467def1983d33a3d0214b8ee659217fd308a5e24b486ba6a7a9377b33138b386d83ff06395727048054
7
+ data.tar.gz: 38a6e9f03a5b691067d34b8048c1399e627caa469fe3c43c4106abc8f2bbf1b3ed60199afb1483162b76c72d921afd6877b3f05aeb4258d4d87b4d25653dd9ad
data/CHANGELOG.md CHANGED
@@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
+ ## 0.3.1
8
+ 2019-11-14
9
+
10
+ - Fixes a bug that caused absolute paths sent to the CLI for the `backup` command to fail
11
+
7
12
  ## 0.3.0
8
13
  2019-11-10
9
14
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- martilla (0.3.1)
4
+ martilla (0.4.0.rc1)
5
5
  aws-sdk-s3 (~> 1.49)
6
6
  aws-sdk-ses (~> 1.26)
7
7
  memoist (~> 0.16.0)
data/README.md CHANGED
@@ -102,6 +102,9 @@ The available Storages types are **local**, **S3** & **SCP**. They each have dif
102
102
  - can be specified with the usual ENV variables or IAM roles
103
103
  - `retention`
104
104
  - An integer that defines the max number of backups stored at the defined location
105
+ - **IMPORTANT NOTE:** Releases `v0.3.0` & `v0.3.1` added a bug where the s3 storage option **will possibly delete other files when enforcing retention**. Ways to avoid this problem:
106
+ - Don't use retention configuration for **s3** storage and wait until a fix is released soon. More details and the status of the issue [here](https://github.com/fdoxyz/martilla/issues/18)
107
+ - Use a subdirectory within your bucket exclusively for the backups by using the `filename` option to something like `/path/to/backups/backup_name.sql`
105
108
  - options for type: **scp**
106
109
  - `filename`
107
110
  - The location to where the backup will be stored within remote server
@@ -26,8 +26,12 @@ module Martilla
26
26
  @options['suffix']
27
27
  end
28
28
 
29
+ def options_filename
30
+ @options['filename'] || 'backup.sql'
31
+ end
32
+
29
33
  def output_filename(gzip)
30
- filename = @options['filename'] || 'backup.sql'
34
+ filename = options_filename
31
35
  filename = append_datetime_suffix(filename) if suffix?
32
36
  filename = "#{filename}.gz" if gzip
33
37
  filename
@@ -4,9 +4,11 @@ module Martilla
4
4
  class S3 < Storage
5
5
  def persist(tmp_file:, gzip:)
6
6
  path = output_filename(gzip)
7
- obj = s3_resource.bucket(bucket_name).object(path)
7
+ # Files in the root path of a bucket need to be stripped of './'
8
+ # See https://github.com/fdoxyz/martilla/issues/17
9
+ path.slice!(0, 2) if path[0...2] == './'
8
10
 
9
- # Upload it
11
+ obj = s3_resource.bucket(bucket_name).object(path)
10
12
  return nil if obj.upload_file(tmp_file)
11
13
  raise Error.new('Error uploading backup to bucket')
12
14
  end
@@ -14,15 +16,44 @@ module Martilla
14
16
  def enfore_retention!(gzip:)
15
17
  return if retention_limit < 1
16
18
 
17
- objs = s3_resource.bucket(bucket_name).objects.sort_by(&:last_modified)
19
+ objs = bucket_objs_for_retention(output_file: output_filename(gzip))
18
20
  while objs.count > retention_limit do
19
- objs.first.delete
21
+ delete_params = { bucket: bucket_name, key: objs.first.key }
22
+ s3_resource.client.delete_object(delete_params)
20
23
  puts "Retention limit met. Removed the backup file: #{objs.shift.key}"
21
24
  end
22
25
  end
23
26
 
24
27
  private
25
28
 
29
+ # Returns array of objs in the bucket that match the backup output file
30
+ # format, ordered by `last_modified` where oldest is first and newest last
31
+ def bucket_objs_for_retention(output_file:)
32
+ res = s3_resource.client.list_objects({ bucket: bucket_name })
33
+ objs = res.contents.sort_by(&:last_modified)
34
+
35
+ # Path & File basename to check against to enforce retention restriction
36
+ path = File.dirname(output_file)
37
+ base_name = File.basename(output_file)
38
+
39
+ if suffix?
40
+ # When using a suffix make sure we replace the actual timestamp for a
41
+ # regexp, otherwise because of different timestamps they'll never match
42
+ index = base_name =~ timestamp_regex
43
+ base_name.slice!(timestamp_regex)
44
+ base_name.insert(index, "\\d{4}-\\d{2}-\\d{2}T\\d{6}")
45
+ end
46
+
47
+ # Rejects objects that don't match the directory location or if they don't
48
+ # match with the same file basename structure
49
+ objs.reject do |obj|
50
+ directory_mismatch = File.dirname(obj.key) != path
51
+ filename_mismatch = !(File.basename(obj.key) =~ /#{base_name}/)
52
+
53
+ directory_mismatch || filename_mismatch
54
+ end
55
+ end
56
+
26
57
  def s3_resource
27
58
  options = {}
28
59
  options[:region] = aws_region unless aws_region.nil?
@@ -1,3 +1,3 @@
1
1
  module Martilla
2
- VERSION = '0.3.1'
2
+ VERSION = '0.4.0.rc1'
3
3
  end
data/martilla.gemspec CHANGED
@@ -6,9 +6,9 @@ Gem::Specification.new do |spec|
6
6
  spec.name = 'martilla'
7
7
  spec.version = Martilla::VERSION
8
8
  spec.authors = ['Fernando Valverde']
9
- spec.email = ['fdov88@gmail.com']
9
+ spec.email = ['fernando@visualcosita.com']
10
10
 
11
- spec.summary = 'Modern backup tool'
11
+ spec.summary = 'Easy to configure backup tool for simple everyday use'
12
12
  spec.description = ''
13
13
  spec.homepage = 'https://github.com/fdoxyz/martilla'
14
14
  spec.license = 'MIT'
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
17
17
 
18
18
  spec.metadata['homepage_uri'] = spec.homepage
19
19
  spec.metadata['source_code_uri'] = 'https://github.com/fdoxyz/martilla'
20
- spec.metadata['changelog_uri'] = 'https://github.com/fdoxyz/martilla/changelog'
20
+ spec.metadata['changelog_uri'] = 'https://github.com/fdoxyz/martilla/blob/master/CHANGELOG.md'
21
21
 
22
22
  # Specify which files should be added to the gem when it is released.
23
23
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: martilla
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fernando Valverde
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-11-14 00:00:00.000000000 Z
11
+ date: 2019-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -180,7 +180,7 @@ dependencies:
180
180
  version: 0.17.1
181
181
  description: ''
182
182
  email:
183
- - fdov88@gmail.com
183
+ - fernando@visualcosita.com
184
184
  executables:
185
185
  - martilla
186
186
  extensions: []
@@ -226,7 +226,7 @@ licenses:
226
226
  metadata:
227
227
  homepage_uri: https://github.com/fdoxyz/martilla
228
228
  source_code_uri: https://github.com/fdoxyz/martilla
229
- changelog_uri: https://github.com/fdoxyz/martilla/changelog
229
+ changelog_uri: https://github.com/fdoxyz/martilla/blob/master/CHANGELOG.md
230
230
  post_install_message:
231
231
  rdoc_options: []
232
232
  require_paths:
@@ -238,12 +238,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
238
238
  version: '0'
239
239
  required_rubygems_version: !ruby/object:Gem::Requirement
240
240
  requirements:
241
- - - ">="
241
+ - - ">"
242
242
  - !ruby/object:Gem::Version
243
- version: '0'
243
+ version: 1.3.1
244
244
  requirements: []
245
245
  rubygems_version: 3.0.3
246
246
  signing_key:
247
247
  specification_version: 4
248
- summary: Modern backup tool
248
+ summary: Easy to configure backup tool for simple everyday use
249
249
  test_files: []