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 }