Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Support creating droplets from snapshots (clone workflow)

Đang mở
#52 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

@gwpl đang làm issue này rồi.

Từ ngày 23/3/2026.

  • #53 của @gwpl — đang mở

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
65/100
Loại issue
Tính năng
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Ít trao đổi
Công nghệ
python
Lĩnh vực
api, cli, cloud

Hướng nghiên cứu

Bắt đầu với lệnh create và phương thức hiện có api.create_droplet_from_snapshot() được wake sử dụng. Theo dõi cách create kết xuất, gửi và giám sát cloud-init, sau đó triển khai luồng snapshot để bỏ qua các bước đó nhưng vẫn giữ việc chờ trạng thái active, cấu hình SSH và gán dự án. Hoàn thành khi --from-snapshot tạo một droplet không có cloud-init và loại trừ lẫn nhau với --image.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

AI Agent with Greg: We wanted to snapshot a perfectly configured droplet and spin up 10 clones from it — like a sysadmin photocopier. Turns out dropkit's create command always injects cloud-init, which re-runs on the snapshot and causes chaos (user creation fails, .zshrc gets overwritten, unconditional reboot). Time to teach dropkit the art of cloning. 🧬🖨️

Use Case

Snapshot → Clone N droplets — a common workflow for:

  • Spinning up pre-configured build/test environments
  • Creating identical workshop/training machines
  • Scaling a known-good configuration quickly
# The dream:
dropkit create my-worker-1 --from-snapshot 12345678 --size s-4vcpu-8gb
dropkit create my-worker-2 --from-snapshot 12345678 --size s-4vcpu-8gb
# ... or even:
for i in $(seq 1 10); do
  dropkit create "worker-$i" --from-snapshot 12345678
done

The Problem

dropkit create always renders and sends cloud-init user_data to the DigitalOcean API. When creating from a snapshot:

  1. Cloud-init re-runs — DO assigns a new droplet ID → instance-ID mismatch → cloud-init treats it as first boot
  2. The template is NOT idempotent — several critical issues:
    • users: directive fails or is skipped if user already exists
    • write_files: overwrites .zshrc (loses user customizations)
    • runcmd: ends with unconditional reboot
    • git config --global resets any user-modified values

Cloud-init is fundamentally a provisioning tool, not an idempotent configuration manager. Making the template fully idempotent is possible but would be a significant effort touching every directive.

Current State

Component Exists? Notes
api.create_droplet_from_snapshot() ✅ Yes Used by wake command, takes snapshot ID, no user_data
dropkit create --image ✅ Yes But always sends cloud-init; image is a slug, not snapshot ID
dropkit wake ✅ Yes Restores from hibernation snapshot only (expects dropkit-<name> naming + metadata tags)
Snapshot-based create without cloud-init ❌ No The missing piece

Proposed Approaches

Option A: --from-snapshot <id> flag on create (Recommended — simplest)

Add a --from-snapshot flag to dropkit create that:

  • Uses api.create_droplet_from_snapshot() instead of api.create_droplet()
  • Skips cloud-init rendering and sending entirely
  • Skips cloud-init completion monitoring
  • Still performs: wait for active, SSH config setup, project assignment
  • Optionally still runs Tailscale setup (snapshot may not have it)
# Mutually exclusive with --image
@app.command()
def create(
    ...
    from_snapshot: int | None = typer.Option(
        None, "--from-snapshot",
        help="Create from snapshot ID (skips cloud-init)"
    ),
    ...
):

Pros: Minimal change (~30 lines), reuses existing API method, clear intent
Cons: Slightly different code path within create, snapshot ID must be known by user

Option B: --no-cloud-init flag (More general)

A flag to skip cloud-init regardless of image source. Combined with --image <snapshot-id>:

dropkit create my-box --image 12345678 --no-cloud-init

Pros: More composable, works with any image scenario
Cons: Two flags needed, easy to forget --no-cloud-init with a snapshot (leading to the reboot-of-doom)

Option C: Make cloud-init template idempotent (Long-term)

Refactor the template to be safe for re-execution:

  • Guard user creation: id {{ username }} || useradd ...
  • Use marker files: [ -f /etc/dropkit/.initialized ] || ...
  • Remove unconditional reboot; use cloud-init-per instance
  • Make write_files conditional or append-only

Pros: dropkit create --image <snapshot-id> "just works"
Cons: Significant template refactor, hard to test all edge cases, changes behavior for fresh installs too

Option D: New dropkit clone command (Most ergonomic)

Dedicated command for the clone workflow:

dropkit clone my-worker --from my-golden-image --count 5 --size s-4vcpu-8gb

Pros: Best UX, can add clone-specific features (auto-naming, parallel creation)
Cons: Largest scope, new command surface area

Recommendation

Start with Option A (--from-snapshot). It's the smallest change, reuses existing infrastructure, and solves the immediate need. Options C and D can follow later as enhancements.

Happy to implement whichever approach the team prefers!

🤖 Generated with Claude Code — your AI that learned the hard way that cloud-init and snapshots are like mixing sudo with optimism

Ngôn ngữ chính
Python
Star
128
Fork
14
Merge trung bình
10 giờ 13 phút
Pull request đã merge (30 ngày)
4

Chuẩn bị môi trường

Mở trong Codespaces

Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.

  • Không có Dockerfile hay tệp Docker Compose
  • Không có mẫu pull request
  • Không có hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của trailofbits/dropkit

Tất cả issue của trailofbits/dropkit

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.