| 265 | } |
| 266 | |
| 267 | func layerFromDir(input imagebuilder.LayerDataInfo) (v1.Layer, error) { |
| 268 | if !fsutil.Exists(input.Source) || |
| 269 | !fsutil.IsDir(input.Source) { |
| 270 | return nil, fmt.Errorf("bad input data") |
| 271 | } |
| 272 | |
| 273 | var b bytes.Buffer |
| 274 | tw := tar.NewWriter(&b) |
| 275 | |
| 276 | layerBasePath := "/" |
| 277 | if input.Params != nil && input.Params.TargetPath != "" { |
| 278 | layerBasePath = input.Params.TargetPath |
| 279 | } |
| 280 | |
| 281 | err := filepath.Walk(input.Source, func(fp string, info os.FileInfo, err error) error { |
| 282 | if err != nil { |
| 283 | return nil |
| 284 | } |
| 285 | rel, err := filepath.Rel(input.Source, fp) |
| 286 | if err != nil { |
| 287 | return fmt.Errorf("failed to calculate relative path: %w", err) |
| 288 | } |
| 289 | |
| 290 | hdr := &tar.Header{ |
| 291 | Name: path.Join(layerBasePath, filepath.ToSlash(rel)), |
| 292 | Mode: int64(info.Mode()), |
| 293 | } |
| 294 | |
| 295 | if !info.IsDir() { |
| 296 | hdr.Size = info.Size() |
| 297 | } |
| 298 | |
| 299 | if info.Mode().IsDir() { |
| 300 | hdr.Typeflag = tar.TypeDir |
| 301 | } else if info.Mode().IsRegular() { |
| 302 | hdr.Typeflag = tar.TypeReg |
| 303 | } else { |
| 304 | return fmt.Errorf("not implemented archiving file type %s (%s)", info.Mode(), rel) |
| 305 | } |
| 306 | |
| 307 | if err := tw.WriteHeader(hdr); err != nil { |
| 308 | return fmt.Errorf("failed to write tar header: %w", err) |
| 309 | } |
| 310 | if !info.IsDir() { |
| 311 | f, err := os.Open(fp) |
| 312 | if err != nil { |
| 313 | return err |
| 314 | } |
| 315 | if _, err := io.Copy(tw, f); err != nil { |
| 316 | return fmt.Errorf("failed to read file into the tar: %w", err) |
| 317 | } |
| 318 | f.Close() |
| 319 | } |
| 320 | return nil |
| 321 | }) |
| 322 | |
| 323 | if err != nil { |
| 324 | return nil, fmt.Errorf("failed to scan files: %w", err) |