Laravel PackageManifest 는 bootstrap/cache/packages.php 가 있으면 stale 여부를 검사하지 않고 그대로 읽어 등재된 provider 를 new 한다. 코어 업데이트는 Step 6/8 에서 vendor 를 --no-dev 로 교체하지만 그 파일은 Step 11 까지 이전 설치본의 것이 남으므로, 옵션 없는 `composer install` 로 깔린 사이트에서는 Step 10 spawn 자식이 새 vendor 에 없는 provider 를 찾다 부팅 단계에서 죽는다. 부팅 전이라 앱 로그에 흔적이 없고 부모에게는 자식의 비정상 종료로만 보여, 운영자에게는 「Class ... not found」 와 수동 재개 안내만 남는다. (sir.kr 커뮤니티 제보, 7.0.9 → 7.0.10) 3계층으로 막는다. 1. 부모 — spawn 직전 PackageManifestCacheHelper::clear 2. 자식 — bootstrap/app.php 가 G7_UPDATE_IN_PROGRESS 를 보고 스스로 정리한다. 이미 배포된 7.0.9·7.0.10 부모는 고칠 수 없으므로 그 아래에서 도는 신버전 자식의 유일한 방어다. App\ 클래스를 참조하지 않고 실패는 무시한다. 3. 범위 — CoreVersionChecker 의 env APP_VERSION 우선을 CoreUpdateContext 트리 안으로 축소한다. 업데이트 전에 뜬 artisan serve·큐 워커가 옛 값을 물고 확장을 incompatible_core 로 끄던 경로를 닫는다(관리자 템플릿이 대상이면 복구 UI 자체에 도달할 수 없다). 업데이트 트리 판정은 App\Support\CoreUpdateContext 가 단독 소유하고 CoreServiceProvider::isCoreUpdateInProgress 는 위임으로 남는다. bootstrap/app.php 의 복제본은 부팅 전이라 불가피한 예외이며, 두 조건의 동형성을 테스트가 단언한다. 실측 중 드러난 결함 2건을 함께 고쳤다. - ConfigCacheHelper::withPreservedContainer 가 파사드 애플리케이션을 되돌리지 않아 Step 11 이 `Target class [command.tinker] does not exist` 로 실패·롤백했다. - updateVersionInEnv 가 프로세스 환경을 갱신하지 않아 config 캐시에 이전 버전이 구워졌다 (Laravel env 저장소가 불변이라 재부팅으로도 덮이지 않는다). 인스톨러는 재사용 vendor 의 개발용 패키지를 installed.json 으로 감지해 설치 환경 확인 카드·설치 로그로 알리되 설치를 차단하지 않고( 결정 D1), 재사용 경로에서도 컴파일 캐시를 정리한다. 실행되는 명령만이 아니라 실패 시 안내하는 수동 명령까지 --no-dev 로 맞췄다. 코어 업데이트 완료·핸드오프·단독 재개 사후 단계에서 queue:restart 신호를 보낸다(D3). 코어 7.0.10 → 7.0.11.
64 lines
2.8 KiB
PHP
64 lines
2.8 KiB
PHP
<?php
|
|
|
|
namespace App\Support;
|
|
|
|
/**
|
|
* 현재 PHP 프로세스가 코어 업데이트 프로세스 트리 안에 있는지 판정하는 단일 SSoT.
|
|
*
|
|
* 코어 업데이트는 부모 `core:update` 가 `core:execute-upgrade-steps` 를 `proc_open` 으로
|
|
* spawn 하고, 그 자식이 다시 `config:cache` 등으로 일회용 Application 을 부팅하는 다층 구조다.
|
|
* 이 트리 안에서만 켜져야 하는 예외 동작이 여럿이라(확장 자동 비활성화 스킵, 코어 버전의
|
|
* env 우선 판독, `bootstrap/app.php` 의 패키지 매니페스트 자가 치유) 판정이 흩어지면
|
|
* 한 곳만 어긋나도 그 경로가 조용히 다르게 동작한다 — 판정을 여기 한 곳에 둔다.
|
|
*
|
|
* 판정 채널이 둘인 이유: `G7_UPDATE_IN_PROGRESS` env 는 부모가 세우고 spawn 자식에게
|
|
* `$env` 로 전파되지만, `variables_order` 에 `E` 가 없는 호스팅에서는 `$_ENV` 가 비어 있을 수
|
|
* 있어 argv 보조 판정을 함께 둔다.
|
|
*
|
|
* 주의: `bootstrap/app.php` 의 자가 치유 블록은 부팅 전이라 이 클래스를 참조할 수 없어
|
|
* 같은 판정을 순수 PHP 로 복제한다. 조건을 바꾸면 그쪽도 함께 고친다.
|
|
*/
|
|
final class CoreUpdateContext
|
|
{
|
|
/**
|
|
* 코어 업데이트를 수행하는 artisan 커맨드 이름 (argv 보조 판정용)
|
|
*/
|
|
private const UPDATE_COMMANDS = ['core:update', 'core:execute-upgrade-steps'];
|
|
|
|
/**
|
|
* 현재 프로세스가 코어 업데이트 트리(부모 core:update 또는 그 spawn 자식) 안에 있는지 판정합니다.
|
|
*
|
|
* 판정 조건 (OR):
|
|
* 1. 환경변수 `G7_UPDATE_IN_PROGRESS=1` — 부모가 시작 시 설정하고 spawn 자식에 전파
|
|
* 2. artisan 커맨드 이름이 `core:update` / `core:execute-upgrade-steps` — 1 이 전파되지
|
|
* 않은 극단 상황 대비 보조 판정
|
|
*
|
|
* @return bool 업데이트 트리 안이면 true
|
|
*/
|
|
public static function isInProgress(): bool
|
|
{
|
|
if (self::hasEnvFlag()) {
|
|
return true;
|
|
}
|
|
|
|
$argv = $_SERVER['argv'] ?? [];
|
|
|
|
return in_array($argv[1] ?? '', self::UPDATE_COMMANDS, true);
|
|
}
|
|
|
|
/**
|
|
* `G7_UPDATE_IN_PROGRESS=1` 환경변수 플래그만 확인합니다 (argv 보조 판정 없음).
|
|
*
|
|
* spawn 자식 여부를 가려야 하는 지점(자식은 사전·사후 단계를 부모에 위임)에서 쓴다.
|
|
* argv 판정을 섞으면 `core:execute-upgrade-steps` 단독 실행이 자식으로 오판된다.
|
|
*
|
|
* @return bool env 플래그가 켜져 있으면 true
|
|
*/
|
|
public static function hasEnvFlag(): bool
|
|
{
|
|
$flag = $_ENV['G7_UPDATE_IN_PROGRESS'] ?? $_SERVER['G7_UPDATE_IN_PROGRESS'] ?? getenv('G7_UPDATE_IN_PROGRESS');
|
|
|
|
return $flag === '1' || $flag === 1 || $flag === true;
|
|
}
|
|
}
|