Skip to content
This repository has been archived by the owner on May 6, 2020. It is now read-only.

feat(api): Allow using an unreleased image for the run command #1208

Closed
wants to merge 5 commits into from

Conversation

robholland
Copy link
Contributor

This is useful for build steps which must be completed before an app is fully
deployed to deis, for example asset compilation.

@deis-admin
Copy link

Thanks for the contribution! Please ensure your commits follow our style guide. This code will be tested once a Deis maintainer reviews it.

@robholland robholland changed the title feat(run-cmd): Allow using an unreleased image feat(api): Allow using an unreleased image Jan 19, 2017
@robholland robholland changed the title feat(api): Allow using an unreleased image feat(api): Allow using an unreleased image for the run command Jan 19, 2017
This is useful for build steps which must be completed before an app is fully
deployed to deis, for example asset compilation.
@vdice
Copy link
Member

vdice commented Jan 19, 2017

Jenkins, add to whitelist.

@vdice
Copy link
Member

vdice commented Jan 19, 2017

@robholland looks like a simple test-style/flake8 error (line length complaints) from the travis build: https://travis-ci.org/deis/controller/builds/193398357

@bacongobbler
Copy link
Member

bacongobbler commented Jan 19, 2017

Hey @robholland, first off I want to say thank you for the PR. I'm sure this is something you require for your application's use case.

My only concern with this PR is that it conflicts directly from the heroku run model in that all run commands are expected to be run inside the currently deployed application image. By supporting the idea of allowing a run command outside of the container image deployed to Workflow, we break this model. However, I understand that the alternative is an out-of-band schema migration before deploying the new image release. I know that Heroku handles this use case by running schema migrations inside the Ruby buildpack, however this is an unsolved problem with Dockerfile deploys.

What are your thoughts on all this? Is there perhaps another way we can resolve this problem while maintaining compatibility with Heroku's run model?

@robholland
Copy link
Contributor Author

An approach we considered earlier was adding a hook to require workflow to run a set command inside a new release after building, but before starting any other pods. If the command failed then the release would be rolled back (as if the readiness probe had failed etc). This would also solve this specific use case of asset compilation and may be closer to the heroku model you are trying to follow?

The downside is that you lose the flexibility that the run argument provides, any command can be run at anytime, with either previous or as-yet-unreleased versions to help find regressions/bugs in production easily. Also potentially useful for migrations, as you mention. If we create a new app, copy configuration over etc then any inferred namespaces in config settings would need adjusting to make services discoverable and so forth, it's quite a lot of overhead to achieve this with a duplicated app.

If the concern is keeping the run command pure, maybe another dedicated command would sit better? No good names are coming to mind right now.

@bacongobbler
Copy link
Member

bacongobbler commented Jan 19, 2017

I think implementing the deis hooks command you proposed in another issue (can't seem to find it now) would be the better way to resolve this use case. That way we can retain staying true to Heroku's run model while still allowing one to run post-build hooks like a schema migration before the app is deployed.

@robholland
Copy link
Contributor Author

For reference this is the issue for the hooks: deis/dockerbuilder#89

@bacongobbler
Copy link
Member

ping @robholland, are you planning on implementing deis/dockerbuilder#89 or do you still want to go ahead with this?

@vdice vdice modified the milestones: v2.12, v2.11 Jan 30, 2017
@robholland
Copy link
Contributor Author

I'm working on patches for deis/dockerbuilder#89, but there are quite a few use cases that doesn't cover, it's only suitable for commands that need to be run pre-deploy everytime. We could still really use the ability to run non-deployed revisions to avoid the need to duplicate applications in order to drain sidekiq queues and other adhoc tasks.

@codecov-io
Copy link

codecov-io commented Feb 1, 2017

Codecov Report

Merging #1208 into master will increase coverage by <.01%.

@@            Coverage Diff            @@
##           master   #1208      +/-   ##
=========================================
+ Coverage   87.29%   87.3%   +<.01%     
=========================================
  Files          43      43              
  Lines        3826    3829       +3     
  Branches      665     667       +2     
=========================================
+ Hits         3340    3343       +3     
  Misses        321     321              
  Partials      165     165

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 62673f2...09b8a3b. Read the comment docs.

@robholland
Copy link
Contributor Author

Please can I have some feedback on whether this is likely to be included in the next workflow release? We have a lot of applications which can't have their web frontend migrated to workflow until we have the ability to compile their assets during deploys.

@mboersma
Copy link
Member

mboersma commented Feb 8, 2017

I have the same concerns as @bacongobbler mentioned: this doesn't fit the heroku run model that we've tried to emulate. Pre- and post-compile hooks as described in deis/dockerbuilder#89 would be a cleaner solution, but I understand that's not trivial to implement. If there were any other way to achieve this behavior, it would be preferable and allow deis run to stay simple.

Having said that, I don't think allowing this would open any particular security issues, just create a bit of conceptual discord.

@robholland
Copy link
Contributor Author

We've implemented our requirement using an ugly kubectl run -n $APP --env="RACK_ENV=$(deis config | grep RACK_ENV ...),MEMCACHE_SERVERS=$(deis config | grep MEMCACHE_SERVERS ...)" ... style command.

Feel free to close this and related PRs if you're not happy with the run override concept.

@robholland
Copy link
Contributor Author

I should say I don't plan to work on the deploy hook PRs currently as they don't solve enough of our use cases to be worth the investment required for me to implement (I don't know django/python well and there are a lot of moving parts here).

@mboersma
Copy link
Member

mboersma commented Mar 1, 2017

@robholland I'm sorry you had to resort to the kubectl hack to accomplish this. Ultimately we considered this to break the Heroku-inspired paradigm a bit too much to be merged into master.

I apologize for dawdling on this one--it was difficult to decide. We appreciate all your contributions immensely. Let's try to implement deploy hooks for a future release, since that seems like a more consistent solution. I'll see if we can find someone to work on that soon.

This pull request was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants