ExtractOrReadBinFS checks the provided fs for compressed coder binaries and extracts them into dest/bin if found. As a fallback, the provided FS is checked for a /bin directory, if it is non-empty it is returned. Finally dest/bin is returned as a fallback allowing binaries to be manually placed in d
(dest string, siteFS fs.FS)
| 155 | // name to SHA1 hash. The returned hash map may be incomplete or contain hashes |
| 156 | // for missing files. |
| 157 | func ExtractOrReadBinFS(dest string, siteFS fs.FS) (http.FileSystem, map[string]string, error) { |
| 158 | if dest == "" { |
| 159 | // No destination on fs, embedded fs is the only option. |
| 160 | binFS, err := fs.Sub(siteFS, "bin") |
| 161 | if err != nil { |
| 162 | return nil, nil, xerrors.Errorf("cache path is empty and embedded fs does not have /bin: %w", err) |
| 163 | } |
| 164 | return http.FS(binFS), nil, nil |
| 165 | } |
| 166 | |
| 167 | dest = filepath.Join(dest, "bin") |
| 168 | mkdest := func() (http.FileSystem, error) { |
| 169 | err := os.MkdirAll(dest, 0o700) |
| 170 | if err != nil { |
| 171 | return nil, xerrors.Errorf("mkdir failed: %w", err) |
| 172 | } |
| 173 | return http.Dir(dest), nil |
| 174 | } |
| 175 | |
| 176 | archive, err := siteFS.Open("bin/coder.tar.zst") |
| 177 | if err != nil { |
| 178 | if xerrors.Is(err, fs.ErrNotExist) { |
| 179 | files, err := fs.ReadDir(siteFS, "bin") |
| 180 | if err != nil { |
| 181 | if xerrors.Is(err, fs.ErrNotExist) { |
| 182 | // Given fs does not have a bin directory, serve from cache |
| 183 | // directory without extracting anything. |
| 184 | binFS, err := mkdest() |
| 185 | if err != nil { |
| 186 | return nil, nil, xerrors.Errorf("mkdest failed: %w", err) |
| 187 | } |
| 188 | return binFS, map[string]string{}, nil |
| 189 | } |
| 190 | return nil, nil, xerrors.Errorf("site fs read dir failed: %w", err) |
| 191 | } |
| 192 | |
| 193 | if len(filterFiles(files, "GITKEEP")) > 0 { |
| 194 | // If there are other files than bin/GITKEEP, serve the files. |
| 195 | binFS, err := fs.Sub(siteFS, "bin") |
| 196 | if err != nil { |
| 197 | return nil, nil, xerrors.Errorf("site fs sub dir failed: %w", err) |
| 198 | } |
| 199 | return http.FS(binFS), nil, nil |
| 200 | } |
| 201 | |
| 202 | // Nothing we can do, serve the cache directory, thus allowing |
| 203 | // binaries to be placed there. |
| 204 | binFS, err := mkdest() |
| 205 | if err != nil { |
| 206 | return nil, nil, xerrors.Errorf("mkdest failed: %w", err) |
| 207 | } |
| 208 | return binFS, map[string]string{}, nil |
| 209 | } |
| 210 | return nil, nil, xerrors.Errorf("open coder binary archive failed: %w", err) |
| 211 | } |
| 212 | defer archive.Close() |
| 213 | |
| 214 | binFS, err := mkdest() |