Scaffolding Envvars no longer being set at build?

Starting at some point in the last day or so, my builds have stopped getting their scaffolding envvars set at build time. This is happening on both of my habitatized applications, one using the node scaffolding, the other the ruby scaffolding.

After much head-scratching, I hit upon adding this to my plans, which has solved the problem and builds are happening properly again:

do_before() {
  for i in "${!scaffolding_env[@]}"
  do
    export $i="${scaffolding_env[$i]}"
    echo "$i=${scaffolding_env[$i]}"
  done
}

The echo line was just in there for debugging, but I’m going to be leaving it for now so that if something related seems to go awry I have logged visibility into the envs I set at build time.

Any thoughts on why this behavior changed? If this was an intended change, omg why?

What version of Habitat are you running, @qhartman ?

@nellshamrell, any guesses?

When this cropped up I was running 0.59.0. I’ve since upgraded to 0.61.0 and the behavior remained the same.

I had the same problem with using ruby scaffolding. Setting an scaffolding_env didn’t make the environment variable available at build time, but I was able to get around this by setting the same variable using:

set_buildtime_env VARIABLE_NAME "value"

So in some cases I am setting the same variable twice, once for build time and again as a scaffolding_env.

Have you always had this problem? For me, the scaffolding_env array has been working to set build-time envvars since I started working with habitat until very recently, the last few days.

Yeah, this has always been my experience using Hab v0.51, v0.56, and v0.59. One of my Ruby apps uses Devise which required SECRET_KEY_BASE to be set at build time in order to compile the assets (otherwise the devise initializer barfs). Once I set it as a build time var it worked.

It’s interesting that you’ve only experienced this recently. Perhaps there is something that I wasn’t doing correctly…I did just recently discover the do_setup_environment() callback which I moved my scaffolding assignments into. Prior to that I was declaring everything directly in the plan outside of any callback functions (like you would set a plan variable). This could be something I should revisit to see if that makes a difference.

Yeah, I’ve been using it for similar things. Up until this issue, adding a block like the following to my plan has always done the right thing, and those K/V pairs were available in the environment at build time:

declare -A scaffolding_env
scaffolding_env[SECRET_KEY_BASE]="really_long_random_string"
scaffolding_env[TARGET_ENV]="production"
scaffolding_env[AN_IMPORTANT_URL]="https://omg-puppies.net"

I’ve done a quick scan through the code and I don’t see anything obvious that has changed in the last couple months that would cause this. I’m not super familiar with the implementation details of scaffolding_env to know what the cause might be. I’ll look into it though, talk with @nellshamrell and report my findings back here.

There’s always a chance that something that seems unrelated may have changed on my end that could be affecting it that I haven’t thought of. Has anyone been able to reproduce it? My first thought is something in my container image that performs the builds?

I’ll try to make time to test some builds using older versions of my build containers and see if the problem exists in those too.

We have not made any major (or minor, really) changes to scaffolding in the last several months, my guess offhand would be that this is related to some Habitat change. @smacfarlane let me know if you are able to reproduce this? And I’m happy to talk it over if you like :slight_smile:

Hi @qhartman, where in your plan do you declare -A scaffolding_env ? Would it be possible to share a redacted version of your plan?

I’ve been digging in to how scaffolding_env is handled by the scaffolding code. It is specific to the scaffolding type, but node and ruby handle it the same way. The code that ensures that variable is present hasn’t been touched in a year, so I wonder if this is a scope problem. It will set the variable if it doesn’t exist, but I can see that you’ve declared it in your snippet above, which is why I think it might be a scoping issue. If you declare in a function, its scope will be limited to that function, but the scaffolding will set the variable for you, which would give us behavior like you’re seeing. It doesn’t explain the sudden change in behavior however :frowning:

That’s the only clue I’ve been able to find so far, and haven’t been able to create a repro yet.

Thanks for looking at this! I’m on the road right now so I can’t easily post the plans, but I can tell you in both of them I’m declaring the scaffolding array first thing, right after I set dependencies. In fact, until I added that do_before callback, that’s all my ruby based plan did, set dependencies and declare the array. Everything else was handled by scaffolding defaults.

When I get settled later tonight I’ll pay both my plans, redacted if needed.

OK, here is my redacted .plan. As stated, it’s basically empty except for the scaffolfing_env and the block I added to work around this new problem:

# DO NOT EDIT THIS FILE DIRECTLY
# Instead, make config changes to the plan.sh.$GIT_BRANCH file that
# corresponds to the env you want to config.

pkg_name=my_app
pkg_origin=my_origin
pkg_version="0.1.2"
pkg_scaffolding="core/scaffolding-ruby"
pkg_deps=(core/curl core/imagemagick core/file)

declare -A scaffolding_env
scaffolding_env[DATABASE_URL]="dsfsgsrsfsadfsdf"
scaffolding_env[DEFAULT_FROM]="gdsgsdfsdfsdfds"
scaffolding_env[ELASTICSEARCH_URL]="https://elasticsearch"
scaffolding_env[HOST]="http://localhost:9200"
scaffolding_env[LANG]="en_US.UTF-8"
scaffolding_env[RACK_ENV]="production"
scaffolding_env[RAILS_ENV]="production"
scaffolding_env[RAILS_LOG_TO_STDOUT]="enabled"
scaffolding_env[RAILS_SERVE_STATIC_FILES]="enabled"
scaffolding_env[REDIS_URL]="redis://redis:6379"
scaffolding_env[UI_URL]="https://localhost"
scaffolding_env[SESSION_TIMEOUT_IN_MINUTES]="1440"
scaffolding_env[WEB_CONCURRENCY]="2"
scaffolding_env[RAILS_MAX_THREADS]="2"

do_before() {
  for i in "${!scaffolding_env[@]}"
  do
    export $i="${scaffolding_env[$i]}"
    echo "$i=${scaffolding_env[$i]}"
  done
}