|
1 | 1 | package image |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "archive/tar" |
| 4 | + // "archive/tar" |
5 | 5 | "context" |
6 | | - "errors" |
| 6 | + // "errors" |
7 | 7 | "fmt" |
8 | 8 | "log/slog" |
9 | | - "path/filepath" |
| 9 | + |
| 10 | + // "path/filepath" |
10 | 11 |
|
11 | 12 | pb "github.com/cheggaaa/pb/v3" |
12 | 13 | "github.com/mholt/archiver" |
13 | 14 | lz4 "github.com/pierrec/lz4/v4" |
| 15 | + "golang.org/x/sys/unix" |
14 | 16 |
|
15 | 17 | "github.com/google/go-containerregistry/pkg/authn" |
16 | 18 | "github.com/google/go-containerregistry/pkg/name" |
@@ -51,21 +53,52 @@ func (i *Image) OciPull(ctx context.Context, imageRef, mountDir, username, passw |
51 | 53 | } |
52 | 54 | } |
53 | 55 |
|
| 56 | + var stat unix.Statfs_t |
| 57 | + |
| 58 | + err = unix.Statfs("/", &stat) |
| 59 | + if err != nil { |
| 60 | + return fmt.Errorf("get disk usage error: %w", err) |
| 61 | + } |
| 62 | + i.log.Info(fmt.Sprintf("disk usage before pulling: %d bytes", stat.Bavail * uint64(stat.Bsize))) |
| 63 | + |
54 | 64 | i.log.Info("pull oci image", "image", imageRef) |
55 | 65 | img, err := remote.Image(ref, remote.WithAuth(auth)) |
56 | 66 | if err != nil { |
57 | 67 | return fmt.Errorf("fetching remote image: %w", err) |
58 | 68 | } |
59 | 69 |
|
| 70 | + imgSize, err := img.Size() |
| 71 | + if err != nil { |
| 72 | + return fmt.Errorf("getting image size: %w", err) |
| 73 | + } |
| 74 | + i.log.Info(fmt.Sprintf("Oci image size: %d", imgSize)) |
| 75 | + |
| 76 | + err = unix.Statfs("/", &stat) |
| 77 | + if err != nil { |
| 78 | + return fmt.Errorf("get disk usage error: %w", err) |
| 79 | + } |
| 80 | + i.log.Info(fmt.Sprintf("disk usage after pulling: %d bytes", stat.Bavail * uint64(stat.Bsize))) |
| 81 | + |
60 | 82 | // Flatten layers and create a tar stream |
61 | 83 | rc := mutate.Extract(img) |
| 84 | + err = unix.Statfs("/", &stat) |
| 85 | + if err != nil { |
| 86 | + return fmt.Errorf("get disk usage error: %w", err) |
| 87 | + } |
| 88 | + i.log.Info(fmt.Sprintf("disk usage after extracting: %d bytes", stat.Bavail * uint64(stat.Bsize))) |
| 89 | + |
62 | 90 | defer rc.Close() |
63 | 91 |
|
64 | 92 | i.log.Info(fmt.Sprintf("untar oci image into %s", mountDir), "image", imageRef) |
65 | | - if err := i.untar(rc, mountDir); err != nil { |
66 | | - return fmt.Errorf("extracting tar: %w", err) |
| 93 | + if err := i.logStreamSize(rc); err != nil { |
| 94 | + return fmt.Errorf("logging oci stream size: %w", err) |
67 | 95 | } |
68 | 96 |
|
| 97 | + // i.log.Info(fmt.Sprintf("untar oci image into %s", mountDir), "image", imageRef) |
| 98 | + // if err := i.untar(rc, mountDir); err != nil { |
| 99 | + // return fmt.Errorf("extracting tar: %w", err) |
| 100 | + // } |
| 101 | + |
69 | 102 | i.log.Info("pull oci image done", "image", imageRef) |
70 | 103 | return nil |
71 | 104 | } |
@@ -217,70 +250,83 @@ func (i *Image) download(source, dest string) error { |
217 | 250 | return nil |
218 | 251 | } |
219 | 252 |
|
220 | | -func (i *Image) untar(r io.Reader, dest string) error { |
221 | | - tr := tar.NewReader(r) |
222 | | - for { |
223 | | - hdr, err := tr.Next() |
224 | | - if errors.Is(err, io.EOF) { |
225 | | - break |
226 | | - } |
227 | | - if err != nil { |
228 | | - return fmt.Errorf("reading tar: %w", err) |
229 | | - } |
230 | | - |
231 | | - target := filepath.Join(dest, hdr.Name) |
232 | | - |
233 | | - fmt.Printf("extracting:%s\n", target) |
| 253 | +func (i *Image) logStreamSize(r io.Reader) error { |
| 254 | + var size int |
| 255 | + ra, err := io.ReadAll(r) |
| 256 | + if err != nil { |
| 257 | + return err |
| 258 | + } |
234 | 259 |
|
235 | | - if strings.HasSuffix(target, ".log") { |
236 | | - fmt.Printf("skipping:%s\n", target) |
237 | | - continue |
238 | | - } |
| 260 | + size = len(ra) |
| 261 | + i.log.Info(fmt.Sprintf("reader size: %d bytes", size)) |
239 | 262 |
|
240 | | - switch hdr.Typeflag { |
241 | | - case tar.TypeDir: |
242 | | - if err := os.MkdirAll(target, os.FileMode(hdr.Mode)); err != nil { |
243 | | - return fmt.Errorf("creating dir: %w", err) |
244 | | - } |
245 | | - if err := os.Lchown(target, hdr.Uid, hdr.Gid); err != nil && !errors.Is(err, os.ErrPermission) { |
246 | | - return fmt.Errorf("chown dir: %w", err) |
247 | | - } |
248 | | - |
249 | | - case tar.TypeReg: |
250 | | - if err := os.MkdirAll(filepath.Dir(target), 0755); err != nil { |
251 | | - return fmt.Errorf("creating parent dir: %w", err) |
252 | | - } |
253 | | - f, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(hdr.Mode)) |
254 | | - if err != nil { |
255 | | - return fmt.Errorf("creating file: %w", err) |
256 | | - } |
257 | | - if _, err := io.Copy(f, tr); err != nil { |
258 | | - f.Close() |
259 | | - return fmt.Errorf("copying file: %w", err) |
260 | | - } |
261 | | - f.Close() |
262 | | - |
263 | | - if err := os.Chmod(target, os.FileMode(hdr.Mode)); err != nil { |
264 | | - return fmt.Errorf("chmod: %w", err) |
265 | | - } |
266 | | - if err := os.Lchown(target, hdr.Uid, hdr.Gid); err != nil && !errors.Is(err, os.ErrPermission) { |
267 | | - return fmt.Errorf("chown file: %w", err) |
268 | | - } |
269 | | - |
270 | | - case tar.TypeSymlink: |
271 | | - if err := os.MkdirAll(filepath.Dir(target), 0755); err != nil { |
272 | | - return fmt.Errorf("creating parent dir: %w", err) |
273 | | - } |
274 | | - if err := os.Symlink(hdr.Linkname, target); err != nil { |
275 | | - return fmt.Errorf("creating symlink: %w", err) |
276 | | - } |
277 | | - if err := os.Lchown(target, hdr.Uid, hdr.Gid); err != nil && !errors.Is(err, os.ErrPermission) { |
278 | | - return fmt.Errorf("chown symlink: %w", err) |
279 | | - } |
280 | | - |
281 | | - default: |
282 | | - // skip unsupported or special files |
283 | | - } |
284 | | - } |
285 | 263 | return nil |
286 | 264 | } |
| 265 | + |
| 266 | +// func (i *Image) untar(r io.Reader, dest string) error { |
| 267 | +// tr := tar.NewReader(r) |
| 268 | +// for { |
| 269 | +// hdr, err := tr.Next() |
| 270 | +// if errors.Is(err, io.EOF) { |
| 271 | +// break |
| 272 | +// } |
| 273 | +// if err != nil { |
| 274 | +// return fmt.Errorf("reading tar: %w", err) |
| 275 | +// } |
| 276 | +// |
| 277 | +// target := filepath.Join(dest, hdr.Name) |
| 278 | +// |
| 279 | +// fmt.Printf("extracting:%s\n", target) |
| 280 | +// |
| 281 | +// if strings.HasSuffix(target, ".log") { |
| 282 | +// fmt.Printf("skipping:%s\n", target) |
| 283 | +// continue |
| 284 | +// } |
| 285 | +// |
| 286 | +// switch hdr.Typeflag { |
| 287 | +// case tar.TypeDir: |
| 288 | +// if err := os.MkdirAll(target, os.FileMode(hdr.Mode)); err != nil { |
| 289 | +// return fmt.Errorf("creating dir: %w", err) |
| 290 | +// } |
| 291 | +// if err := os.Lchown(target, hdr.Uid, hdr.Gid); err != nil && !errors.Is(err, os.ErrPermission) { |
| 292 | +// return fmt.Errorf("chown dir: %w", err) |
| 293 | +// } |
| 294 | +// |
| 295 | +// case tar.TypeReg: |
| 296 | +// if err := os.MkdirAll(filepath.Dir(target), 0755); err != nil { |
| 297 | +// return fmt.Errorf("creating parent dir: %w", err) |
| 298 | +// } |
| 299 | +// f, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(hdr.Mode)) |
| 300 | +// if err != nil { |
| 301 | +// return fmt.Errorf("creating file: %w", err) |
| 302 | +// } |
| 303 | +// if _, err := io.Copy(f, tr); err != nil { |
| 304 | +// f.Close() |
| 305 | +// return fmt.Errorf("copying file: %w", err) |
| 306 | +// } |
| 307 | +// f.Close() |
| 308 | +// |
| 309 | +// if err := os.Chmod(target, os.FileMode(hdr.Mode)); err != nil { |
| 310 | +// return fmt.Errorf("chmod: %w", err) |
| 311 | +// } |
| 312 | +// if err := os.Lchown(target, hdr.Uid, hdr.Gid); err != nil && !errors.Is(err, os.ErrPermission) { |
| 313 | +// return fmt.Errorf("chown file: %w", err) |
| 314 | +// } |
| 315 | +// |
| 316 | +// case tar.TypeSymlink: |
| 317 | +// if err := os.MkdirAll(filepath.Dir(target), 0755); err != nil { |
| 318 | +// return fmt.Errorf("creating parent dir: %w", err) |
| 319 | +// } |
| 320 | +// if err := os.Symlink(hdr.Linkname, target); err != nil { |
| 321 | +// return fmt.Errorf("creating symlink: %w", err) |
| 322 | +// } |
| 323 | +// if err := os.Lchown(target, hdr.Uid, hdr.Gid); err != nil && !errors.Is(err, os.ErrPermission) { |
| 324 | +// return fmt.Errorf("chown symlink: %w", err) |
| 325 | +// } |
| 326 | +// |
| 327 | +// default: |
| 328 | +// // skip unsupported or special files |
| 329 | +// } |
| 330 | +// } |
| 331 | +// return nil |
| 332 | +// } |
0 commit comments