github.com/supabase/cli@v1.168.1/internal/services/services.go (about)

     1  package services
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  	"sync"
     8  
     9  	"github.com/spf13/afero"
    10  	"github.com/supabase/cli/internal/migration/list"
    11  	"github.com/supabase/cli/internal/utils"
    12  	"github.com/supabase/cli/internal/utils/flags"
    13  	"github.com/supabase/cli/internal/utils/tenant"
    14  )
    15  
    16  var suggestLinkCommand = fmt.Sprintf("Run %s to sync your local image versions with the linked project.", utils.Aqua("supabase link"))
    17  
    18  func Run(ctx context.Context, fsys afero.Fs) error {
    19  	_ = utils.LoadConfigFS(fsys)
    20  	serviceImages := GetServiceImages()
    21  
    22  	var linked map[string]string
    23  	if projectRef, err := flags.LoadProjectRef(fsys); err == nil {
    24  		linked = GetRemoteImages(ctx, projectRef)
    25  	}
    26  
    27  	table := `|SERVICE IMAGE|LOCAL|LINKED|
    28  |-|-|-|
    29  `
    30  	for _, image := range serviceImages {
    31  		parts := strings.Split(image, ":")
    32  		version, ok := linked[image]
    33  		if !ok {
    34  			version = "-"
    35  		} else if parts[1] != version && image != utils.Config.Db.Image {
    36  			utils.CmdSuggestion = suggestLinkCommand
    37  		}
    38  		table += fmt.Sprintf("|`%s`|`%s`|`%s`|\n", parts[0], parts[1], version)
    39  	}
    40  
    41  	return list.RenderTable(table)
    42  }
    43  
    44  func GetServiceImages() []string {
    45  	return []string{
    46  		utils.Config.Db.Image,
    47  		utils.Config.Auth.Image,
    48  		utils.Config.Api.Image,
    49  		utils.RealtimeImage,
    50  		utils.Config.Storage.Image,
    51  		utils.EdgeRuntimeImage,
    52  		utils.StudioImage,
    53  		utils.PgmetaImage,
    54  		utils.LogflareImage,
    55  		utils.PgbouncerImage,
    56  		utils.ImageProxyImage,
    57  	}
    58  }
    59  
    60  func GetRemoteImages(ctx context.Context, projectRef string) map[string]string {
    61  	linked := make(map[string]string, 4)
    62  	var wg sync.WaitGroup
    63  	wg.Add(1)
    64  	go func() {
    65  		defer wg.Done()
    66  		if version, err := tenant.GetDatabaseVersion(ctx, projectRef); err == nil {
    67  			linked[utils.Config.Db.Image] = version
    68  		}
    69  	}()
    70  	keys, err := tenant.GetApiKeys(ctx, projectRef)
    71  	if err != nil {
    72  		wg.Wait()
    73  		return linked
    74  	}
    75  	api := tenant.NewTenantAPI(ctx, projectRef, keys.Anon)
    76  	wg.Add(3)
    77  	go func() {
    78  		defer wg.Done()
    79  		if version, err := api.GetGotrueVersion(ctx); err == nil {
    80  			linked[utils.Config.Auth.Image] = version
    81  		}
    82  	}()
    83  	go func() {
    84  		defer wg.Done()
    85  		if version, err := api.GetPostgrestVersion(ctx); err == nil {
    86  			linked[utils.Config.Api.Image] = version
    87  		}
    88  	}()
    89  	go func() {
    90  		defer wg.Done()
    91  		if version, err := api.GetStorageVersion(ctx); err == nil {
    92  			linked[utils.Config.Storage.Image] = version
    93  		}
    94  	}()
    95  	wg.Wait()
    96  	return linked
    97  }