How should I implement continuous integration on my new application? Currently, this is how we're pushing to production - please bear with me, I know this is far from sane:
From local, git push origin production (the production codebase is kept on the production branch, modifications are either written directly there and committed, or files are checked out individually from another branch. Origin is the remote production server)
On the remote box, sudo stop gunicorn (application is running as a process)
cp ~/flaskgit/application.py ~/flask/applicaion.py (the git push origin from local pushes to an init -bare repo with a post-update hook that populates the files in ~/flaskgit. ~/flask is where the gunicorn service runs the application under a virtualenv)
sudo start gunicorn
we do our testing with the ~/flaskgit code running on a different port. once it looks good we do the CP
I would love to have something more fluid. I have used jenkins in the past, and loved the experience - but didn't set it up.
What resources / utilities should I look up in order to do this well?
Thank you!
buildbot, jenkins/hudson but these give you continuous integration in the sense you can run a "make" equivalent with every code base change through a commit hook. You could also look at vagrant if there is something there for you for creating repeatable vm's wrt to config/setup. Could tie it with a commit hook.
Related
We have python services running in pods in a kubernetes cluster. The services are setup to receive their log-level from an environment variable. Those env vars are set during the deployment of the service in a gitlab pipeline. For debugging purposes I want to be able to just change the env var on a single pod and restart it, without having to redeploy the service from gitlab.
Before we moved to kubernetes, we were running our containers in rancher, where the described change was very easy to do in the GUI. Change the env var -> hit update -> container restarts automatically.
I found this article that suggest to change the replica set using a command like
kubectl set env rs [REPLICASET_NAME] [ENV_VAR]=[VALUE]
And then terminating the pod, after which it will be recreated with the env var set accordingly.
But it also states to
Never do it on a production system.
Never even do this on a dev environment without taking care in how it may impact your deployment workflow.
Is that the only / best way to achieve my goal of quickly changing an env var in a running pod for debug purposes?
Is that the only / best way to achieve my goal of quickly changing an
env var in a running pod for debug purposes?
Short answer: Yes.
Long answer: I've never used or read up on Rancher, but I suspect that it was also changing the ReplicaSet or Deployment template env var, which triggered a Pod update. It's really the only way to change an env var in a Pod. You can't change the env vars on a running container or a running Pod. You can't do that in Docker containers, and you can't do it in Kubernetes, so I assume that you can't do it in Rancher. You can only restart a Pod with a different spec.
Why?
Because containers are just processes running on the host machine. Once the process is started, it's not possible to change a process's environment without resorting to nasty hacks.
If you're just concerned about the warnings that state to not do this in dev or prod, I would say that the same warnings apply to the Rancher workflow you described, so if you were willing to take the risks there, it won't be any different here.
Something I do frequently to define my environment variables in the deployment spec. Then while the deployment is running I am able to just do
kubectl edit deployment <name>
and change the environment variables that I want this will restart the pod though but for my development purposes it's typically okay.
If the environment variable is baked into the image though then you will need to either rebuild the image and restart the pod (which will pull the image) or use some of the suggestions others have stated here.
I am coming from a Java/Tomcat background and was wondering if there is anything out there which could be similar to the Tomcat manager application?
I'm imagining a webapp that I can use to easily deploy and un-deploy Flask based webapps. I guess an analogy to Tomcat would be a WSGI server with a web based manager.
Unfortunately, the deployment story for Python / WSGI is not quite as neat as Java's WAR file based deployment. (And, while Python is not Java that doesn't mean that WAR file deployments aren't nice). So you don't have anything that will quite match your expectations there - but you may be able to cobble together something similar.
First, you'll want a web server that can easily load and unload WSGI applications without requiring a server restart - the one that immediately jumps to mind is uwsgi in emperor mode (and here's an example setup).
Second, you need a consistent way lay out your applications so the WSGI file can be picked up / generated. Something as simple as always having a root-level app.wsgi file that can be copied to the directory being watched by uwsgi will do.
Third, you'll need a script that can take a web application folder / virtualenv and move / symlink it to the "available applications" folder. You'll need another one that can add / symlink, touch (to restart) and remove (to shutdown) the app.wsgi files from the directory(ies) that uwsgi is watching for new vassel applications. If you need to run it across multiple machines (or even just one remote machine) you could use Fabric.
Fourth and finally, you'll need a little web application to enable you to manage the WSGI files for these available applications without using the command line. Since you just spent all this time building some infrastructure for it, why not use Flask and deploy it on itself to make sure everything works?
It's not a pre-built solution, but hopefully this at least points you in the right direction.
I commit every time I make some changes that I think might work: I don't do extensive testing before a commit. Also, my commits will soon be automatically pushed to a remote repository. (I'm the only developer, and I have to add features or rewrite parts of the code many times a day.)
I'd like to set up a remote computer to run regression tests automatically whenever I commit anything; and then email me back the differences report.
What's the easiest way to set this up?
All my code is in Python 3. My own system is Windows 7, ActiveState Python, TortoiseHG, and Wing IDE. I can set up the remote computer as either Linux or Windows. The application is all command-line, with text input and output.
Use a continious integration server such as Buildbot or Jenkins and configure it to monitor the repository. Then run the tests using that. Buildbot is written in Python so you should feel right at home with it.
If you feel it's wasteful to make Buildbot or Jenkins poll the repository (even though hg pull uses very few resources when there are no new changesets), then you can configure a changegroup hook in the repository to trigger a build in the CI server.
I would recommend setting up Buildbot. You can have it watch a remote repository (Mercurial is supported) and automatically kick off a build when the repository changes. In your case, a build would just be running your test suite.
Its waterfall display allows you to see which builds failed and when, in relation to commits from the repository. It can even notify you, with the offending commit, when something breaks.
Jenkins is another option, supporting most of the same features. There are even cloud hosting options, like ShiningPanda that can host it for you, and they offer free licensing for open-source projects.
I am creating a app on Google app engine and am wondering if there are ways to do automated testing with python.
Thanks!
We are generally not testing too much. We once had a "80% test coverage" rule but found this doesn't make us better or faster. Most code and data structures we use are designed quite defensively so there is seldom harm which can't be undone. Our users prefer fast turnaround times to 100% uptime.
We have two apps setup: my app.appspot.com and my app-test.appspot.com. The whole codebase is designer to ensure app-test.appspot.com never changes state in external systems.
occasionally we copy the data from app.appspot.com to app-test.appspot.com. It can get messy, because id generation counters for the datastore don't get updated but it works good enough.
We develop on both systems. Frontend development is done mostly on app.appspot.com and experiments with the backend are done on app-test.appspot.com.
We have three branches: master, rc and production.rc gets updated from master and production from rc. rc is deployed daily to rc.app.appspot.com by or operations them. production is deployed weekly to production.app.appspot.com (which is also reachable via an other app name.
Developers usually deply to dev-whoami.app.appspot.com for experimenting. We use the development server very little because wee need a lot of data from the datastore.
Now to testing: we mostly use acceptance tests. We have a little framework called resttest_dsl which we use to describe tests like this:
client.GET('/').responds_access_denied()
client.GET('/', auth='user').responds_html()
client.GET('/admin').responds_access_denied()
client.GET('/admin', auth='user').responds_access_denied()
client.GET('/admin', auth='admin').responds_html()
client.GET('/artikel/').responds_with_html_to_valid_auth()
client.GET('/artikel/?q=Ratzfratz', auth='user').responds_html()
client.GET('/api/ic/v3/a/14600/03/zukunft.json').responds_with_json_to_valid_auth()
client.GET('/kunden/SC50313/o/SO1194829/', auth='user').responds_html()
client.GET('/api/masterdata/artikel/v2/artnr/14600/bild=s210').redirects_to('...')
hostname and credentials have defaults but can be overwritten by environment variables. Most errors we ever have fixed have a regression test in there. We use Makefiles to drive the whole stuff. Eg.g:
deploy:
appcfg.py update -V dev-`whoami` -A app .
TESTHOST=dev-`whoami`.app.appspot.com make resttest
open http://dev-`whoami`.app.appspot.com/
Deployment always happens from the central git repository like this:
deploy_production:
rm -Rf tmp
mkdir tmp
(cd tmp ; git clone git#github.com:user/app.git)
(cd tmp/app ; git checkout production ; make dependencies)
(cd tmp/app ; git show-ref --hash=7 refs/remotes/origin/production > version.txt)
appcfg.py update -V "v`cat tmp/app/version.txt`" -A app tmp/app
(cd tmp/huWaWi ; TESTHOST="v`cat version.txt`".app.appspot.com make resttest)
appcfg.py update -V production -A app tmp/app
appcfg.py backends -V production -A app tmp/huWaWi app
We first deploy to a version tagged with the current revision on AppEngine. We then run resttest.py against this freshly deployed version. On failure the mmake stops execution. If no failure occurred the "production version" is deployed.
We also run mandantory pep8, pyflakes and pylint checks on source code checkin.
All in all we have very simple minded tests but run them a lot and against production code and data. For us this catches most of error we make which relatively little effort.
I use gaeunit - http://code.google.com/p/gaeunit/ - which may or may not suit your needs but once its going it's pretty easy to add to. I also added an xml output so that I can stuff the results back into a junit analyser so my jenkins can report back after code checkins that nothing broke.
David Robinson refers to the development unit testing.
If you are looking for automated user(production) testing using python, go for selenium rc or selenium webdriver(improved version & standalone).
You can do wonders with selenium RC.
Refer to http://seleniumhq.org/projects/webdriver/
I have tried following guides like this one but it just didnt work for me.
So my question is this: What is a good guide for deploying Django, and how do you deploy your Django.
I keep hearing that capastrano is pretty nifty to use, but i have no idea as to how to work it or what it does (apart from automation of deploying code), or even if i want/need to use it or not.
mod_wsgi in combination with a virtualenv for all the dependencies, a mercurial checkout into the virtualenv and a fabric recipe to check out the changes on the server.
I wrote an article about my usual workflow: Deploying Python Web Applications. Hope that helps.
I have had success with mod_wsgi
In my previous work we had real genius guy on deployment duties, he deployed application (Python, SQL, Perl and Java code) as set of deb files built for Ubuntu. Unfortunately now, I have no such support. We are deploying apps manually to virtualenv-ed environments with separate nginx configs for FastCGI. We use paver to deploy to remote servers. It's painful, but it works.
This looks like a good place to start: http://www.unessa.net/en/hoyci/2007/06/using-capistrano-deploy-django-apps/
I use mod_python, and have every site in a git repository with the following subdirs:
mysite
template
media
I have mysite/settings.py in .gitignore, and work like this:
do development on my local machine
create remote repository on webserver
push my changes to webserver repo
set up apache vhost config file, tweak live server settings.py
run git checkout && git reset --hard && sudo /etc/init.d/apache2 restart on webserver repo to get up-to-date version to its working copy and restart apache
repeat steps 1, 3 and 5 whenever change request comes
The easiest way would be to use one of the sites on http://djangofriendly.com/hosts/ that will provide the hosting and set up for you, but even if you're wanting to roll your own it will allow you to see what set up other sites are using.