Skip to content

Commit dffa5e2

Browse files
author
bar
committed
Add DMG apps installer
1 parent 79a49c7 commit dffa5e2

File tree

4 files changed

+73
-1
lines changed

4 files changed

+73
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ If you need to supply an SSH password (if you don't use SSH keys), make sure to
4242

4343
### Running a specific set of tagged tasks
4444

45-
You can filter which part of the provisioning process to run by specifying a set of tags using `ansible-playbook`'s `--tags` flag. The tags available are `dotfiles`, `homebrew`, `mas`, `extra-packages` and `osx`.
45+
You can filter which part of the provisioning process to run by specifying a set of tags using `ansible-playbook`'s `--tags` flag. The tags available are `dotfiles`, `homebrew`, `mas`, `dmg`, `extra-packages` and `osx`.
4646

4747
ansible-playbook main.yml -K --tags "dotfiles,homebrew"
4848

default.config.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ mas_installed_apps: []
8282
mas_email: ""
8383
mas_password: ""
8484

85+
dmg_installed_apps: []
86+
# - name: iTerm
87+
# app_name: iTerm.app # Optional, if the .app file inside the DMG is different from the 'name'.
88+
# url: https://iterm2.com/downloads/stable/iTerm2-3_5_2.dmg
89+
8590
osx_script: "~/.osx --no-restart"
8691

8792
# Install packages from other package managers.

main.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
tags: ['dock']
2828

2929
tasks:
30+
- import_tasks: tasks/dmg.yml
31+
when: dmg_installed_apps
32+
tags: ['dmg']
33+
3034
- import_tasks: tasks/sudoers.yml
3135
when: configure_sudoers
3236
tags: ['sudoers']

tasks/dmg.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
- name: "Install {{ item.name }} from DMG."
3+
loop: "{{ dmg_installed_apps }}"
4+
loop_control:
5+
label: "{{ item.name }}"
6+
block:
7+
- name: "Check if {{ item.name }} is already installed"
8+
ansible.builtin.stat:
9+
path: "/Applications/{{ item.app_name | default(item.name + '.app') }}"
10+
register: app
11+
12+
- when: not app.stat.exists
13+
block:
14+
- name: "Download DMG for {{ item.name }}."
15+
ansible.builtin.get_url:
16+
url: "{{ item.url }}"
17+
dest: "/tmp/{{ item.name | urlencode }}.dmg"
18+
mode: '0644'
19+
20+
- name: "Mount DMG for {{ item.name }}."
21+
ansible.builtin.command: hdiutil attach -nobrowse "/tmp/{{ item.name | urlencode }}.dmg"
22+
register: mount_result
23+
changed_when: true
24+
25+
- name: "Find the mount point of {{ item.name }} DMG."
26+
ansible.builtin.set_fact:
27+
mount_point: "{{ mount_result.stdout_lines | select('match', '^/dev/disk.*') | map('split', '\t') | map('last') | first }}"
28+
29+
- name: "Find the '.app' file in the mounted {{ item.name }} DMG volume."
30+
ansible.builtin.find:
31+
paths: "{{ mount_point }}"
32+
patterns: "*.app"
33+
file_type: directory
34+
recurse: no
35+
register: find_app_result
36+
37+
- name: "Fail if no '.app' file is found."
38+
ansible.builtin.fail:
39+
msg: "Could not find an '.app' file in the DMG for {{ item.name }} at {{ mount_point }}."
40+
when: find_app_result.files | length == 0
41+
42+
- name: "Set the source application path for {{ item.name }}."
43+
ansible.builtin.set_fact:
44+
source_app_path: "{{ find_app_result.files[0].path }}"
45+
46+
- name: "Copy {{ item.name }}.app to /Applications directory."
47+
ansible.builtin.command: "cp -R \"{{ source_app_path }}\" /Applications/"
48+
args:
49+
creates: "/Applications/{{ source_app_path | basename }}"
50+
changed_when: true
51+
52+
always:
53+
- name: "Unmount volume for {{ item.name }}."
54+
ansible.builtin.command: "hdiutil detach \"{{ mount_point | default('') }}\""
55+
when: mount_point is defined and mount_point
56+
changed_when: false
57+
ignore_errors: true
58+
59+
- name: "Remove downloaded DMG for {{ item.name }}."
60+
ansible.builtin.file:
61+
path: "/tmp/{{ item.name | urlencode }}.dmg"
62+
state: absent
63+
when: not app.stat.exists

0 commit comments

Comments
 (0)