浏览代码

fix: create extraction directory before unarchive in trojan role

The unarchive module requires the destination directory to exist
before extraction, but no task created /tmp/trojan-go-extract/.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
kotoyuuko 3 周之前
父节点
当前提交
542e5ffbd2

+ 2 - 0
openspec/changes/archive/2026-04-22-fix-trojan-go-extract-dir/.openspec.yaml

@@ -0,0 +1,2 @@
+schema: spec-driven
+created: 2026-04-22

+ 25 - 0
openspec/changes/archive/2026-04-22-fix-trojan-go-extract-dir/design.md

@@ -0,0 +1,25 @@
+## Context
+
+The `roles/trojan/tasks/main.yml` playbook downloads a trojan-go zip archive to `/tmp/trojan-go.zip`, then attempts to extract it using `ansible.builtin.unarchive` with `dest: /tmp/trojan-go-extract/`. The Ansible `unarchive` module requires the destination directory to already exist on the remote host — it does not create it automatically. No task in the playbook creates this directory, causing a fatal failure on line 23.
+
+## Goals / Non-Goals
+
+**Goals:**
+- Ensure `/tmp/trojan-go-extract/` exists before the unarchive task runs
+- Keep the fix minimal — no architectural changes
+
+**Non-Goals:**
+- No changes to version, download URL, or extraction logic
+- No refactoring of surrounding tasks
+
+## Decisions
+
+Add an `ansible.builtin.file` task with `state: directory` immediately before the existing unarchive task (line 23). This is the most direct fix and matches the pattern already used elsewhere in the same playbook (e.g., line 9-15 for the config directory).
+
+Alternatives considered:
+- Use `unarchive` with a different dest that already exists (e.g., `/tmp/`): would pollute `/tmp` with extra files and require filtering logic.
+- Add `create_dest: yes`-style parameter: no such parameter exists in Ansible's `unarchive` module.
+
+## Risks / Trade-offs
+
+- [Leftover /tmp directory on failure] → The cleanup task at line 46-52 already removes `/tmp/trojan-go-extract` on success. On failure mid-playbook, the directory persists but `/tmp` is volatile and cleaned on reboot.

+ 19 - 0
openspec/changes/archive/2026-04-22-fix-trojan-go-extract-dir/proposal.md

@@ -0,0 +1,19 @@
+## Why
+
+The Ansible `unarchive` module in `roles/trojan/tasks/main.yml` line 23 fails because its `dest: /tmp/trojan-go-extract/` directory does not exist on the remote host. The `unarchive` module requires the destination directory to be present before extraction, but no preceding task creates it. This blocks the entire trojan-go deployment playbook.
+
+## What Changes
+
+- Add a `file` task to create `/tmp/trojan-go-extract/` directory before the unarchive step in `roles/trojan/tasks/main.yml`
+
+## Capabilities
+
+### New Capabilities
+<!-- none needed - this is a bug fix -->
+
+### Modified Capabilities
+<!-- none -->
+
+## Impact
+
+- `roles/trojan/tasks/main.yml`: one new task inserted before line 23

+ 13 - 0
openspec/changes/archive/2026-04-22-fix-trojan-go-extract-dir/specs/trojan-deployment/spec.md

@@ -0,0 +1,13 @@
+## MODIFIED Requirements
+
+### Requirement: Extract trojan-go binary from downloaded archive
+
+The Ansible playbook SHALL ensure the extraction destination directory `/tmp/trojan-go-extract/` exists before invoking the `unarchive` module to extract `trojan-go.zip`.
+
+#### Scenario: Destination directory does not exist
+- **WHEN** the playbook runs on a fresh remote host where `/tmp/trojan-go-extract/` has never been created
+- **THEN** the playbook creates the directory before extraction and the unarchive task succeeds
+
+#### Scenario: Destination directory already exists
+- **WHEN** the playbook runs on a host where `/tmp/trojan-go-extract/` already exists from a prior run
+- **THEN** the directory creation task is idempotent and the unarchive task proceeds normally

+ 3 - 0
openspec/changes/archive/2026-04-22-fix-trojan-go-extract-dir/tasks.md

@@ -0,0 +1,3 @@
+## 1. Fix extract directory creation
+
+- [x] 1.1 Add `ansible.builtin.file` task to create `/tmp/trojan-go-extract/` before the unarchive step in `roles/trojan/tasks/main.yml`

+ 6 - 0
roles/trojan/tasks/main.yml

@@ -20,6 +20,12 @@
     dest: /tmp/trojan-go.zip
     dest: /tmp/trojan-go.zip
     mode: "0644"
     mode: "0644"
 
 
+- name: Create extraction directory
+  ansible.builtin.file:
+    path: /tmp/trojan-go-extract/
+    state: directory
+    mode: "0755"
+
 - name: Extract trojan-go binary
 - name: Extract trojan-go binary
   ansible.builtin.unarchive:
   ansible.builtin.unarchive:
     src: /tmp/trojan-go.zip
     src: /tmp/trojan-go.zip