| skipped 96 lines |
97 | 97 | | } |
98 | 98 | | |
99 | 99 | | var ( |
100 | | - | // NOTE: Using $$ (current process PID) instead of ${SANDBOX_PID} breaks |
101 | | - | // (at least) the nixery program - the /proc symlinks become invalid |
102 | | - | // while chroot-ing and the operation cannot be finished (execve fails |
103 | | - | // with ENOENT, likely because of the missing/misplaced ELF interpreter). |
104 | | - | chrootProgramBusybox = template.Must(template.New("busybox-chroot").Parse(` |
105 | | - | set -eumo pipefail |
| 100 | + | chrootEntrypoint = template.Must(template.New("chroot-entrypoint").Parse(` |
| 101 | + | set -euo pipefail |
106 | 102 | | |
107 | | - | sleep 999999999 & |
108 | | - | SANDBOX_PID=$! |
| 103 | + | {{ if .IsNix }} |
| 104 | + | rm -rf /proc/1/root/nix |
| 105 | + | ln -s /proc/$$/root/nix /proc/1/root/nix |
| 106 | + | {{ end }} |
109 | 107 | | |
110 | | - | ln -s /proc/${SANDBOX_PID}/root/bin/ /proc/1/root/.cdebug-{{ .ID }} |
| 108 | + | ln -s /proc/$$/root/bin/ /proc/1/root/.cdebug-{{ .ID }} |
111 | 109 | | |
| 110 | + | cat > /.cdebug-entrypoint.sh <<EOF |
| 111 | + | #!/bin/sh |
112 | 112 | | export PATH=$PATH:/.cdebug-{{ .ID }} |
113 | 113 | | |
114 | 114 | | chroot /proc/1/root {{ .Cmd }} |
115 | | - | `)) |
116 | | - | |
117 | | - | chrootProgramNixery = template.Must(template.New("nixery-chroot").Parse(` |
118 | | - | set -eumo pipefail |
119 | | - | |
120 | | - | sleep 999999999 & |
121 | | - | SANDBOX_PID=$! |
122 | | - | |
123 | | - | rm -rf /proc/1/root/nix |
124 | | - | ln -s /proc/${SANDBOX_PID}/root/nix /proc/1/root/nix |
125 | | - | |
126 | | - | ln -s /proc/${SANDBOX_PID}/root/bin /proc/1/root/.cdebug-{{ .ID }} |
| 115 | + | EOF |
127 | 116 | | |
128 | | - | export PATH=$PATH:/.cdebug-{{ .ID }} |
129 | | - | |
130 | | - | chroot /proc/1/root {{ .Cmd }} |
| 117 | + | sh /.cdebug-entrypoint.sh |
131 | 118 | | `)) |
132 | 119 | | ) |
133 | 120 | | |
| skipped 23 lines |
157 | 144 | | Cmd: []string{ |
158 | 145 | | "sh", |
159 | 146 | | "-c", |
160 | | - | mustRenderTemplate(func() *template.Template { |
161 | | - | if strings.Contains(opts.image, "nixery") { |
162 | | - | return chrootProgramNixery |
163 | | - | } |
164 | | - | return chrootProgramBusybox |
165 | | - | }(), map[string]string{ |
166 | | - | "ID": runID, |
167 | | - | "Cmd": func() string { |
168 | | - | // TODO: Use `sh -i` when -it is passed. |
169 | | - | if len(opts.cmd) == 0 { |
170 | | - | return "sh" |
171 | | - | } |
172 | | - | return "sh -c '" + strings.Join(shellescape(opts.cmd), " ") + "'" |
173 | | - | }(), |
174 | | - | }), |
| 147 | + | mustRenderTemplate( |
| 148 | + | chrootEntrypoint, |
| 149 | + | map[string]any{ |
| 150 | + | "ID": runID, |
| 151 | + | "IsNix": strings.Contains(opts.image, "nixery"), |
| 152 | + | "Cmd": func() string { |
| 153 | + | if len(opts.cmd) == 0 { |
| 154 | + | return "sh" |
| 155 | + | } |
| 156 | + | return "sh -c '" + strings.Join(shellescape(opts.cmd), " ") + "'" |
| 157 | + | }(), |
| 158 | + | }, |
| 159 | + | ), |
175 | 160 | | }, |
176 | 161 | | Tty: opts.tty, |
177 | 162 | | OpenStdin: opts.stdin, |
| skipped 194 lines |