Cluster-wide Proxmox pmxcfs locks
Project description
pmxlock
Python classes and CLI tools for cluster-wide Proxmox pmxcfs locks.
Installation
Use pip for install:
pip install pmxlock
CLI usage
Start simple command:
pmxlock mylockname echo hello
or
python3 -m pmxlock mylockname echo hello
Only one command with mylockname lock can run in current time in cluster.
Other commands will be blocked until current command completes.
You can exit with failure code instead of blocking.
Use -n flag for nonblocking mode.
Failure exit code is 1 by default. Use -E flag for other failure code:
pmxlock -n -E2 mylockname echo hello
Command above exits with code 2 if mylockname already acquired.
You can use timeout mode also:
pmxlock -w10 mylockname echo hello
Command above waits no more than 10 seconds and exits with code 1 if
mylockname cannot be acquired.
If command has options use -- before command in order stop options parsing by
pmxlock:
pmxlock mylockname -- echo -n hello
For mylockname-lock pmxlock uses node-wide /run/lock/pmxlock/mylockname
flock and cluster-wide /etc/pve/priv/lock/mylockname pmxcfs-lock. If pmxlock
terminated abnormaly (e.g. SIGKILL) /etc/pve/priv/lock/mylockname pmxcfs-lock
will remain locked for pmxcfs timeout period (currently 120 seconds hardcoded
in Proxmox). Other process on the same node can acquire orphaned lock
without waiting. You can use pmxlock-gc cli command for clean all orphaned
locks on current node.
pmxlock-gc
or
python3 -m pmxlock.gc
Class usage
Cluster-wide lock implemented by ClusterLock class:
from pmxlock import ClusterLock
lock = ClusterLock("mylockname")
Short operation in blocking mode:
lock.acquire()
try:
# Your operation should be short or timeouted.
# Hardcoded proxmox timeout == 120 seconds.
# Take overheads into account and use shorter timeout
do_work(timeout=0.8 * 120)
finally:
lock.release()
ClusterLock lock implements context manager protocol for blocking mode:
with ClusterLock("mylockname"):
do_work(timeout=0.8 * 120)
For long operations you need to use lock.update() regularly.
You can use subprocess for it:
import subprocess
with ClusterLock("mylockname") as lock:
proc = subprocess.Popen(command)
while True:
try:
proc.wait(0.8 * 120)
break
except subprocess.TimeoutExpired:
lock.update()
You can start operation in nonblocking mode:
if lock.acquire(blocking=False):
try:
do_work()
finally:
lock.release()
else:
cannot_acquire_lock()
And timeout mode:
if lock.acquire(timeout=10):
try:
do_work()
finally:
lock.release()
else:
cannot_acquire_lock()
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pmxlock-1.1.0.tar.gz.
File metadata
- Download URL: pmxlock-1.1.0.tar.gz
- Upload date:
- Size: 23.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.9.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9330b1fc63ac6acd7f6e5b37f843d1898dd121c021053bf1c4742b5099428d26
|
|
| MD5 |
437374f3641db79702f93e486ae082c9
|
|
| BLAKE2b-256 |
bf4e3a99f811e26b3775c59e503bc57c61ceefb565ee9232014f8ae0f25d4e9e
|
File details
Details for the file pmxlock-1.1.0-py3-none-any.whl.
File metadata
- Download URL: pmxlock-1.1.0-py3-none-any.whl
- Upload date:
- Size: 18.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.9.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ddd1029e4ce7d2cc93f4915e41bc2d43d434fa27b5c91f55d08280f502dc440
|
|
| MD5 |
0aad3a8887d43bf4aa22ab38e41c1e58
|
|
| BLAKE2b-256 |
7772e181ab34c428c27e792375f37eac537ae6931655b6ec2836e9758e410ea5
|