run-controllers reads removed session files after its monitored owner has exited
Maintainer thường phản hồi trong vòng 1 ngày
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 45/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Lĩnh vực
- backend-api-design, cli
Hướng nghiên cứu
Read internal/commands/monitor.go, internal/dcpctrl/commands/run_controllers.go, and internal/hosting/command_service.go at the paired commit to understand cancellation and child-process ownership. Start by running the standalone reproduction against the released executable, then inspect the existing controlled-executor tests. Done means an exited monitored owner avoids session-file validation, a live owner with a missing kubeconfig still errors, and cancellation during launch has a safe ownership boundary.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
run-controllers validates a deleted kubeconfig after its monitored owner has exited
Reproduced on Windows with the released DCP 0.26.6 executable, commit 6096b60432a281962920b8c7d2e9cba20118b750, distributed with Aspire 13.6.4. No application resource or container is needed.
run-controllers --monitor <pid> --monitor-identity-time <creation-time> --kubeconfig <missing-path> first establishes a monitor context. When the monitored owner has already exited, MonitorPid logs Error finding process and synchronously returns an already-canceled context. runControllers then validates the kubeconfig anyway and exits with an error because the owner has removed its session files.
Source at the paired commit:
MonitorPidexplicitly cancels the context when the owner is absent.runControllersdoes not observe that cancellation before requiring the kubeconfig.newRunControllersServiceusesCommandServiceRunOptionDontTerminate.CommandService.Runstarts that child with a background context and returns success when the host context is canceled, without waiting for the child to finish using its session files.
The late-launch boundary is real: in a retained debug run, the apiserver announced controller launch at 16:48:47.917, began shutdown at 16:48:56.965, recorded successful process start at 16:48:57.705, and completed shutdown at 16:48:58.087. The child first logged at 16:49:00.003; it found the monitored parent gone, then reported the missing kubeconfig. The service's start announcement is not proof that the native child has executed.
Standalone reproduction
Create a short-lived parent process that blocks on stdin. While it is alive, retain an OpenProcess(SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION) handle and capture its creation time with GetProcessTimes. Release stdin and wait for the process to exit. Keep the handle open to prevent PID reuse. Verify WaitForSingleObject(handle, 0) == WAIT_OBJECT_0, then invoke the released dcp.exe with that PID, its exact creation time, and a nonexistent kubeconfig path.
Observed output:
info dcp Error finding process {"PID": <exited-owner>}
error dcp the program finished with an error {"ExitCode": 1, "error": "cannot set up connection to the API server without kubeconfig file: kubeconfig file does not exist at '<missing-path>'"}
Control: keep the same kind of parent alive, verify WaitForSingleObject(handle, 0) == WAIT_TIMEOUT, and run the command with its identity. It logs Started monitoring process, then correctly reports the missing kubeconfig and exits 1. The owner remains alive for the whole command.
Expected behavior: an already-canceled monitored lifetime exits without validating or opening session files. A missing kubeconfig under a live owner remains an error.
Suggested boundary and test
Observe ctrlCtx.Err() immediately after GetMonitorContextFromFlags and before accessing the kubeconfig or state store. The monitor helper's contract already states that an absent owner produces an immediately canceled context. Avoid changing resource-readiness deadlines or treating a live-owner missing kubeconfig as success.
There is also an in-flight launch ownership boundary worth testing: block Executor.StartProcess on a channel, cancel the service owner, then complete the launch while withholding the child exit callback. Current CommandService.Run returns nil while the child is still alive. It also invokes the executor when entered with an already-canceled context. A local controlled-executor regression confirms both behaviors with the exact released source; an experimental pre-cancel guard plus stop-and-join for cancellation during launch passes that regression. That experiment is not a complete fix: cancellation immediately after StartProcess returns and before the child initializes its monitor still needs a safe ownership boundary. Simply waiting for the child to notice parent exit can deadlock if the parent waits for the child first.
This report does not establish the cause of process startup delay, and fixing canceled-owner handling alone does not prove that short startup deadlines are reliable under contention.
Standalone Windows reproduction (Python 3)
Run python reproduce.py C:/path/to/dcp.exe. No container or application resource is created.
"""Probe paired DCP's canceled monitor boundary without creating resources."""
import ctypes
from ctypes import wintypes
import datetime
import hashlib
import json
import os
from pathlib import Path
import subprocess
import sys
import tempfile
ROOT = Path(tempfile.mkdtemp(prefix="dcp-canceled-owner-"))
DCP = Path(sys.argv[1]).resolve()
kernel = ctypes.WinDLL("kernel32", use_last_error=True)
kernel.OpenProcess.argtypes = (wintypes.DWORD, wintypes.BOOL, wintypes.DWORD)
kernel.OpenProcess.restype = wintypes.HANDLE
kernel.GetProcessTimes.argtypes = (wintypes.HANDLE, *(ctypes.POINTER(wintypes.FILETIME),) * 4)
kernel.GetProcessTimes.restype = wintypes.BOOL
kernel.WaitForSingleObject.argtypes = (wintypes.HANDLE, wintypes.DWORD)
kernel.WaitForSingleObject.restype = wintypes.DWORD
kernel.CloseHandle.argtypes = (wintypes.HANDLE,)
kernel.CloseHandle.restype = wintypes.BOOL
def case(parent_exits):
name = "exited-owner" if parent_exits else "live-owner"
folder = ROOT / ("native-" + name)
folder.mkdir(exist_ok=True)
owner = subprocess.Popen([sys.executable, "-c", "import sys; sys.stdin.buffer.read(1)"], stdin=subprocess.PIPE)
handle = kernel.OpenProcess(0x00100000 | 0x1000, False, owner.pid)
if not handle:
raise ctypes.WinError(ctypes.get_last_error())
try:
times = [wintypes.FILETIME() for _ in range(4)]
if not kernel.GetProcessTimes(handle, *(ctypes.byref(t) for t in times)):
raise ctypes.WinError(ctypes.get_last_error())
creation = (times[0].dwHighDateTime << 32) + times[0].dwLowDateTime
epoch_ms = creation // 10000 - 11644473600000
identity = datetime.datetime.fromtimestamp(epoch_ms / 1000, datetime.timezone.utc).isoformat(timespec="milliseconds").replace("+00:00", "Z")
if parent_exits:
owner.stdin.write(b"x")
owner.stdin.flush()
owner.wait(timeout=10)
before = kernel.WaitForSingleObject(handle, 0)
assert before == (0 if parent_exits else 258), before
args = [str(DCP), "run-controllers", "--monitor", str(owner.pid), "--monitor-identity-time", identity,
"--kubeconfig", str(folder / "no-kubeconfig")]
env = os.environ.copy()
env["DCP_DIAGNOSTICS_LOG_FOLDER"] = str(folder)
env["DCP_DIAGNOSTICS_LOG_LEVEL"] = "debug"
env.pop("DCP_LOG_SOCKET", None)
result = subprocess.run(args, env=env, capture_output=True, timeout=30)
(ROOT / (name + ".log")).write_bytes(result.stdout + result.stderr)
return {"case": name, "ownerPid": owner.pid, "identityTime": identity, "retainedOwnerHandleWaitBefore": before,
"retainedOwnerHandleWaitAfter": kernel.WaitForSingleObject(handle, 0), "nativeExitCode": result.returncode,
"nativeOutput": (result.stdout + result.stderr).decode(errors="replace")}
finally:
if owner.poll() is None:
owner.stdin.write(b"x")
owner.stdin.flush()
owner.wait(timeout=10)
owner.stdin.close()
kernel.CloseHandle(handle)
results = {"binary": str(DCP), "sha256": hashlib.sha256(DCP.read_bytes()).hexdigest(),
"cases": [case(True), case(False)]}
(ROOT / "parent-exit-results.json").write_text(json.dumps(results, indent=2), encoding="utf-8")
print(json.dumps(results, indent=2))
- Ngôn ngữ chính
- Go
- Star
- 194
- Fork
- 28
- Merge trung bình
- 2 ngày 2 giờ
- Pull request đã merge (30 ngày)
- 30
Chuẩn bị môi trường
Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của microsoft/dcp
-
Windows inherited-access test retains unrelated writable parent ACL entriesCó thể đã có người làm @thomhurst đã nhận 1 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Maintainer thường phản hồi trong vòng 1 ngày
-
ContainerVolume stuck in PendingCó thể đã có người làm @danegsta đã nhận 2 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Add application iconĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 52/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Windows session cleanup retains an open resource log after graceful shutdownCó thể đã có người làm @thomhurst đã nhận 1 ngày trước. Đang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 52/100
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của microsoft/dcp
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
limitlessprojects/Go-Hybrid#3342 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
status/ready type/bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
buildpacks/pack#2733 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
-
kind/bug needs-priority needs-triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
konveyor/tackle2-hub#1166 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 4 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
router-for-me/CLIProxyAPI#7209 ·
Maintainer thường phản hồi trong vòng 1 ngày