Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add envconsul-like support and refactor environment handling #2654

Merged
merged 30 commits into from
May 30, 2017

Conversation

schmichael
Copy link
Member

@schmichael schmichael commented May 18, 2017

Fixes #1765

There's two major goals of this PR:

  1. Add envconsul-like support
  2. Refactor env.TaskEnvironment into a dynamic Builder and a static TaskEnv.

The refactor was to avoid a new circular dependency between environments and templates. Templates get an immutable TaskEnv and task_runner handles populating the environment from environment template files.

Unfortunately there's still a circular dependency between environments and drivers in two places:

  1. To set environment paths we need to call Driver.FSIsolation()
  2. Docker's port_map affects how network env vars are populated

So the new env.Builder struct has to be exposed to task_runner and templates, but everything else (drivers, executors, etc) only have access to the immutable env.TaskEnv.

Graph of the dependencies:

client-dependency-graph

@jippi
Copy link
Contributor

jippi commented May 19, 2017

amazing job @schmichael ! Thank you

@schmichael schmichael changed the title [WIP] Add envconsul-like support and refactor environment handling Add envconsul-like support and refactor environment handling May 24, 2017
@@ -138,6 +138,14 @@ func TestAllocRunner_TerminalUpdate_Destroy(t *testing.T) {
ctestutil.ExecCompatible(t)
upd, ar := testAllocRunner(false)

// Shrink chroot
ar.config.ChrootEnv = map[string]string{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switch to mock driver instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call! Way faster and one more test that doesn't require root.

}

// Set the environment variables
builder.SetTemplateEnv(vars)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks if they have multiple templates generating environment variables.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, good catch. Will add a test as well.

@@ -192,6 +195,12 @@ WAIT:
}
}

for _, t := range tm.templates {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment explaining what you are doing. Blank line between the block please

@@ -243,6 +252,11 @@ WAIT:
}

for _, tmpl := range tmpls {
if err := loadTemplateEnv(envBuilder, taskDir, tmpl); err != nil {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra line


tm.hook.Kill("consul-template", err.Error(), true)
return
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blank below

func (t *TaskEnvironment) ClearRegionName() *TaskEnvironment {
t.Region = ""
return t
func (b *Builder) SetTemplateEnv(m map[string]string) *Builder {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment in consul_template.go

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

cmdArgs := make([]string, 0, 50)

// Run rkt with env command to inject PATH as rkt needs to be able to find iptables
envAbsPath, err := GetAbsolutePath(envCmd)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unclear why we can just use the option -set-env and just run Rkt with all environment variables minus those in the blacklist passed through?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched it to use a fresh env with just the host env vars on it. Seems more reasonable than mutating TaskEnv to add the PATH in just for the rkt command.

@@ -861,6 +861,7 @@ func parseTemplates(result *[]*api.Template, list *ast.ObjectList) error {
"right_delimiter",
"source",
"splay",
"env",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parse test

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

@@ -680,6 +680,7 @@ func ApiTaskToStructsTask(apiTask *api.Task, structsTask *structs.Task) {
Perms: *template.Perms,
LeftDelim: *template.LeftDelim,
RightDelim: *template.RightDelim,
Envvars: *template.Envvars,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add to test

@@ -373,6 +374,9 @@ func (tmpl *Template) Canonicalize() {
if tmpl.RightDelim == nil {
tmpl.RightDelim = helper.StringToPtr("}}")
}
if tmpl.Envvars == nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Believe there is a canonicalize test as well

@schmichael
Copy link
Member Author

Ready for re-review.


FOO=bar
foo=123
ANYTHING-goes=Spaces are=ok!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are newlines okay too?

assume key derp has a value in Consul of the following, and you do DERP={{ key "derp" }}

hello
world

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newlines need to be escaped. The 2 easiest ways are probably:

  1. {{ key "derp" | toJSON}}
  2. {{ key "derp" | printf "%q" }}

Both will properly escape newlines.

However, in this current PR they won't be unescaped and if your task read the environment it would look like:

derp := os.Getenv("derp")
fmt.Printf(">>%s<<\n", derp)

It would print the escaped value:

>>"hello\nworld"<<

So I'll post a followup PR that properly un-escapes values, so that the code above would print:

>>hello
world<<

@schmichael schmichael merged commit aac319c into master May 30, 2017
@schmichael schmichael deleted the f-env-consul branch May 30, 2017 21:40
@c4milo
Copy link
Contributor

c4milo commented May 30, 2017

Excellent work!

@jippi
Copy link
Contributor

jippi commented May 31, 2017

Amazing @schmichael ! :D another $work owned step to remove soon'ish : D

@github-actions
Copy link

github-actions bot commented Apr 1, 2023

I'm going to lock this pull request because it has been closed for 120 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants