defmodule Doex.Cli.Snapshots.Create do
use FnExpr
alias Doex.Cli.Parser
alias Doex.Io.Shell
@moduledoc """
Creates a snapshot of an existing Digital Ocean droplet. This
differs from the underlying snapshot API, as it will ensure all
necessary preconditions are set, and can (if desired) block until
the process is finished
doex snapshots.create <droplet_id> <snapshot_name>
The following options with examples are shown below:
--delete true/false If true, delete droplet when finished
--block true/false Regardless of delete, block until finished
For example
doex snapshots.create 12345 my_app --delete
If you have a specific config file, `mix help doex.config` then add it as an environment variable
DOEX_CONFIG=/tmp/my.doex doex snapshots.create 12345 my_app --delete
"""
@options %{
tag: :boolean,
delete: :boolean,
block: :boolean,
quiet: :boolean,
sleep: :integer
}
def run(raw_args) do
Doex.start()
raw_args
|> Parser.parse(@options)
|> invoke(fn {opts, [droplet_name, snapshot_name]} ->
droplet_name
|> Doex.Client.find_droplet_id(opts)
|> invoke(fn
nil -> Shell.unknown_droplet(droplet_name, ["snapshots.create" | raw_args])
id -> id
end)
|> create_snapshot(snapshot_name, opts)
end)
end
defp create_snapshot(nil, _snapshot_name, _opts), do: nil
defp create_snapshot(droplet_id, snapshot_name, opts) do
Shell.info("Powering off droplet #{droplet_id}...", opts)
Doex.Api.post("/droplets/#{droplet_id}/actions", %{type: "power_off"})
|> Shell.inspect(opts)
|> Doex.Cli.Block.block_until(opts)
Shell.info("DONE, Powering off droplet #{droplet_id}.", opts)
Shell.info("Creating snapshot named #{snapshot_name}...", opts)
Doex.Api.post("/droplets/#{droplet_id}/actions", %{type: "snapshot", name: snapshot_name})
|> invoke(fn resp ->
if opts[:delete] || opts[:block] do
Doex.Cli.Block.block_until(resp, opts)
Shell.info("DONE, Creating snapshot named #{snapshot_name}.", opts)
else
Shell.info("WORKING, Creating snapshot named #{snapshot_name}.", opts)
end
end)
if opts[:delete] do
Shell.info("Deleting droplet #{droplet_id}...", opts)
{:ok, nil} = Doex.Api.delete("/droplets/#{droplet_id}")
end
snapshot_name
end
end