-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdrill
More file actions
executable file
·331 lines (287 loc) · 13 KB
/
drill
File metadata and controls
executable file
·331 lines (287 loc) · 13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
#!/bin/bash
set -euo pipefail
# ════════════════════════════════════════════════════════════════
# DRILL — Daily DevOps Interview Prep
# ════════════════════════════════════════════════════════════════
# Usage: ./drill [linux|docker|k8s|lab|stats|quick]
# Default: linux SR session
# ════════════════════════════════════════════════════════════════
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODULES_DIR="$SCRIPT_DIR/modules"
PROGRESS_DIR="$SCRIPT_DIR/progress"
SR="python3 $PROGRESS_DIR/sr.py"
LOG_FILE="$PROGRESS_DIR/drill-log.txt"
MODE="${1:-linux}"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
BOLD='\033[1m'
DIM='\033[2m'
NC='\033[0m'
mkdir -p "$PROGRESS_DIR"
# ════════════════════════════════════════════════════════════════
# HELPERS
# ════════════════════════════════════════════════════════════════
sr_stats_line() {
local module="${1:-linux}"
local stats
stats=$($SR stats "$module" 2>/dev/null)
local new learning review mastered due
new=$(echo "$stats" | python3 -c "import json,sys; print(json.load(sys.stdin)['new'])")
learning=$(echo "$stats" | python3 -c "import json,sys; print(json.load(sys.stdin)['learning'])")
review=$(echo "$stats" | python3 -c "import json,sys; print(json.load(sys.stdin)['review'])")
mastered=$(echo "$stats" | python3 -c "import json,sys; print(json.load(sys.stdin)['mastered'])")
due=$(echo "$stats" | python3 -c "import json,sys; print(json.load(sys.stdin)['due_today'])")
echo -e " new ${DIM}$new${NC} learning ${YELLOW}$learning${NC} review ${CYAN}$review${NC} mastered ${GREEN}$mastered${NC} due today ${BOLD}$due${NC}"
}
# ════════════════════════════════════════════════════════════════
# THEORY — Spaced Repetition Session
# ════════════════════════════════════════════════════════════════
run_theory_sr() {
local module="${1:-linux}"
clear
echo -e "${BOLD}${CYAN}"
cat << "EOF"
╔═══════════════════════════════════════════════════════════╗
║ DevOps Interview Drill — Theory ║
╚═══════════════════════════════════════════════════════════╝
EOF
echo -e "${NC}"
echo -e "${BLUE}$(date '+%A, %Y-%m-%d')${NC} module: ${BOLD}$module${NC}"
echo ""
# Ensure tracker is seeded
$SR init "$module" 2>/dev/null
# Get today's questions
local questions_json
questions_json=$($SR due "$module" 2>/dev/null)
local total
total=$(echo "$questions_json" | python3 -c "import json,sys; print(len(json.load(sys.stdin)))")
if [[ "$total" -eq 0 ]]; then
echo -e "${GREEN}All caught up — no questions due today.${NC}"
echo ""
sr_stats_line "$module"
echo ""
echo -e " Come back tomorrow, or run ${BOLD}./drill lab${NC} to practice hands-on."
echo ""
return 0
fi
echo -e " Due today: ${BOLD}$total${NC} questions"
echo ""
sr_stats_line "$module"
echo ""
echo -e "${DIM}Rating guide: 1=forgot 2=hard 3=good 4=easy${NC}"
echo ""
read -r -p "Press Enter to start..." _ || true
local i=0 again=0 hard=0 good=0 easy=0
while IFS= read -r question; do
local qid text status
qid=$(echo "$question" | python3 -c "import json,sys; print(json.load(sys.stdin)['id'])")
text=$(echo "$question" | python3 -c "import json,sys; print(json.load(sys.stdin)['text'])")
status=$(echo "$question" | python3 -c "import json,sys; print(json.load(sys.stdin)['status'])")
((i++)) || true
echo -e "${DIM}$i / $total [$qid] status: $status${NC}"
echo ""
echo -e "${BOLD}$text${NC}"
echo ""
echo -e "${DIM}Answer out loud as if you're in an interview.${NC}"
echo ""
read -r -p "Ready to rate? Press Enter..." _ || true
echo ""
echo -e "${BOLD} 1${NC} forgot ${BOLD}2${NC} hard ${BOLD}3${NC} good ${BOLD}4${NC} easy"
echo ""
local rating=""
while [[ ! "$rating" =~ ^[1-4]$ ]]; do
read -r -p " Rating: " rating
done
$SR rate "$qid" "$rating" "$module" 2>/dev/null
case "$rating" in
1) ((again++)) || true ;;
2) ((hard++)) || true ;;
3) ((good++)) || true ;;
4) ((easy++)) || true ;;
esac
done < <(echo "$questions_json" | python3 -c \
"import json,sys; [print(json.dumps(q)) for q in json.load(sys.stdin)]")
echo "$(date '+%Y-%m-%d %H:%M') | theory | $module | $i questions | 1:$again 2:$hard 3:$good 4:$easy" >> "$LOG_FILE"
clear
echo -e "${BOLD}${GREEN}Session complete!${NC}"
echo ""
echo -e " Questions: ${BOLD}$i${NC} forgot: ${RED}$again${NC} hard: ${YELLOW}$hard${NC} good: ${GREEN}$good${NC} easy: ${CYAN}$easy${NC}"
echo ""
sr_stats_line "$module"
echo ""
}
# ════════════════════════════════════════════════════════════════
# LAB SESSION
# ════════════════════════════════════════════════════════════════
run_lab() {
local module="${1:-linux}"
local labs_dir="$MODULES_DIR/$module/labs"
clear
echo -e "${BOLD}${CYAN}"
cat << "EOF"
╔═══════════════════════════════════════════════════════════╗
║ DevOps Interview Drill — Lab ║
╚═══════════════════════════════════════════════════════════╝
EOF
echo -e "${NC}"
echo -e "${BLUE}$(date '+%A, %Y-%m-%d')${NC} module: ${BOLD}$module${NC}"
echo ""
# Load lab completion status
local lab_status
lab_status=$($SR lab-stats "$module" 2>/dev/null || echo "{}")
# List labs with completion indicators
local labs=()
local i=0
while IFS= read -r lab; do
[[ -d "$labs_dir/$lab" ]] || continue
local done_flag
done_flag=$(echo "$lab_status" | python3 -c \
"import json,sys; d=json.load(sys.stdin); print('x' if d.get('$lab',{}).get('completed') else ' ')" 2>/dev/null || echo " ")
labs+=("$lab")
((i++)) || true
echo -e " ${BOLD}$i.${NC} [$done_flag] $lab"
done < <(ls "$labs_dir" 2>/dev/null | sort)
if [[ ${#labs[@]} -eq 0 ]]; then
echo "No labs found for module: $module"
return 1
fi
echo ""
read -r -p "Choose lab [1-$i] or Enter to skip: " choice
[[ -z "$choice" ]] && return 0
[[ ! "$choice" =~ ^[0-9]+$ ]] && return 0
(( choice < 1 || choice > i )) && return 0
local lab="${labs[$((choice-1))]}"
local lab_readme="$labs_dir/$lab/README.md"
local lab_setup="$labs_dir/$lab/setup.sh"
echo ""
echo -e "${YELLOW}━━━ $lab ━━━${NC}"
echo ""
if [[ -f "$lab_readme" ]]; then
head -6 "$lab_readme" | tail -4
echo ""
fi
echo -e " 1. Start (run setup)"
echo -e " 2. Read full instructions"
echo -e " 3. Mark as completed"
echo -e " 4. Back"
echo ""
read -r -p "Choose [1-4]: " action
case "$action" in
1)
if [[ -f "$lab_setup" ]]; then
echo ""
echo -e "${CYAN}Running setup...${NC}"
if echo "$lab" | grep -qE "^(01|02|07)"; then
echo -e "${YELLOW}This lab needs sudo.${NC}"
sudo bash "$lab_setup"
else
bash "$lab_setup"
fi
echo ""
echo -e "${GREEN}Lab ready!${NC} Read tasks: ${BOLD}cat $lab_readme${NC}"
echo "$(date '+%Y-%m-%d %H:%M') | lab-start | $module | $lab" >> "$LOG_FILE"
fi
;;
2)
echo ""
[[ -f "$lab_readme" ]] && cat "$lab_readme"
echo ""
read -r -p "Press Enter to continue..." _ || true
;;
3)
$SR lab-done "$lab" "$module" 2>/dev/null
echo -e "${GREEN}Marked complete!${NC}"
echo "$(date '+%Y-%m-%d %H:%M') | lab-done | $module | $lab" >> "$LOG_FILE"
;;
esac
}
# ════════════════════════════════════════════════════════════════
# STATS
# ════════════════════════════════════════════════════════════════
show_stats() {
local module="${1:-linux}"
echo ""
echo -e "${BOLD}${CYAN}Progress — $module${NC}"
echo ""
sr_stats_line "$module"
echo ""
# Lab stats
local lab_status
lab_status=$($SR lab-stats "$module" 2>/dev/null || echo "{}")
local total_labs completed_labs
total_labs=$(echo "$lab_status" | python3 -c "import json,sys; print(len(json.load(sys.stdin)))")
completed_labs=$(echo "$lab_status" | python3 -c \
"import json,sys; d=json.load(sys.stdin); print(sum(1 for v in d.values() if v.get('completed')))")
echo -e " labs: ${GREEN}$completed_labs${NC} / $total_labs completed"
echo ""
# Recent sessions
if [[ -f "$LOG_FILE" ]]; then
echo -e " ${BOLD}Last 5 sessions:${NC}"
tail -5 "$LOG_FILE" | while IFS= read -r line; do
echo " $line"
done
echo ""
fi
}
# ════════════════════════════════════════════════════════════════
# QUICK WARMUP
# ════════════════════════════════════════════════════════════════
run_quick() {
local module="${1:-docker}"
case "$module" in
docker)
if [[ -f "$MODULES_DIR/docker/quick.sh" ]]; then
bash "$MODULES_DIR/docker/quick.sh"
else
echo "Docker quick warmup not found."
fi
;;
*)
echo -e "${YELLOW}Quick warmup only available for Docker right now.${NC}"
;;
esac
}
# ════════════════════════════════════════════════════════════════
# MAIN
# ════════════════════════════════════════════════════════════════
case "$MODE" in
linux)
run_theory_sr linux
read -r -p "Do the lab? (y/n): " do_lab
[[ "$do_lab" =~ ^[Yy]$ ]] && run_lab linux
show_stats linux
;;
docker)
run_theory_sr docker
;;
k8s|kubernetes)
echo -e "${YELLOW}Kubernetes module coming after you finish Kubecraft!${NC}"
;;
lab)
run_lab "${2:-linux}"
;;
quick)
run_quick "${2:-docker}"
;;
stats)
show_stats "${2:-linux}"
;;
*)
echo -e "${BOLD}DevOps Interview Drill${NC}"
echo ""
echo "Usage: ./drill [command]"
echo ""
echo -e " ${BOLD}./drill${NC} — today's Linux SR session + lab"
echo -e " ${BOLD}./drill linux${NC} — same as above"
echo -e " ${BOLD}./drill docker${NC} — Docker SR session"
echo -e " ${BOLD}./drill lab${NC} — pick a lab to work on"
echo -e " ${BOLD}./drill stats${NC} — progress overview"
echo -e " ${BOLD}./drill quick${NC} — 5-min Docker command warmup"
echo ""
exit 1
;;
esac