(nativeImage *native.Image)
| 690 | } |
| 691 | |
| 692 | func ImageFromNative(nativeImage *native.Image) (*Image, error) { |
| 693 | imgOCI := nativeImage.ImageConfig |
| 694 | repository, tag := imgutil.ParseRepoTag(nativeImage.Image.Name) |
| 695 | |
| 696 | image := &Image{ |
| 697 | // Docker ID (digest of platform-specific config), not containerd ID (digest of multi-platform index or manifest) |
| 698 | ID: nativeImage.ImageConfigDesc.Digest.String(), |
| 699 | Parent: nativeImage.Image.Labels["org.mobyproject.image.parent"], |
| 700 | Architecture: imgOCI.Architecture, |
| 701 | Variant: imgOCI.Platform.Variant, |
| 702 | Os: imgOCI.OS, |
| 703 | Size: nativeImage.Size, |
| 704 | VirtualSize: nativeImage.Size, |
| 705 | RepoTags: []string{fmt.Sprintf("%s:%s", repository, tag)}, |
| 706 | RepoDigests: []string{fmt.Sprintf("%s@%s", repository, nativeImage.Image.Target.Digest.String())}, |
| 707 | } |
| 708 | |
| 709 | if len(imgOCI.History) > 0 { |
| 710 | image.Comment = imgOCI.History[len(imgOCI.History)-1].Comment |
| 711 | if !imgOCI.History[len(imgOCI.History)-1].Created.IsZero() { |
| 712 | image.Created = imgOCI.History[len(imgOCI.History)-1].Created.Format(time.RFC3339Nano) |
| 713 | } |
| 714 | image.Author = imgOCI.History[len(imgOCI.History)-1].Author |
| 715 | } |
| 716 | |
| 717 | image.RootFS.Type = imgOCI.RootFS.Type |
| 718 | for _, d := range imgOCI.RootFS.DiffIDs { |
| 719 | image.RootFS.Layers = append(image.RootFS.Layers, d.String()) |
| 720 | } |
| 721 | |
| 722 | portSet := make(nat.PortSet) |
| 723 | for k := range imgOCI.Config.ExposedPorts { |
| 724 | portSet[nat.Port(k)] = struct{}{} |
| 725 | } |
| 726 | |
| 727 | image.Config = &Config{ |
| 728 | Cmd: imgOCI.Config.Cmd, |
| 729 | Volumes: imgOCI.Config.Volumes, |
| 730 | Env: imgOCI.Config.Env, |
| 731 | User: imgOCI.Config.User, |
| 732 | WorkingDir: imgOCI.Config.WorkingDir, |
| 733 | Entrypoint: imgOCI.Config.Entrypoint, |
| 734 | Labels: imgOCI.Config.Labels, |
| 735 | ExposedPorts: portSet, |
| 736 | Image: nativeImage.Image.Name, |
| 737 | } |
| 738 | |
| 739 | // Add health check if present in labels |
| 740 | if healthStr, ok := imgOCI.Config.Labels[labels.HealthCheck]; ok && healthStr != "" { |
| 741 | healthCheckConfig, err := healthcheck.HealthCheckFromJSON(healthStr) |
| 742 | if err != nil { |
| 743 | return nil, fmt.Errorf("failed to parse healthcheck label: %w", err) |
| 744 | } |
| 745 | image.Config.Healthcheck = healthCheckConfig |
| 746 | } |
| 747 | |
| 748 | return image, nil |
| 749 | } |
searching dependent graphs…