Skip to content

Commit 7478298

Browse files
committed
Sync expiry dates from YAML and delete expired servers in same run
1 parent dc93010 commit 7478298

File tree

2 files changed

+51
-16
lines changed

2 files changed

+51
-16
lines changed

scripts/provision.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,19 +102,34 @@ def main():
102102
try:
103103
expiry_date = datetime.strptime(until, '%Y-%m-%d').date()
104104
today_utc = datetime.now(timezone.utc).date()
105-
if expiry_date < today_utc:
106-
print(f"\n=== {name} (user: {key}) ===")
107-
print(f"Expired on {until}, skipping")
108-
continue
105+
is_expired = expiry_date < today_utc
109106
except ValueError:
110107
print(f"ERROR: Invalid date '{until}'")
111108
continue
112109

113110
print(f"\n=== {name} (user: {key}) ===")
114111

115-
ret, stdout, _ = run_cmd(f"hcloud server list -o noheader -o columns=name | grep -x '{name}' || true", dry_run=False)
112+
# Check if server already exists
113+
ret, stdout, _ = run_cmd(f"hcloud server describe '{name}' -o json 2>/dev/null || true", dry_run=False)
116114
if stdout:
117-
print(f"Already exists, skipping")
115+
server_info = json.loads(stdout)
116+
current_expiry = server_info.get('labels', {}).get('expires')
117+
if current_expiry != until:
118+
print(f"Expiry changed: {current_expiry} -> {until}")
119+
if args.dry_run:
120+
print(f" [DRY-RUN] Would update expiry label")
121+
else:
122+
ret, _, stderr = run_cmd(f"hcloud server add-label '{name}' expires={until} --overwrite")
123+
if ret != 0:
124+
print(f"ERROR: Failed to update label: {stderr}")
125+
else:
126+
print(f"Updated expiry label")
127+
else:
128+
print(f"Already exists with correct expiry")
129+
continue
130+
131+
if is_expired:
132+
print(f"Expired on {until}, skipping creation")
118133
continue
119134

120135
print(f"Fetching SSH keys from github.com/{key}.keys")

scripts/teardown.py

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#!/usr/bin/env python3
2-
"""Delete managed servers not in dev_boxes.yml"""
2+
"""Delete managed servers not in dev_boxes.yml or expired"""
33
import yaml
44
import subprocess
55
import sys
66
import json
7+
from datetime import datetime, timezone
78

89

910
def run_cmd(cmd):
@@ -15,13 +16,20 @@ def main():
1516
# Get current dev_boxes.yml
1617
try:
1718
with open('dev_boxes.yml', 'r') as f:
18-
data = yaml.safe_load(f)
19-
current_names = {box.get('name') for box in (data or []) if box.get('name')}
19+
data = yaml.safe_load(f) or []
20+
boxes_by_name = {}
21+
for box in data:
22+
name = box.get('name')
23+
if name:
24+
until = box.get('until')
25+
if until and not isinstance(until, str):
26+
until = str(until)
27+
boxes_by_name[name] = until
2028
except Exception as e:
2129
print(f"ERROR: Could not read dev_boxes.yml: {e}")
2230
sys.exit(1)
2331

24-
print(f"Current dev_boxes.yml has {len(current_names)} server(s)")
32+
print(f"Current dev_boxes.yml has {len(boxes_by_name)} server(s)")
2533

2634
# Get all managed servers from Hetzner
2735
ret, stdout, _ = run_cmd("hcloud server list -o json -l managed-by=dev-box-provisioner")
@@ -34,19 +42,31 @@ def main():
3442

3543
print(f"Found {len(managed_names)} managed server(s) in Hetzner")
3644

37-
# Find servers to delete (in Hetzner but not in YAML)
38-
to_delete = managed_names - current_names
45+
today_utc = datetime.now(timezone.utc).date()
46+
to_delete = []
47+
48+
for name in managed_names:
49+
if name not in boxes_by_name:
50+
to_delete.append((name, "not in YAML"))
51+
else:
52+
until = boxes_by_name[name]
53+
if until:
54+
try:
55+
expiry_date = datetime.strptime(until, '%Y-%m-%d').date()
56+
if expiry_date < today_utc:
57+
to_delete.append((name, f"expired on {until}"))
58+
except ValueError:
59+
pass
3960

4061
if not to_delete:
4162
print("No servers to delete")
4263
return
4364

44-
print(f"Deleting {len(to_delete)} server(s) not in dev_boxes.yml")
65+
print(f"Deleting {len(to_delete)} server(s)")
4566

46-
for name in to_delete:
47-
print(f"\n=== Deleting: {name} ===")
67+
for name, reason in to_delete:
68+
print(f"\n=== Deleting: {name} ({reason}) ===")
4869

49-
# Delete the server
5070
ret, _, stderr = run_cmd(f"hcloud server delete '{name}'")
5171
if ret != 0:
5272
print(f"ERROR: Failed to delete server: {stderr}")

0 commit comments

Comments
 (0)