changeset 2041:cd51e7e31950 acme-tiny

use try/catch/finally to clean up temp dir even on error
author Violet7
date Sun, 09 Nov 2025 01:56:58 -0800
parents 389f30ed66ea
children 731c4ec1ae86
files src/luan/host/https.luan
diffstat 1 files changed, 77 insertions(+), 76 deletions(-) [+]
line wrap: on
line diff
--- a/src/luan/host/https.luan	Sun Nov 09 01:27:28 2025 -0800
+++ b/src/luan/host/https.luan	Sun Nov 09 01:56:58 2025 -0800
@@ -55,94 +55,95 @@
 			else
 				-- set up a temporary barebones nginx conf
 				-- to serve acme challenges on the domain
-
-				local temp_dir_string = "/tmp/acme_setup/"..domain
+				try
+					local temp_dir_string = "/tmp/acme_setup/"..domain
 
-				-- recursion guard, must have this to prevent
-				-- the http request from invoking this code
-				-- and causing an infinite recursion.
-				local cmd = "mkdir -p /tmp/acme_setup_locks/"
-				local s = uri("bash:"..cmd).read_text()
-				local guard_file = "/tmp/acme_setup_locks/"..domain..".lock"
-				local guard_uri = uri("file:"..guard_file)
-				if guard_uri.exists() then
-						logger.info("set_https already running for "..domain..", skipping")
-						return
-				end
+					-- recursion guard, must have this to prevent
+					-- the http request from invoking this code
+					-- and causing an infinite recursion.
+					local cmd = "mkdir -p /tmp/acme_setup_locks/"
+					local s = uri("bash:"..cmd).read_text()
+					local guard_file = "/tmp/acme_setup_locks/"..domain..".lock"
+					local guard_uri = uri("file:"..guard_file)
+					if guard_uri.exists() then
+							logger.info("set_https already running for "..domain..", skipping")
+							return
+					end
 
-				-- Clean out old temp files
-				local cmd = "rm -rf "..temp_dir_string
-				local s = uri("bash:"..cmd).read_text()
+					-- Clean out old temp files
+					local cmd = "rm -rf "..temp_dir_string
+					local s = uri("bash:"..cmd).read_text()
 
-				-- create all needed dirs at once by using
-				-- mkdir -p on the deepest nested dir (acme-challenge)
-				local webroot = temp_dir_string.."/webroot"
-				local acme_challenges = webroot.."/.well-known/acme-challenge"
-				local cmd = "mkdir -p "..acme_challenges
-				local s = uri("bash:"..cmd).read_text()
+					-- create all needed dirs at once by using
+					-- mkdir -p on the deepest nested dir (acme-challenge)
+					local webroot = temp_dir_string.."/webroot"
+					local acme_challenges = webroot.."/.well-known/acme-challenge"
+					local cmd = "mkdir -p "..acme_challenges
+					local s = uri("bash:"..cmd).read_text()
 
-				guard_uri.write("this is a recursion guard, see https.luan")
+					guard_uri.write("this is a recursion guard, see https.luan")
 
 
-				-- Create the nginx config from the template
-				local temp_dir = uri("file:"..temp_dir_string)
-				-- The *output* file, where the generated config is stored
-				local acme_nginx_file = temp_dir.child("nginx.acme_setup.conf")
-				local conf = load_file "file:startup/nginx/nginx.acme_setup.conf.luan"
-				local acme_nginx = ` conf(webroot,domain) `
-				acme_nginx_file.write(acme_nginx)
+					-- Create the nginx config from the template
+					local temp_dir = uri("file:"..temp_dir_string)
+					-- The *output* file, where the generated config is stored
+					local acme_nginx_file = temp_dir.child("nginx.acme_setup.conf")
+					local conf = load_file "file:startup/nginx/nginx.acme_setup.conf.luan"
+					local acme_nginx = ` conf(webroot,domain) `
+					acme_nginx_file.write(acme_nginx)
 
-				-- Create an index.html to search for in the logs
-				-- to verify everything is working
-				local index_file = webroot.."/index.html"
-				local cmd = "echo 'hi, testing' > "..index_file
-				local s = uri("bash:"..cmd).read_text()
+					-- Create an index.html to search for in the logs
+					-- to verify everything is working
+					local index_file = webroot.."/index.html"
+					local cmd = "echo 'hi, testing' > "..index_file
+					local s = uri("bash:"..cmd).read_text()
 
-				-- The config in ./local/nginx.conf has a directive to
-				-- glob include confs in /tmp/acme_setup/*/nginx.acme_setup.conf
-				-- so we just need to reload it so it can find the one we just made
-				local cmd = [[
-					sudo $(which nginx) -t -c "]]..luanhost_dir..[[/local/nginx.conf" && sudo $(which nginx) -s reload;
-				]]
-				local s = uri("bash:"..cmd).read_text()
-				logger.info("reload_nginx "..s)
+					-- The config in ./local/nginx.conf has a directive to
+					-- glob include confs in /tmp/acme_setup/*/nginx.acme_setup.conf
+					-- so we just need to reload it so it can find the one we just made
+					local cmd = [[
+						sudo $(which nginx) -t -c "]]..luanhost_dir..[[/local/nginx.conf" && sudo $(which nginx) -s reload;
+					]]
+					local s = uri("bash:"..cmd).read_text()
+					logger.info("reload_nginx "..s)
 
-				-- We've set up nginx to serve from our temp root, now we need to
-				-- create a *domain key*, which we then use to sign our cert.
-				local cmd = "openssl genrsa 4096 > "..key_file_str
-				local s = uri("bash:"..cmd).read_text()
-				logger.info("create domain key\n"..s)
+					-- We've set up nginx to serve from our temp root, now we need to
+					-- create a *domain key*, which we then use to sign our cert.
+					local cmd = "openssl genrsa 4096 > "..key_file_str
+					local s = uri("bash:"..cmd).read_text()
+					logger.info("create domain key\n"..s)
 
-				-- create the cert, signed with the key we just made
-				local cmd = 'openssl req -new -sha256 -key '..key_file_str..' -subj "/CN='..domain..'" > '..csr_file_str
-				local s = uri("bash:"..cmd).read_text()
-				logger.info("create cert\n"..s)
+					-- create the cert, signed with the key we just made
+					local cmd = 'openssl req -new -sha256 -key '..key_file_str..' -subj "/CN='..domain..'" > '..csr_file_str
+					local s = uri("bash:"..cmd).read_text()
+					logger.info("create cert\n"..s)
 
-				-- Finally, get our cert signed by letsencrypt.
-				local cmd = [[
-					python3 acme_tiny.py --account-key ./local/tiny_account.key \
-					--csr ]]..csr_file_str..[[ \
-					--acme-dir ]]..acme_challenges..[[ \
-				]]
-				if dry_run == true then
-					cmd = cmd.." --directory-url "..dry_run_dir_url
+					-- Finally, get our cert signed by letsencrypt.
+					local cmd = [[
+						python3 acme_tiny.py --account-key ./local/tiny_account.key \
+						--csr ]]..csr_file_str..[[ \
+						--acme-dir ]]..acme_challenges..[[ \
+					]]
+					if dry_run == true then
+						cmd = cmd.." --directory-url "..dry_run_dir_url
+					end
+					cmd = cmd.."> "..local_cer_file_str
+
+					local s = uri("bash:"..cmd).read_text()
+					logger.info("get cert signed by letsencrypt\n"..s)
+
+					-- The above http requests made by acme_tiny are the only thing
+					-- that could cause a recursion so it is safe to delete the guard here.
+
+				catch e
+					logger.error("Error setting up ACME: "..tostring(e))
+				finally
+					if guard_uri and guard_uri.exists() then
+						guard_uri.delete()
+					end
+					local cmd = "rm -rf "..temp_dir_string
+					local s = uri("bash:"..cmd).read_text()
 				end
-				cmd = cmd.."> "..local_cer_file_str
-
-				local s = uri("bash:"..cmd).read_text()
-				logger.info("get cert signed by letsencrypt\n"..s)
-
-				-- The above http requests made by acme_tiny are the only thing
-				-- that could cause a recursion so it is safe to delete the guard here.
-				guard_uri.delete()
-
-				-- Don't forget to delete the files so the nginx config
-				-- doesn't have 2 server blocks for the same site.
-
-				local cmd = "rm -rf /tmp/acme_setup/"..domain
-				local s = uri("bash:"..cmd).read_text()
-				logger.info("get cert signed by letsencrypt\n"..s)
-
 
 				-- We now have our certificate!
 				-- Now we just need to generate the nginx config