Let’s say that we want to keep our system updated with some code which is not distributed as a regular package, but as a code in a repository (which unfortunately, it’s a pretty common situation).
As a part of the ansible playbooks used for the hosts, I can add a snippet like this:
gitrepos:
- {
url: "https://github.com/myrepo/repo.git",
tag: "tagtocheckout",
folder: "/root/path-for-check-out",
chdir: "subdir to enter",
build: "make build",
exec: "build/mybuiltbinary",
}
With this definition in the host inventory, we can then in our playbook to perform several steps:
First Checkout the repository, note that we loop over
gitreposvariable and use the items defined. We also setignore_errorsto ensure our playbook run doesn’t halt in case of any mistake here.Also, we register the output in the
reposvariable for later processing (we’ll see why later).- name: Checkout git repos at specific versions git: repo: "{{ item.url }}" dest: "{{ item.folder }}" version: "{{ item.tag}}" with_items: "{{ gitrepos }}" ignore_errors: true register: repos when: gitrepos != FalseNext, as we’ll be building the binary from the repo, we want to make sure that previous built ones are absent, so that we can force rebuilding it.
Note that were appending the
chdirpath if it’s defined… it’s a special use case, because some repositories, contain different set of code in sub-folders instead of being on different repositories, so this helps in this situation. Of course, we’re doing this, only when a new release has been checked out in prior step (repos.changed).- name: Remove previous binary if tag changed to get it recompiled file: name: "{{ item.folder }}/{% if item.chdir is defined %}/{{item.chdir}}{% endif %}{{ item.exec }}" state: absent when: repos.changed with_items: "{{ gitrepos }}"Now we’re ready to build the code, as we’ve defined also the
chdirwe get into the relevant folder and run thebuildcommand to generate the binary… as a result it must create a binary initem.execso that we can validate it worked or not and of course, only if we’ve defined a build command.- name: Build git repos shell: cmd: "{{ item.build }}" chdir: "{{ item.folder }}{% if item.chdir is defined %}/{{item.chdir}}{% endif %}" creates: "{{ item.exec }}" with_items: "{{ gitrepos }}" ignore_errors: true when: gitrepos != False and item.build is defined and item.build != FalseLast step… as we got the binary built, we might want to copy it to a folder into our path so that it can be used, in this example, to the
go/binfolder:- name: copy built command copy: remote_src: yes dest: "/root/go/bin/" src: "{{item.folder}}{% if item.chdir is defined %}/{{item.chdir}}{% endif %}/{{ item.exec }}" mode: "0755" with_items: "{{ gitrepos }}" ignore_errors: true when: gitrepos != False and item.build is defined and item.build != False
By defining several repo stanzas, we can automate the process… and this is just the first step, as we can also define the checkout tag by first querying the repo latest release (if we want to live on the bleeding edge), so this whole process keeps your system using latest tools available, and built from source.
Enjoy! (and if you do, you can
Buy Me a Coffee
)