Skip to content

Commit c34d262

Browse files
authored
Merge pull request #69 from lae/feature/ceph-updates
A few Ceph-specific updates
2 parents 52cf2a9 + 9abe74e commit c34d262

File tree

12 files changed

+136
-137
lines changed

12 files changed

+136
-137
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
*.*~*
33
*.bak
44

5-
ansible.cfg
5+
/ansible.cfg
66
*.retry
77
/.project
88
/.pydevproject

.travis.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ env:
1515
install:
1616
- if [ "$ANSIBLE_GIT_VERSION" ]; then pip install "https://github.com/ansible/ansible/archive/${ANSIBLE_GIT_VERSION}.tar.gz";
1717
else pip install "ansible${ANSIBLE_VERSION}"; fi;
18-
pip install --pre ansible-lint; pip install jmespath
18+
pip install --pre ansible-lint; pip install jmespath netaddr
1919
- ansible --version
2020
- ansible-galaxy install lae.travis-lxc,v0.8.1
2121
- ansible-playbook tests/install.yml -i tests/inventory
@@ -25,11 +25,11 @@ before_script: cd tests/
2525
script:
2626
- ansible-lint ../ || true
2727
- ansible-playbook -i inventory deploy.yml --syntax-check
28-
- ansible-playbook -i inventory -v deploy.yml --skip skiponlxc
29-
- 'ANSIBLE_STDOUT_CALLBACK=debug unbuffer ansible-playbook --skip skiponlxc -vv
30-
-i inventory deploy.yml > idempotency.log 2>&1 || (e=$?; cat idempotency.log; exit $e)'
28+
- 'ansible-playbook -i inventory -v deploy.yml --skip skiponlxc & pid=$!; { while true; do sleep 1; kill -0 $pid 2>/dev/null || break; printf "\0"; done }'
29+
- 'ANSIBLE_STDOUT_CALLBACK=debug ANSIBLE_DISPLAY_SKIPPED_HOSTS=no ANSIBLE_DISPLAY_OK_HOSTS=no
30+
unbuffer ansible-playbook --skip skiponlxc -vv -i inventory deploy.yml &> idempotency.log'
3131
- 'grep -A1 "PLAY RECAP" idempotency.log | grep -qP "changed=0 .*failed=0 .*" &&
32-
(echo "Idempotence: PASS"; exit 0) || (echo "Idempotence: FAIL"; exit 1)'
32+
(echo "Idempotence: PASS"; exit 0) || (echo "Idempotence: FAIL"; cat idempotency.log; exit 1)'
3333
- ANSIBLE_STDOUT_CALLBACK=debug ansible-playbook -i inventory -v test.yml
3434
notifications:
3535
webhooks:

README.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -340,9 +340,9 @@ For example:
340340
This will ask for a sudo password, then login to the `admin1` user (using public
341341
key auth - add `-k` for pw) and run the playbook.
342342

343-
That's it! You should now have a fully deployed Proxmox cluster. You may want to
344-
create Ceph storage on it afterward, which this role does not (yet?) do, and
345-
other tasks possibly, but the hard part is mostly complete.
343+
That's it! You should now have a fully deployed Proxmox cluster. You may want
344+
to create Ceph storage on it afterwards (see Ceph for more info) and other
345+
tasks possibly, but the hard part is mostly complete.
346346

347347

348348
## Example Playbook
@@ -553,6 +553,16 @@ documentation.
553553

554554
## Ceph configuration
555555

556+
*This section could use a little more love. If you are actively using this role
557+
to manage your PVE Ceph cluster, please feel free to flesh this section more
558+
thoroughly and open a pull request! See issue #68.*
559+
560+
**PVE Ceph management with this role is experimental.** While users have
561+
successfully used this role to deploy PVE Ceph, it is not fully tested in CI
562+
(due to a lack of usable block devices to use as OSDs in Travis CI). Please
563+
deploy a test environment with your configuration first prior to prod, and
564+
report any issues if you run into any.
565+
556566
This role can configure the Ceph storage system on your Proxmox hosts.
557567

558568
```
@@ -592,6 +602,9 @@ pve_ceph_fs:
592602
mountpoint: /srv/proxmox/backup
593603
```
594604

605+
`pve_ceph_network` by default uses the `ipaddr` filter, which requires the
606+
`netaddr` library to be installed and usable by your Ansible controller.
607+
595608
## Contributors
596609

597610
Musee Ullah ([@lae](https://github.com/lae), <[email protected]>) - Main developer

defaults/main.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pve_zfs_enabled: no
1717
# pve_zfs_options: "parameters to pass to zfs module"
1818
# pve_zfs_zed_email: "email address for zfs events"
1919
pve_ceph_enabled: false
20-
pve_ceph_repository_line: "{{ pve_ceph_repo }}"
20+
pve_ceph_repository_line: "deb http://download.proxmox.com/debian/{% if ansible_distribution_release == 'stretch' %}ceph-luminous stretch{% else %}ceph-nautilus buster{% endif %} main"
2121
pve_ceph_network: "{{ (ansible_default_ipv4.network +'/'+ ansible_default_ipv4.netmask) | ipaddr('net') }}"
2222
pve_ceph_mon_group: "{{ pve_group }}"
2323
pve_ceph_mds_group: "{{ pve_group }}"
@@ -43,4 +43,4 @@ pve_groups: []
4343
pve_users: []
4444
pve_acls: []
4545
pve_storages: []
46-
pve_ssh_port: 22
46+
pve_ssh_port: 22

tasks/ceph.yml

Lines changed: 95 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,4 @@
11
# This is an Ansible version of what "pveceph install" actually does
2-
- name: Configure Ceph package source
3-
apt_repository:
4-
repo: '{{ pve_ceph_repository_line }}'
5-
filename: ceph.list
6-
state: present
7-
8-
- name: Install Ceph packages
9-
apt:
10-
name:
11-
- ceph
12-
- ceph-common
13-
- ceph-mds
14-
- ceph-fuse
15-
- gdisk
16-
install_recommends: false
17-
182
- name: Install custom Ceph systemd service
193
copy:
204
src: /usr/share/doc/pve-manager/examples/ceph.service
@@ -34,79 +18,77 @@
3418
when:
3519
- "ansible_distribution_release == 'stretch'"
3620

37-
- name: Create initial Ceph config
38-
command: 'pveceph init --network {{ pve_ceph_network }}'
39-
args:
40-
creates: /etc/ceph/ceph.conf
41-
when: inventory_hostname == groups[pve_ceph_mon_group][0]
21+
- block:
22+
- name: Create initial Ceph config
23+
command: 'pveceph init --network {{ pve_ceph_network }}'
24+
args:
25+
creates: /etc/ceph/ceph.conf
4226

43-
- name: Create initial Ceph monitor
44-
command: 'pveceph mon create'
45-
args:
46-
creates: '/var/lib/ceph/mon/ceph-{{ ansible_hostname }}/'
47-
register: _ceph_initial_mon
48-
when: inventory_hostname == groups[pve_ceph_mon_group][0]
27+
- name: Create initial Ceph monitor
28+
command: 'pveceph mon create'
29+
args:
30+
creates: '/var/lib/ceph/mon/ceph-{{ ansible_hostname }}/'
31+
register: _ceph_initial_mon
4932

50-
- name: Fail if initial monitor creation failed
51-
fail:
52-
msg: 'Ceph intial monitor creation failed.'
53-
when: hostvars[groups[pve_ceph_mon_group][0]]._ceph_initial_mon is failed
33+
- name: Fail if initial monitor creation failed
34+
fail:
35+
msg: 'Ceph intial monitor creation failed.'
36+
when: _ceph_initial_mon is failed
37+
38+
when: inventory_hostname == groups[pve_ceph_mon_group][0]
5439

5540
- name: Create additional Ceph monitors
5641
command: 'pveceph mon create'
5742
args:
5843
creates: '/var/lib/ceph/mon/ceph-{{ ansible_hostname }}/'
59-
when: not inventory_hostname == groups[pve_ceph_mon_group][0]
44+
when: inventory_hostname != groups[pve_ceph_mon_group][0]
6045

6146
- name: Create Ceph OSDs
6247
command: >-
6348
pveceph osd create {{ item.device }}
64-
{{ ("block.db" in item) | ternary("--journal_dev", "") }} {{ item["block.db"] | default("") }}
49+
{% if "block.db" in item %}--journal_dev {{ item["block.db"] }}{% endif %}
6550
args:
6651
creates: '{{ item.device }}1'
6752
with_items: '{{ pve_ceph_osds }}'
6853

69-
- name: List Ceph CRUSH rules
70-
command: 'ceph osd crush rule ls'
71-
changed_when: false
72-
register: ceph_crush
73-
when: inventory_hostname == groups[pve_ceph_mon_group][0]
54+
- block:
55+
- name: List Ceph CRUSH rules
56+
command: 'ceph osd crush rule ls'
57+
changed_when: false
58+
register: _ceph_crush
59+
60+
- name: Create Ceph CRUSH rules
61+
command: >-
62+
ceph osd crush rule create-replicated
63+
{{ item.name }} default host {{ item.class | default("") }}
64+
when: item.name not in _ceph_crush.stdout_lines
65+
with_items: '{{ pve_ceph_crush_rules }}'
66+
67+
- name: List Ceph Pools
68+
command: ceph osd pool ls
69+
changed_when: false
70+
register: _ceph_pools
71+
72+
- name: Create Ceph Pools
73+
command: >-
74+
pveceph pool create {{ item.name }}
75+
{% if 'storage' in item %}
76+
--add_storages {{ item.storage }}
77+
{% endif %}
78+
{% if 'application' in item %}
79+
--application {{ item.application }}
80+
{% endif %}
81+
{% if 'rule' in item %}
82+
--crush_rule {{ item.rule }}
83+
{% endif %}
84+
{% if 'pgs' in item %}
85+
--pg_num {{ item.pgs }}
86+
{% endif %}
87+
when: item.name not in _ceph_pools.stdout_lines
88+
with_items: '{{ pve_ceph_pools }}'
7489

75-
- name: Create Ceph CRUSH rules
76-
command: >-
77-
ceph osd crush rule create-replicated
78-
{{ item.name }} default host {{ item.class | default("") }}
79-
when:
80-
- inventory_hostname == groups[pve_ceph_mon_group][0]
81-
- item.name not in ceph_crush.stdout_lines
82-
with_items: '{{ pve_ceph_crush_rules }}'
83-
84-
- name: List Ceph Pools
85-
command: ceph osd pool ls
86-
changed_when: false
87-
register: ceph_pools
8890
when: inventory_hostname == groups[pve_ceph_mon_group][0]
8991

90-
- name: Create Ceph Pools
91-
command: >-
92-
pveceph pool create {{ item.name }}
93-
{% if 'storage' in item %}
94-
--add_storages {{ item.storage }}
95-
{% endif %}
96-
{% if 'application' in item %}
97-
--application {{ item.application }}
98-
{% endif %}
99-
{% if 'rule' in item %}
100-
--crush_rule {{ item.rule }}
101-
{% endif %}
102-
{% if 'pgs' in item %}
103-
--pg_num {{ item.pgs }}
104-
{% endif %}
105-
when:
106-
- inventory_hostname == groups[pve_ceph_mon_group][0]
107-
- item.name not in ceph_pools.stdout_lines
108-
with_items: '{{ pve_ceph_pools }}'
109-
11092
- name: Create Ceph MDS servers
11193
command: pveceph mds create
11294
args:
@@ -122,60 +104,52 @@
122104
delay: 2
123105
when: _ceph_mds_create is changed
124106

125-
- name: List Ceph Filesystems
126-
command: ceph fs ls -f json
127-
changed_when: false
128-
when:
129-
- inventory_hostname == groups[pve_ceph_mon_group][0]
130-
- pve_ceph_fs | length > 0
131-
register: ceph_fs
132-
133-
- name: Create Ceph Filesystems
134-
command: >-
135-
pveceph fs create
136-
--name {{ item.name }}
137-
--add-storage {{ item.storage }}
138-
--pg_num {{ item.pgs }}
139-
register: ceph_fs_create
140-
failed_when: ceph_fs_create.stderr
141-
when:
142-
- inventory_hostname == groups[pve_ceph_mon_group][0]
143-
- item.name not in (ceph_fs.stdout | from_json | map(attribute="name"))
144-
with_items: '{{ pve_ceph_fs }}'
145-
146-
- name: Get Ceph Filesystem pool CRUSH rules
147-
command: 'ceph -f json osd pool get {{ item.0.name }}_{{ item.1 }} crush_rule'
148-
changed_when: false
149-
when:
150-
- inventory_hostname == groups[pve_ceph_mon_group][0]
151-
- pve_ceph_fs | length > 0
152-
register: ceph_fs_rule
153-
loop: '{{ pve_ceph_fs | product(["data", "metadata"]) | list }}'
154-
155-
- name: Set Ceph Filesystem pool CRUSH rules
156-
command: >-
157-
ceph osd pool set {{ item.item.0.name }}_{{ item.item.1 }} crush_rule {{ item.item.0.rule }}
158-
when:
159-
- inventory_hostname == groups[pve_ceph_mon_group][0]
160-
- item.item.0.rule != (item.stdout | from_json).crush_rule
161-
loop: '{{ ceph_fs_rule.results }}'
162-
loop_control:
163-
label: '{{ item.item.0.name }}_{{ item.item.1 }}'
164-
165-
- name: Create Ceph filesystem key
166-
command: 'ceph auth get-or-create client.{{ item.name }} osd "allow rw pool={{ item.name }}_data" mon "allow r" mds "allow rw"'
167-
register: ceph_fs_auth
168-
changed_when: '"added key" in ceph_fs_auth.stdout'
169-
when:
170-
- inventory_hostname == groups[pve_ceph_mon_group][0]
171-
- item.mountpoint is defined
172-
loop: '{{ pve_ceph_fs }}'
107+
- block:
108+
- name: List Ceph Filesystems
109+
command: ceph fs ls -f json
110+
changed_when: false
111+
when: pve_ceph_fs | length > 0
112+
register: _ceph_fs
113+
114+
- name: Create Ceph Filesystems
115+
command: >-
116+
pveceph fs create
117+
--name {{ item.name }}
118+
--add-storage {{ item.storage }}
119+
--pg_num {{ item.pgs }}
120+
register: _ceph_fs_create
121+
failed_when: _ceph_fs_create.stderr
122+
when: item.name not in (_ceph_fs.stdout | from_json | map(attribute="name"))
123+
with_items: '{{ pve_ceph_fs }}'
124+
125+
- name: Get Ceph Filesystem pool CRUSH rules
126+
command: 'ceph -f json osd pool get {{ item.0.name }}_{{ item.1 }} crush_rule'
127+
changed_when: false
128+
when: pve_ceph_fs | length > 0
129+
register: _ceph_fs_rule
130+
loop: '{{ pve_ceph_fs | product(["data", "metadata"]) | list }}'
131+
132+
- name: Set Ceph Filesystem pool CRUSH rules
133+
command: >-
134+
ceph osd pool set {{ item.item.0.name }}_{{ item.item.1 }} crush_rule {{ item.item.0.rule }}
135+
when: item.item.0.rule != (item.stdout | from_json).crush_rule
136+
loop: '{{ _ceph_fs_rule.results }}'
137+
loop_control:
138+
label: '{{ item.item.0.name }}_{{ item.item.1 }}'
139+
140+
- name: Create Ceph filesystem key
141+
command: 'ceph auth get-or-create client.{{ item.name }} osd "allow rw pool={{ item.name }}_data" mon "allow r" mds "allow rw"'
142+
register: _ceph_fs_auth
143+
changed_when: '"added key" in _ceph_fs_auth.stdout'
144+
when: item.mountpoint is defined
145+
loop: '{{ pve_ceph_fs }}'
146+
when: inventory_hostname == groups[pve_ceph_mon_group][0]
173147

174148
- name: Fetch Ceph filesystem key
175149
command: 'ceph auth print-key client.{{ item.name }}'
176150
args:
177151
creates: '/etc/ceph/{{ item.name }}.secret'
178-
register: ceph_fs_key
152+
register: _ceph_fs_key
179153
when: item.mountpoint is defined
180154
loop: '{{ pve_ceph_fs }}'
181155

@@ -187,7 +161,7 @@
187161
mode: '0600'
188162
content: '{{ item.stdout }}'
189163
when: item is changed
190-
loop: '{{ ceph_fs_key.results }}'
164+
loop: '{{ _ceph_fs_key.results }}'
191165
loop_control:
192166
label: '{{ item.item }}'
193167

tasks/identify_needed_packages.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
_pve_install_packages: "{{ _pve_install_packages | union(['zfsutils-linux', 'zfs-initramfs', 'zfs-zed']) }}"
1818
when: "pve_zfs_enabled | bool"
1919

20+
- name: Stage Ceph packages if Ceph is enabled
21+
set_fact:
22+
_pve_install_packages: "{{ _pve_install_packages | union(['ceph', 'ceph-common', 'ceph-mds', 'ceph-fuse', 'gdisk']) }}"
23+
when: "pve_ceph_enabled | bool"
24+
2025
- name: Stage any extra packages the user has specified
2126
set_fact:
2227
_pve_install_packages: "{{ _pve_install_packages | union(pve_extra_packages) }}"

tasks/main.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,20 @@
6565
state: present
6666
register: _pve_repo
6767

68+
- name: Add Proxmox Ceph repository
69+
apt_repository:
70+
repo: '{{ pve_ceph_repository_line }}'
71+
filename: ceph
72+
state: present
73+
register: _pve_ceph_repo
74+
when: "pve_ceph_enabled | bool"
75+
6876
- name: Run apt-get dist-upgrade on repository changes
6977
apt:
7078
update_cache: yes
7179
cache_valid_time: 3600
7280
upgrade: dist
73-
when: _pve_repo is changed
81+
when: _pve_repo is changed or _pve_ceph_repo is changed
7482
retries: 2
7583
register: _dist_upgrade
7684
until: _dist_upgrade is succeeded

tests/ansible.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[defaults]
2+
callback_whitelist = profile_tasks

tests/group_vars/all

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pve_run_system_upgrades: true
99
pve_watchdog: ipmi
1010
pve_zfs_enabled: yes
1111
pve_zfs_zed_email: root@localhost
12+
pve_ceph_enabled: yes
1213
pve_ssl_private_key: "{{ lookup('file', ssl_host_key_path) }}"
1314
pve_ssl_certificate: "{{ lookup('file', ssl_host_cert_path) }}"
1415
pve_cluster_enabled: yes

0 commit comments

Comments
 (0)