Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run custom binaries #374

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions config/binary_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package config

import (
"fmt"
"os"

"code.vegaprotocol.io/vegacapsule/utils"
)

type BinaryConfig struct {
/*
description: Name of the service that is going to be used as an identifier when service runs.
example:
type: hcl
value: |
binary_service "service-name" {
...
}
*/
Name string `hcl:"name,label"`

/*
description: Command that will run at the app startup.
example:
type: hcl
value: |
cmd = "serve"
*/
Command string `hcl:"cmd,optional"`

/*
description: List of arguments that will be added to cmd.
example:
type: hcl
value: |
args = [
"--config", "--config=config/config_capsule.yaml",
]
*/
Args []string `hcl:"args,optional"`

/*
description: |
[Go template](templates.md) of a Binary Service config.

The [binary.ConfigTemplateContext](templates.md#binaryconfigtemplatecontext) can be used in the template.
Example can be found in [default network config](net_confs/config.hcl).
examples:
- type: hcl
value: |
config_template = <<EOH
...
EOH

*/

/*
description: |
Allows user to define a Service binary to be used.
A relative or absolute path can be used. If only the binary name is defined, it automatically looks for it in $PATH.
This can help with testing different version compatibilities or a protocol upgrade.
note: Using versions that are not compatible could break the network - therefore this should be used in advanced cases only.
*/
BinaryFile *string `hcl:"binary_path,optional"`

/*
description: |
The [binary.ConfigTemplateContext](templates.md#binaryconfigtemplatecontext) can be used in the template.
Example can be found in [default network config](net_confs/config.hcl).
examples:
- type: hcl
value: |
template = <<EOH
...
EOH

*/
ConfigTemplate *string `hcl:"config_template,optional"`

ConfigTemplateFile *string `hcl:"config_template_file,optional"`

Sync bool `hcl:"sync,optional"`
}

func (b *BinaryConfig) GetConfigTemplate(configDir string) (*string, error) {
if b.ConfigTemplate != nil {
return b.ConfigTemplate, nil
}

if b.ConfigTemplateFile == nil {
return nil, nil
}

templateFile, err := utils.AbsPathWithPrefix(configDir, *b.ConfigTemplateFile)
if err != nil {
return nil, fmt.Errorf("failed to get absolute file path %q: %w", *b.ConfigTemplateFile, err)
}

template, err := os.ReadFile(templateFile)
if err != nil {
return nil, fmt.Errorf("failed to read file %q: %w", templateFile, err)
}

str := string(template)
b.ConfigTemplate = &str

return &str, nil
}
38 changes: 29 additions & 9 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ func (c *Config) Validate(configDir string) error {
return fmt.Errorf("invalid configuration for wallet: %w", err)
}

if err := c.loadAndValidatePSConfigTemplates(); err != nil {
return fmt.Errorf("invalid configuration for PS config templates: %w", err)
}

return nil
}

Expand All @@ -199,7 +203,7 @@ func (c *Config) loadAndValidateNodeSets() error {
continue
}

updatedCt, err := c.loadAndValidateConfigTemplates(nc.ConfigTemplates)
updatedCt, err := c.loadAndValidateNodeConfigTemplates(nc.ConfigTemplates)
if err != nil {
mErr.Add(fmt.Errorf("failed to validate node set config templates: %w", err))
continue
Expand Down Expand Up @@ -261,7 +265,7 @@ func (c *Config) validateClefWalletConfig(nc NodeConfig) error {
return nil
}

func (c Config) loadAndValidatePreGenerate(preGen PreGenerate) (*PreGenerate, error) {
func (c *Config) loadAndValidatePreGenerate(preGen PreGenerate) (*PreGenerate, error) {
mErr := utils.NewMultiError()

for i, nc := range preGen.Nomad {
Expand All @@ -287,7 +291,23 @@ func (c Config) loadAndValidatePreGenerate(preGen PreGenerate) (*PreGenerate, er
return &preGen, nil
}

func (c Config) loadAndValidateConfigTemplates(ct ConfigTemplates) (*ConfigTemplates, error) {
func (c *Config) loadAndValidatePSConfigTemplates() error {
mErr := utils.NewMultiError()
if c.Network.PostStart == nil {
return nil
}
if err := c.Network.PostStart.LoadConfigTemplates(c.configDir); err != nil {
mErr.Add(fmt.Errorf("failed to load post start config templates: %w", err))
}

if mErr.HasAny() {
return mErr
}

return nil
}

func (c *Config) loadAndValidateNodeConfigTemplates(ct ConfigTemplates) (*ConfigTemplates, error) {
mErr := utils.NewMultiError()

if ct.Vega == nil && ct.VegaFile != nil {
Expand Down Expand Up @@ -347,7 +367,7 @@ func (c Config) loadAndValidateConfigTemplates(ct ConfigTemplates) (*ConfigTempl
return &ct, nil
}

func (c Config) LoadConfigTemplateFile(path string) (string, error) {
func (c *Config) LoadConfigTemplateFile(path string) (string, error) {
templateFile, err := utils.AbsPathWithPrefix(c.configDir, path)
if err != nil {
return "", fmt.Errorf("failed to get absolute file path %q: %w", path, err)
Expand All @@ -361,7 +381,7 @@ func (c Config) LoadConfigTemplateFile(path string) (string, error) {
return string(template), nil
}

func (c Config) loadAndValidateNomadJobTemplates(nc NodeConfig) (*NodeConfig, error) {
func (c *Config) loadAndValidateNomadJobTemplates(nc NodeConfig) (*NodeConfig, error) {
if nc.NomadJobTemplate != nil {
return &nc, nil
}
Expand Down Expand Up @@ -450,7 +470,7 @@ func (c *Config) loadAndValidateSetSmartContractsAddresses() error {
return nil
}

func (c Config) SmartContractsInfo() (*types.SmartContractsInfo, error) {
func (c *Config) SmartContractsInfo() (*types.SmartContractsInfo, error) {
smartcontracts := &types.SmartContractsInfo{}

if err := json.Unmarshal([]byte(*c.Network.SmartContractsAddresses), &smartcontracts); err != nil {
Expand All @@ -460,7 +480,7 @@ func (c Config) SmartContractsInfo() (*types.SmartContractsInfo, error) {
return smartcontracts, nil
}

func (c Config) GetSmartContractToken(name string) *types.SmartContractsToken {
func (c *Config) GetSmartContractToken(name string) *types.SmartContractsToken {
token, ok := c.Network.TokenAddresses[name]
if !ok {
return nil
Expand All @@ -476,11 +496,11 @@ func (c *Config) Persist() error {
return os.WriteFile(filepath.Join(*c.OutputDir, "config.hcl"), c.HCLBodyRaw, 0644)
}

func (c Config) LogsDir() string {
func (c *Config) LogsDir() string {
return path.Join(*c.OutputDir, "logs")
}

func (c Config) BinariesDir() string {
func (c *Config) BinariesDir() string {
return path.Join(*c.OutputDir, "bins")
}

Expand Down
2 changes: 1 addition & 1 deletion config/faucet_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type FaucetConfig struct {
example:
type: hcl
value: |
wallet "wallet-name" {
faucet "faucet-name" {
...
}
*/
Expand Down
17 changes: 17 additions & 0 deletions config/network_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,11 @@ type PStartConfig struct {
...
}
*/

Docker []DockerConfig `hcl:"docker_service,block"`
Exec []ExecConfig `hcl:"exec_service,block"`

Binary []BinaryConfig `hcl:"binary_service,block"`
}

func (nc NetworkConfig) GetNodeConfig(name string) (*NodeConfig, error) {
Expand All @@ -266,3 +269,17 @@ func (nc NetworkConfig) GetNodeConfig(name string) (*NodeConfig, error) {

return nil, fmt.Errorf("node config with name %q not found", name)
}

func (ps *PStartConfig) LoadConfigTemplates(configDir string) error {
// skip docker services 🤷
for i, conf := range ps.Binary {
confTemplate, err := conf.GetConfigTemplate(configDir)
if err != nil {
return err
}
conf.ConfigTemplate = confTemplate
ps.Binary[i] = conf
}

return nil
}
2 changes: 1 addition & 1 deletion config/node_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ type NodeConfig struct {
/*
description: |
Allows a user to run a custom service before the node set is generated.
This can be very useful when generating the node set might have some extenal dependency, such as
This can be very useful when generating the node set might have some external dependency, such as
a [Clef wallet](https://geth.ethereum.org/docs/clef/introduction).
note: |
Clef wallet is a good example - since generating a validator node set requires the Ethereum key
Expand Down
4 changes: 3 additions & 1 deletion config/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"os"
"path/filepath"

"code.vegaprotocol.io/vegacapsule/types"
"github.com/hashicorp/go-cty-funcs/crypto"
"github.com/hashicorp/go-cty-funcs/encoding"
"github.com/hashicorp/go-cty-funcs/uuid"
Expand All @@ -17,6 +16,8 @@ import (
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/function"
"github.com/zclconf/go-cty/cty/function/stdlib"

"code.vegaprotocol.io/vegacapsule/types"
)

var envFunc = function.New(&function.Spec{
Expand Down Expand Up @@ -46,6 +47,7 @@ func newEvalContext(genServices cty.Value, homePath string) *hcl.EvalContext {
Variables: map[string]cty.Value{
"generated": genServices,
"network_home_path": cty.StringVal(homePath),
"binary_services": cty.StringVal(filepath.Join(homePath, "binary_services")),
},
Functions: map[string]function.Function{
"abs": stdlib.AbsoluteFunc,
Expand Down
27 changes: 27 additions & 0 deletions generator/binary/commands.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package binary

import (
"fmt"
"log"

"code.vegaprotocol.io/vegacapsule/config"
"code.vegaprotocol.io/vegacapsule/utils"
)

type initBinaryOutput struct {
BinaryConfigFilePath string `json:"binaryConfigFilePath"`
}

func (cg *ConfigGenerator) initiateBinary(conf *config.BinaryConfig) (*initBinaryOutput, error) {
if conf == nil {
return nil, fmt.Errorf("binary config is nil")
}
log.Printf("Initiating binary with: %s %v", *conf.BinaryFile, conf.Args)

out := &initBinaryOutput{}
if _, err := utils.ExecuteBinary(*conf.BinaryFile, conf.Args, out); err != nil {
return nil, err
}

return out, nil
}
Loading