fix(linux): move captures out of protected CUPS cache
Some checks failed
Desktop Release / Bootstrap updater signing key (push) Has been cancelled
Desktop Release / Windows x64 NSIS (push) Has been cancelled
Desktop Release / Linux x64 DEB + AppImage (push) Has been cancelled
Desktop Release / Publish public desktop release (push) Has been cancelled
Some checks failed
Desktop Release / Bootstrap updater signing key (push) Has been cancelled
Desktop Release / Windows x64 NSIS (push) Has been cancelled
Desktop Release / Linux x64 DEB + AppImage (push) Has been cancelled
Desktop Release / Publish public desktop release (push) Has been cancelled
This commit is contained in:
parent
4dc1be87bb
commit
54137bdf86
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@fieldlens/print",
|
"name": "@fieldlens/print",
|
||||||
"version": "0.1.14",
|
"version": "0.1.15",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "fieldlens-print"
|
name = "fieldlens-print"
|
||||||
version = "0.1.14"
|
version = "0.1.15"
|
||||||
description = "FieldLens print-stream barcode capture companion"
|
description = "FieldLens print-stream barcode capture companion"
|
||||||
authors = ["Arrowstack"]
|
authors = ["Arrowstack"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
@ -25,7 +25,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
const SYSTEM_CUPS_SPOOL_DIR: &str = "/var/cache/cups/fieldlens-print";
|
const SYSTEM_CUPS_SPOOL_DIR: &str = "/var/lib/fieldlens-print/capture";
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
const TEST_CAPTURE_SINK_ADDR: &str = "127.0.0.1:9101";
|
const TEST_CAPTURE_SINK_ADDR: &str = "127.0.0.1:9101";
|
||||||
|
|
||||||
|
|||||||
@ -20,14 +20,14 @@ const TEST_CAPTURE_DEVICE_URI: &str = "socket://127.0.0.1:9101";
|
|||||||
const WINDOWS_PORT_NAME: &str = "FieldLensPrint-9100";
|
const WINDOWS_PORT_NAME: &str = "FieldLensPrint-9100";
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
const FIELDLENS_CUPS_SPOOL_DIR: &str = "/var/cache/cups/fieldlens-print";
|
const FIELDLENS_CUPS_SPOOL_DIR: &str = "/var/lib/fieldlens-print/capture";
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
const FIELDLENS_CUPS_FILTER: &str = r#"#!/usr/bin/python3
|
const FIELDLENS_CUPS_FILTER: &str = r#"#!/usr/bin/python3
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
CACHE = os.path.join(os.environ.get("CUPS_CACHEDIR", "/var/cache/cups"), "fieldlens-print")
|
CACHE = "/var/lib/fieldlens-print/capture"\nOWNER_UID = __FIELDLENS_OWNER_UID__\nOWNER_GID = __FIELDLENS_OWNER_GID__
|
||||||
|
|
||||||
def safe(value):
|
def safe(value):
|
||||||
value = re.sub(r"[^A-Za-z0-9._-]+", "-", value or "job").strip("-")
|
value = re.sub(r"[^A-Za-z0-9._-]+", "-", value or "job").strip("-")
|
||||||
@ -84,7 +84,13 @@ try:
|
|||||||
capture.flush()
|
capture.flush()
|
||||||
capture.close()
|
capture.close()
|
||||||
capture = None
|
capture = None
|
||||||
os.chmod(part_path, 0o644)
|
os.chmod(part_path, 0o600)
|
||||||
|
try:
|
||||||
|
os.chown(part_path, OWNER_UID, OWNER_GID)
|
||||||
|
except PermissionError:
|
||||||
|
# On this Linux lane CUPS runs filters as root. Keep printing alive
|
||||||
|
# if a future CUPS policy drops privileges; repair can surface it.
|
||||||
|
pass
|
||||||
os.replace(part_path, final_path)
|
os.replace(part_path, final_path)
|
||||||
captured_ok = True
|
captured_ok = True
|
||||||
print(f"INFO: FieldLens captured {name}", file=sys.stderr)
|
print(f"INFO: FieldLens captured {name}", file=sys.stderr)
|
||||||
@ -111,9 +117,12 @@ target_printer = sys.argv[1]
|
|||||||
target_port = sys.argv[2]
|
target_port = sys.argv[2]
|
||||||
temp_filter = sys.argv[3]
|
temp_filter = sys.argv[3]
|
||||||
filter_path = sys.argv[4]
|
filter_path = sys.argv[4]
|
||||||
|
owner_uid = int(sys.argv[5])
|
||||||
|
owner_gid = int(sys.argv[6])
|
||||||
|
|
||||||
source_ppd = os.path.join("/etc/cups/ppd", f"{target_printer}.ppd")
|
source_ppd = os.path.join("/etc/cups/ppd", f"{target_printer}.ppd")
|
||||||
spool_dir = "/var/cache/cups/fieldlens-print"
|
spool_dir = "/var/lib/fieldlens-print/capture"
|
||||||
|
old_spool_dir = "/var/cache/cups/fieldlens-print"
|
||||||
|
|
||||||
with open(source_ppd, "r", encoding="utf-8", errors="replace") as source:
|
with open(source_ppd, "r", encoding="utf-8", errors="replace") as source:
|
||||||
original = source.read()
|
original = source.read()
|
||||||
@ -142,7 +151,31 @@ try:
|
|||||||
target.write(cleaned)
|
target.write(cleaned)
|
||||||
|
|
||||||
subprocess.run(["install", "-m", "0755", temp_filter, filter_path], check=True)
|
subprocess.run(["install", "-m", "0755", temp_filter, filter_path], check=True)
|
||||||
subprocess.run(["install", "-d", "-m", "0777", spool_dir], check=True)
|
|
||||||
|
os.makedirs(spool_dir, exist_ok=True)
|
||||||
|
os.chown(spool_dir, owner_uid, owner_gid)
|
||||||
|
os.chmod(spool_dir, 0o700)
|
||||||
|
|
||||||
|
# Bring forward captures stranded by 0.1.13/0.1.14 in CUPS' protected
|
||||||
|
# cache. Ignore directories and partial writes.
|
||||||
|
if os.path.isdir(old_spool_dir):
|
||||||
|
for name in os.listdir(old_spool_dir):
|
||||||
|
source = os.path.join(old_spool_dir, name)
|
||||||
|
if not os.path.isfile(source) or name.endswith(".part"):
|
||||||
|
continue
|
||||||
|
target = os.path.join(spool_dir, name)
|
||||||
|
if os.path.exists(target):
|
||||||
|
root, ext = os.path.splitext(name)
|
||||||
|
target = os.path.join(spool_dir, f"{root}-migrated{ext}")
|
||||||
|
try:
|
||||||
|
os.replace(source, target)
|
||||||
|
except OSError:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
os.chown(target, owner_uid, owner_gid)
|
||||||
|
os.chmod(target, 0o600)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
subprocess.run([
|
subprocess.run([
|
||||||
"lpadmin", "-p", "FieldLens-Print", "-E",
|
"lpadmin", "-p", "FieldLens-Print", "-E",
|
||||||
@ -685,7 +718,24 @@ fn install_linux_virtual_printer(target_printer: &str) -> Result<()> {
|
|||||||
uuid::Uuid::new_v4()
|
uuid::Uuid::new_v4()
|
||||||
));
|
));
|
||||||
|
|
||||||
fs::write(&temp_filter, FIELDLENS_CUPS_FILTER)
|
let uid = Command::new("id")
|
||||||
|
.arg("-u")
|
||||||
|
.output()
|
||||||
|
.context("read current Linux user id")?;
|
||||||
|
let gid = Command::new("id")
|
||||||
|
.arg("-g")
|
||||||
|
.output()
|
||||||
|
.context("read current Linux group id")?;
|
||||||
|
if !uid.status.success() || !gid.status.success() {
|
||||||
|
return Err(anyhow!("could not determine the current Linux user for capture ownership"));
|
||||||
|
}
|
||||||
|
let uid = String::from_utf8_lossy(&uid.stdout).trim().to_string();
|
||||||
|
let gid = String::from_utf8_lossy(&gid.stdout).trim().to_string();
|
||||||
|
|
||||||
|
let filter_script = FIELDLENS_CUPS_FILTER
|
||||||
|
.replace("__FIELDLENS_OWNER_UID__", &uid)
|
||||||
|
.replace("__FIELDLENS_OWNER_GID__", &gid);
|
||||||
|
fs::write(&temp_filter, filter_script)
|
||||||
.context("write FieldLens CUPS capture filter")?;
|
.context("write FieldLens CUPS capture filter")?;
|
||||||
fs::write(&temp_helper, FIELDLENS_CUPS_REPAIR_HELPER)
|
fs::write(&temp_helper, FIELDLENS_CUPS_REPAIR_HELPER)
|
||||||
.context("write FieldLens CUPS repair helper")?;
|
.context("write FieldLens CUPS repair helper")?;
|
||||||
@ -697,6 +747,8 @@ fn install_linux_virtual_printer(target_printer: &str) -> Result<()> {
|
|||||||
.arg(&target.port)
|
.arg(&target.port)
|
||||||
.arg(&temp_filter)
|
.arg(&temp_filter)
|
||||||
.arg(&filter_path)
|
.arg(&filter_path)
|
||||||
|
.arg(&uid)
|
||||||
|
.arg(&gid)
|
||||||
.status()
|
.status()
|
||||||
.context("run elevated FieldLens CUPS repair")?;
|
.context("run elevated FieldLens CUPS repair")?;
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "FieldLens Print",
|
"productName": "FieldLens Print",
|
||||||
"version": "0.1.14",
|
"version": "0.1.15",
|
||||||
"identifier": "dev.arrowstack.fieldlens.print",
|
"identifier": "dev.arrowstack.fieldlens.print",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "npm run dev",
|
"beforeDevCommand": "npm run dev",
|
||||||
|
|||||||
@ -85,7 +85,7 @@ let config: AppConfig
|
|||||||
let jobs: Job[] = []
|
let jobs: Job[] = []
|
||||||
let status: Status
|
let status: Status
|
||||||
let loginTimer: number | undefined
|
let loginTimer: number | undefined
|
||||||
let currentVersion = '0.1.14'
|
let currentVersion = '0.1.15'
|
||||||
let bundleType: BundleType | null = null
|
let bundleType: BundleType | null = null
|
||||||
let availableUpdate: Update | null = null
|
let availableUpdate: Update | null = null
|
||||||
let availableManualUpdate: ManualUpdate | null = null
|
let availableManualUpdate: ManualUpdate | null = null
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user