DevArchive

Save and restore snapshots of stateful services to a central archive. Have a development database that you want to restore to a prior state? Just take a snapshot and restore it later!

Backup

# Uses your EDITOR to add details for the snapshot.
# Uses the default configured "stores" for creating the snapshot
dev_archive backup

# Add a message from the command line:
dev_archive backup --message "Add message from command line"
dev_archive backup -m "Add message from command line"

# Override which stores are used for the snapshot
dev_archive --store custom_store_1,custom_store_2

See the "Configure" section for how add a custom store.

Show

# Show the full details for a given snapshot
dev_archive show {id}

Restore

# Restore the given snapshot
dev_archive restore {id}

List

# list all snapshots (pipe to `less` if you like)
dev_archive list

Delete

# Delete the given snapshot
dev_archive rm {id}

Configure

A custom configuration can be written at the location $HOME/.config/dev_archive.rb. It is written in ruby. Here is an example config:


DevArchive.configure do |config|

  # Configure where the snapshots are stored. Defaults to `$HOME/.dev_archive`
  config.storage_path = "/path/to/snapshot_dir"

  # Configure which stores are active by default (can be overridden with --store
  # option on command line). The default store is "mysql_rails" which saves a
  # snapshot of all databases for the Rails app found in the CWD.
  config.active_stores = ["store_1", "store_2"]

  # Creating a custom store:
  #
  # Stores must implement two methods:
  #
  #   backup: accepts a directory for data and returns a JSON hash (with string
  #     keys) for use in restoring.
  #
  #  restore: accepts the metadata JSON data created when making the backup. No
  #    return value.
  #
  # Stores can either be defined as objects/classes/modules or a builtin store
  # builder can be used.

  # Using an object:

  class MyCustomStore
    def backup(dir)
      path = File.join(dir, "my_custom_store.txt")
      File.write(path, "hello")

      { "path" => path }
    end

    def restore()
      puts(File.read(.fetch("path")))
    end
  end

  config.register_store("my_custom_store", MyCustomStore.new)


  # Using the store builder:

  config.register_store("my_customer_store") do |store|
    store.backup do |dir|
      path = File.join(dir, "my_custom_store.txt")
      File.write(path, "hello")

      { "path" => path }
    end

    store.restore do ||
      puts(File.read(.fetch("path")))
    end
  end
end