detached 05295f2

fix(base): configure CachyOS repo on ISO before pacstrap and show package list

- Add configureCachyOSRepo() to setup CachyOS repository on the live ISO before running pacstrap
- Import CachyOS GPG key, add repo to pacman.conf, create mirrorlist, and sync databases
- Add copyCachyOSConfig() to copy CachyOS configuration to installed system after pacstrap
- Display package list before installation instead of just showing count
- Fixes "target not found: linux-cachyos" error during base installation

The issue was that pacstrap was running before the CachyOS repository was configured,
causing linux-cachyos kernel installation to fail. Now the repository is configured
on the ISO first, then copied to the installed system after pacstrap completes.
commit
05295f2b14d664e3009fbab86b0a70d4e0d34df9
author
bnema · · 2025-10-28 21:22 UTC
parent
426201a
signature
GPG Unverified2B82207D370127A0 The key is unknown
1 file · +171 -2
M internal/phases/base.go +171 -2
@@ -59,6 +59,17 @@ func (p *BaseInstallPhase) Execute(progressChan chan<- ProgressUpdate) PhaseResu
5959 return PhaseResult{Success: false, Error: err}
6060 }
6161
62+ // Step 2.5: Configure CachyOS repository on ISO if needed
63+ switch {
64+ case p.config.KernelChoice == config.KernelLinuxCachyOS:
65+ p.SendProgress(progressChan, "Configuring CachyOS repository...", 2, 5)
66+ switch err := p.configureCachyOSRepo(progressChan); {
67+ case err != nil:
68+ p.SendError(progressChan, err)
69+ return PhaseResult{Success: false, Error: err}
70+ }
71+ }
72+
6273 p.SendProgress(progressChan, "Installing base system...", 3, 5)
6374
6475 // Step 3: Run pacstrap
@@ -101,6 +112,147 @@ func (p *BaseInstallPhase) configurePacman(progressChan chan<- ProgressUpdate) e
101112 return nil
102113 }
103114
115+// configureCachyOSRepo configures CachyOS repository on the ISO before pacstrap
116+func (p *BaseInstallPhase) configureCachyOSRepo(progressChan chan<- ProgressUpdate) error {
117+ p.SendOutput(progressChan, "Configuring CachyOS repository on live system...")
118+
119+ // Import CachyOS GPG key
120+ p.SendOutput(progressChan, "Importing CachyOS GPG key...")
121+ result := p.logger.ExecCommand("pacman-key", "--recv-keys", "F3B607488DB35A47", "--keyserver", "keyserver.ubuntu.com")
122+ switch {
123+ case result.ExitCode != 0:
124+ return fmt.Errorf("failed to receive CachyOS GPG key: %w", result.Error)
125+ }
126+
127+ result = p.logger.ExecCommand("pacman-key", "--lsign-key", "F3B607488DB35A47")
128+ switch {
129+ case result.ExitCode != 0:
130+ return fmt.Errorf("failed to sign CachyOS GPG key: %w", result.Error)
131+ }
132+
133+ p.SendOutput(progressChan, "[OK] GPG key imported")
134+
135+ // Check if CachyOS repo already configured
136+ content, err := p.fs.ReadFile("/etc/pacman.conf")
137+ switch {
138+ case err != nil:
139+ return fmt.Errorf("failed to read pacman.conf: %w", err)
140+ }
141+
142+ contentStr := string(content)
143+ if !strings.Contains(contentStr, "[cachyos]") {
144+ // Add CachyOS repo before [core] repository
145+ p.SendOutput(progressChan, "Adding CachyOS repository to pacman.conf...")
146+
147+ // Find [core] and insert before it
148+ lines := strings.Split(contentStr, "\n")
149+ var newLines []string
150+ inserted := false
151+
152+ for _, line := range lines {
153+ if !inserted && strings.TrimSpace(line) == "[core]" {
154+ newLines = append(newLines, "# CachyOS repositories")
155+ newLines = append(newLines, "[cachyos]")
156+ newLines = append(newLines, "Include = /etc/pacman.d/cachyos-mirrorlist")
157+ newLines = append(newLines, "")
158+ inserted = true
159+ }
160+ newLines = append(newLines, line)
161+ }
162+
163+ contentStr = strings.Join(newLines, "\n")
164+
165+ switch err := p.fs.WriteFile("/etc/pacman.conf", []byte(contentStr), 0644); {
166+ case err != nil:
167+ return fmt.Errorf("failed to write pacman.conf: %w", err)
168+ }
169+ }
170+
171+ // Create CachyOS mirrorlist
172+ p.SendOutput(progressChan, "Creating CachyOS mirrorlist...")
173+ mirrorlist := "## CachyOS mirrorlist\nServer = https://mirror.cachyos.org/repo/$arch/$repo\n"
174+
175+ switch err := p.fs.WriteFile("/etc/pacman.d/cachyos-mirrorlist", []byte(mirrorlist), 0644); {
176+ case err != nil:
177+ return fmt.Errorf("failed to create cachyos-mirrorlist: %w", err)
178+ }
179+
180+ // Sync databases
181+ p.SendOutput(progressChan, "Syncing package databases...")
182+ result = p.logger.ExecCommand("pacman", "-Sy")
183+ switch {
184+ case result.ExitCode != 0:
185+ return fmt.Errorf("failed to sync databases: %w", result.Error)
186+ }
187+
188+ p.SendOutput(progressChan, "[OK] CachyOS repository configured")
189+ return nil
190+}
191+
192+// copyCachyOSConfig copies CachyOS repository configuration to installed system
193+func (p *BaseInstallPhase) copyCachyOSConfig(progressChan chan<- ProgressUpdate) error {
194+ // Read ISO's pacman.conf to check if CachyOS is configured
195+ content, err := p.fs.ReadFile("/etc/pacman.conf")
196+ switch {
197+ case err != nil:
198+ return fmt.Errorf("failed to read ISO pacman.conf: %w", err)
199+ }
200+
201+ isoContent := string(content)
202+
203+ // Read installed system's pacman.conf
204+ mntContent, err := p.fs.ReadFile("/mnt/etc/pacman.conf")
205+ switch {
206+ case err != nil:
207+ return fmt.Errorf("failed to read /mnt/etc/pacman.conf: %w", err)
208+ }
209+
210+ mntContentStr := string(mntContent)
211+
212+ // Add CachyOS repo before [core] if not already present
213+ if !strings.Contains(mntContentStr, "[cachyos]") && strings.Contains(isoContent, "[cachyos]") {
214+ lines := strings.Split(mntContentStr, "\n")
215+ var newLines []string
216+ inserted := false
217+
218+ for _, line := range lines {
219+ if !inserted && strings.TrimSpace(line) == "[core]" {
220+ newLines = append(newLines, "# CachyOS repositories")
221+ newLines = append(newLines, "[cachyos]")
222+ newLines = append(newLines, "Include = /etc/pacman.d/cachyos-mirrorlist")
223+ newLines = append(newLines, "")
224+ inserted = true
225+ }
226+ newLines = append(newLines, line)
227+ }
228+
229+ mntContentStr = strings.Join(newLines, "\n")
230+
231+ switch err := p.fs.WriteFile("/mnt/etc/pacman.conf", []byte(mntContentStr), 0644); {
232+ case err != nil:
233+ return fmt.Errorf("failed to write /mnt/etc/pacman.conf: %w", err)
234+ }
235+
236+ p.SendOutput(progressChan, "[OK] Added CachyOS to installed system's pacman.conf")
237+ }
238+
239+ // Copy mirrorlist from ISO to installed system
240+ result := p.logger.ExecCommand("mkdir", "-p", "/mnt/etc/pacman.d")
241+ switch {
242+ case result.ExitCode != 0:
243+ return fmt.Errorf("failed to create /mnt/etc/pacman.d: %w", result.Error)
244+ }
245+
246+ result = p.logger.ExecCommand("cp", "/etc/pacman.d/cachyos-mirrorlist", "/mnt/etc/pacman.d/cachyos-mirrorlist")
247+ switch {
248+ case result.ExitCode != 0:
249+ return fmt.Errorf("failed to copy cachyos-mirrorlist: %w", result.Error)
250+ }
251+
252+ p.SendOutput(progressChan, "[OK] CachyOS repository configured in installed system")
253+ return nil
254+}
255+
104256 // detectCPU detects CPU vendor and selects microcode
105257 func (p *BaseInstallPhase) detectCPU(progressChan chan<- ProgressUpdate) error {
106258 p.SendOutput(progressChan, "Detecting CPU vendor...")
@@ -189,8 +341,15 @@ func (p *BaseInstallPhase) runPacstrap(progressChan chan<- ProgressUpdate) error
189341 p.SendOutput(progressChan, "Adding cryptsetup for LUKS encryption")
190342 }
191343
192- p.SendOutput(progressChan, fmt.Sprintf("Installing %d packages...", len(packages)))
193- p.SendOutput(progressChan, "This may take several minutes...")
344+ p.SendOutput(progressChan, fmt.Sprintf("Installing %d packages:", len(packages)))
345+
346+ // Show package list
347+ for _, pkg := range packages {
348+ p.SendOutput(progressChan, fmt.Sprintf(" - %s", pkg))
349+ }
350+
351+ p.SendOutput(progressChan, "")
352+ p.SendOutput(progressChan, "Starting installation (this may take several minutes)...")
194353
195354 // Run pacstrap
196355 args := append([]string{"/mnt"}, packages...)
@@ -202,6 +361,16 @@ func (p *BaseInstallPhase) runPacstrap(progressChan chan<- ProgressUpdate) error
202361 }
203362
204363 p.SendOutput(progressChan, fmt.Sprintf("[OK] Installed %d packages", len(packages)))
364+
365+ // Copy CachyOS configuration to installed system if needed
366+ switch {
367+ case p.config.KernelChoice == config.KernelLinuxCachyOS:
368+ p.SendOutput(progressChan, "Configuring CachyOS repository in installed system...")
369+ if err := p.copyCachyOSConfig(progressChan); err != nil {
370+ return fmt.Errorf("failed to configure CachyOS in installed system: %w", err)
371+ }
372+ }
373+
205374 return nil
206375 }
207376
@@ -59,6 +59,17 @@ func (p *BaseInstallPhase) Execute(progressChan chan<- ProgressUpdate) PhaseResu
59 return PhaseResult{Success: false, Error: err}59 return PhaseResult{Success: false, Error: err}
60 }60 }
61 61
62+ // Step 2.5: Configure CachyOS repository on ISO if needed
63+ switch {
64+ case p.config.KernelChoice == config.KernelLinuxCachyOS:
65+ p.SendProgress(progressChan, "Configuring CachyOS repository...", 2, 5)
66+ switch err := p.configureCachyOSRepo(progressChan); {
67+ case err != nil:
68+ p.SendError(progressChan, err)
69+ return PhaseResult{Success: false, Error: err}
70+ }
71+ }
72+
62 p.SendProgress(progressChan, "Installing base system...", 3, 5)73 p.SendProgress(progressChan, "Installing base system...", 3, 5)
63 74
64 // Step 3: Run pacstrap75 // Step 3: Run pacstrap
@@ -101,6 +112,147 @@ func (p *BaseInstallPhase) configurePacman(progressChan chan<- ProgressUpdate) e
101 return nil112 return nil
102 }113 }
103 114
115+// configureCachyOSRepo configures CachyOS repository on the ISO before pacstrap
116+func (p *BaseInstallPhase) configureCachyOSRepo(progressChan chan<- ProgressUpdate) error {
117+ p.SendOutput(progressChan, "Configuring CachyOS repository on live system...")
118+
119+ // Import CachyOS GPG key
120+ p.SendOutput(progressChan, "Importing CachyOS GPG key...")
121+ result := p.logger.ExecCommand("pacman-key", "--recv-keys", "F3B607488DB35A47", "--keyserver", "keyserver.ubuntu.com")
122+ switch {
123+ case result.ExitCode != 0:
124+ return fmt.Errorf("failed to receive CachyOS GPG key: %w", result.Error)
125+ }
126+
127+ result = p.logger.ExecCommand("pacman-key", "--lsign-key", "F3B607488DB35A47")
128+ switch {
129+ case result.ExitCode != 0:
130+ return fmt.Errorf("failed to sign CachyOS GPG key: %w", result.Error)
131+ }
132+
133+ p.SendOutput(progressChan, "[OK] GPG key imported")
134+
135+ // Check if CachyOS repo already configured
136+ content, err := p.fs.ReadFile("/etc/pacman.conf")
137+ switch {
138+ case err != nil:
139+ return fmt.Errorf("failed to read pacman.conf: %w", err)
140+ }
141+
142+ contentStr := string(content)
143+ if !strings.Contains(contentStr, "[cachyos]") {
144+ // Add CachyOS repo before [core] repository
145+ p.SendOutput(progressChan, "Adding CachyOS repository to pacman.conf...")
146+
147+ // Find [core] and insert before it
148+ lines := strings.Split(contentStr, "\n")
149+ var newLines []string
150+ inserted := false
151+
152+ for _, line := range lines {
153+ if !inserted && strings.TrimSpace(line) == "[core]" {
154+ newLines = append(newLines, "# CachyOS repositories")
155+ newLines = append(newLines, "[cachyos]")
156+ newLines = append(newLines, "Include = /etc/pacman.d/cachyos-mirrorlist")
157+ newLines = append(newLines, "")
158+ inserted = true
159+ }
160+ newLines = append(newLines, line)
161+ }
162+
163+ contentStr = strings.Join(newLines, "\n")
164+
165+ switch err := p.fs.WriteFile("/etc/pacman.conf", []byte(contentStr), 0644); {
166+ case err != nil:
167+ return fmt.Errorf("failed to write pacman.conf: %w", err)
168+ }
169+ }
170+
171+ // Create CachyOS mirrorlist
172+ p.SendOutput(progressChan, "Creating CachyOS mirrorlist...")
173+ mirrorlist := "## CachyOS mirrorlist\nServer = https://mirror.cachyos.org/repo/$arch/$repo\n"
174+
175+ switch err := p.fs.WriteFile("/etc/pacman.d/cachyos-mirrorlist", []byte(mirrorlist), 0644); {
176+ case err != nil:
177+ return fmt.Errorf("failed to create cachyos-mirrorlist: %w", err)
178+ }
179+
180+ // Sync databases
181+ p.SendOutput(progressChan, "Syncing package databases...")
182+ result = p.logger.ExecCommand("pacman", "-Sy")
183+ switch {
184+ case result.ExitCode != 0:
185+ return fmt.Errorf("failed to sync databases: %w", result.Error)
186+ }
187+
188+ p.SendOutput(progressChan, "[OK] CachyOS repository configured")
189+ return nil
190+}
191+
192+// copyCachyOSConfig copies CachyOS repository configuration to installed system
193+func (p *BaseInstallPhase) copyCachyOSConfig(progressChan chan<- ProgressUpdate) error {
194+ // Read ISO's pacman.conf to check if CachyOS is configured
195+ content, err := p.fs.ReadFile("/etc/pacman.conf")
196+ switch {
197+ case err != nil:
198+ return fmt.Errorf("failed to read ISO pacman.conf: %w", err)
199+ }
200+
201+ isoContent := string(content)
202+
203+ // Read installed system's pacman.conf
204+ mntContent, err := p.fs.ReadFile("/mnt/etc/pacman.conf")
205+ switch {
206+ case err != nil:
207+ return fmt.Errorf("failed to read /mnt/etc/pacman.conf: %w", err)
208+ }
209+
210+ mntContentStr := string(mntContent)
211+
212+ // Add CachyOS repo before [core] if not already present
213+ if !strings.Contains(mntContentStr, "[cachyos]") && strings.Contains(isoContent, "[cachyos]") {
214+ lines := strings.Split(mntContentStr, "\n")
215+ var newLines []string
216+ inserted := false
217+
218+ for _, line := range lines {
219+ if !inserted && strings.TrimSpace(line) == "[core]" {
220+ newLines = append(newLines, "# CachyOS repositories")
221+ newLines = append(newLines, "[cachyos]")
222+ newLines = append(newLines, "Include = /etc/pacman.d/cachyos-mirrorlist")
223+ newLines = append(newLines, "")
224+ inserted = true
225+ }
226+ newLines = append(newLines, line)
227+ }
228+
229+ mntContentStr = strings.Join(newLines, "\n")
230+
231+ switch err := p.fs.WriteFile("/mnt/etc/pacman.conf", []byte(mntContentStr), 0644); {
232+ case err != nil:
233+ return fmt.Errorf("failed to write /mnt/etc/pacman.conf: %w", err)
234+ }
235+
236+ p.SendOutput(progressChan, "[OK] Added CachyOS to installed system's pacman.conf")
237+ }
238+
239+ // Copy mirrorlist from ISO to installed system
240+ result := p.logger.ExecCommand("mkdir", "-p", "/mnt/etc/pacman.d")
241+ switch {
242+ case result.ExitCode != 0:
243+ return fmt.Errorf("failed to create /mnt/etc/pacman.d: %w", result.Error)
244+ }
245+
246+ result = p.logger.ExecCommand("cp", "/etc/pacman.d/cachyos-mirrorlist", "/mnt/etc/pacman.d/cachyos-mirrorlist")
247+ switch {
248+ case result.ExitCode != 0:
249+ return fmt.Errorf("failed to copy cachyos-mirrorlist: %w", result.Error)
250+ }
251+
252+ p.SendOutput(progressChan, "[OK] CachyOS repository configured in installed system")
253+ return nil
254+}
255+
104 // detectCPU detects CPU vendor and selects microcode256 // detectCPU detects CPU vendor and selects microcode
105 func (p *BaseInstallPhase) detectCPU(progressChan chan<- ProgressUpdate) error {257 func (p *BaseInstallPhase) detectCPU(progressChan chan<- ProgressUpdate) error {
106 p.SendOutput(progressChan, "Detecting CPU vendor...")258 p.SendOutput(progressChan, "Detecting CPU vendor...")
@@ -189,8 +341,15 @@ func (p *BaseInstallPhase) runPacstrap(progressChan chan<- ProgressUpdate) error
189 p.SendOutput(progressChan, "Adding cryptsetup for LUKS encryption")341 p.SendOutput(progressChan, "Adding cryptsetup for LUKS encryption")
190 }342 }
191 343
192- p.SendOutput(progressChan, fmt.Sprintf("Installing %d packages...", len(packages)))344+ p.SendOutput(progressChan, fmt.Sprintf("Installing %d packages:", len(packages)))
193- p.SendOutput(progressChan, "This may take several minutes...")345+
346+ // Show package list
347+ for _, pkg := range packages {
348+ p.SendOutput(progressChan, fmt.Sprintf(" - %s", pkg))
349+ }
350+
351+ p.SendOutput(progressChan, "")
352+ p.SendOutput(progressChan, "Starting installation (this may take several minutes)...")
194 353
195 // Run pacstrap354 // Run pacstrap
196 args := append([]string{"/mnt"}, packages...)355 args := append([]string{"/mnt"}, packages...)
@@ -202,6 +361,16 @@ func (p *BaseInstallPhase) runPacstrap(progressChan chan<- ProgressUpdate) error
202 }361 }
203 362
204 p.SendOutput(progressChan, fmt.Sprintf("[OK] Installed %d packages", len(packages)))363 p.SendOutput(progressChan, fmt.Sprintf("[OK] Installed %d packages", len(packages)))
364+
365+ // Copy CachyOS configuration to installed system if needed
366+ switch {
367+ case p.config.KernelChoice == config.KernelLinuxCachyOS:
368+ p.SendOutput(progressChan, "Configuring CachyOS repository in installed system...")
369+ if err := p.copyCachyOSConfig(progressChan); err != nil {
370+ return fmt.Errorf("failed to configure CachyOS in installed system: %w", err)
371+ }
372+ }
373+
205 return nil374 return nil
206 }375 }
207 376

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 0

    ↑↓ moveenter openesc close