#variant (2020-05)
Discuss variant (the “Universal CLI”) https://github.com/mumoshu/variant
Archive: https://archive.sweetops.com/variant/
2020-05-01
@Erik Osterman (Cloud Posse) @mumoshu here is an example of a CLI call not waiting for input.
I don’t have the exact code in play right here, but my guess it is the workspace
running then it immediately goes to a init
which also skips waiting for the input.
Initializing modules...
Initializing the backend...
Backend configuration changed!
Terraform has detected that the configuration specified for the backend
has changed. Terraform will now check for existing state in the backends.
Do you want to migrate all workspaces to "s3"?
Both the existing "s3" backend and the newly configured "s3" backend
support workspaces. When migrating between backends, Terraform will copy
all workspaces (with the same names). THIS WILL OVERWRITE any conflicting
states in the destination.
Terraform initialization doesn't currently migrate only select workspaces.
If you want to migrate a select number of workspaces, you must manually
pull and push those states.
If you answer "yes", Terraform will migrate all states. If you answer
"no", Terraform will abort.
Enter a value:
Do you want to migrate all workspaces to "s3"?
Both the existing "s3" backend and the newly configured "s3" backend
support workspaces. When migrating between backends, Terraform will copy
all workspaces (with the same names). THIS WILL OVERWRITE any conflicting
states in the destination.
Terraform initialization doesn't currently migrate only select workspaces.
If you want to migrate a select number of workspaces, you must manually
pull and push those states.
If you answer "yes", Terraform will migrate all states. If you answer
"no", Terraform will abort.
Enter a value:
Error: Migration aborted by user.
job "terraform init" {
description = "Runs terraform init for a tenant project"
parameter "tenant" {
description = "Tenant to operate on"
type = string
}
parameter "project" {
description = "Terraform project to process"
type = string
}
run "terraform subcommand" {
args = []
command = "init"
project = param.project
tenant = param.tenant
}
}
job "terraform subcommand" {
description = "Execute a terraform subcommand"
private = true
option "args" {
default = []
description = "args to pass to subcommand"
type = list(string)
}
parameter "command" {
type = string
description = "A terraform command to execute"
}
parameter "project" {
description = "Terraform project to process"
type = string
}
option "env" {
default = {}
description = "Environment variables for the command"
type = map(string)
}
variable "cmd-name" {
value = "terraform"
}
variable "cmd" {
value = opt.dry-run ? "echo" : var.cmd-name
}
variable "cmd-args" {
value = compact(concat(list(opt.dry-run ? var.cmd-name : ""), list(param.command), opt.args))
}
exec {
args = var.cmd-args
command = var.cmd
dir = "${opt.tenants-dir}/projects/${param.project}"
env = opt.env
}
}
job "terraform shell" {
description = "Run a terraform subcommand in a shell targeted specifically at a tenants/projects project"
private = true
parameter "tenant" {
description = "Tenant to operate on"
type = string
}
parameter "project" {
description = "Terraform project to process"
type = string
}
parameter "commands" {
description = "List of commands to execute"
type = list(string)
}
run "shell" {
commands = param.commands
dir = "${opt.tenants-dir}/projects/${param.project}"
}
}
#!/usr/bin/env variant
# vim: filetype=hcl
job "echo" {
description = "Echoes the param.message to the console"
private = true
parameter "message" {
description = "A message to output"
type = string
}
exec {
command = "echo"
args = [param.message]
}
}
job "shell" {
description = "Run a command in bash"
private = true
option "dir" {
default = ""
description = "Directory to run the command"
type = string
}
option "env" {
default = {}
description = "Environment variables for the command"
type = map(string)
}
parameter "commands" {
description = "List of commands to execute"
type = list(string)
}
variable "cmd-name" {
value = "bash"
}
variable "cmd" {
value = opt.dry-run ? "echo" : var.cmd-name
}
variable "cmd-args" {
type = list(string)
value = compact(concat(list(opt.dry-run ? var.cmd-name : ""), ["-c", join("\n", param.commands)]))
}
exec {
args = var.cmd-args
command = var.cmd
dir = opt.dir
env = opt.env
}
}
Have you tried interactive = true
? It won’t be able to wait for input without that option, cuz interactive = true
is the only way for connecting your STDIN to the exec, which is a must for the user input to work at all
ah, right. is it at an issue if it is “sometimes” interactive?
what do you mean by sometimes
? does it sometimes wait for the input?
it may not actually prompt
ex:
tf init
the first time doesn’t prompt
i thought it would never wait. terraform would produce a prompt asking the user input regardless of STDIN is there or not. but i thought that’s just that
change the backend storage and it’ll ask to migrate storage
yes, but seems like that’s terraform issue?
i.e. terraform is trying to ask for the user input even when there’s no STDIN connected to your terminal?
i just wanted to know if variant2 would had an issue if it doesn’t prompt and i still put interactive
on it
afaik, no. but im interested. did you observe anything that might be caused by a potential variant2 issue? (did you actually see variant2 not handling user input correctly even when interactive = true
is set?
im a little confused cuz there seemed no interactive = true
set in your example
btw variant2 should never wait for input if thre’s no interactive =true
set
no, there is a stdin. this is on my local system so tf waiting is expected
yeah, but you also need interactive = true
to actually pass your STDIN to those terraform commands run via exec
:
exec {
interactive = true
args = var.cmd-args
command = var.cmd
dir = "${opt.tenants-dir}/projects/${param.project}"
env = opt.env
}
in your example it doesn’t have one
exec {
args = var.cmd-args
command = var.cmd
dir = "${opt.tenants-dir}/projects/${param.project}"
env = opt.env
}
oh, or are you saying that variant2 should automatically set interactive = true
whenever STDIN is connected to a tty?
(i intentionally avoided that cuz it doesn’t always work
@johncblandii Hey! Could you revisit this? I’m still thinking that this is behaving as expected given you don’t have interactive = true
set in execs. But I’m open to suggestions like e.g. make interactive = true
default, or anything else.