Using the Ansible Find Command

The “find” command was added to Ansible in version 2. Here is how I used it to change the permissions on some log files:

- name: Get all log files in django dir
    paths: "{{ django_manage_path }}"
    patterns: "*.log"
    recurse: yes
  register: files_to_change

- name: Make sure Django log files in dir are owned by vagrant
  become: yes
  file: path={{ item.path }} owner=vagrant group=admin mode=0660
  with_items: "{{ files_to_change.files }}"

Ansible Could Not Find Templates After Migration from 1.9 to 2.5

I had a playbook that included a task from another role like this:

  - include: roles/django/tasks/create_server_settings.yml

This include stopped working when I migrated from Ansible 1.9 to 2.5. The task used the “template” command and Ansible could not find the template. It looked in:

  • roles/django/tasks/templates/
  • roles/django/tasks/

I am using the recommended directory structure with the tasks and templates directories both at the same level in the directory tree, in this case:

  • roles/django/templates/

Switching to the command:

  - include_tasks: roles/django/tasks/create_server_settings.yml

did NOT help.

The solution was to use this command:

  - include_role:
      name: django
      tasks_from: create_server_settings

Fixing Hg Mistakes

Removing Pushes from Other Branches

I often create a branch by cloning. I do more involved or experimental things in the clone. While the parent branch is available to make small minor updates. As code in the branch progresses, I do commits. And every once in a while, by accident, I do a commit and push. This puts the experimental code in the main branch before its ready. To remove the pushed change set, cd into main and do:

hg strip -r REV


Django HTTP 404 Not Found Error

So you’ve got everything working on the Django dev server. Almost everything is working on the staging server… except one URL that sometimes fails with an HTTP 404 Not Found error. What is going on here?

More details; it happens to be a Django form page. The page loads with a problem. The problem occurs after you submit the form. The URL that causes the 404 error is the URL of the form. What is going on here?

In my case, the form_valid() was doing a lot of processing of the form data and the server was timing out. Maybe part of the reason I did not catch this earlier is my dev server is much faster than the Digital Ocean droplet I was using.

Python Dates and Times Cheatsheet

Python (2.7) datetimes are a little frustrating because there are many ways to do each manipulation and there are many applicable 3rd party libraries. Below are code snippets that I think show the best solution. While I appreciate the concept of minimizing dependencies, there are some 3rd party libraries that are so useful, that I just include them as requirements on all my projects.

Aware UTC Now

import datetime

import pytz

now = pytz.utc.localize(datetime.datetime.utcnow())

Aware Now in Timezone

The code below will create an aware time in US/Pacific time regardless of the time zone the machine is running in.

import datetime

import pytz

now ='US/Pacific'))

To String and Back

This comes up a lot because json has issues serializing datetimes.

import datetime
import dateutil.parser
import json

aware_dt = pytz.utc.localize(datetime.datetime.utcnow())
as_string = aware_dt.isoformat()
aware_dt = dateutil.parser.parse(as_string)

# If all you want to do is serialize, a quick and dirty solution is to use the 
# "default" keyword to have json automatically convert the datetime to a string. 
# The downside is you need to manually convert the string back to a date
as_json = json.dumps({'my_date': aware_dt}, default=str)
back_again = json.loads(as_json)
back_again['my_date'] = dateutil.parser.parse(back_again['my_date'])

Epoch Time

One problem with datetimes is they do not work will with json. One solution is to save the date and time as a float. Converting to a datetime is pretty easy.

import time
import datetime
import pytz

a_float = time.time()
structTime = time.localtime(a_float)
as_datetime = datetime.datetime(*structTime[:6])

# To UTC
structTime = time.gmtime(a_float)  
naive_UTC = datetime.datetime(*structTime[:6])
aware_UTC = pytz.utc.localize(naive_UTC)
chicago = pytz.timezone('America/Chicago')
chicago_datetime = aware_UTC.astimezone(chicago)