github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/pkg/ociinstaller/fdw.go (about)

     1  package ociinstaller
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"log"
     7  	"os"
     8  	"path/filepath"
     9  	"time"
    10  
    11  	"github.com/turbot/steampipe/pkg/constants"
    12  	"github.com/turbot/steampipe/pkg/filepaths"
    13  	versionfile "github.com/turbot/steampipe/pkg/ociinstaller/versionfile"
    14  )
    15  
    16  // InstallFdw installs the Steampipe Postgres foreign data wrapper from an OCI image
    17  func InstallFdw(ctx context.Context, dbLocation string) (string, error) {
    18  	tempDir := NewTempDir(dbLocation)
    19  	defer func() {
    20  		if err := tempDir.Delete(); err != nil {
    21  			log.Printf("[TRACE] Failed to delete temp dir '%s' after installing fdw: %s", tempDir, err)
    22  		}
    23  	}()
    24  
    25  	imageDownloader := NewOciDownloader()
    26  
    27  	// download the blobs.
    28  	image, err := imageDownloader.Download(ctx, NewSteampipeImageRef(constants.FdwImageRef), ImageTypeFdw, tempDir.Path)
    29  	if err != nil {
    30  		return "", err
    31  	}
    32  
    33  	// install the files
    34  	if err = installFdwFiles(image, tempDir.Path); err != nil {
    35  		return "", err
    36  	}
    37  
    38  	if err := updateVersionFileFdw(image); err != nil {
    39  		return string(image.OCIDescriptor.Digest), err
    40  	}
    41  
    42  	return string(image.OCIDescriptor.Digest), nil
    43  }
    44  
    45  func updateVersionFileFdw(image *SteampipeImage) error {
    46  	timeNow := versionfile.FormatTime(time.Now())
    47  	v, err := versionfile.LoadDatabaseVersionFile()
    48  	if err != nil {
    49  		return err
    50  	}
    51  	v.FdwExtension.Version = image.Config.Fdw.Version
    52  	v.FdwExtension.Name = "fdwExtension"
    53  	v.FdwExtension.ImageDigest = string(image.OCIDescriptor.Digest)
    54  	v.FdwExtension.InstalledFrom = image.ImageRef.requestedRef
    55  	v.FdwExtension.LastCheckedDate = timeNow
    56  	v.FdwExtension.InstallDate = timeNow
    57  	return v.Save()
    58  }
    59  
    60  func installFdwFiles(image *SteampipeImage, tempdir string) error {
    61  	fdwBinDir := filepaths.GetFDWBinaryDir()
    62  	fdwBinFileSourcePath := filepath.Join(tempdir, image.Fdw.BinaryFile)
    63  	fdwBinFileDestPath := filepath.Join(fdwBinDir, constants.FdwBinaryFileName)
    64  
    65  	// NOTE: for Mac M1 machines, if the fdw binary is updated in place without deleting the existing file,
    66  	// the updated fdw may crash on execution - for an undetermined reason
    67  	// to avoid this, first remove the existing .so file
    68  	os.Remove(fdwBinFileDestPath)
    69  	// now unzip the fdw file
    70  	if _, err := ungzip(fdwBinFileSourcePath, fdwBinDir); err != nil {
    71  		return fmt.Errorf("could not unzip %s to %s: %s", fdwBinFileSourcePath, fdwBinDir, err.Error())
    72  	}
    73  
    74  	fdwControlDir := filepaths.GetFDWSQLAndControlDir()
    75  	controlFileName := image.Fdw.ControlFile
    76  	controlFileSourcePath := filepath.Join(tempdir, controlFileName)
    77  	controlFileDestPath := filepath.Join(fdwControlDir, image.Fdw.ControlFile)
    78  
    79  	if err := moveFileWithinPartition(controlFileSourcePath, controlFileDestPath); err != nil {
    80  		return fmt.Errorf("could not install %s to %s", controlFileSourcePath, fdwControlDir)
    81  	}
    82  
    83  	fdwSQLDir := filepaths.GetFDWSQLAndControlDir()
    84  	sqlFileName := image.Fdw.SqlFile
    85  	sqlFileSourcePath := filepath.Join(tempdir, sqlFileName)
    86  	sqlFileDestPath := filepath.Join(fdwSQLDir, sqlFileName)
    87  	if err := moveFileWithinPartition(sqlFileSourcePath, sqlFileDestPath); err != nil {
    88  		return fmt.Errorf("could not install %s to %s", sqlFileSourcePath, fdwSQLDir)
    89  	}
    90  	return nil
    91  }