Merge pull request #276 from hashicorp/machine-readable-flag
Machine readable flag
This commit is contained in:
commit
fa1f45732b
2
go.mod
2
go.mod
@ -45,7 +45,7 @@ require (
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.7.1-0.20201023000745-3de61ecba298
|
||||
github.com/hashicorp/nomad/api v0.0.0-20200814140818-42de70466a9d
|
||||
github.com/hashicorp/vagrant-plugin-sdk v0.0.0-20220525200400-f1459dc0d92b
|
||||
github.com/hashicorp/vagrant-plugin-sdk v0.0.0-20220603142803-c69edee0b0a1
|
||||
github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce // indirect
|
||||
github.com/imdario/mergo v0.3.11
|
||||
github.com/improbable-eng/grpc-web v0.13.0
|
||||
|
||||
2
go.sum
2
go.sum
@ -357,6 +357,8 @@ github.com/hashicorp/nomad/api v0.0.0-20200814140818-42de70466a9d h1:afuZ/KNbxwU
|
||||
github.com/hashicorp/nomad/api v0.0.0-20200814140818-42de70466a9d/go.mod h1:DCi2k47yuUDzf2qWAK8E1RVmWgz/lc0jZQeEnICTxmY=
|
||||
github.com/hashicorp/vagrant-plugin-sdk v0.0.0-20220525200400-f1459dc0d92b h1:GidqljOXwQSIFn+nk4DOpa0kpR/1x/yS/yCNnA7sUFE=
|
||||
github.com/hashicorp/vagrant-plugin-sdk v0.0.0-20220525200400-f1459dc0d92b/go.mod h1:KWfWOiotOWKiAqdroXVc7GUFnuOzlzhnRkGTV9Js7/s=
|
||||
github.com/hashicorp/vagrant-plugin-sdk v0.0.0-20220603142803-c69edee0b0a1 h1:zp+NV96agdfbsO7FI7U8VaL3PkbTNCOvPJxCuIZB8rM=
|
||||
github.com/hashicorp/vagrant-plugin-sdk v0.0.0-20220603142803-c69edee0b0a1/go.mod h1:KWfWOiotOWKiAqdroXVc7GUFnuOzlzhnRkGTV9Js7/s=
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce h1:7UnVY3T/ZnHUrfviiAgIUjg2PXxsQfs5bphsG8F7Keo=
|
||||
github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
|
||||
@ -91,6 +91,9 @@ type baseCommand struct {
|
||||
// flagInteractive is whether the output is interactive
|
||||
flagInteractive bool
|
||||
|
||||
// flagMachineReadable is whether the terminal ui should only output machine readable data
|
||||
flagMachineReadable bool
|
||||
|
||||
// flagConnection contains manual flag-based connection info.
|
||||
flagConnection clicontext.Config
|
||||
|
||||
@ -154,8 +157,11 @@ func BaseCommand(ctx context.Context, log hclog.Logger, logOutput io.Writer, opt
|
||||
|
||||
// Set UI
|
||||
var ui terminal.UI
|
||||
// Set non interactive if the --no-interactive flag is provided
|
||||
if !bc.flagInteractive {
|
||||
if bc.flagMachineReadable {
|
||||
// Set machine readable ui if the --machine-readable flag is provided
|
||||
ui = terminal.MachineReadableUI(ctx, terminal.TableFormat)
|
||||
} else if !bc.flagInteractive {
|
||||
// Set non interactive if the --no-interactive flag is provided
|
||||
ui = terminal.NonInteractiveUI(ctx)
|
||||
} else {
|
||||
// If no ui related flags are set, create a new one
|
||||
@ -285,8 +291,11 @@ func (c *baseCommand) Init(opts ...Option) (err error) {
|
||||
|
||||
// Set UI
|
||||
var ui terminal.UI
|
||||
// Set non interactive if the --no-interactive flag is provided
|
||||
if !c.flagInteractive {
|
||||
if c.flagMachineReadable {
|
||||
// Set machine readable ui if the --machine-readable flag is provided
|
||||
ui = terminal.MachineReadableUI(c.Ctx, terminal.TableFormat)
|
||||
} else if !c.flagInteractive {
|
||||
// Set non interactive if the --no-interactive flag is provided
|
||||
ui = terminal.NonInteractiveUI(c.Ctx)
|
||||
} else {
|
||||
// If no ui related flags are set, use the base config ui
|
||||
@ -407,6 +416,12 @@ func (c *baseCommand) flagSet(bit flagSetBit, f func([]*component.CommandFlag) [
|
||||
DefaultValue: "true",
|
||||
Type: component.FlagBool,
|
||||
},
|
||||
{
|
||||
LongName: "machine-readable",
|
||||
Description: "Target to apply command",
|
||||
DefaultValue: "false",
|
||||
Type: component.FlagBool,
|
||||
},
|
||||
}
|
||||
|
||||
if bit&flagSetOperation != 0 {
|
||||
@ -493,6 +508,8 @@ func (c *baseCommand) Parse(
|
||||
c.flagRemote = pf.DefaultValue().(bool)
|
||||
case "interactive":
|
||||
c.flagInteractive = pf.DefaultValue().(bool)
|
||||
case "machine-readable":
|
||||
c.flagMachineReadable = pf.DefaultValue().(bool)
|
||||
}
|
||||
if !pf.Updated() {
|
||||
continue
|
||||
@ -509,6 +526,8 @@ func (c *baseCommand) Parse(
|
||||
c.flagRemote = pf.Value().(bool)
|
||||
case "interactive":
|
||||
c.flagInteractive = pf.Value().(bool)
|
||||
case "machine-readable":
|
||||
c.flagMachineReadable = pf.Value().(bool)
|
||||
}
|
||||
c.flagData[f] = pf.Value()
|
||||
}
|
||||
|
||||
@ -42,6 +42,10 @@ func (u *runnerUI) Interactive() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (u *runnerUI) MachineReadable() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (u *runnerUI) ClearLine() {
|
||||
// NO-OP - noninteractive
|
||||
}
|
||||
|
||||
@ -52,6 +52,15 @@ func (u *multiUI) Interactive() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (u *multiUI) MachineReadable() bool {
|
||||
for _, u := range u.UIs {
|
||||
if u.MachineReadable() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (u *multiUI) Output(msg string, raw ...interface{}) {
|
||||
for _, u := range u.UIs {
|
||||
u.Output(msg, raw...)
|
||||
|
||||
@ -62,16 +62,6 @@ module Vagrant
|
||||
@state_mutex = Mutex.new
|
||||
# TODO: get trigger config from go
|
||||
@triggers = Vagrant::Plugin::V2::Trigger.new(@env, @config.trigger, self, @ui)
|
||||
|
||||
# If the ID is the special not created ID, then set our ID to
|
||||
# nil so that we destroy all our data.
|
||||
# if state.id == MachineState::NOT_CREATED_ID
|
||||
# self.id = nil
|
||||
# end
|
||||
|
||||
# Output a bunch of information about this machine in
|
||||
# machine-readable format in case someone is listening.
|
||||
@ui.machine("metadata", "provider", provider_name)
|
||||
end
|
||||
|
||||
# @return [Box]
|
||||
|
||||
@ -308,6 +308,9 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
||||
add_message "hashicorp.vagrant.sdk.TerminalUI.IsInteractiveResponse" do
|
||||
optional :interactive, :bool, 1
|
||||
end
|
||||
add_message "hashicorp.vagrant.sdk.TerminalUI.IsMachineReadableResponse" do
|
||||
optional :machine_readable, :bool, 1
|
||||
end
|
||||
add_message "hashicorp.vagrant.sdk.TerminalUI.OutputRequest" do
|
||||
repeated :lines, :string, 1
|
||||
optional :style, :enum, 2, "hashicorp.vagrant.sdk.TerminalUI.OutputRequest.Style"
|
||||
@ -1020,6 +1023,7 @@ module Hashicorp
|
||||
ImplementsResp = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.ImplementsResp").msgclass
|
||||
TerminalUI = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.TerminalUI").msgclass
|
||||
TerminalUI::IsInteractiveResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.TerminalUI.IsInteractiveResponse").msgclass
|
||||
TerminalUI::IsMachineReadableResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.TerminalUI.IsMachineReadableResponse").msgclass
|
||||
TerminalUI::OutputRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.TerminalUI.OutputRequest").msgclass
|
||||
TerminalUI::OutputRequest::Style = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.TerminalUI.OutputRequest.Style").enummodule
|
||||
TerminalUI::Response = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.TerminalUI.Response").msgclass
|
||||
|
||||
@ -26,6 +26,7 @@ module Hashicorp
|
||||
rpc :Output, ::Hashicorp::Vagrant::Sdk::TerminalUI::OutputRequest, ::Google::Protobuf::Empty
|
||||
rpc :Events, stream(::Hashicorp::Vagrant::Sdk::TerminalUI::Event), stream(::Hashicorp::Vagrant::Sdk::TerminalUI::Response)
|
||||
rpc :IsInteractive, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::TerminalUI::IsInteractiveResponse
|
||||
rpc :IsMachineReadable, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::TerminalUI::IsMachineReadableResponse
|
||||
end
|
||||
|
||||
Stub = Service.rpc_stub_class
|
||||
|
||||
@ -20,6 +20,7 @@ module Vagrant
|
||||
def initialize(client)
|
||||
super()
|
||||
@client = client
|
||||
@logger = Log4r::Logger.new("vagrant::ui")
|
||||
end
|
||||
|
||||
def clear_line
|
||||
@ -42,6 +43,30 @@ module Vagrant
|
||||
client.output(message.gsub("%", "%%"), **opts)
|
||||
end
|
||||
|
||||
def machine(type, *data)
|
||||
if !client.is_machine_readable
|
||||
@logger.info("Machine: #{type} #{data.inspect}")
|
||||
return
|
||||
end
|
||||
|
||||
opts = {}
|
||||
opts = data.pop if data.last.kind_of?(Hash)
|
||||
target = opts[:target] || ""
|
||||
|
||||
# Prepare the data by replacing characters that aren't outputted
|
||||
data.each_index do |i|
|
||||
data[i] = data[i].to_s.dup
|
||||
data[i].gsub!(",", "%!(VAGRANT_COMMA)")
|
||||
data[i].gsub!("\n", "\\n")
|
||||
data[i].gsub!("\r", "\\r")
|
||||
end
|
||||
table_data = {
|
||||
rows: [[Time.now.utc.to_i, target, type, data.join(",")]]
|
||||
}
|
||||
|
||||
client.table(table_data, **opts)
|
||||
end
|
||||
|
||||
def to_proto
|
||||
@client.proto
|
||||
end
|
||||
|
||||
@ -19,7 +19,11 @@ module VagrantPlugins
|
||||
end
|
||||
|
||||
def is_interactive
|
||||
client.is_interactive.interactive
|
||||
client.is_interactive(Empty.new).interactive
|
||||
end
|
||||
|
||||
def is_machine_readable
|
||||
client.is_machine_readable(Empty.new).machine_readable
|
||||
end
|
||||
|
||||
def input(prompt, **opts)
|
||||
@ -72,6 +76,36 @@ module VagrantPlugins
|
||||
].each
|
||||
).each {}
|
||||
end
|
||||
|
||||
# @params [Map] data has the table data for the event. The form of
|
||||
# this map is:
|
||||
# { headers: List<string>, rows: List<List<string>> }
|
||||
def table(data, **opts)
|
||||
rows = data[:rows].map { |r|
|
||||
SDK::TerminalUI::Event::TableRow.new(
|
||||
entries: r.map { |e|
|
||||
SDK::TerminalUI::Event::TableEntry.new(value: e.to_s)
|
||||
}
|
||||
)
|
||||
}
|
||||
event_resp = client.events(
|
||||
[
|
||||
SDK::TerminalUI::Event.new(
|
||||
table: SDK::TerminalUI::Event::Table.new(
|
||||
headers: data[:headers],
|
||||
rows: rows
|
||||
)
|
||||
),
|
||||
].each
|
||||
)
|
||||
|
||||
event_resp.map { |resp|
|
||||
input = resp.input
|
||||
if !input.error.nil?
|
||||
raise Vagrant::Errors::VagrantRemoteError, msg: input.error.message
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user