Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 62 additions & 11 deletions dropkit/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3263,8 +3263,8 @@ def rename(
def resize(
droplet_name: str = typer.Argument(..., autocompletion=complete_droplet_or_snapshot_name),
size: str | None = typer.Option(None, "--size", "-s", help="New size slug (e.g., s-4vcpu-8gb)"),
disk: bool = typer.Option(
True, "--disk/--no-disk", help="Resize disk (permanent, default: True)"
disk: bool | None = typer.Option(
None, "--disk/--no-disk", help="Resize disk (permanent, asked interactively if omitted)"
),
):
"""
Expand Down Expand Up @@ -3449,12 +3449,13 @@ def resize(
else 0
)
disk_change = f"{current_disk} GB → {new_disk} GB"
if disk and disk_diff > 0:
if disk is False:
# User explicitly passed --no-disk
disk_change = f"{current_disk} GB (not resized)"
elif disk_diff > 0:
disk_change += f" [green](+{disk_diff} GB)[/green]"
elif disk and disk_diff < 0:
elif disk_diff < 0:
disk_change += f" [yellow]({disk_diff} GB)[/yellow]"
elif not disk:
disk_change = f"{current_disk} GB (not resized)"
changes_table.add_row("Disk:", disk_change)

# Price
Expand All @@ -3468,19 +3469,41 @@ def resize(

console.print(changes_table)

# If --disk/--no-disk was not explicitly passed, ask interactively
# when the new size has a different disk. This surfaces the
# permanent/irreversible nature of disk resize at decision time,
# consistent with how region/size/image are handled interactively.
if disk is None:
if isinstance(disk_diff, int) and disk_diff != 0:
console.print()
console.print(
"[bold yellow]Disk resize is PERMANENT and cannot be undone.[/bold yellow]"
)
console.print("[dim]Skipping disk resize keeps the option to downsize later.[/dim]")
disk_choice = Prompt.ask(
"[bold]Resize disk too?[/bold]",
choices=["yes", "no"],
default="no",
)
disk = disk_choice == "yes"
else:
# No disk change — default to True (no-op for disk)
disk = True

# Show warnings
console.print()
console.print(
"[bold yellow]⚠ WARNING: This operation will cause downtime (droplet will be powered off)[/bold yellow]"
"[bold yellow]⚠ WARNING: This operation will cause downtime "
"(droplet will be powered off)[/bold yellow]"
)

if disk:
if disk and isinstance(disk_diff, int) and disk_diff > 0:
console.print(
"[bold red]⚠ WARNING: Disk resize is PERMANENT and cannot be undone![/bold red]"
)
else:
elif not disk:
console.print(
"[dim]Note: Disk will NOT be resized. You can resize it later, but it's permanent.[/dim]"
"[dim]Note: Disk will NOT be resized. You can resize back down later.[/dim]"
)

# Confirmation
Expand Down Expand Up @@ -3517,9 +3540,37 @@ def resize(
api.wait_for_action_complete(action_id, timeout=600) # 10 minutes

console.print("[green]✓[/green] Resize completed successfully")

# Power the droplet back on — DigitalOcean leaves it powered off
# after resize (no auto-power-on API flag exists). Since the user
# almost certainly wants their droplet running, we power it on
# automatically instead of leaving them to discover it's off.
console.print()
console.print("[dim]Powering on droplet...[/dim]")

power_action = api.power_on_droplet(droplet_id)
power_action_id = power_action.get("id")

if not power_action_id:
console.print(
"[yellow]Warning: Could not get power-on action ID. "
f"You may need to run: dropkit on {droplet_name}[/yellow]"
)
else:
console.print(
f"[green]✓[/green] Power on action started (ID: [cyan]{power_action_id}[/cyan])"
)
console.print("[dim]Waiting for droplet to power on...[/dim]")

with console.status("[cyan]Powering on...[/cyan]"):
api.wait_for_action_complete(power_action_id, timeout=120)

console.print("[green]✓[/green] Droplet powered on successfully")

console.print()
console.print(
f"[bold green]Droplet {droplet_name} has been resized to {new_size_slug}[/bold green]"
f"[bold green]Droplet {droplet_name} has been resized to "
f"{new_size_slug} and is now active[/bold green]"
)

except DigitalOceanAPIError as e:
Expand Down