Skip to content

Commit 5d0ee15

Browse files
authored
Merge branch 'develop' into jf_domain_cfg_1_rebased_with_pw_storage_and_sync
2 parents 9b16310 + 83941db commit 5d0ee15

File tree

10 files changed

+192
-37
lines changed

10 files changed

+192
-37
lines changed

README.md

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
lae.proxmox
44
===========
55

6-
Installs and configures Proxmox Virtual Environment 6.x/7.x on Debian servers.
6+
Installs and configures Proxmox Virtual Environment 6.x/7.x/8.x on Debian servers.
77

88
This role allows you to deploy and manage single-node PVE installations and PVE
99
clusters (3+ nodes) on Debian Buster (10) and Bullseye (11). You are able to
@@ -78,7 +78,7 @@ file containing a list of hosts).
7878
Once complete, you should be able to access your Proxmox VE instance at
7979
`https://$SSH_HOST_FQDN:8006`.
8080

81-
## Deploying a fully-featured PVE 7.x cluster
81+
## Deploying a fully-featured PVE 8.x cluster
8282

8383
Create a new playbook directory. We call ours `lab-cluster`. Our playbook will
8484
eventually look like this, but yours does not have to follow all of the steps:
@@ -395,7 +395,7 @@ pve_zfs_enabled: no # Specifies whether or not to install and configure ZFS pack
395395
pve_zfs_create_volumes: [] # List of ZFS Volumes to create (to use as PVE Storages). See section on Storage Management.
396396
pve_ceph_enabled: false # Specifies wheter or not to install and configure Ceph packages. See below for an example configuration.
397397
pve_ceph_repository_line: "deb http://download.proxmox.com/debian/ceph-pacific bullseye main" # apt-repository configuration. Will be automatically set for 6.x and 7.x (Further information: https://pve.proxmox.com/wiki/Package_Repositories)
398-
pve_ceph_network: "{{ (ansible_default_ipv4.network +'/'+ ansible_default_ipv4.netmask) | ipaddr('net') }}" # Ceph public network
398+
pve_ceph_network: "{{ (ansible_default_ipv4.network +'/'+ ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') }}" # Ceph public network
399399
# pve_ceph_cluster_network: "" # Optional, if the ceph cluster network is different from the public network (see https://pve.proxmox.com/pve-docs/chapter-pveceph.html#pve_ceph_install_wizard)
400400
pve_ceph_nodes: "{{ pve_group }}" # Host group containing all Ceph nodes
401401
pve_ceph_mon_group: "{{ pve_group }}" # Host group containing all Ceph monitor hosts
@@ -585,8 +585,8 @@ Refer to `library/proxmox_role.py` [link][user-module] and
585585

586586
You can use this role to manage storage within Proxmox VE (both in
587587
single server deployments and cluster deployments). For now, the only supported
588-
types are `dir`, `rbd`, `nfs`, `cephfs`, `lvm`,`lvmthin`, and `zfspool`.
589-
Here are some examples.
588+
types are `dir`, `rbd`, `nfs`, `cephfs`, `lvm`,`lvmthin`, `zfspool`, `btrfs`,
589+
and `pbs`. Here are some examples.
590590

591591
```
592592
pve_storages:
@@ -629,13 +629,28 @@ pve_storages:
629629
- 10.0.0.1
630630
- 10.0.0.2
631631
- 10.0.0.3
632+
- name: pbs1
633+
type: pbs
634+
content: [ "backup" ]
635+
server: 192.168.122.2
636+
username: user@pbs
637+
password: PBSPassword1
638+
datastore: main
632639
- name: zfs1
633640
type: zfspool
634641
content: [ "images", "rootdir" ]
635642
pool: rpool/data
636643
sparse: true
644+
- name: btrfs1
645+
type: btrfs
646+
content: [ "images", "rootdir" ]
647+
nodes: [ "lab-node01.local", "lab-node02.local" ]
648+
path: /mnt/proxmox_storage
649+
is_mountpoint: true
637650
```
638651

652+
Refer to https://pve.proxmox.com/pve-docs/api-viewer/index.html for more information.
653+
639654
Currently the `zfspool` type can be used only for `images` and `rootdir` contents.
640655
If you want to store the other content types on a ZFS volume, you need to specify
641656
them with type `dir`, path `/<POOL>/<VOLUME>` and add an entry in
@@ -734,8 +749,9 @@ pve_ceph_fs:
734749
mountpoint: /srv/proxmox/backup
735750
```
736751

737-
`pve_ceph_network` by default uses the `ipaddr` filter, which requires the
738-
`netaddr` library to be installed and usable by your Ansible controller.
752+
`pve_ceph_network` by default uses the `ansible.utils.ipaddr` filter, which
753+
requires the `netaddr` library to be installed and usable by your Ansible
754+
controller.
739755

740756
`pve_ceph_nodes` by default uses `pve_group`, this parameter allows to specify
741757
on which nodes install Ceph (e.g. if you don't want to install Ceph on all your
@@ -777,7 +793,17 @@ Jonas Meurer ([@mejo-](https://github.com/mejo-))
777793
Ondrej Flidr ([@SniperCZE](https://github.com/SniperCZE))
778794
niko2 ([@niko2](https://github.com/niko2))
779795
Christian Aublet ([@caublet](https://github.com/caublet))
796+
Gille Pietri ([@gilou](https://github.com/gilou))
780797
Michael Holasek ([@mholasek](https://github.com/mholasek))
798+
Alexander Petermann ([@lexxxel](https://github.com/lexxxel)) - PVE 8.x support, etc
799+
Bruno Travouillon ([@btravouillon](https://github.com/btravouillon)) - UX improvements
800+
Tobias Negd ([@wu3rstle](https://github.com/wu3rstle)) - Ceph support
801+
PendaGTP ([@PendaGTP](https://github.com/PendaGTP)) - Ceph support
802+
John Marion ([@jmariondev](https://github.com/jmariondev))
803+
foerkede ([@foerkede](https://github.com/foerkede)) - ZFS storage support
804+
Guiffo Joel ([@futuriste](https://github.com/futuriste)) - Pool configuration support
805+
806+
[Full list of contributors](https://github.com/lae/ansible-role-proxmox/graphs/contributors)
781807

782808
[pve-cluster]: https://pve.proxmox.com/wiki/Cluster_Manager
783809
[install-ansible]: http://docs.ansible.com/ansible/intro_installation.html

defaults/main.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ pve_zfs_enabled: no
1818
# pve_zfs_zed_email: "email address for zfs events"
1919
pve_zfs_create_volumes: []
2020
pve_ceph_enabled: false
21-
pve_ceph_repository_line: "deb http://download.proxmox.com/debian/{% if ansible_distribution_release == 'buster' %}ceph-nautilus buster{% else %}ceph-pacific bullseye{% endif %} main"
22-
pve_ceph_network: "{{ (ansible_default_ipv4.network +'/'+ ansible_default_ipv4.netmask) | ipaddr('net') }}"
21+
pve_ceph_repository_line: "deb http://download.proxmox.com/debian/{% if ansible_distribution_release == 'buster' %}ceph-nautilus buster{% else %}ceph-quincy bullseye{% endif %} main"
22+
pve_ceph_network: "{{ (ansible_default_ipv4.network +'/'+ ansible_default_ipv4.netmask) | ansible.utils.ipaddr('net') }}"
2323
pve_ceph_nodes: "{{ pve_group }}"
2424
pve_ceph_mon_group: "{{ pve_group }}"
2525
pve_ceph_mgr_group: "{{ pve_ceph_mon_group }}"

files/proxmox-release-bookworm.gpg

1.16 KB
Binary file not shown.

library/proxmox_storage.py

Lines changed: 78 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
type:
2323
required: true
2424
aliases: [ "storagetype" ]
25-
choices: [ "dir", "nfs", "rbd", "lvm", "lvmthin", "cephfs", "zfspool" ]
25+
choices: [ "dir", "nfs", "rbd", "lvm", "lvmthin", "cephfs", "zfspool", "btrfs" ]
2626
description:
2727
- Type of storage, must be supported by Proxmox.
2828
disable:
@@ -98,6 +98,11 @@
9898
required: false
9999
description:
100100
- Use ZFS thin-provisioning.
101+
is_mountpoint:
102+
required: false
103+
description:
104+
- Specifies whether or not the given path is an externally managed
105+
mountpoint.
101106
102107
author:
103108
- Fabien Brachere (@fbrachere)
@@ -154,6 +159,17 @@
154159
- 10.0.0.1
155160
- 10.0.0.2
156161
- 10.0.0.3
162+
- name: Create a Proxmox Backup Server storage type
163+
proxmox_storage:
164+
name: pbs1
165+
type: pbs
166+
content: [ "backup" ]
167+
server: 192.168.122.2
168+
username: user@pbs
169+
password: PBSPassword1
170+
datastore: main
171+
fingerprint: f2:fb:85:76:d2:2a:c4:96:5c:6e:d8:71:37:36:06:17:09:55:f7:04:e3:74:bb:aa:9e:26:85:92:63:c8:b9:23
172+
encryption_key: autogen
157173
- name: Create a ZFS storage type
158174
proxmox_storage:
159175
name: zfs1
@@ -170,16 +186,27 @@
170186
from ansible.module_utils._text import to_text
171187
from ansible.module_utils.pvesh import ProxmoxShellError
172188
import ansible.module_utils.pvesh as pvesh
189+
import re
190+
import json
191+
from json import JSONDecodeError, loads as parse_json
192+
173193

174194
class ProxmoxStorage(object):
175195
def __init__(self, module):
176196
self.module = module
177197
self.name = module.params['name']
178198
self.state = module.params['state']
179-
self.type = module.params['type']
199+
# Globally applicable PVE API arguments
180200
self.disable = module.params['disable']
181201
self.content = module.params['content']
182202
self.nodes = module.params['nodes']
203+
self.type = module.params['type']
204+
# Remaining PVE API arguments (depending on type) past this point
205+
self.datastore = module.params['datastore']
206+
self.encryption_key = module.params['encryption_key']
207+
self.master_pubkey = module.params['master_pubkey']
208+
self.fingerprint = module.params['fingerprint']
209+
self.password = module.params['password']
183210
self.path = module.params['path']
184211
self.pool = module.params['pool']
185212
self.monhost = module.params['monhost']
@@ -192,7 +219,26 @@ def __init__(self, module):
192219
self.vgname = module.params['vgname']
193220
self.thinpool = module.params['thinpool']
194221
self.sparse = module.params['sparse']
195-
222+
self.is_mountpoint = module.params['is_mountpoint']
223+
224+
# Validate the parameters given to us
225+
fingerprint_re = re.compile('^([A-Fa-f0-9]{2}:){31}[A-Fa-f0-9]{2}$')
226+
if self.fingerprint is not None and not fingerprint_re.match(self.fingerprint):
227+
self.module.fail_json(msg=(f"fingerprint must be of the format, "
228+
f"{fingerprint_re.pattern}."))
229+
230+
if self.type == 'pbs':
231+
if self.content != ['backup']:
232+
self.module.fail_json(msg="PBS storage type only supports the "
233+
"'backup' content type.")
234+
try:
235+
if self.encryption_key not in ["autogen", None]:
236+
parse_json(self.encryption_key)
237+
except JSONDecodeError:
238+
self.module.fail_json(msg=("encryption_key needs to be valid "
239+
"JSON or set to 'autogen'."))
240+
241+
# Attempt to retrieve current/live storage definitions
196242
try:
197243
self.existing_storages = pvesh.get("storage")
198244
except ProxmoxShellError as e:
@@ -227,6 +273,16 @@ def prepare_storage_args(self):
227273
args['nodes'] = ','.join(self.nodes)
228274
if self.disable is not None:
229275
args['disable'] = 1 if self.disable else 0
276+
if self.datastore is not None:
277+
args['datastore'] = self.datastore
278+
if self.encryption_key is not None:
279+
args['encryption-key'] = self.encryption_key
280+
if self.fingerprint is not None:
281+
args['fingerprint'] = self.fingerprint
282+
if self.master_pubkey is not None:
283+
args['master-pubkey'] = self.master_pubkey
284+
if self.password is not None:
285+
args['password'] = self.password
230286
if self.path is not None:
231287
args['path'] = self.path
232288
if self.pool is not None:
@@ -251,6 +307,8 @@ def prepare_storage_args(self):
251307
args['thinpool'] = self.thinpool
252308
if self.sparse is not None:
253309
args['sparse'] = 1 if self.sparse else 0
310+
if self.is_mountpoint is not None:
311+
args['is_mountpoint'] = 1 if self.is_mountpoint else 0
254312

255313
if self.maxfiles is not None and 'backup' not in self.content:
256314
self.module.fail_json(msg="maxfiles is not allowed when there is no 'backup' in content")
@@ -321,13 +379,20 @@ def main():
321379
# Refer to https://pve.proxmox.com/pve-docs/api-viewer/index.html
322380
module_args = dict(
323381
name=dict(type='str', required=True, aliases=['storage', 'storageid']),
382+
state=dict(default='present', choices=['present', 'absent'], type='str'),
383+
# Globally applicable PVE API arguments
324384
content=dict(type='list', required=True, aliases=['storagetype']),
385+
disable=dict(required=False, type='bool', default=False),
325386
nodes=dict(type='list', required=False, default=None),
326387
type=dict(default=None, type='str', required=True,
327388
choices=["dir", "nfs", "rbd", "lvm", "lvmthin", "cephfs",
328-
"zfspool"]),
329-
disable=dict(required=False, type='bool', default=False),
330-
state=dict(default='present', choices=['present', 'absent'], type='str'),
389+
"zfspool", "btrfs", "pbs"]),
390+
# Remaining PVE API arguments (depending on type) past this point
391+
datastore=dict(default=None, type='str', required=False),
392+
encryption_key=dict(default=None, type='str', required=False),
393+
fingerprint=dict(default=None, type='str', required=False),
394+
master_pubkey=dict(default=None, type='str', required=False),
395+
password=dict(default=None, type='str', required=False),
331396
path=dict(default=None, required=False, type='str'),
332397
pool=dict(default=None, type='str', required=False),
333398
monhost=dict(default=None, type='list', required=False),
@@ -340,6 +405,7 @@ def main():
340405
vgname=dict(default=None, type='str', required=False),
341406
thinpool=dict(default=None, type='str', required=False),
342407
sparse=dict(default=None, type='bool', required=False),
408+
is_mountpoint=dict(default=None, type='bool', required=False),
343409
)
344410

345411
module = AnsibleModule(
@@ -353,7 +419,12 @@ def main():
353419
["type", "lvm", ["vgname", "content"]],
354420
["type", "lvmthin", ["vgname", "thinpool", "content"]],
355421
["type", "zfspool", ["pool", "content"]],
356-
]
422+
["type", "btrfs", ["path", "content"]],
423+
["type", "pbs", ["server", "username", "password", "datastore"]]
424+
],
425+
required_by={
426+
"master_pubkey": "encryption_key"
427+
}
357428
)
358429
storage = ProxmoxStorage(module)
359430

meta/main.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ galaxy_info:
1313
versions:
1414
- buster
1515
- bullseye
16+
- bookworm
1617

1718
galaxy_tags:
1819
- proxmox

module_utils/pvesh.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ def run_command(handler, resource, **params):
5656

5757
if handler == "get":
5858
if any(re.match(pattern, stderr[0]) for pattern in [
59-
"^no such user \('.{3,64}?'\)$",
60-
"^(group|role|pool) '[A-Za-z0-9\.\-_]+' does not exist$",
61-
"^domain '[A-Za-z][A-Za-z0-9\.\-_]+' does not exist$"]):
59+
r"^no such user \('.{3,64}?'\)$",
60+
r"^(group|role|pool) '[A-Za-z0-9\.\-_]+' does not exist$",
61+
r"^domain '[A-Za-z][A-Za-z0-9\.\-_]+' does not exist$"]):
6262
return {u"status": 404, u"message": stderr[0]}
6363

6464
# This will occur when a param is invalid

tasks/ceph.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@
241241
path: '{{ item.mountpoint }}'
242242
src: |-
243243
{% for h in groups[pve_ceph_mon_group] -%}
244-
{{ hostvars[h].ansible_all_ipv4_addresses | ipaddr(pve_ceph_network) | first -}}
244+
{{ hostvars[h].ansible_all_ipv4_addresses | ansible.utils.ipaddr(pve_ceph_network) | first -}}
245245
{{ loop.last | ternary("", ",") -}}
246246
{% endfor %}:/
247247
fstype: 'ceph'

0 commit comments

Comments
 (0)