|
40 | 40 | # Ensure model directory exists |
41 | 41 | mkdir -p "$INSTALL_DIR/data/models" |
42 | 42 |
|
43 | | - # Download GGUF model if not already present (with retry) |
| 43 | + # Download GGUF model if not already present (with retry and integrity verification) |
44 | 44 | GGUF_DIR="$INSTALL_DIR/data/models" |
45 | | - if [[ "${DREAM_MODE:-local}" != "cloud" && ! -f "$GGUF_DIR/$GGUF_FILE" && -n "$GGUF_URL" ]]; then |
46 | | - ai "Downloading GGUF model: $GGUF_FILE" |
47 | | - signal "This is the big one. I've got it — sit back." |
48 | | - echo "" |
| 45 | + if [[ "${DREAM_MODE:-local}" != "cloud" && -n "$GGUF_URL" ]]; then |
| 46 | + # Check if model exists and verify integrity |
| 47 | + if [[ -f "$GGUF_DIR/$GGUF_FILE" ]]; then |
| 48 | + if [[ -n "$GGUF_SHA256" ]]; then |
| 49 | + if command -v sha256sum &>/dev/null; then |
| 50 | + ai "Verifying model integrity (SHA256)..." |
| 51 | + ACTUAL_HASH=$(sha256sum "$GGUF_DIR/$GGUF_FILE" 2>/dev/null | awk '{print $1}') |
| 52 | + if [[ -n "$ACTUAL_HASH" && "$ACTUAL_HASH" == "$GGUF_SHA256" ]]; then |
| 53 | + ai_ok "Model verified: $GGUF_FILE" |
| 54 | + elif [[ -z "$ACTUAL_HASH" ]]; then |
| 55 | + ai_warn "Could not compute checksum for existing model file" |
| 56 | + ai_ok "GGUF model already present: $GGUF_FILE (verification skipped)" |
| 57 | + else |
| 58 | + ai_warn "Model file is corrupt (SHA256 mismatch)." |
| 59 | + ai " Expected: $GGUF_SHA256" |
| 60 | + ai " Got: $ACTUAL_HASH" |
| 61 | + ai "Removing corrupt file and re-downloading..." |
| 62 | + rm -f "$GGUF_DIR/$GGUF_FILE" |
| 63 | + fi |
| 64 | + else |
| 65 | + ai_warn "sha256sum not available, skipping integrity check" |
| 66 | + ai_ok "GGUF model already present: $GGUF_FILE (verification skipped)" |
| 67 | + fi |
| 68 | + else |
| 69 | + ai_ok "GGUF model already present: $GGUF_FILE" |
| 70 | + fi |
| 71 | + fi |
| 72 | + |
| 73 | + # Download if not present or was removed due to corruption |
| 74 | + if [[ ! -f "$GGUF_DIR/$GGUF_FILE" ]]; then |
| 75 | + ai "Downloading GGUF model: $GGUF_FILE" |
| 76 | + signal "This is the big one. I've got it — sit back." |
| 77 | + echo "" |
49 | 78 |
|
50 | | - # Retry loop: up to 3 attempts with resume support (-c flag) |
51 | | - _dl_success=false |
52 | | - for _attempt in 1 2 3; do |
53 | | - [[ $_attempt -gt 1 ]] && ai "Retry attempt $_attempt of 3..." |
54 | | - wget -c -q -O "$GGUF_DIR/$GGUF_FILE.part" "$GGUF_URL" \ |
55 | | - >> "$INSTALL_DIR/logs/model-download.log" 2>&1 & |
56 | | - dl_pid=$! |
57 | | - |
58 | | - if spin_task $dl_pid "Downloading $GGUF_FILE"; then |
59 | | - mv "$GGUF_DIR/$GGUF_FILE.part" "$GGUF_DIR/$GGUF_FILE" |
60 | | - printf "\r ${BGRN}✓${NC} %-60s\n" "Model downloaded: $GGUF_FILE" |
61 | | - _dl_success=true |
62 | | - break |
| 79 | + # Retry loop: up to 3 attempts with resume support (-c flag) |
| 80 | + _dl_success=false |
| 81 | + for _attempt in 1 2 3; do |
| 82 | + [[ $_attempt -gt 1 ]] && ai "Retry attempt $_attempt of 3..." |
| 83 | + wget -c -q -O "$GGUF_DIR/$GGUF_FILE.part" "$GGUF_URL" \ |
| 84 | + >> "$INSTALL_DIR/logs/model-download.log" 2>&1 & |
| 85 | + dl_pid=$! |
| 86 | + |
| 87 | + if spin_task $dl_pid "Downloading $GGUF_FILE"; then |
| 88 | + mv "$GGUF_DIR/$GGUF_FILE.part" "$GGUF_DIR/$GGUF_FILE" |
| 89 | + printf "\r ${BGRN}✓${NC} %-60s\n" "Model downloaded: $GGUF_FILE" |
| 90 | + _dl_success=true |
| 91 | + break |
| 92 | + fi |
| 93 | + printf "\r ${AMB}⚠${NC} %-60s\n" "Download attempt $_attempt failed" |
| 94 | + sleep 3 |
| 95 | + done |
| 96 | + |
| 97 | + if [[ "$_dl_success" != "true" ]]; then |
| 98 | + printf "\r ${RED}✗${NC} %-60s\n" "Download failed after 3 attempts: $GGUF_FILE" |
| 99 | + ai "Manual retry: wget -c -O '$GGUF_DIR/$GGUF_FILE.part' '$GGUF_URL' && mv '$GGUF_DIR/$GGUF_FILE.part' '$GGUF_DIR/$GGUF_FILE'" |
| 100 | + else |
| 101 | + # Verify freshly downloaded file |
| 102 | + if [[ -n "$GGUF_SHA256" ]]; then |
| 103 | + if command -v sha256sum &>/dev/null; then |
| 104 | + ai "Verifying download integrity (SHA256)..." |
| 105 | + ACTUAL_HASH=$(sha256sum "$GGUF_DIR/$GGUF_FILE" 2>/dev/null | awk '{print $1}') |
| 106 | + if [[ -n "$ACTUAL_HASH" && "$ACTUAL_HASH" == "$GGUF_SHA256" ]]; then |
| 107 | + ai_ok "Download verified OK" |
| 108 | + elif [[ -z "$ACTUAL_HASH" ]]; then |
| 109 | + ai_warn "Could not compute checksum for downloaded file" |
| 110 | + ai_warn "Proceeding without verification (file may be corrupt)" |
| 111 | + else |
| 112 | + printf "\r ${RED}✗${NC} %-60s\n" "Downloaded file is corrupt (SHA256 mismatch)" |
| 113 | + ai " Expected: $GGUF_SHA256" |
| 114 | + ai " Got: $ACTUAL_HASH" |
| 115 | + rm -f "$GGUF_DIR/$GGUF_FILE" |
| 116 | + ai_warn "Corrupt file removed. Re-run installer to download again." |
| 117 | + _dl_success=false |
| 118 | + fi |
| 119 | + else |
| 120 | + ai_warn "sha256sum not available, skipping integrity check" |
| 121 | + ai_warn "Proceeding without verification (file may be corrupt)" |
| 122 | + fi |
| 123 | + fi |
63 | 124 | fi |
64 | | - printf "\r ${AMB}⚠${NC} %-60s\n" "Download attempt $_attempt failed" |
65 | | - sleep 3 |
66 | | - done |
| 125 | + fi |
67 | 126 |
|
68 | | - if [[ "$_dl_success" != "true" ]]; then |
69 | | - printf "\r ${RED}✗${NC} %-60s\n" "Download failed after 3 attempts: $GGUF_FILE" |
70 | | - ai "Manual retry: wget -c -O '$GGUF_DIR/$GGUF_FILE.part' '$GGUF_URL' && mv '$GGUF_DIR/$GGUF_FILE.part' '$GGUF_DIR/$GGUF_FILE'" |
| 127 | + # Abort if model download/verification failed |
| 128 | + if [[ "${DREAM_MODE:-local}" != "cloud" && -n "$GGUF_URL" && ! -f "$GGUF_DIR/$GGUF_FILE" ]]; then |
| 129 | + ai_bad "Model file missing or verification failed. Cannot proceed without a valid model." |
| 130 | + ai "Re-run the installer to retry the download." |
| 131 | + exit 1 |
71 | 132 | fi |
72 | | - elif [[ -f "$GGUF_DIR/$GGUF_FILE" ]]; then |
73 | | - ai_ok "GGUF model already present: $GGUF_FILE" |
74 | 133 | fi |
75 | 134 |
|
76 | 135 | # ── FLUX.1-schnell model download (ComfyUI image generation) ── |
|
0 commit comments