[__letsencrypt_cert] Revamp explorers, add locking.
Closes #839 See merge request ungleich-public/cdist!976 This patch joins all explorers in one to avoid starting multiple remote python processes and uses a cdist-specific lock in /tmp/certbot.cdist.lock with a 60 seconds timeout.
This commit is contained in:
		
				commit
				
					
						81b426e4e2
					
				
			
		
					 7 changed files with 87 additions and 42 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +0,0 @@
 | 
			
		|||
#!/bin/sh -e
 | 
			
		||||
 | 
			
		||||
command -v certbot 2>/dev/null || true
 | 
			
		||||
							
								
								
									
										78
									
								
								cdist/conf/type/__letsencrypt_cert/explorer/certificate-data
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										78
									
								
								cdist/conf/type/__letsencrypt_cert/explorer/certificate-data
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,78 @@
 | 
			
		|||
#!/bin/sh -e
 | 
			
		||||
certbot_path="$(command -v certbot 2>/dev/null || true)"
 | 
			
		||||
# Defaults
 | 
			
		||||
certificate_exists="no"
 | 
			
		||||
certificate_is_test="no"
 | 
			
		||||
 | 
			
		||||
if [ -n "${certbot_path}" ]; then
 | 
			
		||||
	# Find python executable that has access to certbot's module
 | 
			
		||||
	python_path=$(sed -n '1s/^#! *//p' "${certbot_path}")
 | 
			
		||||
 | 
			
		||||
	# Use a lock for cdist due to certbot not exiting with failure
 | 
			
		||||
	# or having any flags for concurrent use.
 | 
			
		||||
	_certbot() {
 | 
			
		||||
		${python_path} - 2>/dev/null <<EOF
 | 
			
		||||
from certbot.main import main
 | 
			
		||||
import fcntl
 | 
			
		||||
lock_file = "/tmp/certbot.cdist.lock"
 | 
			
		||||
timeout=60
 | 
			
		||||
with open(lock_file, 'w') as fd:
 | 
			
		||||
    for i in range(timeout):
 | 
			
		||||
        try:
 | 
			
		||||
            # Get exclusive lock
 | 
			
		||||
            fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
 | 
			
		||||
            break
 | 
			
		||||
        except:
 | 
			
		||||
            # Wait if that fails
 | 
			
		||||
            import time
 | 
			
		||||
            time.sleep(1)
 | 
			
		||||
    else:
 | 
			
		||||
        # Timed out, exit with failure
 | 
			
		||||
        import sys
 | 
			
		||||
        sys.exit(1)
 | 
			
		||||
    # Do list certificates
 | 
			
		||||
    main(["certificates", "--cert-name", "${__object_id:?}"])
 | 
			
		||||
EOF
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	_certificate_exists() {
 | 
			
		||||
		if grep -q "  Certificate Name: ${__object_id:?}$"; then
 | 
			
		||||
			echo yes
 | 
			
		||||
		else
 | 
			
		||||
			echo no
 | 
			
		||||
		fi
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_certificate_is_test() {
 | 
			
		||||
		if grep -q 'INVALID: TEST_CERT'; then
 | 
			
		||||
			echo yes
 | 
			
		||||
		else
 | 
			
		||||
			echo no
 | 
			
		||||
		fi
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_certificate_domains() {
 | 
			
		||||
		grep '    Domains: ' | cut -d ' ' -f 6- | tr ' ' '\n'
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	# Get data about all available certificates
 | 
			
		||||
	certificates="$(_certbot)"
 | 
			
		||||
 | 
			
		||||
	# Check whether or not the certificate exists
 | 
			
		||||
	certificate_exists="$(echo "${certificates}" | _certificate_exists)"
 | 
			
		||||
 | 
			
		||||
	# Check whether or not the certificate is for testing
 | 
			
		||||
	certificate_is_test="$(echo "${certificates}" | _certificate_is_test)"
 | 
			
		||||
 | 
			
		||||
	# Get domains for certificate
 | 
			
		||||
	certificate_domains="$(echo "${certificates}" | _certificate_domains)"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Return received data
 | 
			
		||||
cat <<EOF
 | 
			
		||||
certbot_path:${certbot_path}
 | 
			
		||||
certificate_exists:${certificate_exists}
 | 
			
		||||
certificate_is_test:${certificate_is_test}
 | 
			
		||||
${certificate_domains}
 | 
			
		||||
EOF
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +0,0 @@
 | 
			
		|||
#!/bin/sh -e
 | 
			
		||||
 | 
			
		||||
certbot_path=$("${__type_explorer}/certbot-path")
 | 
			
		||||
if [ -n "${certbot_path}" ]
 | 
			
		||||
then
 | 
			
		||||
	certbot certificates --cert-name "${__object_id:?}" | grep '    Domains: ' | \
 | 
			
		||||
		cut -d ' ' -f 6- | tr ' ' '\n'
 | 
			
		||||
fi
 | 
			
		||||
| 
						 | 
				
			
			@ -1,13 +0,0 @@
 | 
			
		|||
#!/bin/sh -e
 | 
			
		||||
 | 
			
		||||
certbot_path=$("${__type_explorer}/certbot-path")
 | 
			
		||||
if [ -n "${certbot_path}" ]
 | 
			
		||||
then
 | 
			
		||||
	if certbot certificates | grep -q "  Certificate Name: ${__object_id:?}$"; then
 | 
			
		||||
		echo yes
 | 
			
		||||
	else
 | 
			
		||||
		echo no
 | 
			
		||||
	fi
 | 
			
		||||
else
 | 
			
		||||
	echo no
 | 
			
		||||
fi
 | 
			
		||||
| 
						 | 
				
			
			@ -1,14 +0,0 @@
 | 
			
		|||
#!/bin/sh -e
 | 
			
		||||
 | 
			
		||||
certbot_path=$("${__type_explorer}/certbot-path")
 | 
			
		||||
if [ -n "${certbot_path}" ]
 | 
			
		||||
then
 | 
			
		||||
	if certbot certificates --cert-name "${__object_id:?}" | \
 | 
			
		||||
		grep -q 'INVALID: TEST_CERT'; then
 | 
			
		||||
		echo yes
 | 
			
		||||
	else
 | 
			
		||||
		echo no
 | 
			
		||||
	fi
 | 
			
		||||
else
 | 
			
		||||
	echo no
 | 
			
		||||
fi
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,10 @@
 | 
			
		|||
#!/bin/sh -e
 | 
			
		||||
 | 
			
		||||
certificate_exists=$(cat "${__object:?}/explorer/certificate-exists")
 | 
			
		||||
_explorer_var() {
 | 
			
		||||
	grep "^$1:" "${__object:?}/explorer/certificate-data" | cut -d ':' -f 2-
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
certificate_exists="$(_explorer_var certificate_exists)"
 | 
			
		||||
name="${__object_id:?}"
 | 
			
		||||
state=$(cat "${__object}/parameter/state")
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -29,8 +33,9 @@ case "${state}" in
 | 
			
		|||
		fi
 | 
			
		||||
 | 
			
		||||
		if [ "${certificate_exists}" = "yes" ]; then
 | 
			
		||||
			existing_domains="${__object}/explorer/certificate-domains"
 | 
			
		||||
			certificate_is_test=$(cat "${__object}/explorer/certificate-is-test")
 | 
			
		||||
			existing_domains=$(mktemp "${TMPDIR:-/tmp}/existing_domains.cdist.XXXXXXXXXX")
 | 
			
		||||
			tail -n +4 "${__object:?}/explorer/certificate-data" | grep -v '^$' > "${existing_domains}"
 | 
			
		||||
			certificate_is_test="$(_explorer_var certificate_is_test)"
 | 
			
		||||
 | 
			
		||||
			sort -uo "${requested_domains}" "${requested_domains}"
 | 
			
		||||
			sort -uo "${existing_domains}" "${existing_domains}"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
certbot_fullpath="$(cat "${__object:?}/explorer/certbot-path")"
 | 
			
		||||
certbot_fullpath="$(grep "^certbot_path:" "${__object:?}/explorer/certificate-data" | cut -d ':' -f 2-)"
 | 
			
		||||
state=$(cat "${__object}/parameter/state")
 | 
			
		||||
os="$(cat "${__global:?}/explorer/os")"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue