Adds initial HCP config support

Adds initial basic support for HCP based configuration in vagrant-go.
The initalization process has been updated to remove Vagrantfile parsing
from the client, moving it to the runner using init jobs for the basis
and the project (if there is one). Detection is done on the file based
on extension for Ruby based parsing or HCP based parsing.

Current HCP parsing is extremely simple and currently just a base to
build off. Config components will be able to implement an `Init`
function to handle receiving configuration data from a non-native source
file. This will be extended to include a default approach for injecting
defined data in the future.

Some cleanup was done in the state around validations. Some logging
adjustments were applied on the Ruby side for better behavior
consistency.

VirtualBox provider now caches locale detection to prevent multiple
checks every time the driver is initialized.
This commit is contained in:
Chris Roberts 2023-08-24 14:59:04 -07:00
parent fb7e673b61
commit e958c6183a
66 changed files with 2374 additions and 3655 deletions

View File

@ -4,8 +4,7 @@
package configvagrant
import (
"fmt"
"github.com/hashicorp/go-argmapper"
"github.com/hashicorp/go-hclog"
sdk "github.com/hashicorp/vagrant-plugin-sdk"
"github.com/hashicorp/vagrant-plugin-sdk/component"
@ -24,6 +23,7 @@ var CommandOptions = []sdk.Option{
type Vagrant struct {
Sensitive []string `hcl:"sensitive,optional" json:",omitempty"`
Host *string `hcl:"host,optional" json:"host,omitempty"`
FinalizedInfo *string `hcl:"finalized_info,optional" json:"finalized_info,omitempty"`
Plugins []Plugin `hcl:"plugins,block" json:"plugins,omitempty"`
}
@ -43,6 +43,14 @@ func (c *Config) Register() (*component.ConfigRegistration, error) {
}, nil
}
func (c *Config) InitFunc() any {
return c.Init
}
func (c *Config) Init(in *component.ConfigData) (*component.ConfigData, error) {
return in, nil
}
func (c *Config) StructFunc() interface{} {
return c.Struct
}
@ -56,28 +64,27 @@ func (c *Config) MergeFunc() interface{} {
}
func (c *Config) Merge(
input *component.ConfigMerge,
log hclog.Logger,
) (*component.ConfigData, error) {
log.Info("merging config values for the vagrants namespace")
result := &component.ConfigData{
Data: map[string]interface{}{},
input struct {
argmapper.Struct
Base *Vagrant
Overlay *Vagrant
Log hclog.Logger
},
) (*Vagrant, error) {
log := input.Log
log.Info("merging config values in vagrants namespace",
"base", input.Base, "overlay", input.Overlay)
result := input.Base
if input.Overlay.Host != nil {
result.Host = input.Overlay.Host
}
for k, v := range input.Base.Data {
log.Info("Base value", "key", k, "value", v)
result.Data[k] = v
for _, s := range input.Overlay.Sensitive {
result.Sensitive = append(result.Sensitive, s)
}
for k, v := range input.Overlay.Data {
log.Info("Merged value", "key", k, "value", v, "pre-existing", result.Data[k])
if v == result.Data[k] {
return nil, fmt.Errorf("values for merge should not match (%#v == %#v)", v, result.Data[k])
}
result.Data[k] = v
}
result.Data["merged"] = "omg"
log.Info("merged config value for vagrants namespace", "config", result)
return result, nil
}
@ -86,13 +93,14 @@ func (c *Config) FinalizeFunc() interface{} {
return c.Finalize
}
func (c *Config) Finalize(l hclog.Logger, f *component.ConfigFinalize) (*component.ConfigData, error) {
d := f.Config
d.Data["finalized"] = "yep, it's finalzied"
l.Info("config data that is finalized and going back",
"config", hclog.Fmt("%#v", d),
)
return d, nil
func (c *Config) Finalize(l hclog.Logger, conf *Vagrant) (*Vagrant, error) {
l.Warn("checking current content", "host", conf.Host)
if conf.Host != nil {
l.Warn("checking current value", "host", *conf.Host)
}
info := "go plugin finalization test content"
conf.FinalizedInfo = &info
return conf, nil
}
type Command struct{}

View File

@ -38,9 +38,42 @@ type DownloaderConfig struct {
UrlQueryParams map[string]string
}
// Config implements Configurable
func (d *Downloader) Config() (interface{}, error) {
return &d.config, nil
func (d *Downloader) InitFunc() any {
return d.Init
}
func (d *Downloader) Init(in *component.ConfigData) (*component.ConfigData, error) {
return in, nil
}
func (d *Downloader) StructFunc() any {
return d.Struct
}
func (d *Downloader) MergeFunc() any {
return d.Merge
}
func (d *Downloader) FinalizeFunc() any {
return d.Finalize
}
func (d *Downloader) Struct() *DownloaderConfig {
return &DownloaderConfig{}
}
func (d *Downloader) Merge(val *component.ConfigMerge) *component.ConfigData {
return val.Base
}
func (d *Downloader) Finalize(val *component.ConfigData) *component.ConfigData {
return val
}
func (d *Downloader) Register() (*component.ConfigRegistration, error) {
return &component.ConfigRegistration{
Identifier: "downloader",
}, nil
}
func (d *Downloader) DownloadFunc() interface{} {
@ -101,5 +134,5 @@ func (d *Downloader) Download() (err error) {
var (
_ component.Downloader = (*Downloader)(nil)
_ component.Configurable = (*Downloader)(nil)
_ component.Config = (*Downloader)(nil)
)

10
go.mod
View File

@ -6,6 +6,8 @@ require (
github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2
github.com/bmatcuk/doublestar v1.3.4
github.com/fatih/color v1.15.0
github.com/fatih/structs v1.1.0
github.com/fatih/structtag v1.2.0
github.com/glebarez/sqlite v1.8.0
github.com/go-git/go-git/v5 v5.7.0
github.com/go-ozzo/ozzo-validation/v4 v4.3.0
@ -20,7 +22,7 @@ require (
github.com/hashicorp/go-retryablehttp v0.7.4
github.com/hashicorp/go-version v1.6.0
github.com/hashicorp/hcl/v2 v2.17.0
github.com/hashicorp/vagrant-plugin-sdk v0.0.0-20230304003807-c1e77438a1ef
github.com/hashicorp/vagrant-plugin-sdk v0.0.0-20230908002302-5b51f0768f72
github.com/imdario/mergo v0.3.16
github.com/improbable-eng/grpc-web v0.15.0
github.com/kr/text v0.2.0
@ -43,10 +45,10 @@ require (
golang.org/x/sys v0.8.0
golang.org/x/text v0.9.0
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc
google.golang.org/grpc v1.55.0
google.golang.org/grpc v1.56.2
google.golang.org/protobuf v1.30.0
gorm.io/datatypes v1.2.0
gorm.io/gorm v1.25.1
gorm.io/gorm v1.25.3
)
require (
@ -80,7 +82,6 @@ require (
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/fatih/structs v1.1.0 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/glebarez/go-sqlite v1.21.1 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
@ -160,4 +161,5 @@ require (
)
// replace github.com/hashicorp/go-argmapper => ../go-argmapper
// replace github.com/hashicorp/vagrant-plugin-sdk => ../vagrant-plugin-sdk

54
go.sum
View File

@ -216,11 +216,9 @@ github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAU
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/adrg/xdg v0.2.1/go.mod h1:ZuOshBmzV4Ta+s23hdfFZnBsdzmoR3US0d7ErpqSbTQ=
github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=
github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@ -232,9 +230,6 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
@ -263,7 +258,6 @@ github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQ
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0=
github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
github.com/briandowns/spinner v1.11.1/go.mod h1:QOuQk7x+EaDASo80FEXwlwiA+j/PPIcX3FScO+3/ZPQ=
github.com/briandowns/spinner v1.23.0 h1:alDF2guRWqa/FOZZYWjlMIx2L6H0wyewPxo/CH4Pt2A=
github.com/briandowns/spinner v1.23.0/go.mod h1:rPG4gmXeN3wQV/TsAY4w8lPdIM6RX3yqeBQJSrbXjuE=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
@ -306,7 +300,6 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -337,12 +330,13 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
@ -392,7 +386,6 @@ github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M=
github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8=
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
@ -423,7 +416,6 @@ github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@ -535,7 +527,6 @@ github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyN
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-argmapper v0.2.3/go.mod h1:WA3PocIo+40wf4ko3dRdL3DEgxIQB4qaqp+jVccLV1I=
github.com/hashicorp/go-argmapper v0.2.4 h1:HSnbvNcapx5PWtA6qvnlESc69LQXYrfDO/FRf1zroXg=
github.com/hashicorp/go-argmapper v0.2.4/go.mod h1:WA3PocIo+40wf4ko3dRdL3DEgxIQB4qaqp+jVccLV1I=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
@ -543,10 +534,8 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-getter v1.7.1 h1:SWiSWN/42qdpR0MdhaOc/bLR48PLuP1ZQtYLRlM69uY=
github.com/hashicorp/go-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744=
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v0.14.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
@ -560,7 +549,6 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-plugin v1.3.0/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0=
github.com/hashicorp/go-plugin v1.4.10 h1:xUbmA4jC6Dq163/fWcp8P3JuHilrHHMLNRxzGQJ9hNk=
github.com/hashicorp/go-plugin v1.4.10/go.mod h1:6/1TEzT0eQznvI/gV2CM29DLSkAK/e58mUWKVsPaph0=
github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA=
@ -582,16 +570,14 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl/v2 v2.6.0/go.mod h1:bQTN5mpo+jewjJgh8jr0JUguIi7qPHUF6yIfAEN3jqY=
github.com/hashicorp/hcl/v2 v2.17.0 h1:z1XvSUyXd1HP10U4lrLg5e0JMVz6CPaJvAgxM0KNZVY=
github.com/hashicorp/hcl/v2 v2.17.0/go.mod h1:gJyW2PTShkJqQBKpAmPO3yxMxIuoXkOF2TpqXzrQyx4=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hashicorp/vagrant-plugin-sdk v0.0.0-20230304003807-c1e77438a1ef h1:33vPdfuFwUuFfezyF+36tJHbjNuuS+8Vu9ia51ArMo0=
github.com/hashicorp/vagrant-plugin-sdk v0.0.0-20230304003807-c1e77438a1ef/go.mod h1:zA5vDskG3gH306C+obL+yURiUiLMAlx52yqO8MC2r9w=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/vagrant-plugin-sdk v0.0.0-20230908002302-5b51f0768f72 h1:QsewUkg7Ykg+BHkh2LAGMDy90TgvIiF7HOjkSZaL0uE=
github.com/hashicorp/vagrant-plugin-sdk v0.0.0-20230908002302-5b51f0768f72/go.mod h1:tfojVWg3L6om47/i2joXbg6nXXDV2GPExR4fufd4H5M=
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
@ -616,7 +602,6 @@ github.com/jackc/pgx/v5 v5.3.0 h1:/NQi8KHMpKWHInxXesC8yD4DhkXPrVhmnwYkjp9AmBA=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
@ -660,10 +645,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lab47/vterm v0.0.0-20201001232628-a9dd795f94c2/go.mod h1:IODMeTGM8OBitkNwP3bvFuccNVzo1gIevvC3dM6MujU=
github.com/lab47/vterm v0.0.0-20211107042118-80c3d2849f9c h1:xTdFl6QIaKyRUSrFAAnR2/9dij1gzUaVG8rLcteEwVY=
github.com/lab47/vterm v0.0.0-20211107042118-80c3d2849f9c/go.mod h1:IODMeTGM8OBitkNwP3bvFuccNVzo1gIevvC3dM6MujU=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
@ -677,7 +660,6 @@ github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlW
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
@ -686,7 +668,6 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
@ -708,24 +689,20 @@ github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2c
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-glint v0.0.0-20200930000256-df5e721f3258/go.mod h1:NrJbv11op7A0gjSLtfvzm74YkVKRS24KxucwneYUX4M=
github.com/mitchellh/go-glint v0.0.0-20210722152315-6515ceb4a127 h1:/EdGXMUGYFdp0+cmGjVLl/Qbx3G10csqgj22ZkrPFEA=
github.com/mitchellh/go-glint v0.0.0-20210722152315-6515ceb4a127/go.mod h1:9X3rpO+I3yuihb6p8ktF8qWxROGwij9DBW/czUsMlhk=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/protostructure v0.0.0-20200814180458-3cfccdb015ce h1:VCR1UYdCg/9zbbnDVsULhmoGVsR5JJ91aPjTGv304Z4=
@ -752,7 +729,6 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/nicksnyder/go-i18n/v2 v2.2.0/go.mod h1:4OtLfzqyAxsscyCb//3gfqSvBc81gImX91LrZzczN1o=
github.com/nicksnyder/go-i18n/v2 v2.2.1 h1:aOzRCdwsJuoExfZhoiXHy4bjruwCMdt5otbYojM/PaA=
github.com/nicksnyder/go-i18n/v2 v2.2.1/go.mod h1:fF2++lPHlo+/kPaj3nB0uxtPwzlPm+BlgwGX7MkeGj0=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
@ -763,7 +739,6 @@ github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DV
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@ -842,7 +817,6 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
@ -867,7 +841,6 @@ github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
@ -886,7 +859,6 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
@ -905,7 +877,6 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vektra/neko v0.0.0-20170502000624-99acbdf12420 h1:OMelMt+D75Fax25tMcBfUoOyNp8OziZK/Ca8dB8BX38=
github.com/vektra/neko v0.0.0-20170502000624-99acbdf12420/go.mod h1:7tfPLehrsToaevw9Vi9iL6FOslcBJ/uqYQc8y3YIbdI=
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
@ -920,7 +891,6 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
github.com/zclconf/go-cty v1.13.2 h1:4GvrUxe/QUDYuJKAav4EYqdM47/kZa672LwmXFmEKT0=
github.com/zclconf/go-cty v1.13.2/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0=
github.com/zclconf/go-cty-yaml v1.0.3 h1:og/eOQ7lvA/WWhHGFETVWNduJM7Rjsv2RRpx1sdFMLc=
@ -951,7 +921,6 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@ -959,7 +928,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
@ -1009,9 +977,7 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -1131,7 +1097,6 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -1215,7 +1180,6 @@ golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@ -1371,7 +1335,6 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@ -1405,7 +1368,6 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201002142447-3860012362da/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
@ -1483,7 +1445,6 @@ google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:
google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
@ -1525,8 +1486,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu
google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI=
google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
@ -1581,8 +1542,9 @@ gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5
gorm.io/driver/postgres v1.5.0 h1:u2FXTy14l45qc3UeCJ7QaAXZmZfDDv0YrthvmRq1l0U=
gorm.io/driver/sqlite v1.4.3 h1:HBBcZSDnWi5BW3B3rwvVTc510KGkBkexlOg0QrmLUuU=
gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0=
gorm.io/gorm v1.25.1 h1:nsSALe5Pr+cM3V1qwwQ7rOkw+6UeLrX5O4v3llhHa64=
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/gorm v1.25.3 h1:zi4rHZj1anhZS2EuEODMhDisGy+Daq9jtPrNGgbQYD8=
gorm.io/gorm v1.25.3/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@ -18,6 +18,7 @@ import (
"github.com/hashicorp/vagrant-plugin-sdk/component"
"github.com/hashicorp/vagrant-plugin-sdk/helper/paths"
"github.com/hashicorp/vagrant-plugin-sdk/internal-shared/cleanup"
"github.com/hashicorp/vagrant-plugin-sdk/proto/vagrant_plugin_sdk"
"github.com/hashicorp/vagrant-plugin-sdk/terminal"
"github.com/hashicorp/vagrant/internal/clicontext"
"github.com/hashicorp/vagrant/internal/client"
@ -59,11 +60,11 @@ type baseCommand struct {
// client for performing operations
client *clientpkg.Client
// basis to root these operations within
basis *clientpkg.Basis
basis *vagrant_plugin_sdk.Ref_Basis
// optional project to run operations within
project *clientpkg.Project
project *vagrant_plugin_sdk.Ref_Project
// optional target to run operations against
target *clientpkg.Target
target *vagrant_plugin_sdk.Ref_Target
// clientContext is set to the context information for the current
// connection. This might not exist in the contextStorage yet if this
@ -263,37 +264,40 @@ warning set the environment variable 'VAGRANT_SUPPRESS_GO_EXPERIMENTAL_WARNING'.
return nil, err
}
// We always have a basis, so load that
if bc.basis, err = bc.client.LoadBasis(bc.flagBasis); err != nil {
bc.Log.Info("basis seeding", "name", bc.flagBasis, "path", bc.flagBasis)
b, err := bc.client.LoadBasis(bc.flagBasis)
if err != nil {
return nil, err
}
// We always have a basis, so seed the basis
// ref and initialize it
bc.basis = &vagrant_plugin_sdk.Ref_Basis{
Name: b.Name,
Path: b.Path,
ResourceId: b.ResourceId,
}
if bc.basis, err = bc.client.BasisInit(ctx, bc.Modifier()); err != nil {
return nil, err
}
log.Warn("created basis client",
log.Info("vagrant basis has been initialized",
"basis", bc.basis,
)
// A project is optional (though generally needed) and there are
// two possibilites for how we load the project.
if bc.flagProject != "" {
// The first is that we are given a specific project that should be
// used within the defined basis. So lets load that.
if bc.project, err = bc.basis.LoadProject(bc.flagProject); err != nil {
return nil, err
}
} else {
if bc.project, err = bc.basis.DetectProject(); err != nil {
return nil, err
}
}
// Load in basis vagrantfile if there is one
if err = bc.basis.LoadVagrantfile(); err != nil {
project, err := bc.client.LoadProject(bc.flagProject, bc.basis)
if err != nil {
return nil, err
}
// And if we have a project, load that vagrantfile too
if bc.project != nil {
if err = bc.project.LoadVagrantfile(); err != nil {
if project != nil {
bc.project = &vagrant_plugin_sdk.Ref_Project{
Name: project.Name,
Path: project.Path,
ResourceId: project.ResourceId,
Basis: project.Basis,
}
if bc.project, err = bc.client.ProjectInit(ctx, bc.Modifier()); err != nil {
return nil, err
}
}
@ -305,9 +309,9 @@ warning set the environment variable 'VAGRANT_SUPPRESS_GO_EXPERIMENTAL_WARNING'.
return nil, fmt.Errorf("cannot load target without valid project")
}
if bc.target, err = bc.project.LoadTarget(bc.flagTarget); err != nil {
return nil, err
}
// if bc.target, err = bc.project.LoadTarget(bc.flagTarget); err != nil {
// return nil, err
// }
}
return bc, err
@ -408,21 +412,15 @@ func (c *baseCommand) Do(ctx context.Context, f func(context.Context, *client.Cl
func (c *baseCommand) Modifier() client.JobModifier {
return func(j *vagrant_server.Job) {
if c.target != nil {
j.Scope = &vagrant_server.Job_Target{
Target: c.target.Ref(),
}
return
}
if c.project != nil {
j.Scope = &vagrant_server.Job_Project{
Project: c.project.Ref(),
Project: c.project,
}
return
}
if c.basis != nil {
j.Scope = &vagrant_server.Job_Basis{
Basis: c.basis.Ref(),
Basis: c.basis,
}
return
}

View File

@ -7,6 +7,7 @@ import (
"fmt"
"path/filepath"
"github.com/hashicorp/vagrant-plugin-sdk/helper/path"
clientpkg "github.com/hashicorp/vagrant/internal/client"
configpkg "github.com/hashicorp/vagrant/internal/config"
)
@ -34,7 +35,7 @@ func (c *baseCommand) initConfig(optional bool) (*configpkg.Config, error) {
// initConfigPath returns the configuration path to load.
func (c *baseCommand) initConfigPath() (string, error) {
// This configuarion is for the Vagrant process, not the same as a Vagrantfile
path, err := configpkg.FindPath(c.basis.Path(), "vagrant-config.hcl")
path, err := configpkg.FindPath(path.NewPath(c.basis.GetPath()), "vagrant-config.hcl")
if err != nil {
return "", fmt.Errorf("error looking for a Vagrant configuration: %s", err)
}

View File

@ -259,8 +259,10 @@ func logger(args []string) ([]string, hclog.Logger, io.Writer, error) {
}
}
// Set default log level
// Set default log level it not already set
if os.Getenv("VAGRANT_LOG") == "" {
_ = os.Setenv("VAGRANT_LOG", "fatal")
}
// Process arguments looking for `-v` flags to control the log level.
// This overrides whatever the env var set.

View File

@ -6,14 +6,14 @@ package cli
import (
"fmt"
"strings"
"time"
// "time"
"github.com/skratchdot/open-golang/open"
"github.com/hashicorp/vagrant-plugin-sdk/component"
"github.com/hashicorp/vagrant-plugin-sdk/terminal"
"github.com/hashicorp/vagrant/internal/clierrors"
"github.com/hashicorp/vagrant/internal/server/proto/vagrant_server"
// "github.com/hashicorp/vagrant/internal/server/proto/vagrant_server"
)
type UICommand struct {
@ -37,35 +37,35 @@ func (c *UICommand) Run(args []string) int {
// c.client.UI().Output("Vagrant must be configured in server mode to access the UI", terminal.WithWarningStyle())
// }
// Get our API client
client := c.basis.Client()
// // Get our API client
// client := c.basis.Client()
var inviteToken string
if c.flagAuthenticate {
c.ui.Output("Creating invite token", terminal.WithStyle(terminal.HeaderStyle))
c.ui.Output("This invite token will be exchanged for an authentication \ntoken that your browser stores.")
// var inviteToken string
// if c.flagAuthenticate {
// c.ui.Output("Creating invite token", terminal.WithStyle(terminal.HeaderStyle))
// c.ui.Output("This invite token will be exchanged for an authentication \ntoken that your browser stores.")
resp, err := client.GenerateInviteToken(c.Ctx, &vagrant_server.InviteTokenRequest{
Duration: (2 * time.Minute).String(),
})
if err != nil {
c.basis.UI().Output(clierrors.Humanize(err), terminal.WithErrorStyle())
return 1
}
// resp, err := client.GenerateInviteToken(c.Ctx, &vagrant_server.InviteTokenRequest{
// Duration: (2 * time.Minute).String(),
// })
// if err != nil {
// c.client.UI().Output(clierrors.Humanize(err), terminal.WithErrorStyle())
// return 1
// }
inviteToken = resp.Token
}
// inviteToken = resp.Token
// }
// Get our default context (used context)
name, err := c.contextStorage.Default()
if err != nil {
c.basis.UI().Output(clierrors.Humanize(err), terminal.WithErrorStyle())
c.client.UI().Output(clierrors.Humanize(err), terminal.WithErrorStyle())
return 1
}
ctxConfig, err := c.contextStorage.Load(name)
if err != nil {
c.basis.UI().Output(clierrors.Humanize(err), terminal.WithErrorStyle())
c.client.UI().Output(clierrors.Humanize(err), terminal.WithErrorStyle())
return 1
}
@ -74,16 +74,16 @@ func (c *UICommand) Run(args []string) int {
// Default Docker platform HTTP port, for now
port := 9702
if err != nil {
c.basis.UI().Output(clierrors.Humanize(err), terminal.WithErrorStyle())
c.client.UI().Output(clierrors.Humanize(err), terminal.WithErrorStyle())
return 1
}
c.ui.Output("Opening browser", terminal.WithStyle(terminal.HeaderStyle))
uiAddr := fmt.Sprintf("https://%s:%d", addr, port)
if c.flagAuthenticate {
uiAddr = fmt.Sprintf("%s/auth/invite?token=%s&cli=true", uiAddr, inviteToken)
}
// if c.flagAuthenticate {
// uiAddr = fmt.Sprintf("%s/auth/invite?token=%s&cli=true", uiAddr, inviteToken)
// }
open.Run(uiAddr)

View File

@ -1,225 +0,0 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package client
import (
"context"
"io"
"os"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-plugin"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/hashicorp/vagrant-plugin-sdk/config"
"github.com/hashicorp/vagrant-plugin-sdk/helper/path"
"github.com/hashicorp/vagrant-plugin-sdk/proto/vagrant_plugin_sdk"
"github.com/hashicorp/vagrant-plugin-sdk/terminal"
"github.com/hashicorp/vagrant/internal/server/proto/vagrant_server"
"github.com/hashicorp/vagrant/internal/serverclient"
)
type Basis struct {
basis *vagrant_server.Basis
cleanupFuncs []func() error
client *Client
ctx context.Context
logger hclog.Logger
path path.Path
ui terminal.UI
vagrant *serverclient.VagrantClient
}
func (b *Basis) DetectProject() (p *Project, err error) {
// look for a vagrantfile!
v, err := config.FindPath(nil, nil)
// if an error was encountered, or no path was found, we return
if err != nil || v == nil {
return
}
// we did find a path, so use the directory name as project name
// TODO(spox): we'll need to do better than just dir name
_, n := v.Dir().Base().Split()
p, err = b.LoadProject(n)
if err != nil && status.Code(err) != codes.NotFound {
return
}
if err == nil {
p.vagrantfile = v
return
}
b.logger.Warn("basis set during project detect",
"basis", b.basis,
)
result, err := b.vagrant.UpsertProject(
b.ctx,
&vagrant_server.UpsertProjectRequest{
Project: &vagrant_server.Project{
Name: n,
Basis: b.Ref(),
Path: v.Dir().String(),
},
},
)
if err != nil {
return
}
return &Project{
basis: b,
client: b.client,
ctx: b.ctx,
logger: b.logger.Named("project"),
project: result.Project,
ui: b.ui,
vagrant: b.vagrant,
vagrantfile: v,
}, nil
}
func (b *Basis) LoadProject(n string) (*Project, error) {
b.logger.Warn("loading project now",
"basis", b.basis,
"ref", b.Ref(),
)
result, err := b.vagrant.FindProject(
b.ctx,
&vagrant_server.FindProjectRequest{
Project: &vagrant_server.Project{
Name: n,
Basis: b.Ref(),
},
},
)
if err != nil {
return nil, err
}
if result == nil {
return nil, NotFoundErr
}
return &Project{
basis: b,
client: b.client,
ctx: b.ctx,
logger: b.logger.Named("project"),
project: result.Project,
ui: b.ui,
vagrant: b.vagrant,
}, nil
}
// Finds the Vagrantfile associated with the basis
func (b *Basis) LoadVagrantfile() error {
vpath, err := config.ExistingPath(b.path, config.GetVagrantfileName())
l := b.logger.With(
"basis", b.basis.Name,
"path", vpath,
)
// If the path does not exist, no Vagrantfile was found
if os.IsNotExist(err) {
l.Warn("basis vagrantfile does not exist",
"path", b.path.String(),
)
// Upsert the basis so the record exists
result, err := b.vagrant.UpsertBasis(b.ctx, &vagrant_server.UpsertBasisRequest{Basis: b.basis})
if err != nil {
return err
}
b.basis = result.Basis
return nil
} else if err != nil {
l.Error("failed to load basis vagrantfile",
"error", err,
)
return err
}
l.Trace("attempting to load basis vagrantfile")
raw, err := b.VagrantRubyRuntime().Dispense("vagrantrubyruntime")
if err != nil {
return err
}
p, err := LoadVagrantfile(
vpath, l, raw.(serverclient.RubyVagrantClient))
if err != nil {
return err
}
l.Trace("storing updated basis configuration",
"configuration", p.Unfinalized,
)
b.basis.Configuration = p
// Push Vagrantfile updates to basis
result, err := b.vagrant.UpsertBasis(
b.ctx,
&vagrant_server.UpsertBasisRequest{
Basis: b.basis,
},
)
if err != nil {
l.Error("failed to store basis updates",
"error", err,
)
return err
}
b.basis = result.Basis
return nil
}
func (b *Basis) Ref() *vagrant_plugin_sdk.Ref_Basis {
if b.basis == nil {
return nil
}
return &vagrant_plugin_sdk.Ref_Basis{
Name: b.basis.Name,
ResourceId: b.basis.ResourceId,
}
}
func (b *Basis) Close() error {
for _, f := range b.cleanupFuncs {
f()
}
if closer, ok := b.ui.(io.Closer); ok {
closer.Close()
}
return nil
}
// Client returns the raw Vagrant server API client.
func (b *Basis) Client() *serverclient.VagrantClient {
return b.vagrant
}
func (b *Basis) VagrantRubyRuntime() plugin.ClientProtocol {
return b.client.rubyRuntime
}
func (b *Basis) UI() terminal.UI {
return b.ui
}
// Client returns the raw Vagrant server API client.
func (b *Basis) Path() path.Path {
return b.path
}

View File

@ -6,9 +6,6 @@ package client
import (
"context"
"errors"
"io"
"os"
"path/filepath"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-multierror"
@ -16,8 +13,7 @@ import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
vconfig "github.com/hashicorp/vagrant-plugin-sdk/config"
"github.com/hashicorp/vagrant-plugin-sdk/helper/path"
sdkconfig "github.com/hashicorp/vagrant-plugin-sdk/config"
"github.com/hashicorp/vagrant-plugin-sdk/helper/paths"
"github.com/hashicorp/vagrant-plugin-sdk/internal-shared/cleanup"
"github.com/hashicorp/vagrant-plugin-sdk/proto/vagrant_plugin_sdk"
@ -144,13 +140,18 @@ func New(ctx context.Context, opts ...Option) (c *Client, err error) {
return
}
func (c *Client) LoadBasis(n string) (*Basis, error) {
func (c *Client) LoadBasis(n string) (*vagrant_server.Basis, error) {
var basis *vagrant_server.Basis
p, err := paths.NamedVagrantConfig(n)
if err != nil {
return nil, err
}
basisVagrantfile, err := sdkconfig.FindPath(p, nil)
if err != nil {
return nil, err
}
result, err := c.client.FindBasis(
c.ctx,
&vagrant_server.FindBasisRequest{
@ -161,36 +162,110 @@ func (c *Client) LoadBasis(n string) (*Basis, error) {
},
)
if err != nil {
if status.Code(err) != codes.NotFound {
if err != nil && status.Code(err) != codes.NotFound {
return nil, err
}
if err == nil {
basis = result.Basis
} else {
basis = &vagrant_server.Basis{
Name: n,
Path: p.String(),
}
}
if err == nil {
basis = result.Basis
} else {
basis = &vagrant_server.Basis{
Name: n,
Path: p.String(),
}
}
basis.Configuration = &vagrant_server.Vagrantfile{
Path: &vagrant_plugin_sdk.Args_Path{
Path: basisVagrantfile.String(),
},
}
uresult, err := c.client.UpsertBasis(
c.ctx,
&vagrant_server.UpsertBasisRequest{
Basis: &vagrant_server.Basis{
Name: n,
Path: p.String(),
Basis: basis,
},
)
if err != nil {
return nil, err
}
basis = uresult.Basis
return basis, nil
}
func (c *Client) LoadProject(n string, b *vagrant_plugin_sdk.Ref_Basis) (*vagrant_server.Project, error) {
var project *vagrant_server.Project
projectVagrantfile, err := sdkconfig.FindPath(nil, nil)
if err != nil {
return nil, err
}
// No project was found, so return
if projectVagrantfile == nil {
return nil, nil
}
projectDir := projectVagrantfile.Dir()
if n == "" {
n = projectDir.String()
}
result, err := c.client.FindProject(
c.ctx,
&vagrant_server.FindProjectRequest{
Project: &vagrant_server.Project{
Name: n,
Path: projectDir.String(),
Basis: b,
},
},
)
if err != nil && status.Code(err) != codes.NotFound {
return nil, err
}
if err == nil {
project = result.Project
} else {
project = &vagrant_server.Project{
Name: n,
Path: projectDir.String(),
Basis: b,
}
}
project.Configuration = &vagrant_server.Vagrantfile{
Path: &vagrant_plugin_sdk.Args_Path{
Path: projectVagrantfile.String(),
},
}
uresult, err := c.client.UpsertProject(
c.ctx,
&vagrant_server.UpsertProjectRequest{
Project: project,
},
)
if err != nil {
return nil, err
}
basis = uresult.Basis
} else {
basis = result.Basis
}
project = uresult.Project
return &Basis{
basis: basis,
client: c,
ctx: c.ctx,
logger: c.logger.Named("basis"),
path: p,
ui: c.ui,
vagrant: c.client,
}, nil
return project, nil
}
// Close the client and call any cleanup functions
@ -277,63 +352,3 @@ func WithConfig(cfg *config.Config) Option {
return nil
}
}
// Load a Vagrantfile
func LoadVagrantfile(
file path.Path, // path to the Vagrantfile
l hclog.Logger, // logger
c serverclient.RubyVagrantClient, // vagrant ruby runtime for ruby based Vagrantfiles
) (p *vagrant_server.Vagrantfile, err error) {
var v *vconfig.Vagrantfile
p = &vagrant_server.Vagrantfile{}
format := vconfig.JSON
protoFormat := vagrant_server.Vagrantfile_JSON
// We support three types of Vagrantfiles:
// * Ruby (original)
// * HCL
// * JSON (which is HCL in JSON form)
ext := filepath.Ext(file.String())
if ext == ".hcl" {
format = vconfig.HCL
protoFormat = vagrant_server.Vagrantfile_HCL
}
switch ext {
case ".hcl", ".json":
f, err := os.Open(file.String())
if err != nil {
return nil, err
}
p.Raw, err = io.ReadAll(f)
if err != nil {
return nil, err
}
v, err = vconfig.LoadVagrantfile(p.Raw, file.String(), format)
if err != nil {
return nil, err
}
if p.Unfinalized, err = vconfig.EncodeVagrantfile(v); err != nil {
return nil, err
}
default:
p.Unfinalized, err = c.ParseVagrantfile(file.String())
if err != nil {
l.Error("failed to parse vagrantfile",
"error", err,
)
return nil, err
}
l.Info("initial vagrantfile value set",
"path", file.String(),
"value", p.Unfinalized,
)
protoFormat = vagrant_server.Vagrantfile_RUBY
}
p.Path = &vagrant_plugin_sdk.Args_Path{Path: file.String()}
p.Format = protoFormat
return
}

View File

@ -7,6 +7,7 @@ import (
"context"
"github.com/hashicorp/vagrant-plugin-sdk/component"
"github.com/hashicorp/vagrant-plugin-sdk/proto/vagrant_plugin_sdk"
"github.com/hashicorp/vagrant/internal/server/logviewer"
"github.com/hashicorp/vagrant/internal/server/proto/vagrant_server"
)
@ -64,6 +65,42 @@ func (c *Client) Commands(
return result.Init, nil
}
func (c *Client) BasisInit(
ctx context.Context,
mod JobModifier,
) (*vagrant_plugin_sdk.Ref_Basis, error) {
job := c.job()
job.Operation = &vagrant_server.Job_InitBasis{
InitBasis: &vagrant_server.Job_InitBasisOp{},
}
// Apply scoping to job
mod(job)
result, err := c.doJob(ctx, job, c.ui)
if err != nil {
return nil, err
}
return result.Basis.Basis, nil
}
func (c *Client) ProjectInit(
ctx context.Context,
mod JobModifier,
) (*vagrant_plugin_sdk.Ref_Project, error) {
job := c.job()
job.Operation = &vagrant_server.Job_InitProject{
InitProject: &vagrant_server.Job_InitProjectOp{},
}
// Apply scoping to job
mod(job)
result, err := c.doJob(ctx, job, c.ui)
if err != nil {
return nil, err
}
return result.Project.Project, nil
}
func (c *Client) Command(
ctx context.Context,
op *vagrant_server.Job_CommandOp,

View File

@ -1,141 +0,0 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package client
import (
"context"
"fmt"
"os"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/vagrant-plugin-sdk/helper/path"
vagrant_plugin_sdk "github.com/hashicorp/vagrant-plugin-sdk/proto/vagrant_plugin_sdk"
"github.com/hashicorp/vagrant-plugin-sdk/terminal"
"github.com/hashicorp/vagrant/internal/server/proto/vagrant_server"
"github.com/hashicorp/vagrant/internal/serverclient"
)
// Project is the primary structure for interacting with a Vagrant
// server as a client. The client exposes a slightly higher level of
// abstraction over the server API for performing operations locally and
// remotely.
type Project struct {
basis *Basis
client *Client
ctx context.Context
logger hclog.Logger
path path.Path
project *vagrant_server.Project
ui terminal.UI
vagrant *serverclient.VagrantClient
vagrantfile path.Path
}
// Finds the Vagrantfile associated with the project
func (p *Project) LoadVagrantfile() error {
l := p.logger.With(
"basis", p.basis.basis.Name,
"project", p.project.Name,
"path", p.vagrantfile,
)
l.Trace("attempting to load project vagrantfile")
if p.vagrantfile == nil {
l.Warn("project vagrantfile has not been set")
return nil
}
// If the path does not exist, no Vagrantfile was found
if _, err := os.Stat(p.vagrantfile.String()); os.IsNotExist(err) {
l.Warn("project vagrantfile does not exist")
return nil
}
raw, err := p.client.rubyRuntime.Dispense("vagrantrubyruntime")
if err != nil {
l.Warn("failed to load ruby runtime for vagrantfile parsing",
"error", err,
)
return err
}
vp, err := LoadVagrantfile(
p.vagrantfile, l, raw.(serverclient.RubyVagrantClient))
if err != nil {
return err
}
p.project.Configuration = vp
p.project.Basis = p.basis.Ref()
// Push Vagrantfile updates to project
result, err := p.vagrant.UpsertProject(
p.ctx,
&vagrant_server.UpsertProjectRequest{
Project: p.project,
},
)
if err != nil {
l.Error("failed to store project updates",
"error", err,
)
return err
}
p.project = result.Project
return nil
}
func (p *Project) LoadTarget(n string) (*Target, error) {
result, err := p.vagrant.FindTarget(
p.ctx,
&vagrant_server.FindTargetRequest{
Target: &vagrant_server.Target{
Name: n,
Project: p.Ref(),
},
},
)
if err != nil {
return nil, err
}
// If the target exists, load and return
if result != nil {
return &Target{
client: p.client,
ctx: p.ctx,
logger: p.logger.Named("target"),
project: p,
target: result.Target,
ui: p.ui,
vagrant: p.vagrant,
}, nil
}
// TODO(spox): Some adjustment is needed on how targets
// should be loaded here when their origin
// will be the vagrantfile
return nil, fmt.Errorf("cannot load target")
}
func (p *Project) UI() terminal.UI {
return p.ui
}
func (p *Project) Close() error {
return p.basis.Close()
}
// Ref returns the raw Vagrant server API client.
func (p *Project) Ref() *vagrant_plugin_sdk.Ref_Project {
return &vagrant_plugin_sdk.Ref_Project{
Name: p.project.Name,
ResourceId: p.project.ResourceId,
Basis: p.basis.Ref(),
}
}

View File

@ -12,8 +12,10 @@ import (
"os/exec"
"path/filepath"
"strings"
// "time"
"github.com/glebarez/sqlite"
// "github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-plugin"
"github.com/hashicorp/vagrant-plugin-sdk/helper/paths"
"google.golang.org/grpc"
@ -40,7 +42,6 @@ import (
//
// 2. If WithLocal was specified and no connection addresses can be
// found, this will spin up an in-memory server.
//
func (c *Client) initServerClient(ctx context.Context, cfg *clientConfig) (*grpc.ClientConn, error) {
log := c.logger.ResetNamed("vagrant.server")
@ -108,6 +109,15 @@ func (c *Client) initLocalServer(ctx context.Context) (_ *grpc.ClientConn, err e
// Open our database
db, err := gorm.Open(sqlite.Open(path), &gorm.Config{
Logger: logger.Default.LogMode(logger.Silent),
// Logger: logger.New(
// log.StandardLogger(&hclog.StandardLoggerOptions{InferLevels: true}),
// logger.Config{
// SlowThreshold: 200 * time.Millisecond,
// LogLevel: logger.Info,
// IgnoreRecordNotFoundError: false,
// Colorful: true,
// },
// ),
})
db.Exec("PRAGMA foreign_keys = ON")
if err != nil {

View File

@ -1,37 +0,0 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package client
import (
"context"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/vagrant-plugin-sdk/proto/vagrant_plugin_sdk"
"github.com/hashicorp/vagrant-plugin-sdk/terminal"
"github.com/hashicorp/vagrant/internal/server/proto/vagrant_server"
"github.com/hashicorp/vagrant/internal/serverclient"
)
type Target struct {
client *Client
ctx context.Context
logger hclog.Logger
project *Project
target *vagrant_server.Target
ui terminal.UI
vagrant *serverclient.VagrantClient
}
func (m *Target) UI() terminal.UI {
return m.ui
}
func (m *Target) Ref() *vagrant_plugin_sdk.Ref_Target {
return &vagrant_plugin_sdk.Ref_Target{
ResourceId: m.target.ResourceId,
Name: m.target.Name,
Project: m.project.Ref(),
}
}

View File

@ -21,6 +21,7 @@ import (
"google.golang.org/protobuf/proto"
"github.com/hashicorp/vagrant-plugin-sdk/component"
vconfig "github.com/hashicorp/vagrant-plugin-sdk/config"
"github.com/hashicorp/vagrant-plugin-sdk/core"
"github.com/hashicorp/vagrant-plugin-sdk/datadir"
"github.com/hashicorp/vagrant-plugin-sdk/helper/path"
@ -193,9 +194,6 @@ func (b *Basis) Init() error {
// Create our vagrantfile
b.vagrantfile = NewVagrantfile(b.factory, b.boxCollection, b.mappers, b.logger)
// Register the basis as a Vagrantfile source
b.vagrantfile.Source(b.basis.Configuration, VAGRANTFILE_BASIS)
// Register configuration plugins when they are loaded
b.plugins.Initializer(b.configRegistration)
@ -249,6 +247,11 @@ func (b *Basis) Init() error {
// Set seeds for any plugins that may be used
b.seed(nil)
// Register the basis as a Vagrantfile source
if err = b.vagrantfile.Source(b.basis.Configuration, VAGRANTFILE_BASIS); err != nil {
return err
}
// Initialize the Vagrantfile for the basis
if err = b.vagrantfile.Init(); err != nil {
b.logger.Error("basis setup failed to initialize vagrantfile",
@ -306,8 +309,9 @@ func (b *Basis) String() string {
}
// Config implements core.Basis
func (b *Basis) Config() (core.Vagrantfile, error) {
return b.vagrantfile, nil
func (b *Basis) Config() (*vconfig.Vagrantfile, error) {
return nil, fmt.Errorf("not implemented")
//return vconfig.DecodeVagrantfile(b.basis.Configuration.Finalized)
}
// CWD implements core.Basis
@ -503,24 +507,29 @@ func (b *Basis) Host() (host core.Host, err error) {
return h.(core.Host), nil
}
rawHostName, err := b.vagrantfile.GetValue("vagrant", "host")
if err == nil {
b.logger.Debug("extracted host information from config",
"host", rawHostName,
)
// TODO(spox): this is for when we have implemented vagrantfile conversions
// bConfig, err := b.Config()
// if err != nil {
// b.logger.Error("failed to get configuration for basis")
// return
// }
hostName, ok := rawHostName.(string)
if ok && hostName != "" {
// If a host is set, then just try to detect that
hostComponent, err := b.component(b.ctx, component.HostType, hostName)
if err != nil {
return nil, fmt.Errorf("failed to find requested host plugin")
}
b.cache.Register("host", hostComponent.Value.(core.Host))
b.logger.Info("host detection overridden by local configuration")
return hostComponent.Value.(core.Host), nil
}
}
// if bConfig != nil {
// var hostName string
// if bConfig.Vagrant.Host != nil {
// hostName = *bConfig.Vagrant.Host
// }
// if hostName != "" {
// // If a host is set, then just try to detect that
// hostComponent, err := b.component(b.ctx, component.HostType, hostName)
// if err != nil {
// return nil, fmt.Errorf("failed to find requested host plugin")
// }
// b.cache.Register("host", hostComponent.Value.(core.Host))
// b.logger.Info("host detection overridden by local configuration")
// return hostComponent.Value.(core.Host), nil
// }
// }
// If a host is not defined in the Vagrantfile, try to detect it
hosts, err := b.typeComponents(b.ctx, component.HostType)

View File

@ -495,7 +495,8 @@ func (m *Machine) AsTarget() (core.Target, error) {
func (m *Machine) SaveMachine() (err error) {
m.logger.Debug("saving machine to db", "machine", m.machine.Id)
// Update the target record and uuid to match the machine's new state
m.target.Uuid = m.machine.Id
// TODO(spox): the uuid shouldn't be getting set to the Id, was there any reason for this?
// m.target.Uuid = m.machine.Id
m.target.Record, err = anypb.New(m.machine)
if err != nil {
m.logger.Warn("failed to convert machine data to any value",

View File

@ -35,7 +35,12 @@ func TestMachineSetValidId(t *testing.T) {
if err != nil {
t.Errorf("Failed to get target")
}
require.Equal(t, dbTarget.Target.Uuid, "something")
var dbMachine vagrant_server.Target_Machine
err = dbTarget.Target.Record.UnmarshalTo(&dbMachine)
require.NoError(t, err)
require.Equal(t, dbMachine.Id, "something")
}
func TestMachineSetEmptyId(t *testing.T) {

View File

@ -221,6 +221,20 @@ func (p *Project) Init() error {
return p.Save()
})
// TODO(spox): this was just added for testing. make cleaner
_, err = p.Client().UpsertProject(p.ctx,
&vagrant_server.UpsertProjectRequest{
Project: p.project,
},
)
if err != nil {
p.logger.Trace("failed to save project",
"error", err,
)
return err
}
// Set flag that this instance is setup
p.ready = true
@ -712,6 +726,9 @@ func (p *Project) Save() error {
"error", err,
)
} else {
if p.project.Configuration == nil {
p.project.Configuration = &vagrant_server.Vagrantfile{}
}
p.project.Configuration.Finalized = val.Data
}
}

View File

@ -6,16 +6,25 @@ package core
import (
"context"
"fmt"
"path/filepath"
"reflect"
"strings"
"sync"
"github.com/fatih/structs"
"github.com/fatih/structtag"
"github.com/hashicorp/go-argmapper"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/gohcl"
"github.com/hashicorp/hcl/v2/hclsimple"
"github.com/mitchellh/protostructure"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
"github.com/hashicorp/vagrant-plugin-sdk/component"
"github.com/hashicorp/vagrant-plugin-sdk/config"
"github.com/hashicorp/vagrant-plugin-sdk/core"
"github.com/hashicorp/vagrant-plugin-sdk/helper/types"
"github.com/hashicorp/vagrant-plugin-sdk/internal-shared/cacher"
@ -66,6 +75,10 @@ func (r *registration) String() string {
r.identifier, r.plugin, r.set, r.subregistrations)
}
func (r *registration) hasSubs() bool {
return len(r.subregistrations) > 0
}
// Register a config component as a subconfig
func (r *registration) sub(scope string, p *plugin.Plugin) error {
if _, ok := r.subregistrations[scope]; !ok {
@ -128,9 +141,10 @@ func (r registrations) register(n string, p *plugin.Plugin) error {
// Represents an individual Vagrantfile source
type source struct {
base *vagrant_server.Vagrantfile
finalized *component.ConfigData
unfinalized *component.ConfigData
base *vagrant_server.Vagrantfile // proto representing the Vagrantfile
finalized *component.ConfigData // raw configuration data after finalization
unfinalized *component.ConfigData // raw configuration data prior to finalization
vagrantfile *config.Vagrantfile // vagrantfile as processed
}
// And here's our Vagrantfile!
@ -205,10 +219,7 @@ func (v *Vagrantfile) GetSource(
) (*vagrant_server.Vagrantfile, error) {
s, ok := v.sources[l]
if !ok {
return nil, fmt.Errorf(
"no vagrantfile source for given location (%s)",
l.String(),
)
return nil, fmt.Errorf("no vagrantfile source for given location (%s)", l)
}
return s.base, nil
@ -372,8 +383,18 @@ func (v *Vagrantfile) GetConfig(
return c, nil
}
// Get the configuration for the given namespace and load
// it into the provided configuration struct
func (v *Vagrantfile) Get(
namespace string, // top level key in vagrantfile
config any, // pointer to configuration struct to populate
) error {
return nil
}
// Get the primary target name
// TODO(spox): VM options support is not implemented yet, so this
//
// will not return the correct value when default option
// has been specified in the Vagrantfile
func (v *Vagrantfile) PrimaryTargetName() (n string, err error) {
@ -437,6 +458,7 @@ func (v *Vagrantfile) TargetNames() (list []string, err error) {
// Load a new target instance
// TODO(spox): Probably add a name check against TargetNames
//
// before doing the config load
func (v *Vagrantfile) Target(
name, // Name of the target
@ -836,12 +858,23 @@ func (v *Vagrantfile) newSource(
) (s *source, err error) {
s = &source{
base: f,
unfinalized: &component.ConfigData{},
}
// Start with loading the Vagrantfile if it hasn't
// yet been loaded
if s.base.Unfinalized == nil {
if err := v.loadVagrantfile(s); err != nil {
return nil, err
}
}
if s.unfinalized == nil {
// First we need to unpack the unfinalized data.
if s.unfinalized, err = v.generateConfig(f.Unfinalized); err != nil {
return
}
}
// Next, if we have finalized data already set, just restore it
// and be done.
@ -853,6 +886,250 @@ func (v *Vagrantfile) newSource(
return s, nil
}
func (v *Vagrantfile) loadVagrantfile(
source *source,
) error {
var err error
if source.base.Path == nil {
return nil
}
// Set the format and load the file based on extension
switch filepath.Ext(source.base.Path.Path) {
case ".hcl":
source.base.Format = vagrant_server.Vagrantfile_HCL
if err = v.parseHCL(source); err != nil {
return err
}
// Need to load and encode from here. Thoughts about protostructure and
// if we should be treating hcl processed config differently
case ".json":
source.base.Format = vagrant_server.Vagrantfile_JSON
if err = v.parseHCL(source); err != nil {
return err
}
default:
source.base.Format = vagrant_server.Vagrantfile_RUBY
source.base.Unfinalized, err = v.rubyClient.ParseVagrantfile(source.base.Path.Path)
source.unfinalized, err = v.generateConfig(source.base.Unfinalized)
if err != nil {
return err
}
}
return nil
}
func (v *Vagrantfile) parseHCL(source *source) error {
if source == nil {
panic("vagrantfile source is nil")
}
target := &config.Vagrantfile{}
// This handles loading native configuration
err := hclsimple.DecodeFile(source.base.Path.Path, nil, target)
if err != nil {
v.logger.Error("failed to decode vagrantfile", "path", source.base.Path.Path, "error", err)
return err
}
if source.unfinalized == nil {
source.unfinalized = &component.ConfigData{}
}
source.unfinalized.Source = structs.Name(target)
source.unfinalized.Data = map[string]interface{}{}
// Serialize all non-plugin configuration values/namespaces
fields := structs.Fields(target)
for _, field := range fields {
// TODO(spox): This is just implemented enough to get things
// working. It needs to be reimplemented with helpers and all
// that stuff.
// if the field is the body content or remaining content after
// being parsed, ignore it
tags, err := structtag.Parse(`hcl:"` + field.Tag("hcl") + `"`)
if err != nil {
return err
}
tag, err := tags.Get("hcl")
if err != nil {
return err
}
skip := false
for _, opt := range tag.Options {
if opt == "remain" || opt == "body" {
skip = true
}
}
if skip {
continue
}
// If there is no field name, or if the value is empty
// just ignore it
n := field.Name()
np := strings.Split(field.Tag("hcl"), ",")
if len(np) > 0 {
n = np[0]
}
if n == "" {
continue
}
val := field.Value()
if field.IsZero() {
val = &component.ConfigData{Data: map[string]any{}}
}
rval := reflect.ValueOf(val)
// If the value is a struct, convert it to a map before storing
if rval.Kind() == reflect.Struct || (rval.Kind() == reflect.Pointer && rval.Elem().Kind() == reflect.Struct) {
val = &component.ConfigData{
Source: structs.Name(val),
Data: structs.Map(val),
}
}
source.unfinalized.Data[n] = val
}
// Now load all configuration which has registrations
for namespace, registration := range v.registrations {
// If no plugin is attached to registration, skip
if registration.plugin == nil {
continue
}
// Not handling subregistrations yet
if registration.hasSubs() {
continue
}
config, err := v.componentForKey(namespace)
if err != nil {
v.logger.Error("failed to dispense config plugin", "namespace", namespace, "error", err)
return err
}
configTarget, err := config.Struct()
if err != nil {
v.logger.Error("failed to receive config structure", "namespace", namespace)
return err
}
// If the struct value is a boolean, then the plugin is Ruby based. Take any configuration
// that is currently defined (would have been populated via HCL file) and ship it to the
// plugin to attempt to initialize itself with the existing data.
//
// TODO(spox): the data structure generated should use the hcl tag name as the key which
// should match up better with the expected ruby configs
if _, ok := configTarget.(bool); ok {
vc := structs.New(target)
// Find the configuration data for the current namespace
var field *structs.Field
for _, f := range vc.Fields() {
t := f.Tag("hcl")
np := strings.Split(t, ",")
if len(np) < 1 {
break
}
n := np[0]
if n == namespace {
field = f
break
}
}
var data map[string]any
// If no field was found for namespace, or the value is empty, skip
if field == nil || field.IsZero() {
data = map[string]any{}
} else {
data = structs.Map(field.Value())
}
cd, err := config.Init(&component.ConfigData{Data: data})
if err != nil {
v.logger.Error("ruby config init failed", "error", err)
return err
}
source.unfinalized.Data[namespace] = cd
v.logger.Trace("stored unfinalized configuration data", "namespace", namespace, "value", cd)
continue
}
v.logger.Trace("config structure received", "namespace", namespace, "struct", hclog.Fmt("%#v", configTarget))
// A protostructure.Struct value is expected to build the configuration structure
cs, ok := configTarget.(*protostructure.Struct)
if !ok {
v.logger.Error("config value is not protostructure.Struct", "namespace", namespace,
"type", hclog.Fmt("%T", configTarget))
return fmt.Errorf("invalid configuration type received %T", configTarget)
}
// Create the configuration structure
configStruct, err := protostructure.New(cs)
if err != nil {
return err
}
// Build a struct which contains the configuration structure
// so the Vagrantfile contents can be decoded into it
wrapStructType := reflect.StructOf(
[]reflect.StructField{
{
Name: "Remain",
Type: reflect.TypeOf((*hcl.Body)(nil)).Elem(),
Tag: reflect.StructTag(`hcl:",remain"`),
},
{
Name: "Content",
Type: reflect.TypeOf(configStruct),
Tag: reflect.StructTag(fmt.Sprintf(`hcl:"%s,block"`, namespace)),
},
},
)
wrapStruct := reflect.New(wrapStructType)
// Decode the Vagrantfile into the new wrapper
diag := gohcl.DecodeBody(target.Remain, nil, wrapStruct.Interface())
if diag.HasErrors() {
return fmt.Errorf("failed to load config namespace %s: %s", namespace, diag.Error())
}
// Extract the decoded configuration
str := structs.New(wrapStruct.Interface())
f, ok := str.FieldOk("Content")
if !ok {
v.logger.Debug("missing 'Content' field in wrapper struct", "wrapper", wrapStruct.Interface())
return fmt.Errorf("unexpected missing data during Vagrantfile decoding")
}
decodedConfig := f.Value()
v.logger.Trace("configuration value decoded", "namespace", namespace, "config", decodedConfig)
// Use reflect to do a proper nil check since interface
// will be typed
if reflect.ValueOf(decodedConfig).IsNil() {
v.logger.Debug("decoded configuration was nil, continuing...", "namespace", namespace)
continue
}
// Convert the configuration value into a map and store in the unfinalized
// data for the plugin's namespace
decodedMap := structs.Map(decodedConfig)
source.unfinalized.Data[namespace] = &component.ConfigData{Data: decodedMap}
v.logger.Trace("stored unfinalized configuration data", "namespace", namespace, "value", decodedMap)
}
return nil
}
// Finalize all configuration held within the provided
// config data. This assumes the given config data is
// the top level, with each key being the namespace
@ -865,60 +1142,56 @@ func (v *Vagrantfile) finalize(
}
var c core.Config
var r *component.ConfigData
for k, val := range conf.Data {
v.logger.Trace("starting configuration finalization",
"namespace", k,
)
if c, err = v.componentForKey(k); err != nil {
return
}
data, ok := val.(*component.ConfigData)
seen := map[string]struct{}{}
for n, val := range conf.Data {
seen[n] = struct{}{}
reg, ok := v.registrations[n]
if !ok {
v.logger.Error("invalid config type",
"key", k,
"type", hclog.Fmt("%T", val),
"value", hclog.Fmt("%#v", val),
)
return nil, fmt.Errorf("config for %s is invalid type %T", k, val)
}
v.logger.Trace("finalizing configuration data",
"namespace", k,
"data", data,
)
if r, err = c.Finalize(data); err != nil {
return
}
v.logger.Trace("finalized configuration data",
"namespace", k,
)
result.Data[k] = r
v.logger.Trace("finalized data has been stored in result",
"namespace", k,
)
}
// Now we need to run through all our registered config components
// and for any we don't have a value for, and automatically finalize
for n, reg := range v.registrations {
// If no plugin is attached, skip
if reg.plugin == nil {
v.logger.Warn("no plugin registered", "namespace", n)
continue
}
// If we have data already, skip
v.logger.Trace("starting finalization", "namespace", n)
// if no plugin attached, skip
if reg.plugin == nil {
v.logger.Warn("missing plugin registration", "namespace", n)
continue
}
var data *component.ConfigData
data, ok = val.(*component.ConfigData)
if !ok {
v.logger.Error("invalid data for namespace", "type", hclog.Fmt("%T", val))
return nil, fmt.Errorf("invalid data encountered in '%s' namespace", n)
}
v.logger.Trace("finalizing", "namespace", n, "data", data)
if c, err = v.componentForKey(n); err != nil {
return nil, err
}
if r, err = c.Finalize(data); err != nil {
return nil, err
}
v.logger.Trace("finalized", "namespace", n, "data", r)
result.Data[n] = r
}
for n, reg := range v.registrations {
if _, ok := result.Data[n]; ok {
continue
}
// Get the config component and send an empty request
// so we can store the default finalized config
if reg.plugin == nil {
v.logger.Warn("missing plugin registration", "namespace", n)
continue
}
if c, err = v.componentForKey(n); err != nil {
return
return nil, err
}
if r, err = c.Finalize(&component.ConfigData{}); err != nil {
return
if result.Data[n], err = c.Finalize(&component.ConfigData{}); err != nil {
return nil, err
}
result.Data[n] = r
}
v.logger.Trace("configuration data finalization is now complete")
@ -946,8 +1219,10 @@ func (v *Vagrantfile) setFinalized(
),
)
if err != nil {
v.logger.Error("failed to convert data into finalized proto value")
return err
}
s.base.Finalized = raw.(*vagrant_plugin_sdk.Args_Hash)
return nil
@ -1038,7 +1313,7 @@ func (v *Vagrantfile) componentForKey(
// Merge two config data instances
func (v *Vagrantfile) merge(
base, // initial config data
toMerge *component.ConfigData, // config data to merge into base
overlay *component.ConfigData, // config data to merge into base
) (*component.ConfigData, error) {
result := &component.ConfigData{
Data: make(map[string]interface{}),
@ -1049,52 +1324,60 @@ func (v *Vagrantfile) merge(
for k, _ := range base.Data {
keys[k] = struct{}{}
}
for k, _ := range toMerge.Data {
for k, _ := range overlay.Data {
keys[k] = struct{}{}
}
for k, _ := range keys {
c, err := v.componentForKey(k)
if err != nil {
return nil, err
v.logger.Debug("no config component for namespace, skipping", "namespace", k)
}
rawBase, ok1 := base.Data[k]
rawToMerge, ok2 := toMerge.Data[k]
rawBase, okBase := base.Data[k]
rawOverlay, okOverlay := overlay.Data[k]
if ok1 && !ok2 {
if okBase && !okOverlay {
result.Data[k] = rawBase
v.logger.Debug("only base value available, no merge performed",
"namespace", k,
"namespace", k, "config", rawBase,
)
continue
}
if !ok1 && ok2 {
result.Data[k] = rawToMerge
v.logger.Debug("only toMerge value available, no merge performed",
"namespace", k,
if !okBase && okOverlay {
result.Data[k] = rawOverlay
v.logger.Debug("only overlay value available, no merge performed",
"namespace", k, "config", rawOverlay,
)
continue
}
if c == nil {
result.Data[k] = rawOverlay
v.logger.Debug("no component for namespace, applying overlay directly",
"namespace", k, "config", rawOverlay,
)
continue
}
var ok bool
var valBase, valToMerge *component.ConfigData
var valBase, valOverlay *component.ConfigData
valBase, ok = rawBase.(*component.ConfigData)
if !ok {
return nil, fmt.Errorf("bad value type for merge %T", rawBase)
}
valToMerge, ok = rawToMerge.(*component.ConfigData)
valOverlay, ok = rawOverlay.(*component.ConfigData)
if !ok {
return nil, fmt.Errorf("bad value type for merge %T", rawToMerge)
return nil, fmt.Errorf("bad value type for merge %T", rawOverlay)
}
v.logger.Debug("merging values",
"namespace", k,
"base", valBase,
"overlay", valToMerge,
"overlay", valOverlay,
)
r, err := c.Merge(valBase, valToMerge)
r, err := c.Merge(valBase, valOverlay)
if err != nil {
return nil, err
}
@ -1275,4 +1558,17 @@ func optionToString(
return
}
func structToMap(in any) map[string]any {
new := structs.Map(in)
for key, _ := range new {
val := new[key]
rval := reflect.ValueOf(val)
if rval.Kind() == reflect.Struct || (rval.Kind() == reflect.Pointer && rval.Elem().Kind() == reflect.Struct) {
new[key] = structToMap(val)
}
}
return new
}
var _ core.Vagrantfile = (*Vagrantfile)(nil)

View File

@ -123,6 +123,12 @@ func (r *Runner) executeJob(
case *vagrant_server.Job_Init:
return r.executeInitOp(ctx, job, b)
case *vagrant_server.Job_InitProject:
return r.executeInitProjectOp(ctx, job, p)
case *vagrant_server.Job_InitBasis:
return r.executeInitBasisOp(ctx, job, b)
case *vagrant_server.Job_Command:
log.Warn("running a run operation", "scope", scope, "job", job)
return r.executeRunOp(ctx, job, scope)

View File

@ -0,0 +1,29 @@
package runner
import (
"context"
"github.com/hashicorp/vagrant-plugin-sdk/proto/vagrant_plugin_sdk"
"github.com/hashicorp/vagrant/internal/core"
"github.com/hashicorp/vagrant/internal/server/proto/vagrant_server"
)
func (r *Runner) executeInitBasisOp(
ctx context.Context,
job *vagrant_server.Job,
basis *core.Basis,
) (result *vagrant_server.Job_Result, err error) {
_, ok := job.Operation.(*vagrant_server.Job_InitBasis)
if !ok {
panic("operation not expected type")
}
ref, ok := basis.Ref().(*vagrant_plugin_sdk.Ref_Basis)
// x, err := basis.RunInit()
result = &vagrant_server.Job_Result{
Basis: &vagrant_server.Job_InitBasisResult{
Basis: ref,
},
}
return
}

View File

@ -0,0 +1,29 @@
package runner
import (
"context"
"github.com/hashicorp/vagrant-plugin-sdk/proto/vagrant_plugin_sdk"
"github.com/hashicorp/vagrant/internal/core"
"github.com/hashicorp/vagrant/internal/server/proto/vagrant_server"
)
func (r *Runner) executeInitProjectOp(
ctx context.Context,
job *vagrant_server.Job,
project *core.Project,
) (result *vagrant_server.Job_Result, err error) {
_, ok := job.Operation.(*vagrant_server.Job_InitProject)
if !ok {
panic("operation not expected type")
}
ref, ok := project.Ref().(*vagrant_plugin_sdk.Ref_Project)
// x, err := basis.RunInit()
result = &vagrant_server.Job_Result{
Project: &vagrant_server.Job_InitProjectResult{
Project: ref,
},
}
return
}

View File

@ -1,6 +0,0 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
// Package component has component implementations for the various
// resulting types.
package component

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.19.4
// protoc v3.21.12
// source: proto/ruby_vagrant/ruby-server.proto
package ruby_vagrant

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v3.19.4
// - protoc-gen-go-grpc v1.3.0
// - protoc v3.21.12
// source: proto/ruby_vagrant/ruby-server.proto
package ruby_vagrant
@ -19,6 +19,15 @@ import (
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
const (
RubyVagrant_GetPlugins_FullMethodName = "/hashicorp.vagrant.RubyVagrant/GetPlugins"
RubyVagrant_ParseVagrantfile_FullMethodName = "/hashicorp.vagrant.RubyVagrant/ParseVagrantfile"
RubyVagrant_ParseVagrantfileProc_FullMethodName = "/hashicorp.vagrant.RubyVagrant/ParseVagrantfileProc"
RubyVagrant_ParseVagrantfileSubvm_FullMethodName = "/hashicorp.vagrant.RubyVagrant/ParseVagrantfileSubvm"
RubyVagrant_ParseVagrantfileProvider_FullMethodName = "/hashicorp.vagrant.RubyVagrant/ParseVagrantfileProvider"
RubyVagrant_Stop_FullMethodName = "/hashicorp.vagrant.RubyVagrant/Stop"
)
// RubyVagrantClient is the client API for RubyVagrant service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
@ -42,7 +51,7 @@ func NewRubyVagrantClient(cc grpc.ClientConnInterface) RubyVagrantClient {
func (c *rubyVagrantClient) GetPlugins(ctx context.Context, in *GetPluginsRequest, opts ...grpc.CallOption) (*GetPluginsResponse, error) {
out := new(GetPluginsResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.RubyVagrant/GetPlugins", in, out, opts...)
err := c.cc.Invoke(ctx, RubyVagrant_GetPlugins_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -51,7 +60,7 @@ func (c *rubyVagrantClient) GetPlugins(ctx context.Context, in *GetPluginsReques
func (c *rubyVagrantClient) ParseVagrantfile(ctx context.Context, in *ParseVagrantfileRequest, opts ...grpc.CallOption) (*ParseVagrantfileResponse, error) {
out := new(ParseVagrantfileResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.RubyVagrant/ParseVagrantfile", in, out, opts...)
err := c.cc.Invoke(ctx, RubyVagrant_ParseVagrantfile_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -60,7 +69,7 @@ func (c *rubyVagrantClient) ParseVagrantfile(ctx context.Context, in *ParseVagra
func (c *rubyVagrantClient) ParseVagrantfileProc(ctx context.Context, in *ParseVagrantfileProcRequest, opts ...grpc.CallOption) (*ParseVagrantfileResponse, error) {
out := new(ParseVagrantfileResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.RubyVagrant/ParseVagrantfileProc", in, out, opts...)
err := c.cc.Invoke(ctx, RubyVagrant_ParseVagrantfileProc_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -69,7 +78,7 @@ func (c *rubyVagrantClient) ParseVagrantfileProc(ctx context.Context, in *ParseV
func (c *rubyVagrantClient) ParseVagrantfileSubvm(ctx context.Context, in *ParseVagrantfileSubvmRequest, opts ...grpc.CallOption) (*ParseVagrantfileResponse, error) {
out := new(ParseVagrantfileResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.RubyVagrant/ParseVagrantfileSubvm", in, out, opts...)
err := c.cc.Invoke(ctx, RubyVagrant_ParseVagrantfileSubvm_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -78,7 +87,7 @@ func (c *rubyVagrantClient) ParseVagrantfileSubvm(ctx context.Context, in *Parse
func (c *rubyVagrantClient) ParseVagrantfileProvider(ctx context.Context, in *ParseVagrantfileProviderRequest, opts ...grpc.CallOption) (*ParseVagrantfileResponse, error) {
out := new(ParseVagrantfileResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.RubyVagrant/ParseVagrantfileProvider", in, out, opts...)
err := c.cc.Invoke(ctx, RubyVagrant_ParseVagrantfileProvider_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -87,7 +96,7 @@ func (c *rubyVagrantClient) ParseVagrantfileProvider(ctx context.Context, in *Pa
func (c *rubyVagrantClient) Stop(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) {
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.RubyVagrant/Stop", in, out, opts...)
err := c.cc.Invoke(ctx, RubyVagrant_Stop_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -153,7 +162,7 @@ func _RubyVagrant_GetPlugins_Handler(srv interface{}, ctx context.Context, dec f
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.RubyVagrant/GetPlugins",
FullMethod: RubyVagrant_GetPlugins_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RubyVagrantServer).GetPlugins(ctx, req.(*GetPluginsRequest))
@ -171,7 +180,7 @@ func _RubyVagrant_ParseVagrantfile_Handler(srv interface{}, ctx context.Context,
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.RubyVagrant/ParseVagrantfile",
FullMethod: RubyVagrant_ParseVagrantfile_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RubyVagrantServer).ParseVagrantfile(ctx, req.(*ParseVagrantfileRequest))
@ -189,7 +198,7 @@ func _RubyVagrant_ParseVagrantfileProc_Handler(srv interface{}, ctx context.Cont
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.RubyVagrant/ParseVagrantfileProc",
FullMethod: RubyVagrant_ParseVagrantfileProc_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RubyVagrantServer).ParseVagrantfileProc(ctx, req.(*ParseVagrantfileProcRequest))
@ -207,7 +216,7 @@ func _RubyVagrant_ParseVagrantfileSubvm_Handler(srv interface{}, ctx context.Con
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.RubyVagrant/ParseVagrantfileSubvm",
FullMethod: RubyVagrant_ParseVagrantfileSubvm_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RubyVagrantServer).ParseVagrantfileSubvm(ctx, req.(*ParseVagrantfileSubvmRequest))
@ -225,7 +234,7 @@ func _RubyVagrant_ParseVagrantfileProvider_Handler(srv interface{}, ctx context.
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.RubyVagrant/ParseVagrantfileProvider",
FullMethod: RubyVagrant_ParseVagrantfileProvider_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RubyVagrantServer).ParseVagrantfileProvider(ctx, req.(*ParseVagrantfileProviderRequest))
@ -243,7 +252,7 @@ func _RubyVagrant_Stop_Handler(srv interface{}, ctx context.Context, dec func(in
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.RubyVagrant/Stop",
FullMethod: RubyVagrant_Stop_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RubyVagrantServer).Stop(ctx, req.(*emptypb.Empty))

File diff suppressed because it is too large Load Diff

View File

@ -186,7 +186,7 @@ message Vagrantfile {
// Format of this Vagrantfile
Format format = 4;
// Original path of the Vagrantfileo
// Original path of the Vagrantfile
sdk.Args.Path path = 5;
}
@ -325,7 +325,7 @@ message Target {
// Custom metadata
sdk.Args.MetadataSet metadata = 9;
// Serialized configuration of the target
// Serialized configuration of the target (Vagrantfile)
sdk.Args.ConfigData configuration = 10;
// Specialized target information (from provider)
@ -583,7 +583,7 @@ message ValidateJobResponse {
// A Job is a job that executes on a runner and is queued by QueueOperation.
message Job {
reserved 56 to 79; // future operation range
reserved 58 to 79; // future operation range
// id of the job. This is generated on the server side when queued. If
// you are queueing a job, this must be empty or unset.
@ -625,6 +625,8 @@ message Job {
ValidateOp validate = 53;
CommandOp command = 54;
InitOp init = 55;
InitBasisOp init_basis = 56;
InitProjectOp init_project = 57;
}
//-----------------------------------------------------------------
@ -679,6 +681,8 @@ message Job {
ValidateResult validate = 3;
InitResult init = 4;
CommandResult run = 5;
InitBasisResult basis = 6;
InitProjectResult project = 7;
}
message DataSource {
@ -731,6 +735,18 @@ message Job {
repeated Hook hooks = 3;
}
message InitBasisOp { }
message InitBasisResult {
sdk.Ref.Basis basis = 1;
}
message InitProjectOp { }
message InitProjectResult {
sdk.Ref.Project project = 1;
}
message Action {
string name = 1;
string source = 2;

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v3.19.4
// - protoc-gen-go-grpc v1.3.0
// - protoc v3.21.12
// source: proto/vagrant_server/server.proto
package vagrant_server
@ -19,6 +19,43 @@ import (
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
const (
Vagrant_GetVersionInfo_FullMethodName = "/hashicorp.vagrant.Vagrant/GetVersionInfo"
Vagrant_UpsertBasis_FullMethodName = "/hashicorp.vagrant.Vagrant/UpsertBasis"
Vagrant_GetBasis_FullMethodName = "/hashicorp.vagrant.Vagrant/GetBasis"
Vagrant_FindBasis_FullMethodName = "/hashicorp.vagrant.Vagrant/FindBasis"
Vagrant_ListBasis_FullMethodName = "/hashicorp.vagrant.Vagrant/ListBasis"
Vagrant_UpsertProject_FullMethodName = "/hashicorp.vagrant.Vagrant/UpsertProject"
Vagrant_GetProject_FullMethodName = "/hashicorp.vagrant.Vagrant/GetProject"
Vagrant_FindProject_FullMethodName = "/hashicorp.vagrant.Vagrant/FindProject"
Vagrant_ListProjects_FullMethodName = "/hashicorp.vagrant.Vagrant/ListProjects"
Vagrant_UpsertTarget_FullMethodName = "/hashicorp.vagrant.Vagrant/UpsertTarget"
Vagrant_DeleteTarget_FullMethodName = "/hashicorp.vagrant.Vagrant/DeleteTarget"
Vagrant_GetTarget_FullMethodName = "/hashicorp.vagrant.Vagrant/GetTarget"
Vagrant_FindTarget_FullMethodName = "/hashicorp.vagrant.Vagrant/FindTarget"
Vagrant_ListTargets_FullMethodName = "/hashicorp.vagrant.Vagrant/ListTargets"
Vagrant_UpsertBox_FullMethodName = "/hashicorp.vagrant.Vagrant/UpsertBox"
Vagrant_DeleteBox_FullMethodName = "/hashicorp.vagrant.Vagrant/DeleteBox"
Vagrant_GetBox_FullMethodName = "/hashicorp.vagrant.Vagrant/GetBox"
Vagrant_ListBoxes_FullMethodName = "/hashicorp.vagrant.Vagrant/ListBoxes"
Vagrant_FindBox_FullMethodName = "/hashicorp.vagrant.Vagrant/FindBox"
Vagrant_GetLogStream_FullMethodName = "/hashicorp.vagrant.Vagrant/GetLogStream"
Vagrant_QueueJob_FullMethodName = "/hashicorp.vagrant.Vagrant/QueueJob"
Vagrant_CancelJob_FullMethodName = "/hashicorp.vagrant.Vagrant/CancelJob"
Vagrant_GetJob_FullMethodName = "/hashicorp.vagrant.Vagrant/GetJob"
Vagrant_XListJobs_FullMethodName = "/hashicorp.vagrant.Vagrant/_ListJobs"
Vagrant_ValidateJob_FullMethodName = "/hashicorp.vagrant.Vagrant/ValidateJob"
Vagrant_GetJobStream_FullMethodName = "/hashicorp.vagrant.Vagrant/GetJobStream"
Vagrant_PruneOldJobs_FullMethodName = "/hashicorp.vagrant.Vagrant/PruneOldJobs"
Vagrant_GetRunner_FullMethodName = "/hashicorp.vagrant.Vagrant/GetRunner"
Vagrant_BootstrapToken_FullMethodName = "/hashicorp.vagrant.Vagrant/BootstrapToken"
Vagrant_GenerateInviteToken_FullMethodName = "/hashicorp.vagrant.Vagrant/GenerateInviteToken"
Vagrant_GenerateLoginToken_FullMethodName = "/hashicorp.vagrant.Vagrant/GenerateLoginToken"
Vagrant_ConvertInviteToken_FullMethodName = "/hashicorp.vagrant.Vagrant/ConvertInviteToken"
Vagrant_RunnerConfig_FullMethodName = "/hashicorp.vagrant.Vagrant/RunnerConfig"
Vagrant_RunnerJobStream_FullMethodName = "/hashicorp.vagrant.Vagrant/RunnerJobStream"
)
// VagrantClient is the client API for Vagrant service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
@ -115,7 +152,7 @@ func NewVagrantClient(cc grpc.ClientConnInterface) VagrantClient {
func (c *vagrantClient) GetVersionInfo(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*GetVersionInfoResponse, error) {
out := new(GetVersionInfoResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/GetVersionInfo", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_GetVersionInfo_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -124,7 +161,7 @@ func (c *vagrantClient) GetVersionInfo(ctx context.Context, in *emptypb.Empty, o
func (c *vagrantClient) UpsertBasis(ctx context.Context, in *UpsertBasisRequest, opts ...grpc.CallOption) (*UpsertBasisResponse, error) {
out := new(UpsertBasisResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/UpsertBasis", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_UpsertBasis_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -133,7 +170,7 @@ func (c *vagrantClient) UpsertBasis(ctx context.Context, in *UpsertBasisRequest,
func (c *vagrantClient) GetBasis(ctx context.Context, in *GetBasisRequest, opts ...grpc.CallOption) (*GetBasisResponse, error) {
out := new(GetBasisResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/GetBasis", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_GetBasis_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -142,7 +179,7 @@ func (c *vagrantClient) GetBasis(ctx context.Context, in *GetBasisRequest, opts
func (c *vagrantClient) FindBasis(ctx context.Context, in *FindBasisRequest, opts ...grpc.CallOption) (*FindBasisResponse, error) {
out := new(FindBasisResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/FindBasis", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_FindBasis_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -151,7 +188,7 @@ func (c *vagrantClient) FindBasis(ctx context.Context, in *FindBasisRequest, opt
func (c *vagrantClient) ListBasis(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListBasisResponse, error) {
out := new(ListBasisResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/ListBasis", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_ListBasis_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -160,7 +197,7 @@ func (c *vagrantClient) ListBasis(ctx context.Context, in *emptypb.Empty, opts .
func (c *vagrantClient) UpsertProject(ctx context.Context, in *UpsertProjectRequest, opts ...grpc.CallOption) (*UpsertProjectResponse, error) {
out := new(UpsertProjectResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/UpsertProject", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_UpsertProject_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -169,7 +206,7 @@ func (c *vagrantClient) UpsertProject(ctx context.Context, in *UpsertProjectRequ
func (c *vagrantClient) GetProject(ctx context.Context, in *GetProjectRequest, opts ...grpc.CallOption) (*GetProjectResponse, error) {
out := new(GetProjectResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/GetProject", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_GetProject_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -178,7 +215,7 @@ func (c *vagrantClient) GetProject(ctx context.Context, in *GetProjectRequest, o
func (c *vagrantClient) FindProject(ctx context.Context, in *FindProjectRequest, opts ...grpc.CallOption) (*FindProjectResponse, error) {
out := new(FindProjectResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/FindProject", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_FindProject_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -187,7 +224,7 @@ func (c *vagrantClient) FindProject(ctx context.Context, in *FindProjectRequest,
func (c *vagrantClient) ListProjects(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListProjectsResponse, error) {
out := new(ListProjectsResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/ListProjects", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_ListProjects_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -196,7 +233,7 @@ func (c *vagrantClient) ListProjects(ctx context.Context, in *emptypb.Empty, opt
func (c *vagrantClient) UpsertTarget(ctx context.Context, in *UpsertTargetRequest, opts ...grpc.CallOption) (*UpsertTargetResponse, error) {
out := new(UpsertTargetResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/UpsertTarget", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_UpsertTarget_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -205,7 +242,7 @@ func (c *vagrantClient) UpsertTarget(ctx context.Context, in *UpsertTargetReques
func (c *vagrantClient) DeleteTarget(ctx context.Context, in *DeleteTargetRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/DeleteTarget", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_DeleteTarget_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -214,7 +251,7 @@ func (c *vagrantClient) DeleteTarget(ctx context.Context, in *DeleteTargetReques
func (c *vagrantClient) GetTarget(ctx context.Context, in *GetTargetRequest, opts ...grpc.CallOption) (*GetTargetResponse, error) {
out := new(GetTargetResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/GetTarget", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_GetTarget_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -223,7 +260,7 @@ func (c *vagrantClient) GetTarget(ctx context.Context, in *GetTargetRequest, opt
func (c *vagrantClient) FindTarget(ctx context.Context, in *FindTargetRequest, opts ...grpc.CallOption) (*FindTargetResponse, error) {
out := new(FindTargetResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/FindTarget", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_FindTarget_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -232,7 +269,7 @@ func (c *vagrantClient) FindTarget(ctx context.Context, in *FindTargetRequest, o
func (c *vagrantClient) ListTargets(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListTargetsResponse, error) {
out := new(ListTargetsResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/ListTargets", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_ListTargets_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -241,7 +278,7 @@ func (c *vagrantClient) ListTargets(ctx context.Context, in *emptypb.Empty, opts
func (c *vagrantClient) UpsertBox(ctx context.Context, in *UpsertBoxRequest, opts ...grpc.CallOption) (*UpsertBoxResponse, error) {
out := new(UpsertBoxResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/UpsertBox", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_UpsertBox_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -250,7 +287,7 @@ func (c *vagrantClient) UpsertBox(ctx context.Context, in *UpsertBoxRequest, opt
func (c *vagrantClient) DeleteBox(ctx context.Context, in *DeleteBoxRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/DeleteBox", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_DeleteBox_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -259,7 +296,7 @@ func (c *vagrantClient) DeleteBox(ctx context.Context, in *DeleteBoxRequest, opt
func (c *vagrantClient) GetBox(ctx context.Context, in *GetBoxRequest, opts ...grpc.CallOption) (*GetBoxResponse, error) {
out := new(GetBoxResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/GetBox", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_GetBox_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -268,7 +305,7 @@ func (c *vagrantClient) GetBox(ctx context.Context, in *GetBoxRequest, opts ...g
func (c *vagrantClient) ListBoxes(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ListBoxesResponse, error) {
out := new(ListBoxesResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/ListBoxes", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_ListBoxes_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -277,7 +314,7 @@ func (c *vagrantClient) ListBoxes(ctx context.Context, in *emptypb.Empty, opts .
func (c *vagrantClient) FindBox(ctx context.Context, in *FindBoxRequest, opts ...grpc.CallOption) (*FindBoxResponse, error) {
out := new(FindBoxResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/FindBox", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_FindBox_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -285,7 +322,7 @@ func (c *vagrantClient) FindBox(ctx context.Context, in *FindBoxRequest, opts ..
}
func (c *vagrantClient) GetLogStream(ctx context.Context, in *GetLogStreamRequest, opts ...grpc.CallOption) (Vagrant_GetLogStreamClient, error) {
stream, err := c.cc.NewStream(ctx, &Vagrant_ServiceDesc.Streams[0], "/hashicorp.vagrant.Vagrant/GetLogStream", opts...)
stream, err := c.cc.NewStream(ctx, &Vagrant_ServiceDesc.Streams[0], Vagrant_GetLogStream_FullMethodName, opts...)
if err != nil {
return nil, err
}
@ -318,7 +355,7 @@ func (x *vagrantGetLogStreamClient) Recv() (*LogBatch, error) {
func (c *vagrantClient) QueueJob(ctx context.Context, in *QueueJobRequest, opts ...grpc.CallOption) (*QueueJobResponse, error) {
out := new(QueueJobResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/QueueJob", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_QueueJob_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -327,7 +364,7 @@ func (c *vagrantClient) QueueJob(ctx context.Context, in *QueueJobRequest, opts
func (c *vagrantClient) CancelJob(ctx context.Context, in *CancelJobRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/CancelJob", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_CancelJob_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -336,7 +373,7 @@ func (c *vagrantClient) CancelJob(ctx context.Context, in *CancelJobRequest, opt
func (c *vagrantClient) GetJob(ctx context.Context, in *GetJobRequest, opts ...grpc.CallOption) (*Job, error) {
out := new(Job)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/GetJob", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_GetJob_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -345,7 +382,7 @@ func (c *vagrantClient) GetJob(ctx context.Context, in *GetJobRequest, opts ...g
func (c *vagrantClient) XListJobs(ctx context.Context, in *ListJobsRequest, opts ...grpc.CallOption) (*ListJobsResponse, error) {
out := new(ListJobsResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/_ListJobs", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_XListJobs_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -354,7 +391,7 @@ func (c *vagrantClient) XListJobs(ctx context.Context, in *ListJobsRequest, opts
func (c *vagrantClient) ValidateJob(ctx context.Context, in *ValidateJobRequest, opts ...grpc.CallOption) (*ValidateJobResponse, error) {
out := new(ValidateJobResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/ValidateJob", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_ValidateJob_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -362,7 +399,7 @@ func (c *vagrantClient) ValidateJob(ctx context.Context, in *ValidateJobRequest,
}
func (c *vagrantClient) GetJobStream(ctx context.Context, in *GetJobStreamRequest, opts ...grpc.CallOption) (Vagrant_GetJobStreamClient, error) {
stream, err := c.cc.NewStream(ctx, &Vagrant_ServiceDesc.Streams[1], "/hashicorp.vagrant.Vagrant/GetJobStream", opts...)
stream, err := c.cc.NewStream(ctx, &Vagrant_ServiceDesc.Streams[1], Vagrant_GetJobStream_FullMethodName, opts...)
if err != nil {
return nil, err
}
@ -395,7 +432,7 @@ func (x *vagrantGetJobStreamClient) Recv() (*GetJobStreamResponse, error) {
func (c *vagrantClient) PruneOldJobs(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) {
out := new(emptypb.Empty)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/PruneOldJobs", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_PruneOldJobs_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -404,7 +441,7 @@ func (c *vagrantClient) PruneOldJobs(ctx context.Context, in *emptypb.Empty, opt
func (c *vagrantClient) GetRunner(ctx context.Context, in *GetRunnerRequest, opts ...grpc.CallOption) (*Runner, error) {
out := new(Runner)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/GetRunner", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_GetRunner_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -413,7 +450,7 @@ func (c *vagrantClient) GetRunner(ctx context.Context, in *GetRunnerRequest, opt
func (c *vagrantClient) BootstrapToken(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*NewTokenResponse, error) {
out := new(NewTokenResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/BootstrapToken", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_BootstrapToken_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -422,7 +459,7 @@ func (c *vagrantClient) BootstrapToken(ctx context.Context, in *emptypb.Empty, o
func (c *vagrantClient) GenerateInviteToken(ctx context.Context, in *InviteTokenRequest, opts ...grpc.CallOption) (*NewTokenResponse, error) {
out := new(NewTokenResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/GenerateInviteToken", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_GenerateInviteToken_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -431,7 +468,7 @@ func (c *vagrantClient) GenerateInviteToken(ctx context.Context, in *InviteToken
func (c *vagrantClient) GenerateLoginToken(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*NewTokenResponse, error) {
out := new(NewTokenResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/GenerateLoginToken", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_GenerateLoginToken_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -440,7 +477,7 @@ func (c *vagrantClient) GenerateLoginToken(ctx context.Context, in *emptypb.Empt
func (c *vagrantClient) ConvertInviteToken(ctx context.Context, in *ConvertInviteTokenRequest, opts ...grpc.CallOption) (*NewTokenResponse, error) {
out := new(NewTokenResponse)
err := c.cc.Invoke(ctx, "/hashicorp.vagrant.Vagrant/ConvertInviteToken", in, out, opts...)
err := c.cc.Invoke(ctx, Vagrant_ConvertInviteToken_FullMethodName, in, out, opts...)
if err != nil {
return nil, err
}
@ -448,7 +485,7 @@ func (c *vagrantClient) ConvertInviteToken(ctx context.Context, in *ConvertInvit
}
func (c *vagrantClient) RunnerConfig(ctx context.Context, opts ...grpc.CallOption) (Vagrant_RunnerConfigClient, error) {
stream, err := c.cc.NewStream(ctx, &Vagrant_ServiceDesc.Streams[2], "/hashicorp.vagrant.Vagrant/RunnerConfig", opts...)
stream, err := c.cc.NewStream(ctx, &Vagrant_ServiceDesc.Streams[2], Vagrant_RunnerConfig_FullMethodName, opts...)
if err != nil {
return nil, err
}
@ -479,7 +516,7 @@ func (x *vagrantRunnerConfigClient) Recv() (*RunnerConfigResponse, error) {
}
func (c *vagrantClient) RunnerJobStream(ctx context.Context, opts ...grpc.CallOption) (Vagrant_RunnerJobStreamClient, error) {
stream, err := c.cc.NewStream(ctx, &Vagrant_ServiceDesc.Streams[3], "/hashicorp.vagrant.Vagrant/RunnerJobStream", opts...)
stream, err := c.cc.NewStream(ctx, &Vagrant_ServiceDesc.Streams[3], Vagrant_RunnerJobStream_FullMethodName, opts...)
if err != nil {
return nil, err
}
@ -723,7 +760,7 @@ func _Vagrant_GetVersionInfo_Handler(srv interface{}, ctx context.Context, dec f
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/GetVersionInfo",
FullMethod: Vagrant_GetVersionInfo_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).GetVersionInfo(ctx, req.(*emptypb.Empty))
@ -741,7 +778,7 @@ func _Vagrant_UpsertBasis_Handler(srv interface{}, ctx context.Context, dec func
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/UpsertBasis",
FullMethod: Vagrant_UpsertBasis_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).UpsertBasis(ctx, req.(*UpsertBasisRequest))
@ -759,7 +796,7 @@ func _Vagrant_GetBasis_Handler(srv interface{}, ctx context.Context, dec func(in
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/GetBasis",
FullMethod: Vagrant_GetBasis_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).GetBasis(ctx, req.(*GetBasisRequest))
@ -777,7 +814,7 @@ func _Vagrant_FindBasis_Handler(srv interface{}, ctx context.Context, dec func(i
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/FindBasis",
FullMethod: Vagrant_FindBasis_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).FindBasis(ctx, req.(*FindBasisRequest))
@ -795,7 +832,7 @@ func _Vagrant_ListBasis_Handler(srv interface{}, ctx context.Context, dec func(i
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/ListBasis",
FullMethod: Vagrant_ListBasis_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).ListBasis(ctx, req.(*emptypb.Empty))
@ -813,7 +850,7 @@ func _Vagrant_UpsertProject_Handler(srv interface{}, ctx context.Context, dec fu
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/UpsertProject",
FullMethod: Vagrant_UpsertProject_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).UpsertProject(ctx, req.(*UpsertProjectRequest))
@ -831,7 +868,7 @@ func _Vagrant_GetProject_Handler(srv interface{}, ctx context.Context, dec func(
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/GetProject",
FullMethod: Vagrant_GetProject_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).GetProject(ctx, req.(*GetProjectRequest))
@ -849,7 +886,7 @@ func _Vagrant_FindProject_Handler(srv interface{}, ctx context.Context, dec func
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/FindProject",
FullMethod: Vagrant_FindProject_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).FindProject(ctx, req.(*FindProjectRequest))
@ -867,7 +904,7 @@ func _Vagrant_ListProjects_Handler(srv interface{}, ctx context.Context, dec fun
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/ListProjects",
FullMethod: Vagrant_ListProjects_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).ListProjects(ctx, req.(*emptypb.Empty))
@ -885,7 +922,7 @@ func _Vagrant_UpsertTarget_Handler(srv interface{}, ctx context.Context, dec fun
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/UpsertTarget",
FullMethod: Vagrant_UpsertTarget_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).UpsertTarget(ctx, req.(*UpsertTargetRequest))
@ -903,7 +940,7 @@ func _Vagrant_DeleteTarget_Handler(srv interface{}, ctx context.Context, dec fun
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/DeleteTarget",
FullMethod: Vagrant_DeleteTarget_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).DeleteTarget(ctx, req.(*DeleteTargetRequest))
@ -921,7 +958,7 @@ func _Vagrant_GetTarget_Handler(srv interface{}, ctx context.Context, dec func(i
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/GetTarget",
FullMethod: Vagrant_GetTarget_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).GetTarget(ctx, req.(*GetTargetRequest))
@ -939,7 +976,7 @@ func _Vagrant_FindTarget_Handler(srv interface{}, ctx context.Context, dec func(
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/FindTarget",
FullMethod: Vagrant_FindTarget_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).FindTarget(ctx, req.(*FindTargetRequest))
@ -957,7 +994,7 @@ func _Vagrant_ListTargets_Handler(srv interface{}, ctx context.Context, dec func
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/ListTargets",
FullMethod: Vagrant_ListTargets_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).ListTargets(ctx, req.(*emptypb.Empty))
@ -975,7 +1012,7 @@ func _Vagrant_UpsertBox_Handler(srv interface{}, ctx context.Context, dec func(i
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/UpsertBox",
FullMethod: Vagrant_UpsertBox_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).UpsertBox(ctx, req.(*UpsertBoxRequest))
@ -993,7 +1030,7 @@ func _Vagrant_DeleteBox_Handler(srv interface{}, ctx context.Context, dec func(i
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/DeleteBox",
FullMethod: Vagrant_DeleteBox_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).DeleteBox(ctx, req.(*DeleteBoxRequest))
@ -1011,7 +1048,7 @@ func _Vagrant_GetBox_Handler(srv interface{}, ctx context.Context, dec func(inte
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/GetBox",
FullMethod: Vagrant_GetBox_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).GetBox(ctx, req.(*GetBoxRequest))
@ -1029,7 +1066,7 @@ func _Vagrant_ListBoxes_Handler(srv interface{}, ctx context.Context, dec func(i
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/ListBoxes",
FullMethod: Vagrant_ListBoxes_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).ListBoxes(ctx, req.(*emptypb.Empty))
@ -1047,7 +1084,7 @@ func _Vagrant_FindBox_Handler(srv interface{}, ctx context.Context, dec func(int
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/FindBox",
FullMethod: Vagrant_FindBox_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).FindBox(ctx, req.(*FindBoxRequest))
@ -1086,7 +1123,7 @@ func _Vagrant_QueueJob_Handler(srv interface{}, ctx context.Context, dec func(in
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/QueueJob",
FullMethod: Vagrant_QueueJob_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).QueueJob(ctx, req.(*QueueJobRequest))
@ -1104,7 +1141,7 @@ func _Vagrant_CancelJob_Handler(srv interface{}, ctx context.Context, dec func(i
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/CancelJob",
FullMethod: Vagrant_CancelJob_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).CancelJob(ctx, req.(*CancelJobRequest))
@ -1122,7 +1159,7 @@ func _Vagrant_GetJob_Handler(srv interface{}, ctx context.Context, dec func(inte
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/GetJob",
FullMethod: Vagrant_GetJob_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).GetJob(ctx, req.(*GetJobRequest))
@ -1140,7 +1177,7 @@ func _Vagrant_XListJobs_Handler(srv interface{}, ctx context.Context, dec func(i
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/_ListJobs",
FullMethod: Vagrant_XListJobs_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).XListJobs(ctx, req.(*ListJobsRequest))
@ -1158,7 +1195,7 @@ func _Vagrant_ValidateJob_Handler(srv interface{}, ctx context.Context, dec func
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/ValidateJob",
FullMethod: Vagrant_ValidateJob_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).ValidateJob(ctx, req.(*ValidateJobRequest))
@ -1197,7 +1234,7 @@ func _Vagrant_PruneOldJobs_Handler(srv interface{}, ctx context.Context, dec fun
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/PruneOldJobs",
FullMethod: Vagrant_PruneOldJobs_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).PruneOldJobs(ctx, req.(*emptypb.Empty))
@ -1215,7 +1252,7 @@ func _Vagrant_GetRunner_Handler(srv interface{}, ctx context.Context, dec func(i
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/GetRunner",
FullMethod: Vagrant_GetRunner_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).GetRunner(ctx, req.(*GetRunnerRequest))
@ -1233,7 +1270,7 @@ func _Vagrant_BootstrapToken_Handler(srv interface{}, ctx context.Context, dec f
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/BootstrapToken",
FullMethod: Vagrant_BootstrapToken_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).BootstrapToken(ctx, req.(*emptypb.Empty))
@ -1251,7 +1288,7 @@ func _Vagrant_GenerateInviteToken_Handler(srv interface{}, ctx context.Context,
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/GenerateInviteToken",
FullMethod: Vagrant_GenerateInviteToken_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).GenerateInviteToken(ctx, req.(*InviteTokenRequest))
@ -1269,7 +1306,7 @@ func _Vagrant_GenerateLoginToken_Handler(srv interface{}, ctx context.Context, d
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/GenerateLoginToken",
FullMethod: Vagrant_GenerateLoginToken_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).GenerateLoginToken(ctx, req.(*emptypb.Empty))
@ -1287,7 +1324,7 @@ func _Vagrant_ConvertInviteToken_Handler(srv interface{}, ctx context.Context, d
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hashicorp.vagrant.Vagrant/ConvertInviteToken",
FullMethod: Vagrant_ConvertInviteToken_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(VagrantServer).ConvertInviteToken(ctx, req.(*ConvertInviteTokenRequest))

View File

@ -7,6 +7,7 @@ import (
"errors"
"github.com/go-ozzo/ozzo-validation/v4"
// "github.com/hashicorp/go-hclog"
"github.com/hashicorp/vagrant-plugin-sdk/proto/vagrant_plugin_sdk"
"github.com/hashicorp/vagrant/internal/server"
"github.com/hashicorp/vagrant/internal/server/proto/vagrant_server"
@ -32,11 +33,11 @@ type Basis struct {
DataSource *ProtoValue
Jobs []*InternalJob `gorm:"polymorphic:Scope" mapstructure:"-"`
Metadata MetadataSet
Name string `gorm:"uniqueIndex,not null"`
Path string `gorm:"uniqueIndex,not null"`
Name string `gorm:"uniqueIndex;not null"`
Path string `gorm:"uniqueIndex;not null"`
Projects []*Project `gorm:"constraint:OnDelete:SET NULL"`
RemoteEnabled bool
ResourceId string `gorm:"uniqueIndex,not null"` // TODO(spox): readonly permission not working as expected
ResourceId string `gorm:"<-:create;uniqueIndex;not null"`
}
// Returns a fully populated instance of the current basis
@ -134,64 +135,67 @@ func (b *Basis) BeforeUpdate(tx *gorm.DB) error {
}
func (b *Basis) Validate(tx *gorm.DB) error {
// NOTE: We should be able to use `tx.Statement.Changed("ResourceId")`
// for change detection but it doesn't appear to be set correctly
// so we don't get any notice of change (maybe because it's a pointer?)
existing, err := b.find(tx)
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return err
}
if existing == nil {
existing = &Basis{}
}
err = validation.ValidateStruct(b,
return validation.ValidateStruct(b,
validation.Field(&b.Name,
validation.Required,
validation.When(
b.ID == 0,
validation.By(
checkUnique(
tx.Model(&Basis{}).
Where(&Basis{Name: b.Name}).
tx.Model(&Basis{}).Where(&Basis{Name: b.Name}),
),
),
),
validation.When(
b.ID != 0,
validation.By(
checkUnique(
tx.Model(&Basis{}).Where(&Basis{Name: b.Name}).
Not(&Basis{Model: Model{ID: b.ID}}),
),
),
),
),
validation.Field(&b.Path,
validation.Required,
validation.When(
b.ID == 0,
validation.By(
checkUnique(
tx.Model(&Basis{}).
Where(&Basis{Path: b.Path}).
tx.Model(&Basis{}).Where(&Basis{Path: b.Path}),
),
),
),
validation.When(
b.ID != 0,
validation.By(
checkUnique(
tx.Model(&Basis{}).Where(&Basis{Path: b.Path}).
Not(&Basis{Model: Model{ID: b.ID}}),
),
),
),
),
validation.Field(&b.ResourceId,
validation.Required,
validation.When(
b.ID == 0,
validation.By(
checkUnique(
tx.Model(&Basis{}).
Where(&Basis{ResourceId: b.ResourceId}).
Not(&Basis{Model: Model{ID: b.ID}}),
tx.Model(&Basis{}).Where(&Basis{ResourceId: b.ResourceId}),
),
),
),
validation.When(
b.ID != 0,
validation.By(
checkNotModified(
existing.ResourceId,
tx.Statement.Changed("ResourceId"),
),
),
),
),
)
if err != nil {
return err
}
return nil
}
func (b *Basis) setId() error {

View File

@ -156,10 +156,14 @@ func TestBasis_Update(t *testing.T) {
result = db.First(&reloadBasis, &Basis{Model: Model{ID: basis.ID}})
require.NoError(result.Error)
originalResourceId := reloadBasis.ResourceId
reloadBasis.ResourceId = "NEW VALUE"
result = db.Save(&reloadBasis)
require.Error(result.Error)
require.ErrorContains(result.Error, "ResourceId:")
require.NoError(result.Error)
result = db.First(&reloadBasis, &Basis{Model: Model{ID: basis.ID}})
require.NoError(result.Error)
require.Equal(reloadBasis.ResourceId, originalResourceId)
})
t.Run("Adds Vagrantfile", func(t *testing.T) {

View File

@ -82,16 +82,7 @@ func (b *Box) setId() error {
}
func (b *Box) Validate(tx *gorm.DB) error {
existing, err := b.find(tx)
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return err
}
if existing == nil {
existing = &Box{}
}
err = validation.ValidateStruct(b,
err := validation.ValidateStruct(b,
validation.Field(&b.Directory,
validation.Required,
validation.By(
@ -117,7 +108,7 @@ func (b *Box) Validate(tx *gorm.DB) error {
b.ID != 0,
validation.By(
checkNotModified(
existing.ResourceId,
tx.Statement.Changed("ResourceId"),
),
),
),

View File

@ -10,12 +10,10 @@ package state
import (
"errors"
"fmt"
"sort"
"github.com/hashicorp/go-memdb"
"github.com/hashicorp/vagrant-plugin-sdk/proto/vagrant_plugin_sdk"
"github.com/hashicorp/vagrant/internal/server/proto/vagrant_server"
serversort "github.com/hashicorp/vagrant/internal/server/sort"
"gorm.io/gorm"
)
@ -188,8 +186,6 @@ func (s *State) configGetMerged(
result = append(result, v)
}
sort.Sort(serversort.ConfigName(result))
return result, nil
}

View File

@ -501,6 +501,10 @@ func protobufToProtoValueHookFunc(
}
switch v := data.(type) {
case *vagrant_server.Job_InitProject:
return &ProtoValue{Message: v.InitProject}, nil
case *vagrant_server.Job_InitBasis:
return &ProtoValue{Message: v.InitBasis}, nil
case *vagrant_server.Job_Init:
return &ProtoValue{Message: v.Init}, nil
case *vagrant_server.Job_Command:
@ -653,7 +657,7 @@ func protoValueToProtoHookFunc(
}
if p.Message == nil {
return nil, fmt.Errorf("proto value contents is nil (destination: %s)", to)
return nil, fmt.Errorf("proto value contents is nil (destination: %s -> %s) V: %#v", from, to, data)
}
if reflect.ValueOf(p.Message).Type().AssignableTo(to) {
@ -674,6 +678,14 @@ func protoValueToProtoHookFunc(
if reflect.TypeOf((*vagrant_server.Job_Noop_)(nil)).AssignableTo(to) {
return &vagrant_server.Job_Noop_{Noop: v}, nil
}
case *vagrant_server.Job_InitBasisOp:
if reflect.TypeOf((*vagrant_server.Job_InitBasis)(nil)).AssignableTo(to) {
return &vagrant_server.Job_InitBasis{InitBasis: v}, nil
}
case *vagrant_server.Job_InitProjectOp:
if reflect.TypeOf((*vagrant_server.Job_InitProject)(nil)).AssignableTo(to) {
return &vagrant_server.Job_InitProject{InitProject: v}, nil
}
}
return data, nil

View File

@ -29,10 +29,10 @@ type Project struct {
DataSource *ProtoValue
Jobs []*InternalJob `gorm:"polymorphic:Scope"`
Metadata MetadataSet
Name string `gorm:"uniqueIndex:idx_bname,not null"`
Path string `gorm:"uniqueIndex,not null"`
Name string `gorm:"uniqueIndex:idx_bname;not null"`
Path string `gorm:"uniqueIndex:idx_bname;not null"`
RemoteEnabled bool
ResourceId string `gorm:"<-:create,uniqueIndex,not null"`
ResourceId string `gorm:"<-:create;uniqueIndex;not null"`
Targets []*Target
}
@ -125,21 +125,12 @@ func (p *Project) BeforeUpdate(tx *gorm.DB) error {
}
func (p *Project) Validate(tx *gorm.DB) error {
existing, err := p.find(tx)
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return err
}
if existing == nil {
existing = &Project{}
}
basisID := p.BasisID
if p.Basis != nil {
basisID = p.Basis.ID
}
err = validation.ValidateStruct(p,
err := validation.ValidateStruct(p,
validation.Field(&p.BasisID,
validation.Required.When(p.Basis == nil),
),
@ -148,6 +139,8 @@ func (p *Project) Validate(tx *gorm.DB) error {
),
validation.Field(&p.Name,
validation.Required,
validation.When(
p.ID != 0,
validation.By(
checkUnique(
tx.Model(&Project{}).
@ -156,8 +149,20 @@ func (p *Project) Validate(tx *gorm.DB) error {
),
),
),
validation.When(
p.ID == 0,
validation.By(
checkUnique(
tx.Model(&Project{}).
Where(&Project{Name: p.Name, BasisID: basisID}),
),
),
),
),
validation.Field(&p.Path,
validation.Required,
validation.When(
p.ID != 0,
validation.By(
checkUnique(
tx.Model(&Project{}).
@ -166,20 +171,32 @@ func (p *Project) Validate(tx *gorm.DB) error {
),
),
),
validation.Field(&p.ResourceId,
validation.Required,
validation.When(
p.ID == 0,
validation.By(
checkUnique(
tx.Model(&Project{}).
Where(&Project{ResourceId: p.ResourceId}).
Not(&Project{Model: Model{ID: p.ID}}),
Where(&Project{Path: p.Path, BasisID: basisID}),
),
),
),
),
validation.Field(&p.ResourceId,
validation.Required,
validation.When(
p.ID == 0,
validation.By(
checkUnique(
tx.Model(&Project{}).
Where(&Project{ResourceId: p.ResourceId}),
),
),
),
validation.When(
p.ID != 0,
validation.By(
checkNotModified(
existing.ResourceId,
tx.Statement.Changed("ResourceId"),
),
),
),
@ -375,6 +392,10 @@ func (s *State) ProjectPut(
return nil, saveErrorToStatus("project", err)
}
if p.Configuration != nil && p.Configuration.Finalized == nil {
project.Vagrantfile.Finalized = nil
}
if err := s.upsertFull(project); err != nil {
return nil, saveErrorToStatus("project", err)
}

View File

@ -307,10 +307,14 @@ func TestProject_Update(t *testing.T) {
result = db.First(&reloadProject, &Project{Model: Model{ID: project.ID}})
require.NoError(result.Error)
originalResourceId := reloadProject.ResourceId
reloadProject.ResourceId = "NEW VALUE"
result = db.Save(&reloadProject)
require.Error(result.Error)
require.ErrorContains(result.Error, "ResourceId:")
require.NoError(result.Error)
result = db.First(&reloadProject, &Project{Model: Model{ID: project.ID}})
require.NoError(result.Error)
require.Equal(originalResourceId, reloadProject.ResourceId)
})
t.Run("Adds Vagrantfile", func(t *testing.T) {

View File

@ -32,7 +32,7 @@ type Target struct {
ProjectID uint `gorm:"uniqueIndex:idx_pname" mapstructure:"-"`
Provider *string
Record *ProtoValue
ResourceId string `gorm:"uniqueIndex"`
ResourceId string `gorm:"<-:create;uniqueIndex;not null"`
State vagrant_server.Operation_PhysicalState
Subtargets []*Target `gorm:"foreignkey:ParentID;constraint:OnDelete:SET NULL"`
Uuid *string `gorm:"uniqueIndex"`
@ -92,15 +92,6 @@ func (t *Target) BeforeSave(tx *gorm.DB) error {
// project matching. It currently does basic check but
// will miss edge cases easily.
func (t *Target) validate(tx *gorm.DB) error {
existing, err := t.find(tx)
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return err
}
if existing == nil {
existing = &Target{}
}
projectID := t.ProjectID
if t.Project != nil {
projectID = t.Project.ID
@ -123,9 +114,11 @@ func (t *Target) validate(tx *gorm.DB) error {
}
}
err = validation.ValidateStruct(t,
err := validation.ValidateStruct(t,
validation.Field(&t.Name,
validation.Required,
validation.When(
t.ID != 0,
validation.By(
checkUnique(
tx.Model(&Target{}).
@ -134,18 +127,38 @@ func (t *Target) validate(tx *gorm.DB) error {
),
),
),
validation.Field(&t.ResourceId,
validation.Required,
validation.When(
t.ID == 0,
validation.By(
checkUnique(
tx.Model(&Target{}).
Where(&Target{ResourceId: t.ResourceId}).
Not(&Target{Model: Model{ID: t.ID}}),
Where(&Target{Name: t.Name, ProjectID: projectID}),
),
),
),
),
validation.Field(&t.ResourceId,
validation.Required,
validation.When(
t.ID == 0,
validation.By(
checkUnique(
tx.Model(&Target{}).
Where(&Target{ResourceId: t.ResourceId}),
),
),
),
validation.When(
t.ID != 0,
validation.By(
checkNotModified(
tx.Statement.Changed("ResourceId"),
),
),
),
),
validation.Field(&t.Uuid,
validation.When(t.Uuid != nil,
validation.When(t.Uuid != nil && t.ID != 0,
validation.By(
checkUnique(
tx.Model(&Target{}).
@ -154,6 +167,14 @@ func (t *Target) validate(tx *gorm.DB) error {
),
),
),
validation.When(t.Uuid != nil && t.ID == 0,
validation.By(
checkUnique(
tx.Model(&Target{}).
Where(&Target{Uuid: t.Uuid}),
),
),
),
),
validation.Field(&t.ProjectID,
validation.Required.When(t.Project == nil),
@ -406,6 +427,12 @@ func (s *State) TargetPut(
target = &Target{}
}
// TODO(spox): forcing the record to be updated here
// but the soft decoding should be handling it properly
if t.Record != nil {
target.Record = nil
}
err = s.softDecode(t, target)
if err != nil {
return nil, saveErrorToStatus("target", err)
@ -424,6 +451,8 @@ func (s *State) TargetPut(
return nil, saveErrorToStatus("target", err)
}
s.log.Info("target has been upserted", "record", target.Record, "original-record", t.Record)
return target.ToProto(), nil
}

View File

@ -240,14 +240,18 @@ func TestTarget_Update(t *testing.T) {
require.NoError(result.Error)
require.NotEmpty(target.ResourceId)
var reloadTarget Basis
var reloadTarget Target
result = db.First(&reloadTarget, &Target{Model: Model{ID: target.ID}})
require.NoError(result.Error)
originalResourceId := reloadTarget.ResourceId
reloadTarget.ResourceId = "NEW VALUE"
result = db.Save(&reloadTarget)
require.Error(result.Error)
require.ErrorContains(result.Error, "ResourceId:")
require.NoError(result.Error)
result = db.First(&reloadTarget, &Target{Model: Model{ID: target.ID}})
require.NoError(result.Error)
require.Equal(originalResourceId, reloadTarget.ResourceId)
})
t.Run("Updates the state", func(t *testing.T) {

View File

@ -41,7 +41,19 @@ func checkUnique(tx *gorm.DB) validation.RuleFunc {
}
}
func checkNotModified(original interface{}) validation.RuleFunc {
func checkNotModified(changed bool) validation.RuleFunc {
return func(_ any) error {
if changed {
return validation.NewError(
string(VALIDATION_MODIFIED),
"cannot be modified",
)
}
return nil
}
}
func checkNotModified2(original interface{}) validation.RuleFunc {
return func(value interface{}) error {
if !reflect.DeepEqual(original, value) {
return validation.NewError(

View File

@ -1,36 +0,0 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package sort
// import (
// "sort"
// "google.golang.org/protobuf/ptypes"
// pb "github.com/hashicorp/vagrant/internal/server/gen"
// )
// // ArtifactStartDesc sorts builds by start time descending (most recent first).
// // For the opposite, use sort.Reverse.
// type ArtifactStartDesc []*pb.PushedArtifact
// func (s ArtifactStartDesc) Len() int { return len(s) }
// func (s ArtifactStartDesc) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// func (s ArtifactStartDesc) Less(i, j int) bool {
// t1, err := ptypes.Timestamp(s[i].Status.StartTime)
// if err != nil {
// return false
// }
// t2, err := ptypes.Timestamp(s[j].Status.StartTime)
// if err != nil {
// return false
// }
// return t2.Before(t1)
// }
// var (
// _ sort.Interface = (ArtifactStartDesc)(nil)
// )

View File

@ -1,36 +0,0 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package sort
// import (
// "sort"
// "google.golang.org/protobuf/ptypes"
// pb "github.com/hashicorp/vagrant/internal/server/gen"
// )
// // BuildStartDesc sorts builds by start time descending (most recent first).
// // For the opposite, use sort.Reverse.
// type BuildStartDesc []*pb.Build
// func (s BuildStartDesc) Len() int { return len(s) }
// func (s BuildStartDesc) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// func (s BuildStartDesc) Less(i, j int) bool {
// t1, err := ptypes.Timestamp(s[i].Status.StartTime)
// if err != nil {
// return false
// }
// t2, err := ptypes.Timestamp(s[j].Status.StartTime)
// if err != nil {
// return false
// }
// return t2.Before(t1)
// }
// var (
// _ sort.Interface = (BuildStartDesc)(nil)
// )

View File

@ -1,23 +0,0 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package sort
import (
"sort"
"github.com/hashicorp/vagrant/internal/server/proto/vagrant_server"
)
// ConfigName sorts config variables by name.
type ConfigName []*vagrant_server.ConfigVar
func (s ConfigName) Len() int { return len(s) }
func (s ConfigName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s ConfigName) Less(i, j int) bool {
return s[i].Name < s[j].Name
}
var (
_ sort.Interface = (ConfigName)(nil)
)

View File

@ -1,55 +0,0 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package sort
// import (
// "sort"
// "google.golang.org/protobuf/ptypes"
// pb "github.com/hashicorp/vagrant/internal/server/gen"
// )
// // DeploymentStartDesc sorts deployments by start time descending.
// type DeploymentStartDesc []*pb.Deployment
// func (s DeploymentStartDesc) Len() int { return len(s) }
// func (s DeploymentStartDesc) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// func (s DeploymentStartDesc) Less(i, j int) bool {
// t1, err := ptypes.Timestamp(s[i].Status.StartTime)
// if err != nil {
// return false
// }
// t2, err := ptypes.Timestamp(s[j].Status.StartTime)
// if err != nil {
// return false
// }
// return t2.Before(t1)
// }
// // DeploymentCompleteDesc sorts deployments by completion time descending.
// type DeploymentCompleteDesc []*pb.Deployment
// func (s DeploymentCompleteDesc) Len() int { return len(s) }
// func (s DeploymentCompleteDesc) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// func (s DeploymentCompleteDesc) Less(i, j int) bool {
// t1, err := ptypes.Timestamp(s[i].Status.CompleteTime)
// if err != nil {
// return false
// }
// t2, err := ptypes.Timestamp(s[j].Status.CompleteTime)
// if err != nil {
// return false
// }
// return t2.Before(t1)
// }
// var (
// _ sort.Interface = (DeploymentStartDesc)(nil)
// _ sort.Interface = (DeploymentCompleteDesc)(nil)
// )

View File

@ -51,6 +51,17 @@ require "vagrant/plugin/manager"
# Enable logging if it is requested. We do this before
# anything else so that we can setup the output before
# any logging occurs.
# NOTE: We must do this little hack to allow
# rest-client to write using the `<<` operator.
# See https://github.com/rest-client/rest-client/issues/34#issuecomment-290858
# for more information
class VagrantLogger < Log4r::Logger
def << msg
debug(msg.strip)
end
end
if ENV["VAGRANT_LOG"] && ENV["VAGRANT_LOG"] != ""
level = Log4r::LNAMES.index(ENV["VAGRANT_LOG"].upcase)
if level.nil?
@ -69,16 +80,6 @@ if ENV["VAGRANT_LOG"] && ENV["VAGRANT_LOG"] != ""
# Set the logging level on all "vagrant" namespaced
# logs as long as we have a valid level.
if level
# NOTE: We must do this little hack to allow
# rest-client to write using the `<<` operator.
# See https://github.com/rest-client/rest-client/issues/34#issuecomment-290858
# for more information
class VagrantLogger < Log4r::Logger
def << msg
debug(msg.strip)
end
end
["vagrant", "vagrantplugins"].each do |lname|
logger = VagrantLogger.new(lname)
if ENV["VAGRANT_LOG_FILE"] && ENV["VAGRANT_LOG_FILE"] != ""
@ -88,6 +89,7 @@ if ENV["VAGRANT_LOG"] && ENV["VAGRANT_LOG"] != ""
end
logger.level = level
end
Log4r::RootLogger.instance.level = level
base_formatter = Log4r::BasicFormatter.new
if ENV["VAGRANT_LOG_TIMESTAMP"]

View File

@ -1014,11 +1014,12 @@ module Vagrant
def process_configured_plugins
return if !Vagrant.plugins_enabled?
errors = vagrantfile.config.vagrant.validate(nil)
if !errors["vagrant"].empty?
if !Array(errors["vagrant"]).empty?
raise Errors::ConfigInvalid,
errors: Util::TemplateRenderer.render(
"config/validation_failed",
errors: errors)
errors: {vagrant: errors["vagrant"]}
)
end
# Check if defined plugins are installed
installed = Plugin::Manager.instance.installed_plugins

View File

@ -50,7 +50,13 @@ module Vagrant
@aliases_path ||= @home_path && @home_path.join("aliases")
@default_private_key_path = Pathname.new(@client.default_private_key)
copy_insecure_private_key
@default_private_keys_directory = @home_path.join("insecure_private_keys")
if !@default_private_keys_directory.directory?
@default_private_keys_directory.mkdir
end
@default_private_key_paths = []
copy_insecure_private_keys
# Initialize localized plugins
plugins = Vagrant::Plugin::Manager.instance.localize!(self)

View File

@ -39,4 +39,16 @@ if !Log4r::Logger::LoggerFactory.respond_to?(:fake_define_methods)
alias_method :set_log, :fake_set_log
end
end
class Log4r::Logger
# The factory allows using a previously created logger
# instance if it exists. Doing this prevents knocking
# out configuration that may have already been applied
# to the logger instance (like log level)
def self.factory(name, *args)
l = Log4r::Logger::Repository[name]
return l unless l.nil?
Log4r::Logger.new(name, *args)
end
end
end

View File

@ -110,6 +110,7 @@ module Vagrant
}
raise Errors::NoEnvironmentError if requires_local_env && !@env.root_path
@logger.info("getting active machines")
# Cache the active machines outside the loop
active_machines = @env.active_machines
@ -217,6 +218,8 @@ module Vagrant
end
end
@logger.debug("have machine list to process")
# Make sure we're only working with one VM if single target
if options[:single_target] && machines.length != 1
@logger.debug("Using primary machine since single target")

View File

@ -1,16 +1,34 @@
# frozen_string_literal: true
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: plugin/grpc_broker.proto
require 'google/protobuf'
Google::Protobuf::DescriptorPool.generated_pool.build do
add_file("plugin/grpc_broker.proto", :syntax => :proto3) do
add_message "plugin.ConnInfo" do
optional :service_id, :uint32, 1
optional :network, :string, 2
optional :address, :string, 3
descriptor_data = "\n\x18plugin/grpc_broker.proto\x12\x06plugin\"@\n\x08\x43onnInfo\x12\x12\n\nservice_id\x18\x01 \x01(\r\x12\x0f\n\x07network\x18\x02 \x01(\t\x12\x0f\n\x07\x61\x64\x64ress\x18\x03 \x01(\t2C\n\nGRPCBroker\x12\x35\n\x0bStartStream\x12\x10.plugin.ConnInfo\x1a\x10.plugin.ConnInfo(\x01\x30\x01\x42\x08Z\x06pluginb\x06proto3"
pool = Google::Protobuf::DescriptorPool.generated_pool
begin
pool.add_serialized_file(descriptor_data)
rescue TypeError => e
# Compatibility code: will be removed in the next major version.
require 'google/protobuf/descriptor_pb'
parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
parsed.clear_dependency
serialized = parsed.class.encode(parsed)
file = pool.add_serialized_file(serialized)
warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
imports = [
]
imports.each do |type_name, expected_filename|
import_file = pool.lookup(type_name).file_descriptor
if import_file.name != expected_filename
warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
end
end
warn "Each proto file must use a consistent fully-qualified name."
warn "This will become an error in the next major version."
end
module Plugin

View File

@ -1,5 +1,9 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
# Source: plugin/grpc_broker.proto for package 'plugin'
# Original file comments:
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
#
require 'grpc'
require 'plugin/grpc_broker_pb'

View File

@ -1,36 +1,34 @@
# frozen_string_literal: true
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: protostructure.proto
require 'google/protobuf'
Google::Protobuf::DescriptorPool.generated_pool.build do
add_file("protostructure.proto", :syntax => :proto3) do
add_message "protostructure.Struct" do
repeated :fields, :message, 1, "protostructure.Struct.Field"
end
add_message "protostructure.Struct.Field" do
optional :Name, :string, 1
optional :PkgPath, :string, 2
optional :Tag, :string, 3
optional :type, :message, 4, "protostructure.Type"
end
add_message "protostructure.Type" do
oneof :type do
optional :primitive, :message, 1, "protostructure.Primitive"
optional :container, :message, 2, "protostructure.Container"
optional :struct, :message, 3, "protostructure.Struct"
end
end
add_message "protostructure.Primitive" do
optional :kind, :uint32, 1
end
add_message "protostructure.Container" do
optional :kind, :uint32, 1
optional :elem, :message, 2, "protostructure.Type"
optional :key, :message, 3, "protostructure.Type"
optional :count, :int32, 4
descriptor_data = "\n\x14protostructure.proto\x12\x0eprotostructure\"\x8f\x01\n\x06Struct\x12,\n\x06\x66ields\x18\x01 \x03(\x0b\x32\x1c.protostructure.Struct.Field\x1aW\n\x05\x46ield\x12\x0c\n\x04Name\x18\x01 \x01(\t\x12\x0f\n\x07PkgPath\x18\x02 \x01(\t\x12\x0b\n\x03Tag\x18\x03 \x01(\t\x12\"\n\x04type\x18\x04 \x01(\x0b\x32\x14.protostructure.Type\"\x98\x01\n\x04Type\x12.\n\tprimitive\x18\x01 \x01(\x0b\x32\x19.protostructure.PrimitiveH\x00\x12.\n\tcontainer\x18\x02 \x01(\x0b\x32\x19.protostructure.ContainerH\x00\x12(\n\x06struct\x18\x03 \x01(\x0b\x32\x16.protostructure.StructH\x00\x42\x06\n\x04type\"\x19\n\tPrimitive\x12\x0c\n\x04kind\x18\x01 \x01(\r\"o\n\tContainer\x12\x0c\n\x04kind\x18\x01 \x01(\r\x12\"\n\x04\x65lem\x18\x02 \x01(\x0b\x32\x14.protostructure.Type\x12!\n\x03key\x18\x03 \x01(\x0b\x32\x14.protostructure.Type\x12\r\n\x05\x63ount\x18\x04 \x01(\x05\x42%Z#github.com/mitchellh/protostructureb\x06proto3"
pool = Google::Protobuf::DescriptorPool.generated_pool
begin
pool.add_serialized_file(descriptor_data)
rescue TypeError => e
# Compatibility code: will be removed in the next major version.
require 'google/protobuf/descriptor_pb'
parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
parsed.clear_dependency
serialized = parsed.class.encode(parsed)
file = pool.add_serialized_file(serialized)
warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
imports = [
]
imports.each do |type_name, expected_filename|
import_file = pool.lookup(type_name).file_descriptor
if import_file.name != expected_filename
warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
end
end
warn "Each proto file must use a consistent fully-qualified name."
warn "This will become an error in the next major version."
end
module Protostructure

View File

@ -1,3 +1,4 @@
# frozen_string_literal: true
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: proto/ruby_vagrant/ruby-server.proto
@ -7,53 +8,34 @@ require 'google/protobuf/empty_pb'
require 'google/protobuf/any_pb'
require 'google/rpc/error_details_pb'
require 'plugin_pb'
Google::Protobuf::DescriptorPool.generated_pool.build do
add_file("proto/ruby_vagrant/ruby-server.proto", :syntax => :proto3) do
add_message "hashicorp.vagrant.GetPluginsRequest" do
optional :project_path, :string, 1
end
add_message "hashicorp.vagrant.GetPluginsResponse" do
repeated :plugins, :message, 1, "hashicorp.vagrant.Plugin"
end
add_message "hashicorp.vagrant.Plugin" do
optional :name, :string, 1
optional :type, :enum, 2, "hashicorp.vagrant.Plugin.Type"
optional :options, :message, 3, "google.protobuf.Any"
end
add_enum "hashicorp.vagrant.Plugin.Type" do
value :UNKNOWN, 0
value :COMMAND, 1
value :COMMUNICATOR, 2
value :GUEST, 3
value :HOST, 4
value :PROVIDER, 5
value :PROVISIONER, 6
value :SYNCEDFOLDER, 7
value :AUTHENTICATOR, 8
value :LOGPLATFORM, 9
value :LOGVIEWER, 10
value :MAPPER, 11
value :CONFIG, 12
value :PLUGININFO, 13
value :PUSH, 14
end
add_message "hashicorp.vagrant.ParseVagrantfileRequest" do
optional :path, :string, 1
end
add_message "hashicorp.vagrant.ParseVagrantfileProcRequest" do
optional :proc, :message, 1, "hashicorp.vagrant.sdk.Args.ProcRef"
end
add_message "hashicorp.vagrant.ParseVagrantfileResponse" do
optional :data, :message, 1, "hashicorp.vagrant.sdk.Args.Hash"
end
add_message "hashicorp.vagrant.ParseVagrantfileSubvmRequest" do
optional :subvm, :message, 1, "hashicorp.vagrant.sdk.Config.RawRubyValue"
end
add_message "hashicorp.vagrant.ParseVagrantfileProviderRequest" do
optional :subvm, :message, 1, "hashicorp.vagrant.sdk.Config.RawRubyValue"
optional :provider, :string, 2
descriptor_data = "\n$proto/ruby_vagrant/ruby-server.proto\x12\x11hashicorp.vagrant\x1a\x1bgoogle/protobuf/empty.proto\x1a\x19google/protobuf/any.proto\x1a\x1egoogle/rpc/error_details.proto\x1a\x0cplugin.proto\")\n\x11GetPluginsRequest\x12\x14\n\x0cproject_path\x18\x01 \x01(\t\"@\n\x12GetPluginsResponse\x12*\n\x07plugins\x18\x01 \x03(\x0b\x32\x19.hashicorp.vagrant.Plugin\"\xcb\x02\n\x06Plugin\x12\x0c\n\x04name\x18\x01 \x01(\t\x12,\n\x04type\x18\x02 \x01(\x0e\x32\x1e.hashicorp.vagrant.Plugin.Type\x12%\n\x07options\x18\x03 \x01(\x0b\x32\x14.google.protobuf.Any\"\xdd\x01\n\x04Type\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0b\n\x07\x43OMMAND\x10\x01\x12\x10\n\x0c\x43OMMUNICATOR\x10\x02\x12\t\n\x05GUEST\x10\x03\x12\x08\n\x04HOST\x10\x04\x12\x0c\n\x08PROVIDER\x10\x05\x12\x0f\n\x0bPROVISIONER\x10\x06\x12\x10\n\x0cSYNCEDFOLDER\x10\x07\x12\x11\n\rAUTHENTICATOR\x10\x08\x12\x0f\n\x0bLOGPLATFORM\x10\t\x12\r\n\tLOGVIEWER\x10\n\x12\n\n\x06MAPPER\x10\x0b\x12\n\n\x06\x43ONFIG\x10\x0c\x12\x0e\n\nPLUGININFO\x10\r\x12\x08\n\x04PUSH\x10\x0e\"\'\n\x17ParseVagrantfileRequest\x12\x0c\n\x04path\x18\x01 \x01(\t\"P\n\x1bParseVagrantfileProcRequest\x12\x31\n\x04proc\x18\x01 \x01(\x0b\x32#.hashicorp.vagrant.sdk.Args.ProcRef\"J\n\x18ParseVagrantfileResponse\x12.\n\x04\x64\x61ta\x18\x01 \x01(\x0b\x32 .hashicorp.vagrant.sdk.Args.Hash\"Y\n\x1cParseVagrantfileSubvmRequest\x12\x39\n\x05subvm\x18\x01 \x01(\x0b\x32*.hashicorp.vagrant.sdk.Config.RawRubyValue\"n\n\x1fParseVagrantfileProviderRequest\x12\x39\n\x05subvm\x18\x01 \x01(\x0b\x32*.hashicorp.vagrant.sdk.Config.RawRubyValue\x12\x10\n\x08provider\x18\x02 \x01(\t2\xf6\x04\n\x0bRubyVagrant\x12Y\n\nGetPlugins\x12$.hashicorp.vagrant.GetPluginsRequest\x1a%.hashicorp.vagrant.GetPluginsResponse\x12k\n\x10ParseVagrantfile\x12*.hashicorp.vagrant.ParseVagrantfileRequest\x1a+.hashicorp.vagrant.ParseVagrantfileResponse\x12s\n\x14ParseVagrantfileProc\x12..hashicorp.vagrant.ParseVagrantfileProcRequest\x1a+.hashicorp.vagrant.ParseVagrantfileResponse\x12u\n\x15ParseVagrantfileSubvm\x12/.hashicorp.vagrant.ParseVagrantfileSubvmRequest\x1a+.hashicorp.vagrant.ParseVagrantfileResponse\x12{\n\x18ParseVagrantfileProvider\x12\x32.hashicorp.vagrant.ParseVagrantfileProviderRequest\x1a+.hashicorp.vagrant.ParseVagrantfileResponse\x12\x36\n\x04Stop\x12\x16.google.protobuf.Empty\x1a\x16.google.protobuf.EmptyBAZ?github.com/hashicorp/vagrant/internal/server/proto/ruby_vagrantb\x06proto3"
pool = Google::Protobuf::DescriptorPool.generated_pool
begin
pool.add_serialized_file(descriptor_data)
rescue TypeError => e
# Compatibility code: will be removed in the next major version.
require 'google/protobuf/descriptor_pb'
parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
parsed.clear_dependency
serialized = parsed.class.encode(parsed)
file = pool.add_serialized_file(serialized)
warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
imports = [
["google.protobuf.Any", "google/protobuf/any.proto"],
["hashicorp.vagrant.sdk.Args.ProcRef", "plugin.proto"],
]
imports.each do |type_name, expected_filename|
import_file = pool.lookup(type_name).file_descriptor
if import_file.name != expected_filename
warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
end
end
warn "Each proto file must use a consistent fully-qualified name."
warn "This will become an error in the next major version."
end
module Hashicorp

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,9 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
# Source: vagrant_plugin_sdk/plugin.proto for package 'hashicorp.vagrant.sdk'
# Original file comments:
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
#
require 'grpc'
require 'vagrant_plugin_sdk/plugin_pb'
@ -251,12 +255,14 @@ module Hashicorp
self.unmarshal_class_method = :decode
self.service_name = 'hashicorp.vagrant.sdk.ConfigService'
rpc :InitSpec, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::FuncSpec
rpc :Init, ::Hashicorp::Vagrant::Sdk::FuncSpec::Args, ::Hashicorp::Vagrant::Sdk::Config::InitResponse
rpc :StructSpec, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::FuncSpec
rpc :Struct, ::Hashicorp::Vagrant::Sdk::FuncSpec::Args, ::Hashicorp::Vagrant::Sdk::Config::StructResponse
rpc :MergeSpec, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::FuncSpec
rpc :Merge, ::Hashicorp::Vagrant::Sdk::FuncSpec::Args, ::Hashicorp::Vagrant::Sdk::Args::ConfigData
rpc :FinalizeSpec, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::FuncSpec
rpc :Finalize, ::Hashicorp::Vagrant::Sdk::FuncSpec::Args, ::Hashicorp::Vagrant::Sdk::Args::ConfigData
rpc :Finalize, ::Hashicorp::Vagrant::Sdk::FuncSpec::Args, ::Hashicorp::Vagrant::Sdk::Config::FinalizeResponse
rpc :Register, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::Config::RegisterResponse
rpc :Seed, ::Hashicorp::Vagrant::Sdk::Args::Seeds, ::Google::Protobuf::Empty
rpc :Seeds, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::Args::Seeds

File diff suppressed because one or more lines are too long

View File

@ -238,26 +238,36 @@ module Vagrant
# @return [true]
def self.enable_server_mode!
if !server_mode?
load_vagrant_proto!
SERVER_MODE_CALLBACKS.each(&:call)
Util::HCLogOutputter.new("hclog")
Log4r::Outputter["hclog"].formatter = Util::HCLogFormatter.new
Log4r::Outputter.stderr.formatter = Log4r::Outputter["hclog"].formatter
Log4r::RootLogger.instance.outputters = Log4r::Outputter["hclog"]
Log4r::Logger.each_logger do |l|
l.outputters = Log4r::Outputter["hclog"] if l.parent == Log4r::RootLogger.instance
l.outputters = Log4r::Outputter["hclog"] #if l.parent&.is_root?
end
Log4r::Logger::Repository.class_eval do
def self.[]=(n, l)
self.synchronize do
l.outputters = Log4r::Outputter["hclog"] if l.parent == Log4r::RootLogger.instance
l.outputters = Log4r::Outputter["hclog"] # if l.parent&.is_root?
instance.loggers[n] = l
end
end
end
end
# By default only display error logs from the mappers unless explicitly
# requested due to their verbosity
if ENV["VAGRANT_LOG_MAPPER"].to_s == ""
l = Log4r::Logger.new("vagrantplugins::commandserve::mappers::internal")
l = Log4r::Logger.factory("vagrantplugins::commandserve::mappers")
l.level = Log4r::ERROR
end
end
Log4r::Logger.factory("vagrant").trace("service logger initialization")
Log4r::Logger.factory("vagrantplugins").trace("service logger initialization")
load_vagrant_proto!
SERVER_MODE_CALLBACKS.each(&:call)
@_server_mode = true
end

View File

@ -49,7 +49,8 @@ module Vagrant
d = {
"@timestamp" => Time.now.strftime("%Y-%m-%dT%H:%M:%S.%6N%:z"),
"@level" => Log4r::LNAMES[event.level].downcase,
"@module" => event.fullname.gsub("::", "."),
"@module" => event.fullname,
"@name" => event.name,
"@message" => msg,
}
d["@caller"] = event.tracer[0] if event.tracer

View File

@ -88,12 +88,9 @@ module VagrantPlugins
# return [Vagrant::Machine]
def machine(name, provider)
t = client.target(SDK::Project::TargetRequest.new(
name: name,
provider: provider,
))
machine = mapper.map(t, to: Vagrant::Machine)
return machine
logger.info("getting machine from vagrant-go name: #{name} provider: #{provider}")
t = target(name, provider)
Vagrant::Machine.new(client: t)
end
# return [String]

View File

@ -128,7 +128,7 @@ module VagrantPlugins
s.handle(health_checker)
logger.debug("writing connection informatation to stdout for go-plugin")
logger.debug("writing connection information to stdout for go-plugin")
STDOUT.puts "1|1|tcp|#{bind_addr}:#{port}|grpc"
STDOUT.flush
logger.info("Vagrant GRPC service is now running addr=#{bind_addr.inspect} port=#{port.inspect}")

View File

@ -205,13 +205,15 @@ module VagrantPlugins
# @param to [Class] Resultant type (optional)
# @return [Object]
def direct_convert(value, to:)
logger.debug { "direct conversion on #{value.class} to destination type #{to}" }
# If we don't have a destination, attempt to do direct conversion
if to.nil?
begin
logger.trace { "running direct blind pre-map on #{value.class}" }
logger.debug { "running direct blind pre-map on #{value.class}" }
return value.is_a?(Google::Protobuf::MessageExts) ? value.to_ruby : value.to_proto
rescue => err
logger.trace { "direct blind conversion failed in pre-map stage, reason: #{err}" }
logger.debug { "direct blind conversion failed in pre-map stage, reason: #{err}" }
end
end
@ -221,7 +223,7 @@ module VagrantPlugins
begin
return value.to_any
rescue => err
logger.trace { "direct any conversion failed in pre-map stage, reason: #{err}"}
logger.debug { "direct any conversion failed in pre-map stage, reason: #{err}"}
end
end
@ -231,7 +233,7 @@ module VagrantPlugins
proto = value.to_proto
return proto if proto.is_a?(to)
rescue => err
logger.trace { "direct proto conversion failed in pre-map stage, reason: #{err}" }
logger.debug { "direct proto conversion failed in pre-map stage, reason: #{err}" }
end
end
@ -241,7 +243,7 @@ module VagrantPlugins
val = value.to_ruby
return val if val.is_a?(to)
rescue => err
logger.trace { "direct ruby conversion failed in pre-map stage, reason: #{err}" }
logger.debug { "direct ruby conversion failed in pre-map stage, reason: #{err}" }
end
end
end

View File

@ -62,6 +62,22 @@ module VagrantPlugins
end
end
class ConfigFinalizeResponseProtoFromConfigDataProto < Mapper
def initialize
super(
inputs: [
Input.new(type: SDK::Args::ConfigData),
],
output: SDK::Config::FinalizeResponse,
func: method(:converter),
)
end
def converter(c)
SDK::Config::FinalizeResponse.new(data: c)
end
end
class ConfigFromConfigDataProto < Mapper
include Util::HasLogger

View File

@ -151,8 +151,8 @@ module VagrantPlugins
SDK::Communicator::ExecuteResp.new(
exit_code: exit_code,
stdout: output[:stdout],
stderr: output[:stderr]
stdout: output[:stdout].force_encoding("UTF-8"),
stderr: output[:stderr].force_encoding("UTF-8")
)
end
end

View File

@ -31,8 +31,49 @@ module VagrantPlugins
end
end
def init_spec(*_)
funcspec(
args: [
SDK::Args::ConfigData,
],
result: SDK::Config::InitResponse
)
end
def init(req, ctx)
with_plugin(ctx, :config, broker: broker) do |plugin|
config_data_p = mapper.unfuncspec(req.args.first)
config_data = mapper.map(config_data_p.data)
instance = plugin.new
config_data.each do |key, value|
key = key.downcase.to_sym
if instance.respond_to?("#{key}=".to_sym)
instance.send("#{key}=".to_sym, value)
elsif instance.respond_to?(key)
instance.send(key, value)
else
logger.warn("unknown config key to apply: class: #{plugin} key: #{key}")
end
end
SDK::Config::InitResponse.new(data: mapper.map(instance, to: SDK::Args::ConfigData))
end
end
def struct_spec(*_)
funcspec(
args: [
],
result: SDK::Config::StructResponse
)
end
def struct(req, ctx)
SDK::Config::StructResponse.new(raw: true)
end
def merge_spec(*_)
logger.debug("generating merge spec")
funcspec(
args: [
SDK::Config::Merge,
@ -62,8 +103,6 @@ module VagrantPlugins
def finalize(req, ctx)
with_plugin(ctx, CONFIG_LOCATIONS, broker: broker) do |plugin|
logger.debug("finalizing configuration for plugin #{plugin}")
# Extract the proto from the funcspec
f = mapper.unfuncspec(req.args.first)
cproto = f.config
@ -81,7 +120,7 @@ module VagrantPlugins
# responsible for the finalization
config.instance_variable_set("@__service_finalized", true)
mapper.map(config, to: SDK::Args::ConfigData)
SDK::Config::FinalizeResponse.new(data: mapper.map(config, to: SDK::Args::ConfigData))
end
end
end

View File

@ -15,10 +15,20 @@ class Object
Hashicorp::Vagrant::Sdk::Args::Class.new(name: name)
end
# simple stub so non-proto objects won't
# error if conversion is attempted
def to_ruby
self
end
def to_any
pro = to_proto
source_proto = if !self.class.ancestors.include?(Google::Protobuf::MessageExts)
to_proto
else
self
end
begin
Google::Protobuf::Any.pack(pro)
Google::Protobuf::Any.pack(source_proto)
rescue
PROTO_LOGGER.warn("failed to any this type: #{self.class} value: #{self}")
raise
@ -435,6 +445,12 @@ class Hashicorp::Vagrant::Sdk::Args::Host
end
end
class Hashicorp::Vagrant::Sdk::Args::MetadataSet
def to_ruby
{}
end
end
class Hashicorp::Vagrant::Sdk::Args::NamedCapability
def to_ruby
capability.to_s.to_sym
@ -569,7 +585,7 @@ class Hashicorp::Vagrant::Sdk::Args::Target
VagrantPlugins::CommandServe.cache.registered?(cid)
client = _vagrant_load_client(VagrantPlugins::CommandServe::Client::Target)
env = client.project.to_ruby
env = client.environment.to_ruby
machine = env.machine(client.name.to_sym, client.provider_name.to_sym)
VagrantPlugins::CommandServe.cache.register(cid, machine)
machine
@ -592,7 +608,7 @@ end
class Hashicorp::Vagrant::Sdk::Args::Target::Machine::State
def to_ruby
Vagrant::MachineState.new(
m.id.to_sym, m.short_description, m.long_description
id.to_sym, short_description, long_description
)
end
end

View File

@ -9,7 +9,7 @@ module VagrantPlugins
module HasLogger
def logger
if !@logger
@logger = Log4r::Logger.new(self.class.name.to_s.downcase)
@logger = Log4r::Logger.factory(self.class.name.to_s.downcase)
end
@logger
end

View File

@ -493,6 +493,10 @@ module VagrantPlugins
# If the locale command is not available, return default
return @env_lang if !Vagrant::Util::Which.which("locale")
if defined?(@@env_lang)
return @env_lang = @@env_lang
end
@logger.debug("validating LANG value for virtualbox cli commands")
# Get list of available locales on the system
result = Vagrant::Util::Subprocess.execute("locale", "-a")
@ -514,10 +518,10 @@ module VagrantPlugins
if lang
@logger.debug("valid variation found for LANG value: #{lang}")
@env_lang[:LANG] = lang
@@env_lang = @env_lang
end
@logger.debug("LANG value set: #{@env_lang[:LANG].inspect}")
@env_lang
end
end

View File

@ -20,7 +20,7 @@ Gem::Specification.new do |s|
s.add_dependency "ed25519", "~> 1.3.0"
s.add_dependency "erubi"
s.add_dependency 'googleapis-common-protos-types', '~> 1.3'
s.add_dependency "grpc"
s.add_dependency "grpc", "~> 1.56.0"
s.add_dependency "hashicorp-checkpoint", "~> 0.1.5"
s.add_dependency "i18n", "~> 1.12"
s.add_dependency "listen", "~> 3.7"