Skip to content

계정/도메인 서버 완전 삭제 구현 - #8

Draft
eondcom wants to merge 6 commits into
mainfrom
plan-account-delete
Draft

계정/도메인 서버 완전 삭제 구현#8
eondcom wants to merge 6 commits into
mainfrom
plan-account-delete

Conversation

@eondcom

@eondcom eondcom commented Jul 29, 2026

Copy link
Copy Markdown
Owner

구현 완료

계정 관리의 신규 위험 작업 탭에서 도메인 또는 계정을 한 번에 하나씩 서버에서 완전히 삭제하는 기능을 구현했습니다. 사이드바 휴지통은 기존처럼 로컬 기록만 다루며 서버 삭제 후에도 자동 변경하지 않습니다.

작업 흐름

  1. 점검 (읽기 전용) — HestiaCP 등록, 파일 크기, DB 이름·크기, DNS·메일, DB 공유 여부, 백업 여유 확인
  2. 백업 — 도메인은 파일+DB를 로컬에 저장하고 계정은 v-backup-user 실행. 계정 크기 + 1GB 여유가 없거나 백업이 실패하면 삭제 차단
  3. 서버에서 완전 삭제 — 화면과 전용 확인 모달에서 대상명을 각각 입력해야 실행

안전장치

  • 웹루트 직접 rm -rf 금지, v-delete-web-domain / v-delete-user만 사용
  • admin, root, 시스템 계정, 설정의 SSH 계정은 Rust와 원격 셸 양쪽에서 차단
  • DB 공유 감지 시 DB 이름을 삭제 작업에 전달하지 않음
  • 대상 변경·재점검 시 점검/백업/DB 상태 전부 초기화
  • 삭제 전 HestiaCP 등록 재확인, 삭제 후 잔존 검증
  • /var/log/hostmover/deletions.log에 삭제 결과 기록

Phase별 커밋

  • 1d7af3c 계정·도메인 삭제 사전 점검과 위험 작업 탭
  • 8e5c624 삭제 전 도메인·계정 백업
  • 2d6c50f 도메인 서버 완전 삭제
  • cf5e2dd 계정 서버 완전 삭제와 복원 문서

로컬 검증

  • cargo test: 35개 전부 통과
  • cargo build: 통과, 경고 없음
  • cargo build --release: 통과, 경고 없음
  • 신규 원격 셸 5개: 테스트에서 bash -n 통과
  • 점검 스크립트에 v-delete- / DROP DATABASE / rm -rf가 없음을 테스트로 강제
  • 삭제 스크립트가 HestiaCP 삭제 명령과 서버 이력을 포함하고 웹루트를 직접 삭제하지 않음을 테스트로 강제

⚠ 실서버 검증 미수행

Codex는 실제 서버에 접속하지 않았습니다. 운영 사용 전 스펙 §7대로 테스트 계정 hmtest에서 점검 → 백업 → 삭제 → v-restore-user 복원을 사람이 1회 검증해야 합니다.

구현 스펙: .claude/plans/2026-07-30-account-domain-delete-SPEC.md
운영 안내: docs/account-delete.md

eondcom and others added 2 commits July 30, 2026 06:59
요구: 계정 관리에서 유저/도메인을 골라 삭제하면 파일·DB·HestiaCP 등록까지 정리.

조사 결과 셋 다 가능하다. HestiaCP 쪽 도메인 제거는 어려운 게 아니라 오히려
정석이다 — v-delete-web-domain 이 파일·설정·nginx·SSL 을 한 번에 정리한다.
반대로 rm -rf 로 파일만 지우면 패널에 유령 도메인이 남아 재등록 때 충돌한다.

계획의 핵심은 "가능한가"가 아니라 안전장치다:

- 사이드바의 기존 '삭제'는 로컬 기록 휴지통이고 서버를 안 건드린다.
  여기에 서버 실삭제를 같은 모양으로 붙이면 언젠가 잘못 누른다.
  → 서버 삭제는 계정 관리 페이지 안에만, 문구도 '서버에서 완전 삭제' 로 분리
- 점검(읽기) → 백업 → 삭제 3단계 분리, 백업 실패 시 삭제 차단
- 계정/도메인 이름 타이핑 확인
- DB 공유 검사: 한 DB 를 여러 도메인이 참조하면(스테이징이 운영 DB 를 쓰는
  흔한 경우) 도메인 하나 지우려다 다른 사이트가 죽는다 → DB 삭제 건너뜀
- 보호 대상 거부: admin, 설정의 ssh_user 자신, 시스템 계정, 비-Hestia 계정
- 삭제 후 잔존 검증 + /var/log/hostmover/deletions.log 이력

읽기 기능부터 4단계로 끊어 진행하도록 제안했다. 미확정 4건은 문서 7장.

함께: .gitignore 에 .claude/* (plans/ 만 예외) 추가.
settings.local.json 은 승인한 명령 전문이 저장돼 비밀번호·토큰이 섞일 수 있다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WxEiSzFMdeAzvohAQ39nyJ
검토 문서(#8)에 남아 있던 미확정 4건을 닫고, 구현만 하면 되는 스펙으로 정리했다.
스펙 작성 자체가 판단이라 여기서 확정하고 구현은 Codex 가 맡는다.

확정 사항
  삭제 후 사이드바 로컬 기록  → 건드리지 않는다(경계 유지, 로그 안내만)
  백업 실패 시                → 삭제 차단, 무시 옵션 없음
  백업 전 디스크 확인          → df 로 계정크기+1GB 확인, 부족하면 중단
  일괄 삭제                   → 한 번에 하나만
  UI 위치                     → 계정 관리의 신규 '위험 작업' 탭
  조회 방식                   → SSH (파일·DB 크기·공유검사는 API 로 못 한다)

문서에 담은 것
  - 리포 컨텍스트: Job/eondcms_exec 실행 모델, 재사용 헬퍼 6개의 정확한 시그니처와 위치
  - Phase 1~4 (점검 → 백업 → 도메인삭제 → 계정삭제), 각 DoD 와 커밋 단위
  - 셸 스크립트 5개 전문 (그대로 옮겨 쓸 수 있는 수준)
  - 신규 App 필드 6개, 전용 확인 모달(타이핑 확인) 요구사항
  - 테스트 케이스: 점검에 파괴명령 부재 강제, 웹루트 직접 rm 금지 강제,
    보호계정·주입 거부, 원격 셸 2차 방어 존재 확인
  - 흔한 함정 6개 (format! 중괄호, grep -qx, du 시점, DB 탐지 순서, set -e, 상태 리셋)

검증
  스펙에 실은 셸 5개 전부 bash -n 통과. 도메인 점검 스크립트는 v-* shim +
  가짜 사이트로 실제 실행해 3케이스 확인:
    단독 DB → HM_DBSHARED=0 / 다른 도메인이 같은 DB 참조 → 1 + 경고 / 미검출 → 빈 값

  이 과정에서 결함 하나를 잡아 보강: DB 미검출 분기에서 HM_DBSHARED 가 출력되지
  않아 이전 점검 값이 남을 수 있었다(→ 다른 도메인 DB 삭제 위험).
  모든 분기에서 두 줄 출력 + 점검 시작 시 UI 상태 리셋을 스펙에 명시.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WxEiSzFMdeAzvohAQ39nyJ
@eondcom eondcom changed the title 계정/도메인 서버 삭제 기능 계획 (구현 전 검토) 계정/도메인 서버 삭제 — 검토 + Codex 개발 스펙 Jul 29, 2026
@eondcom eondcom changed the title 계정/도메인 서버 삭제 — 검토 + Codex 개발 스펙 계정/도메인 서버 완전 삭제 구현 Jul 30, 2026
eondcom added a commit that referenced this pull request Jul 31, 2026
지시서(PR #13)는 한 번의 작업 계획이라 끝나면 사라진다. 다음에 화면을 손댈 때
기준이 다시 흐려지므로, 규칙 자체를 스킬로 박아 앞으로 모든 UI 작업에 적용되게 한다.

기준은 IBM Carbon·Grafana 계열 데이터 밀도형이다. Apple HIG 같은 터치 기준
(44pt 타겟·넉넉한 여백)은 쓰지 않는다 — 운영자가 하루 종일 보는 도구라
여백보다 정보 밀도가 중요하고, HIG 를 따르면 지금보다 오히려 헐거워진다.

담은 것
  · 절대 제약: egui/egui_extras =0.31.1 고정(올리면 한글 입력이 깨진다), 폰트 교체 금지
  · 색은 의미에만(정상/주의/위험/미조회), 색만으로 상태를 전달하지 않는다(색각 이상)
  · 표는 반드시 TableBuilder — Grid 금지, body.rows() 로 가상 스크롤,
    행 22/헤더 24 고정, 정렬 시 원본 Vec 순서를 바꾸지 않는다(체크박스가 어긋난다)
  · 숫자는 우측정렬 + 고정폭, 단위 필수, 빈칸 대신 '조회불가'
    (빈칸은 정상으로 오해된다)
  · 미조회를 정상으로 표시하지 않는다
  · 빈 상태에는 왜 비었는지와 다음 행동을 쓴다
  · 조회 결과에는 기준 시각을 표시한다

.gitignore 에 !.claude/skills/ 예외를 함께 넣었다. PR #8 이 머지되면
.claude/* 규칙이 들어와 스킬이 통째로 무시될 상황이었다.
settings.local.json 이 여전히 차단되는 것도 확인했다.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WxEiSzFMdeAzvohAQ39nyJ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant