code.vegaprotocol.io/vega@v0.79.0/visor/visor_folders.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package visor
    17  
    18  import (
    19  	"context"
    20  	"fmt"
    21  	"os"
    22  	"path"
    23  
    24  	"code.vegaprotocol.io/vega/logging"
    25  	"code.vegaprotocol.io/vega/visor/config"
    26  	"code.vegaprotocol.io/vega/visor/github"
    27  	"code.vegaprotocol.io/vega/visor/utils"
    28  )
    29  
    30  var vegaDataNodeStartCmdArgs = []string{"datanode", "start"}
    31  
    32  func (v *Visor) setCurrentFolder(sourceFolder, currentFolder string) error {
    33  	v.log.Info("Setting current folder",
    34  		logging.String("sourceFolder", sourceFolder),
    35  		logging.String("currentFolder", currentFolder),
    36  	)
    37  
    38  	runConfPath := path.Join(sourceFolder, config.RunConfigFileName)
    39  	runConfExists, err := utils.PathExists(runConfPath)
    40  	if err != nil {
    41  		return err
    42  	}
    43  
    44  	if !runConfExists {
    45  		return fmt.Errorf("missing run config in %q folder", runConfPath)
    46  	}
    47  
    48  	if err := os.RemoveAll(currentFolder); err != nil {
    49  		return fmt.Errorf("failed to remove current folder: %w", err)
    50  	}
    51  
    52  	if err := os.Symlink(sourceFolder, currentFolder); err != nil {
    53  		return fmt.Errorf("failed to set current folder as current: %w", err)
    54  	}
    55  
    56  	return nil
    57  }
    58  
    59  func (v *Visor) installUpgradeFolder(ctx context.Context, folder, releaseTag string, conf config.AutoInstallConfig) error {
    60  	v.log.Info("Automatically installing upgrade folder")
    61  
    62  	runConf, err := config.ParseRunConfig(v.conf.CurrentRunConfigPath())
    63  	if err != nil {
    64  		return err
    65  	}
    66  
    67  	if conf.Asset.Name == "" {
    68  		return missingAutoInstallAssetError("vega")
    69  	}
    70  
    71  	if err := os.MkdirAll(folder, 0o755); err != nil {
    72  		return fmt.Errorf("failed to create upgrade folder %q, %w", folder, err)
    73  	}
    74  
    75  	assetsFetcher := github.NewAssetsFetcher(
    76  		conf.GithubRepositoryOwner,
    77  		conf.GithubRepository,
    78  		[]string{conf.Asset.Name},
    79  	)
    80  
    81  	v.log.Info("Downloading asset from Github", logging.String("asset", conf.Asset.Name))
    82  	if err := assetsFetcher.Download(ctx, releaseTag, folder); err != nil {
    83  		return fmt.Errorf("failed to download release assets for tag %q: %w", releaseTag, err)
    84  	}
    85  
    86  	runConf.Name = releaseTag
    87  	runConf.Vega.Binary.Path = conf.Asset.GetBinaryPath()
    88  
    89  	if runConf.DataNode != nil {
    90  		runConf.DataNode.Binary.Path = conf.Asset.GetBinaryPath()
    91  
    92  		if len(runConf.DataNode.Binary.Args) != 0 && runConf.DataNode.Binary.Args[0] != vegaDataNodeStartCmdArgs[0] {
    93  			runConf.DataNode.Binary.Args = append(vegaDataNodeStartCmdArgs, runConf.DataNode.Binary.Args[1:]...)
    94  		}
    95  	}
    96  
    97  	runConfPath := path.Join(folder, config.RunConfigFileName)
    98  	if err := runConf.WriteToFile(runConfPath); err != nil {
    99  		return fmt.Errorf("failed to create run config %q: %w", runConfPath, err)
   100  	}
   101  
   102  	return nil
   103  }
   104  
   105  func (v *Visor) prepareNextUpgradeFolder(ctx context.Context, releaseTag string) error {
   106  	v.log.Debug("preparing next upgrade folder",
   107  		logging.String("vegaTagVersion", releaseTag),
   108  	)
   109  
   110  	upgradeFolder := v.conf.UpgradeFolder(releaseTag)
   111  	upgradeFolderExists, err := utils.PathExists(upgradeFolder)
   112  	if err != nil {
   113  		return err
   114  	}
   115  
   116  	if !upgradeFolderExists {
   117  		autoInstallConf := v.conf.AutoInstall()
   118  		if !autoInstallConf.Enabled {
   119  			return fmt.Errorf("required upgrade folder %q is missing", upgradeFolder)
   120  		}
   121  
   122  		if err := v.installUpgradeFolder(ctx, upgradeFolder, releaseTag, autoInstallConf); err != nil {
   123  			return fmt.Errorf("failed to auto install folder %q for release %q: %w", upgradeFolder, releaseTag, err)
   124  		}
   125  	}
   126  
   127  	if err := v.setCurrentFolder(upgradeFolder, v.conf.CurrentFolder()); err != nil {
   128  		return fmt.Errorf("failed to set current folder to %q: %w", v.conf.CurrentFolder(), err)
   129  	}
   130  
   131  	return nil
   132  }
   133  
   134  func missingAutoInstallAssetError(asset string) error {
   135  	return fmt.Errorf("missing required auto install %s asset definition in Visor config", asset)
   136  }