working on it

This commit is contained in:
kai
2024-09-02 13:47:08 +01:00
committed by Puskar Basu
parent ad49f0828a
commit f16cf35a85
10 changed files with 203 additions and 410 deletions

View File

@@ -592,7 +592,7 @@ func installPlugin(ctx context.Context, resolvedPlugin plugin.ResolvedPluginVers
}
}()
image, err := plugin.Install(ctx, resolvedPlugin, progress, putils.WithSkipConfig(viper.GetBool(constants.ArgSkipConfig)))
image, err := plugin.Install(ctx, resolvedPlugin, progress, constants.BaseImageRef, putils.WithSkipConfig(viper.GetBool(constants.ArgSkipConfig)))
if err != nil {
msg := ""
// used to build data for the plugin install report to be used for display purposes

View File

@@ -1,8 +0,0 @@
package constants
const (
ArchAMD64 = "amd64"
ArchARM64 = "arm64"
OSLinux = "linux"
OSDarwin = "darwin"
)

View File

@@ -22,7 +22,7 @@ func InstallAssets(ctx context.Context, assetsLocation string) error {
// download the blobs
imageDownloader := ociinstaller.NewOciDownloader()
image, err := imageDownloader.Download(ctx, ociinstaller.NewImageRef(constants.DashboardAssetsImageRef), ImageTypeAssets, tempDir.Path)
image, err := imageDownloader.Download(ctx, ociinstaller.NewImageRef(constants.DashboardAssetsImageRef), ociinstaller.ImageTypeAssets, tempDir.Path)
if err != nil {
return err
}
@@ -35,7 +35,7 @@ func InstallAssets(ctx context.Context, assetsLocation string) error {
return nil
}
func installAssetsFiles(image *OciImage, tempdir string, dest string) error {
func installAssetsFiles(image *ociinstaller.OciImage, tempdir string, dest string) error {
fileName := image.Assets.ReportUI
sourcePath := filepath.Join(tempdir, fileName)
if err := ociinstaller.MoveFolderWithinPartition(sourcePath, filepaths.EnsureDashboardAssetsDir()); err != nil {

View File

@@ -24,7 +24,7 @@ func InstallDB(ctx context.Context, dblocation string) (string, error) {
imageDownloader := ociinstaller.NewOciDownloader()
// Download the blobs
image, err := imageDownloader.Download(ctx, ociinstaller.NewImageRef(constants.PostgresImageRef), ImageTypeDatabase, tempDir.Path)
image, err := imageDownloader.Download(ctx, ociinstaller.NewImageRef(constants.PostgresImageRef), ociinstaller.ImageTypeDatabase, tempDir.Path)
if err != nil {
return "", err
}
@@ -40,7 +40,7 @@ func InstallDB(ctx context.Context, dblocation string) (string, error) {
return string(image.OCIDescriptor.Digest), nil
}
func updateVersionFileDB(image *OciImage) error {
func updateVersionFileDB(image *ociinstaller.OciImage) error {
timeNow := utils.FormatTime(time.Now())
v, err := versionfile.LoadDatabaseVersionFile()
if err != nil {
@@ -55,7 +55,7 @@ func updateVersionFileDB(image *OciImage) error {
return v.Save()
}
func installDbFiles(image *OciImage, tempDir string, dest string) error {
func installDbFiles(image *ociinstaller.OciImage, tempDir string, dest string) error {
source := filepath.Join(tempDir, image.Database.ArchiveDir)
return ociinstaller.MoveFolderWithinPartition(source, dest)
}

View File

@@ -24,7 +24,7 @@ func InstallFdw(ctx context.Context, dbLocation string) (string, error) {
}
}()
imageDownloader := ociinstaller.NewOciDownloader()
imageDownloader := ociinstaller.NewOciDownloader(constants.BaseImageRef, GetAllMediaTypes)
// download the blobs.
image, err := imageDownloader.Download(ctx, ociinstaller.NewImageRef(constants.FdwImageRef), ImageTypeFdw, tempDir.Path)
@@ -44,7 +44,7 @@ func InstallFdw(ctx context.Context, dbLocation string) (string, error) {
return string(image.OCIDescriptor.Digest), nil
}
func updateVersionFileFdw(image *OciImage) error {
func updateVersionFileFdw(image *ociinstaller.OciImage) error {
timeNow := putils.FormatTime(time.Now())
v, err := versionfile.LoadDatabaseVersionFile()
if err != nil {
@@ -59,7 +59,7 @@ func updateVersionFileFdw(image *OciImage) error {
return v.Save()
}
func installFdwFiles(image *OciImage, tempdir string) error {
func installFdwFiles(image *ociinstaller.OciImage, tempdir string) error {
fdwBinDir := filepaths.GetFDWBinaryDir()
fdwBinFileSourcePath := filepath.Join(tempdir, image.Fdw.BinaryFile)
fdwBinFileDestPath := filepath.Join(fdwBinDir, constants.FdwBinaryFileName)

View File

@@ -1,76 +0,0 @@
package ociinstaller
import (
"encoding/json"
)
const DefaultConfigSchema string = "2020-11-18"
type OciImageConfig interface {
Name()
}
type OciConfig interface {
GetSchemaVersion() string
SetSchemaVersion(string)
}
type OciConfigBase struct {
SchemaVersion string `json:"schemaVersion"`
}
func (c *OciConfigBase) GetSchemaVersion() string {
return c.SchemaVersion
}
func (c *OciConfigBase) SetSchemaVersion(version string) {
c.SchemaVersion = version
}
type configPlugin struct {
OciConfigBase
Plugin struct {
Name string `json:"name,omitempty"`
Organization string `json:"organization,omitempty"`
Version string `json:"version"`
}
}
type configDb struct {
OciConfigBase
Database struct {
Name string `json:"name,omitempty"`
Organization string `json:"organization,omitempty"`
Version string `json:"version"`
DBVersion string `json:"dbVersion,omitempty"`
}
}
type configFdw struct {
OciConfigBase
Fdw struct {
Name string `json:"name,omitempty"`
Organization string `json:"organization,omitempty"`
Version string `json:"version"`
}
}
func newSteampipeImageConfig(configBytes []byte, imageType ImageType) (OciConfig, error) {
var target OciConfig
switch imageType {
case ImageTypeDatabase:
target = &configDb{}
case ImageTypeFdw:
target = &configFdw{}
case ImageTypePlugin:
target = &configPlugin{}
}
if err := json.Unmarshal(configBytes, target); err != nil {
return nil, err
}
if target.GetSchemaVersion() == "" {
target.SetSchemaVersion(DefaultConfigSchema)
}
return target, nil
}

View File

@@ -2,46 +2,47 @@ package ociinstaller
import (
"fmt"
"github.com/turbot/pipe-fittings/constants"
"runtime"
"github.com/turbot/pipe-fittings/ociinstaller"
"github.com/turbot/pipe-fittings/utils"
"github.com/turbot/steampipe/pkg/constants"
)
// Steampipe Media Types
const (
MediaTypeConfig = "application/vnd.turbot.steampipe.config.v1+json"
//MediaTypeConfig = "application/vnd.turbot.steampipe.config.v1+json"
//deprecate this....
MediaTypePluginConfig = "application/vnd.turbot.steampipe.plugin.config.v1+json"
//MediaTypePluginConfig = "application/vnd.turbot.steampipe.plugin.config.v1+json"
MediaTypePluginDarwinAmd64Layer = "application/vnd.turbot.steampipe.plugin.darwin-amd64.layer.v1+gzip"
MediaTypePluginLinuxAmd64Layer = "application/vnd.turbot.steampipe.plugin.linux-amd64.layer.v1+gzip"
MediaTypePluginWindowsAmd64Layer = "application/vnd.turbot.steampipe.plugin.windows-amd64.layer.v1+gzip"
MediaTypePluginDarwinArm64Layer = "application/vnd.turbot.steampipe.plugin.darwin-arm64.layer.v1+gzip"
MediaTypePluginLinuxArm64Layer = "application/vnd.turbot.steampipe.plugin.linux-arm64.layer.v1+gzip"
MediaTypePluginWindowsArm64Layer = "application/vnd.turbot.steampipe.plugin.windows-arm64.layer.v1+gzip"
MediaTypePluginLicenseLayer = "application/vnd.turbot.steampipe.plugin.license.layer.v1+text"
MediaTypePluginDocsLayer = "application/vnd.turbot.steampipe.plugin.docs.layer.v1+tar"
MediaTypePluginSpcLayer = "application/vnd.turbot.steampipe.plugin.spc.layer.v1+tar"
//MediaTypePluginDarwinAmd64Layer = "application/vnd.turbot.steampipe.plugin.darwin-amd64.layer.v1+gzip"
//MediaTypePluginLinuxAmd64Layer = "application/vnd.turbot.steampipe.plugin.linux-amd64.layer.v1+gzip"
//MediaTypePluginWindowsAmd64Layer = "application/vnd.turbot.steampipe.plugin.windows-amd64.layer.v1+gzip"
//MediaTypePluginDarwinArm64Layer = "application/vnd.turbot.steampipe.plugin.darwin-arm64.layer.v1+gzip"
//MediaTypePluginLinuxArm64Layer = "application/vnd.turbot.steampipe.plugin.linux-arm64.layer.v1+gzip"
//MediaTypePluginWindowsArm64Layer = "application/vnd.turbot.steampipe.plugin.windows-arm64.layer.v1+gzip"
//MediaTypePluginLicenseLayer = "application/vnd.turbot.steampipe.plugin.license.layer.v1+text"
//MediaTypePluginDocsLayer = "application/vnd.turbot.steampipe.plugin.docs.layer.v1+tar"
//MediaTypePluginSpcLayer = "application/vnd.turbot.steampipe.plugin.spc.layer.v1+tar"
MediaTypeDbDarwinAmd64Layer = "application/vnd.turbot.steampipe.db.darwin-amd64.layer.v1+tar"
MediaTypeDbLinuxAmd64Layer = "application/vnd.turbot.steampipe.db.linux-amd64.layer.v1+tar"
MediaTypeDbWindowsAmd64Layer = "application/vnd.turbot.steampipe.db.windows-amd64.layer.v1+tar"
MediaTypeDbDarwinArm64Layer = "application/vnd.turbot.steampipe.db.darwin-arm64.layer.v1+tar"
MediaTypeDbLinuxArm64Layer = "application/vnd.turbot.steampipe.db.linux-arm64.layer.v1+tar"
MediaTypeDbWindowsArm64Layer = "application/vnd.turbot.steampipe.db.windows-arm64.layer.v1+tar"
MediaTypeDbDocLayer = "application/vnd.turbot.steampipe.db.doc.layer.v1+text"
MediaTypeDbLicenseLayer = "application/vnd.turbot.steampipe.db.license.layer.v1+text"
//MediaTypeDbDarwinAmd64Layer = "application/vnd.turbot.steampipe.db.darwin-amd64.layer.v1+tar"
//MediaTypeDbLinuxAmd64Layer = "application/vnd.turbot.steampipe.db.linux-amd64.layer.v1+tar"
//MediaTypeDbWindowsAmd64Layer = "application/vnd.turbot.steampipe.db.windows-amd64.layer.v1+tar"
//MediaTypeDbDarwinArm64Layer = "application/vnd.turbot.steampipe.db.darwin-arm64.layer.v1+tar"
//MediaTypeDbLinuxArm64Layer = "application/vnd.turbot.steampipe.db.linux-arm64.layer.v1+tar"
//MediaTypeDbWindowsArm64Layer = "application/vnd.turbot.steampipe.db.windows-arm64.layer.v1+tar"
MediaTypeDbDocLayer = "application/vnd.turbot.steampipe.db.doc.layer.v1+text"
MediaTypeDbLicenseLayer = "application/vnd.turbot.steampipe.db.license.layer.v1+text"
MediaTypeFdwDarwinAmd64Layer = "application/vnd.turbot.steampipe.fdw.darwin-amd64.layer.v1+gzip"
MediaTypeFdwLinuxAmd64Layer = "application/vnd.turbot.steampipe.fdw.linux-amd64.layer.v1+gzip"
MediaTypeFdwWindowsAmd64Layer = "application/vnd.turbot.steampipe.fdw.windows-amd64.layer.v1+gzip"
MediaTypeFdwDarwinArm64Layer = "application/vnd.turbot.steampipe.fdw.darwin-arm64.layer.v1+gzip"
MediaTypeFdwLinuxArm64Layer = "application/vnd.turbot.steampipe.fdw.linux-arm64.layer.v1+gzip"
MediaTypeFdwWindowsArm64Layer = "application/vnd.turbot.steampipe.fdw.windows-arm64.layer.v1+gzip"
MediaTypeFdwDocLayer = "application/vnd.turbot.steampipe.fdw.doc.layer.v1+text"
MediaTypeFdwLicenseLayer = "application/vnd.turbot.steampipe.fdw.license.layer.v1+text"
//MediaTypeFdwDarwinAmd64Layer = "application/vnd.turbot.steampipe.fdw.darwin-amd64.layer.v1+gzip"
//MediaTypeFdwLinuxAmd64Layer = "application/vnd.turbot.steampipe.fdw.linux-amd64.layer.v1+gzip"
//MediaTypeFdwWindowsAmd64Layer = "application/vnd.turbot.steampipe.fdw.windows-amd64.layer.v1+gzip"
//MediaTypeFdwDarwinArm64Layer = "application/vnd.turbot.steampipe.fdw.darwin-arm64.layer.v1+gzip"
//MediaTypeFdwLinuxArm64Layer = "application/vnd.turbot.steampipe.fdw.linux-arm64.layer.v1+gzip"
//MediaTypeFdwWindowsArm64Layer = "application/vnd.turbot.steampipe.fdw.windows-arm64.layer.v1+gzip"
MediaTypeFdwDocLayer = "application/vnd.turbot.steampipe.fdw.doc.layer.v1+text"
MediaTypeFdwLicenseLayer = "application/vnd.turbot.steampipe.fdw.license.layer.v1+text"
MediaTypeFdwControlLayer = "application/vnd.turbot.steampipe.fdw.control.layer.v1+text"
MediaTypeFdwSqlLayer = "application/vnd.turbot.steampipe.fdw.sql.layer.v1+text"
@@ -49,9 +50,19 @@ const (
MediaTypeAssetReportLayer = "application/vnd.turbot.steampipe.assets.report.layer.v1+tar"
)
func GetAllMediaTypes(imageType ociinstaller.ImageType) ([]string, error) {
p, err := MediaTypeForPlatform(imageType)
if err != nil {
return nil, err
}
s := SharedMediaTypes(imageType)
c := ConfigMediaTypes()
return append(append(p, s...), c...), nil
}
// MediaTypeForPlatform returns media types for binaries for this OS and architecture
// and it's fallbacks in order of priority
func MediaTypeForPlatform(imageType ImageType) ([]string, error) {
func MediaTypeForPlatform(imageType ociinstaller.ImageType) ([]string, error) {
layerFmtGzip := "application/vnd.turbot.steampipe.%s.%s-%s.layer.v1+gzip"
layerFmtTar := "application/vnd.turbot.steampipe.%s.%s-%s.layer.v1+tar"
@@ -68,7 +79,7 @@ func MediaTypeForPlatform(imageType ImageType) ([]string, error) {
return nil, err
}
return []string{fmt.Sprintf(layerFmtGzip, imageType, runtime.GOOS, arch)}, nil
case ImageTypePlugin:
case ociinstaller.ImageTypePlugin:
pluginMediaTypes := []string{fmt.Sprintf(layerFmtGzip, imageType, runtime.GOOS, arch)}
if runtime.GOOS == constants.OSDarwin && arch == constants.ArchARM64 {
// add the amd64 layer as well, so that we can fall back to it
@@ -83,7 +94,7 @@ func MediaTypeForPlatform(imageType ImageType) ([]string, error) {
}
// SharedMediaTypes returns media types that are NOT specific to the os and arch (readmes, control files, etc)
func SharedMediaTypes(imageType ImageType) []string {
func SharedMediaTypes(imageType ociinstaller.ImageType) []string {
switch imageType {
case ImageTypeAssets:
return []string{MediaTypeAssetReportLayer}
@@ -91,13 +102,13 @@ func SharedMediaTypes(imageType ImageType) []string {
return []string{MediaTypeDbDocLayer, MediaTypeDbLicenseLayer}
case ImageTypeFdw:
return []string{MediaTypeFdwDocLayer, MediaTypeFdwLicenseLayer, MediaTypeFdwControlLayer, MediaTypeFdwSqlLayer}
case ImageTypePlugin:
return []string{MediaTypePluginDocsLayer, MediaTypePluginSpcLayer, MediaTypePluginLicenseLayer}
case ociinstaller.ImageTypePlugin:
return []string{ociinstaller.MediaTypePluginSpcLayer(), ociinstaller.MediaTypePluginLicenseLayer()}
}
return nil
}
// ConfigMediaTypes :: returns media types for OCI $config data ( in the config, not a layer)
func ConfigMediaTypes() []string {
return []string{MediaTypeConfig, MediaTypePluginConfig}
return []string{ociinstaller.MediaTypeConfig(), ociinstaller.MediaTypePluginConfig()}
}

View File

@@ -0,0 +1,22 @@
package ociinstaller
import "github.com/turbot/pipe-fittings/ociinstaller"
type ConfigDb struct {
ociinstaller.OciConfigBase
Database struct {
Name string `json:"name,omitempty"`
Organization string `json:"organization,omitempty"`
Version string `json:"version"`
DBVersion string `json:"dbVersion,omitempty"`
}
}
type ConfigFdw struct {
ociinstaller.OciConfigBase
Fdw struct {
Name string `json:"name,omitempty"`
Organization string `json:"organization,omitempty"`
Version string `json:"version"`
}
}

View File

@@ -0,0 +1,127 @@
package ociinstaller
import (
"fmt"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/turbot/pipe-fittings/ociinstaller"
)
const (
ImageTypeDatabase ociinstaller.ImageType = "db"
ImageTypeFdw ociinstaller.ImageType = "fdw"
ImageTypeAssets ociinstaller.ImageType = "assets"
)
type DbImage struct {
ArchiveDir string
ReadmeFile string
LicenseFile string
}
func (s *DbImage) Type() ociinstaller.ImageType {
return ImageTypeDatabase
}
type FdwImage struct {
BinaryFile string
ReadmeFile string
LicenseFile string
ControlFile string
SqlFile string
}
func (s *FdwImage) Type() ociinstaller.ImageType {
return ImageTypeFdw
}
type AssetsImage struct {
ReportUI string
}
func (s *AssetsImage) Type() ociinstaller.ImageType {
return ImageTypeAssets
}
func getAssetImageData(layers []ocispec.Descriptor) (*AssetsImage, error) {
var assetImage AssetsImage
// get the report dir
foundLayers := ociinstaller.FindLayersForMediaType(layers, MediaTypeAssetReportLayer)
if len(foundLayers) > 0 {
assetImage.ReportUI = foundLayers[0].Annotations["org.opencontainers.image.title"]
}
return &assetImage, nil
}
func getDBImageData(layers []ocispec.Descriptor) (*DbImage, error) {
res := &DbImage{}
// get the binary jar file
mediaType, err := MediaTypeForPlatform("db")
if err != nil {
return nil, err
}
foundLayers := ociinstaller.FindLayersForMediaType(layers, mediaType[0])
if len(foundLayers) != 1 {
return nil, fmt.Errorf("invalid Image - should contain 1 installation file per platform, found %d", len(foundLayers))
}
res.ArchiveDir = foundLayers[0].Annotations["org.opencontainers.image.title"]
// get the readme file info
foundLayers = ociinstaller.FindLayersForMediaType(layers, MediaTypeDbDocLayer)
if len(foundLayers) > 0 {
res.ReadmeFile = foundLayers[0].Annotations["org.opencontainers.image.title"]
}
// get the license file info
foundLayers = ociinstaller.FindLayersForMediaType(layers, MediaTypeDbLicenseLayer)
if len(foundLayers) > 0 {
res.LicenseFile = foundLayers[0].Annotations["org.opencontainers.image.title"]
}
return res, nil
}
func getFdwImageData(layers []ocispec.Descriptor) (*FdwImage, error) {
res := &FdwImage{}
// get the binary (steampipe-postgres-fdw.so) info
mediaType, err := MediaTypeForPlatform("fdw")
if err != nil {
return nil, err
}
foundLayers := ociinstaller.FindLayersForMediaType(layers, mediaType[0])
if len(foundLayers) != 1 {
return nil, fmt.Errorf("invalid image - image should contain 1 binary file per platform, found %d", len(foundLayers))
}
res.BinaryFile = foundLayers[0].Annotations["org.opencontainers.image.title"]
//sourcePath := filepath.Join(tempDir.Path, fileName)
// get the control file info
foundLayers = ociinstaller.FindLayersForMediaType(layers, MediaTypeFdwControlLayer)
if len(foundLayers) != 1 {
return nil, fmt.Errorf("invalid image - image should contain 1 control file, found %d", len(foundLayers))
}
res.ControlFile = foundLayers[0].Annotations["org.opencontainers.image.title"]
// get the sql file info
foundLayers = ociinstaller.FindLayersForMediaType(layers, MediaTypeFdwSqlLayer)
if len(foundLayers) != 1 {
return nil, fmt.Errorf("invalid image - image should contain 1 SQL file, found %d", len(foundLayers))
}
res.SqlFile = foundLayers[0].Annotations["org.opencontainers.image.title"]
// get the readme file info
foundLayers = ociinstaller.FindLayersForMediaType(layers, MediaTypeFdwDocLayer)
if len(foundLayers) > 0 {
res.ReadmeFile = foundLayers[0].Annotations["org.opencontainers.image.title"]
}
// get the license file info
foundLayers = ociinstaller.FindLayersForMediaType(layers, MediaTypeFdwLicenseLayer)
if len(foundLayers) > 0 {
res.LicenseFile = foundLayers[0].Annotations["org.opencontainers.image.title"]
}
return res, nil
}

View File

@@ -1,283 +0,0 @@
package ociinstaller
import (
"context"
"errors"
"fmt"
"github.com/turbot/pipe-fittings/ociinstaller"
"log"
"strings"
"github.com/containerd/containerd/remotes"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/turbot/steampipe/pkg/constants"
)
type OciImageData interface {
Type() ImageType
}
type OciImage struct {
OCIDescriptor *ocispec.Descriptor
ImageRef *ociinstaller.ImageRef
ImageConfig OciConfig
ImageData OciImageData
resolver *remotes.Resolver
}
type PluginImage struct {
BinaryFile string
BinaryDigest string
BinaryArchitecture string
DocsDir string
ConfigFileDir string
LicenseFile string
}
func (s *PluginImage) Type() ImageType {
return ImageTypePlugin
}
type DbImage struct {
ArchiveDir string
ReadmeFile string
LicenseFile string
}
func (s *DbImage) Type() ImageType {
return ImageTypeDatabase
}
type FdwImage struct {
BinaryFile string
ReadmeFile string
LicenseFile string
ControlFile string
SqlFile string
}
func (s *FdwImage) Type() ImageType {
return ImageTypeFdw
}
type AssetsImage struct {
ReportUI string
}
func (s *AssetsImage) Type() ImageType {
return ImageTypeAssets
}
func (o *ociinstaller.ociDownloader) newSteampipeImage() *OciImage {
SteampipeImage := &OciImage{
resolver: &o.resolver,
}
o.Images = append(o.Images, SteampipeImage)
return SteampipeImage
}
type ImageType string
const (
ImageTypeDatabase ImageType = "db"
ImageTypeFdw ImageType = "fdw"
ImageTypeAssets ImageType = "assets"
ImageTypePlugin ImageType = "plugin"
)
func (o *ociinstaller.ociDownloader) Download(ctx context.Context, ref *ociinstaller.ImageRef, imageType ImageType, destDir string) (*OciImage, error) {
var mediaTypes []string
Image := o.newSteampipeImage()
Image.ImageRef = ref
mediaType, err := MediaTypeForPlatform(imageType)
if err != nil {
return nil, err
}
mediaTypes = append(mediaTypes, mediaType...)
mediaTypes = append(mediaTypes, SharedMediaTypes(imageType)...)
mediaTypes = append(mediaTypes, ConfigMediaTypes()...)
log.Println("[TRACE] ociDownloader.Download:", "downloading", ref.ActualImageRef())
// Download the files
imageDesc, _, configBytes, layers, err := o.Pull(ctx, ref.ActualImageRef(), mediaTypes, destDir)
if err != nil {
return nil, err
}
Image.OCIDescriptor = imageDesc
Image.Config, err = newSteampipeImageConfig(configBytes)
if err != nil {
return nil, errors.New("invalid image - missing $config")
}
// Get the metadata
switch imageType {
case ImageTypeDatabase:
Image.Database, err = getDBImageData(layers)
case ImageTypeFdw:
Image.Fdw, err = getFdwImageData(layers)
case ImageTypePlugin:
Image.Plugin, err = getPluginImageData(layers)
case ImageTypeAssets:
Image.Assets, err = getAssetImageData(layers)
default:
return nil, errors.New("invalid Type - image types are: plugin, db, fdw")
}
if err != nil {
return nil, err
}
return Image, nil
}
func getAssetImageData(layers []ocispec.Descriptor) (*AssetsImage, error) {
var assetImage AssetsImage
// get the report dir
foundLayers := findLayersForMediaType(layers, MediaTypeAssetReportLayer)
if len(foundLayers) > 0 {
assetImage.ReportUI = foundLayers[0].Annotations["org.opencontainers.image.title"]
}
return &assetImage, nil
}
func getDBImageData(layers []ocispec.Descriptor) (*DbImage, error) {
res := &DbImage{}
// get the binary jar file
mediaType, err := MediaTypeForPlatform("db")
if err != nil {
return nil, err
}
foundLayers := findLayersForMediaType(layers, mediaType[0])
if len(foundLayers) != 1 {
return nil, fmt.Errorf("invalid Image - should contain 1 installation file per platform, found %d", len(foundLayers))
}
res.ArchiveDir = foundLayers[0].Annotations["org.opencontainers.image.title"]
// get the readme file info
foundLayers = findLayersForMediaType(layers, MediaTypeDbDocLayer)
if len(foundLayers) > 0 {
res.ReadmeFile = foundLayers[0].Annotations["org.opencontainers.image.title"]
}
// get the license file info
foundLayers = findLayersForMediaType(layers, MediaTypeDbLicenseLayer)
if len(foundLayers) > 0 {
res.LicenseFile = foundLayers[0].Annotations["org.opencontainers.image.title"]
}
return res, nil
}
func getFdwImageData(layers []ocispec.Descriptor) (*FdwImage, error) {
res := &FdwImage{}
// get the binary (steampipe-postgres-fdw.so) info
mediaType, err := MediaTypeForPlatform("fdw")
if err != nil {
return nil, err
}
foundLayers := findLayersForMediaType(layers, mediaType[0])
if len(foundLayers) != 1 {
return nil, fmt.Errorf("invalid image - image should contain 1 binary file per platform, found %d", len(foundLayers))
}
res.BinaryFile = foundLayers[0].Annotations["org.opencontainers.image.title"]
//sourcePath := filepath.Join(tempDir.Path, fileName)
// get the control file info
foundLayers = findLayersForMediaType(layers, MediaTypeFdwControlLayer)
if len(foundLayers) != 1 {
return nil, fmt.Errorf("invalid image - image should contain 1 control file, found %d", len(foundLayers))
}
res.ControlFile = foundLayers[0].Annotations["org.opencontainers.image.title"]
// get the sql file info
foundLayers = findLayersForMediaType(layers, MediaTypeFdwSqlLayer)
if len(foundLayers) != 1 {
return nil, fmt.Errorf("invalid image - image should contain 1 SQL file, found %d", len(foundLayers))
}
res.SqlFile = foundLayers[0].Annotations["org.opencontainers.image.title"]
// get the readme file info
foundLayers = findLayersForMediaType(layers, MediaTypeFdwDocLayer)
if len(foundLayers) > 0 {
res.ReadmeFile = foundLayers[0].Annotations["org.opencontainers.image.title"]
}
// get the license file info
foundLayers = findLayersForMediaType(layers, MediaTypeFdwLicenseLayer)
if len(foundLayers) > 0 {
res.LicenseFile = foundLayers[0].Annotations["org.opencontainers.image.title"]
}
return res, nil
}
func getPluginImageData(layers []ocispec.Descriptor) (*PluginImage, error) {
res := &PluginImage{}
var foundLayers []ocispec.Descriptor
// get the binary plugin file info
// iterate in order of mediatypes - as given by MediaTypeForPlatform (see function docs)
mediaTypes, err := MediaTypeForPlatform("plugin")
if err != nil {
return nil, err
}
for _, mediaType := range mediaTypes {
// find out the layer with the correct media type
foundLayers = findLayersForMediaType(layers, mediaType)
if len(foundLayers) == 1 {
// when found, assign and exit
res.BinaryFile = foundLayers[0].Annotations["org.opencontainers.image.title"]
res.BinaryDigest = string(foundLayers[0].Digest)
res.BinaryArchitecture = constants.ArchAMD64
if strings.Contains(mediaType, constants.ArchARM64) {
res.BinaryArchitecture = constants.ArchARM64
}
break
}
// loop over to the next one
log.Println("[TRACE] could not find data for", mediaType)
log.Println("[TRACE] falling back to the next one, if any")
}
if len(res.BinaryFile) == 0 {
return nil, fmt.Errorf("invalid image - should contain 1 binary file per platform, found %d", len(foundLayers))
}
// get the docs dir
foundLayers = findLayersForMediaType(layers, MediaTypePluginDocsLayer)
if len(foundLayers) > 0 {
res.DocsDir = foundLayers[0].Annotations["org.opencontainers.image.title"]
}
// get the .spc config / connections file dir
foundLayers = findLayersForMediaType(layers, MediaTypePluginSpcLayer)
if len(foundLayers) > 0 {
res.ConfigFileDir = foundLayers[0].Annotations["org.opencontainers.image.title"]
}
// get the license file info
foundLayers = findLayersForMediaType(layers, MediaTypePluginLicenseLayer)
if len(foundLayers) > 0 {
res.LicenseFile = foundLayers[0].Annotations["org.opencontainers.image.title"]
}
return res, nil
}
func findLayersForMediaType(layers []ocispec.Descriptor, mediaType string) []ocispec.Descriptor {
log.Println("[TRACE] looking for", mediaType)
var matchedLayers []ocispec.Descriptor
for _, layer := range layers {
if layer.MediaType == mediaType {
matchedLayers = append(matchedLayers, layer)
}
}
return matchedLayers
}