Dynamic first boot scripts with Imagr and Flask05 Jan 2016
Some may wonder why you would go to the trouble of dynamically generating first boot scripts. I mean, how many can you need?
Let’s say you have ten sites, each with five builds - that fifty first boot scripts to maintain already. It’s entirely possible that they’re all the same, so you could use Imagr’s ability to use a script from a central URL. But you also may need to make slight tweaks depending on what type of machine it is and where it is located.
Over the next few posts, we are going to build an app using the Flask framework that will:
- Read in headers sent by Imagr to return a dynamically generated first boot script
- Create a Munki manifest for the Mac
- Wrap up the application into a Docker image so it can be easily deployed
Let’s get started
The first thing we are going to do is to set up a virtual env. We are using Python to create our app and putting our dependencies in a virtual env means that we are not potentially messing up our system.
Now we can start building our app. Assuming you are going to keep your app in
And now we need to switch to using the Python in the virtualenv rather than the system one
Now we can install our first dependency - Flask itself. Pip is the package manager that is installed in every new virtualenv you create. It’s pretty easy to use:
Now Flask is installed, we can start on the web app. Crack open your favourite editor (not textedit! Python is picky about spaces) and create the following file:
And now we can run it:
Now head over to
http://localhost:5000 in a browser and…
Yeah! Your first flask app! But we will be wanting to restrict who can access this. We are going to implement basic HTTP authentication to give our app some protection. Make your
bootstrap.py look like the below:
We’ve made a couple of changes here. We’ve enabled debug mode - this throws up more useful errors in the unlikely event I make a mistake (ahem). When we move into production, we will want to disable this for security reasons.
We have also added a few functions that will let us add basic authentication. If you would like to change the username from
admin and password from
secret, change the values at the end of
When we run this with Docker, we’ll use environment variables to pass in the username and password, but for now we’ll use command line options. Add this in below
DEBUG=True and above
def check_auth(username, password):
def check_auth to look like:
Now you can pass in your own username and password when you run your development server:
That’s all there is to adding basic authentication to our app. Next time we’ll start looking at using headers sent by Imagr to serve up the customised script to our clients.
And for those following along at home, here’s our code after part 1: