magic-pocket-cli 0.31.2__tar.gz → 0.32.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/.gitignore +3 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/PKG-INFO +2 -2
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/aws_auth.py +29 -5
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/deploy_cli.py +5 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/main_cli.py +11 -1
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/django_cli.py +26 -7
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/builders/context_check.py +41 -3
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/lambdahandler.py +12 -1
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pyproject.toml +2 -2
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/__init__.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/__init__.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/backup_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/cloudfront_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/cloudfront_keys_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/cloudfront_waf_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/container_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/destroy_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/dsql_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/image_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/interaction.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/migrate_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/neon_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/permissions_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/rds_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/removed_flags.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/resource_helper.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/runtime_config_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/s3_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/status_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/store_url_helper.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/tidb_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/upstash_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/url_helper.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/vpc_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/cli/waf_cli.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/mediator.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/migrations.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/__init__.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/__init__.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/backup_common.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/builders/__init__.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/builders/codebuild.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/builders/depot.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/builders/docker.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/builders/dockerignore.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/cloudformation.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/ecr.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/efs.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/poll.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/s3_utils.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/stack_backed.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/state.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/backup.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/cloudfront.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/cloudfront_acm.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/cloudfront_keys.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/cloudfront_waf.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/container.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/dsql.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/neon.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/rds.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/s3.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/tidb.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/upstash.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/vpc.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/cloudformation/cf_function_api_host.js +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/cloudformation/cf_function_basic_auth_prelude.js +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/cloudformation/cf_function_host_redirect_prelude.js +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/cloudformation/cf_function_spa_auth.js +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/cloudformation/cf_function_spa_fallback.js +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/cloudformation/cloudfront.yaml +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/cloudformation/cloudfront_acm.yaml +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/cloudformation/cloudfront_keys.yaml +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/cloudformation/cloudfront_waf.yaml +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/cloudformation/container.yaml +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/cloudformation/vpc.yaml +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/init/django-dotenv.env +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/init/django-settings.py +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/init/pocket.Dockerfile +0 -0
- {magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/init/pocket_simple.toml +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: magic-pocket-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.32.0
|
|
4
4
|
Summary: CLI and deploy tools for magic-pocket.
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
6
|
Requires-Dist: awscrt>=0.19.0
|
|
7
7
|
Requires-Dist: click>=8.1.7
|
|
8
8
|
Requires-Dist: deepdiff>=6.7.1
|
|
9
9
|
Requires-Dist: jinja2>=3.1.3
|
|
10
|
-
Requires-Dist: magic-pocket<0.
|
|
10
|
+
Requires-Dist: magic-pocket<0.33,>=0.32.0
|
|
11
11
|
Requires-Dist: pathspec>=1.0.4
|
|
12
12
|
Requires-Dist: python-on-whales>=0.68.0
|
|
13
13
|
Requires-Dist: pyyaml>=6.0.1
|
|
@@ -2,24 +2,48 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import boto3
|
|
4
4
|
from botocore.exceptions import (
|
|
5
|
+
BotoCoreError,
|
|
5
6
|
ClientError,
|
|
6
7
|
NoCredentialsError,
|
|
8
|
+
ProfileNotFound,
|
|
9
|
+
SSOTokenLoadError,
|
|
7
10
|
TokenRetrievalError,
|
|
11
|
+
UnauthorizedSSOTokenError,
|
|
8
12
|
)
|
|
9
13
|
|
|
10
14
|
from pocket.utils import echo
|
|
11
15
|
|
|
16
|
+
# 認証情報が無効なときに botocore が送出する例外。CLI 層 (PocketCLI.invoke) が
|
|
17
|
+
# これを捕捉して traceback でなく認証ガイドに変換する (どのサブコマンドでも
|
|
18
|
+
# boto3 呼び出しの途中で送出されうるため、precheck では網羅できない)。
|
|
19
|
+
CREDENTIAL_EXCEPTIONS = (
|
|
20
|
+
TokenRetrievalError,
|
|
21
|
+
UnauthorizedSSOTokenError,
|
|
22
|
+
SSOTokenLoadError,
|
|
23
|
+
NoCredentialsError,
|
|
24
|
+
ProfileNotFound,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def print_credential_guide(e: BotoCoreError) -> None:
|
|
29
|
+
"""認証系例外を 1 行の原因 + 認証手順の案内に変換して表示する"""
|
|
30
|
+
if isinstance(e, (TokenRetrievalError, UnauthorizedSSOTokenError)):
|
|
31
|
+
_print_auth_guide("SSO トークンの有効期限が切れています。")
|
|
32
|
+
elif isinstance(e, SSOTokenLoadError):
|
|
33
|
+
_print_auth_guide("SSO セッションが見つかりません (未ログイン)。")
|
|
34
|
+
elif isinstance(e, ProfileNotFound):
|
|
35
|
+
_print_auth_guide(str(e))
|
|
36
|
+
else:
|
|
37
|
+
_print_auth_guide("AWS 認証情報が見つかりません。")
|
|
38
|
+
|
|
12
39
|
|
|
13
40
|
def check_aws_credentials() -> None:
|
|
14
41
|
"""AWS 認証情報が有効か確認し、無効ならガイドを表示して終了する"""
|
|
15
42
|
try:
|
|
16
43
|
sts = boto3.client("sts")
|
|
17
44
|
sts.get_caller_identity()
|
|
18
|
-
except
|
|
19
|
-
|
|
20
|
-
raise SystemExit(1) from None
|
|
21
|
-
except NoCredentialsError:
|
|
22
|
-
_print_auth_guide("AWS 認証情報が見つかりません。")
|
|
45
|
+
except CREDENTIAL_EXCEPTIONS as e:
|
|
46
|
+
print_credential_guide(e)
|
|
23
47
|
raise SystemExit(1) from None
|
|
24
48
|
except ClientError as e:
|
|
25
49
|
if e.response["Error"]["Code"] in (
|
|
@@ -9,6 +9,9 @@ from pocket_cli import migrations
|
|
|
9
9
|
from pocket_cli.cli import interaction
|
|
10
10
|
from pocket_cli.cli.removed_flags import removed_skip_check_existing
|
|
11
11
|
from pocket_cli.mediator import Mediator
|
|
12
|
+
from pocket_cli.resources.aws.builders.context_check import (
|
|
13
|
+
resummarize_world_read_warnings,
|
|
14
|
+
)
|
|
12
15
|
from pocket_cli.resources.aws.state import StateStore, create_state_store
|
|
13
16
|
from pocket_cli.resources.backup import Backup
|
|
14
17
|
from pocket_cli.resources.cloudfront import CloudFront
|
|
@@ -220,6 +223,8 @@ def _deploy_pipeline(context: Context, *, openpath=None, skip_frontend=False):
|
|
|
220
223
|
upload_managed_assets(context)
|
|
221
224
|
if not skip_frontend:
|
|
222
225
|
deploy_frontend(context)
|
|
226
|
+
# build 時の other-read 警告はログに埋もれて気付けないため最後に再掲する
|
|
227
|
+
resummarize_world_read_warnings()
|
|
223
228
|
# デプロイ完了後の URL 表示
|
|
224
229
|
url = _get_deploy_url(context)
|
|
225
230
|
if url:
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
1
3
|
import click
|
|
2
4
|
|
|
3
5
|
from pocket import __version__
|
|
@@ -24,6 +26,7 @@ from pocket_cli.cli import (
|
|
|
24
26
|
vpc_cli,
|
|
25
27
|
waf_cli,
|
|
26
28
|
)
|
|
29
|
+
from pocket_cli.cli.aws_auth import CREDENTIAL_EXCEPTIONS, print_credential_guide
|
|
27
30
|
|
|
28
31
|
|
|
29
32
|
class PocketCLI(click.Group):
|
|
@@ -33,11 +36,18 @@ class PocketCLI(click.Group):
|
|
|
33
36
|
except ValueError as e:
|
|
34
37
|
click.echo(f"エラー: {e}", err=True)
|
|
35
38
|
ctx.exit(1)
|
|
39
|
+
except CREDENTIAL_EXCEPTIONS as e:
|
|
40
|
+
# SSO 失効等で botocore の traceback が 100 行流れると「login し直せば
|
|
41
|
+
# よい」という結論に辿り着けない。原因 1 行 + 認証手順に変換する
|
|
42
|
+
print_credential_guide(e)
|
|
43
|
+
ctx.exit(1)
|
|
36
44
|
|
|
37
45
|
|
|
38
46
|
@click.group(cls=PocketCLI)
|
|
39
47
|
def main():
|
|
40
|
-
|
|
48
|
+
# SSO token の refresh 失敗時に botocore.tokens が WARNING + traceback を
|
|
49
|
+
# 出すのを抑制する (失敗自体は上の CREDENTIAL_EXCEPTIONS 捕捉で案内される)
|
|
50
|
+
logging.getLogger("botocore.tokens").setLevel(logging.ERROR)
|
|
41
51
|
|
|
42
52
|
|
|
43
53
|
@main.command()
|
|
@@ -83,8 +83,14 @@ def _update_dotenv(jinja2_env):
|
|
|
83
83
|
@click.option(
|
|
84
84
|
"--yes", "-y", is_flag=True, default=False, help="確認プロンプトをスキップ"
|
|
85
85
|
)
|
|
86
|
+
@click.option(
|
|
87
|
+
"--skip-migrate",
|
|
88
|
+
is_flag=True,
|
|
89
|
+
default=False,
|
|
90
|
+
help="migrate を実行しない (確認も出さない)。-y と併用可",
|
|
91
|
+
)
|
|
86
92
|
@removed_skip_check_existing
|
|
87
|
-
def deploy(stage: str, openpath, yes):
|
|
93
|
+
def deploy(stage: str, openpath, yes, skip_migrate):
|
|
88
94
|
from pocket_cli.cli.deploy_cli import deploy as pocket_deploy
|
|
89
95
|
|
|
90
96
|
# pocket deploy を実行(インフラ + SPA フロントエンド)
|
|
@@ -96,11 +102,16 @@ def deploy(stage: str, openpath, yes):
|
|
|
96
102
|
skip_frontend=False,
|
|
97
103
|
yes=yes,
|
|
98
104
|
)
|
|
99
|
-
_django_post_deploy(stage, yes=yes, openpath=openpath)
|
|
105
|
+
_django_post_deploy(stage, yes=yes, openpath=openpath, skip_migrate=skip_migrate)
|
|
106
|
+
|
|
100
107
|
|
|
108
|
+
def _django_post_deploy(stage: str, *, yes: bool, openpath, skip_migrate: bool = False):
|
|
109
|
+
"""deploy / promote 共通の Django 固有後処理 (collectstatic + migrate + URL)。
|
|
101
110
|
|
|
102
|
-
|
|
103
|
-
|
|
111
|
+
skip_migrate=True なら migrate は確認ごと省く。`-y` は「聞かれたことに全部
|
|
112
|
+
yes」の意味を保ちたいので、非対話で migrate を外す手段はフラグ側に置く
|
|
113
|
+
(DB が到達不能でもインフラ更新だけ通したい、という状況が実在する)。
|
|
114
|
+
"""
|
|
104
115
|
if yes:
|
|
105
116
|
interaction.set_assume_yes(True)
|
|
106
117
|
context = Context.from_toml(stage=stage)
|
|
@@ -112,7 +123,9 @@ def _django_post_deploy(stage: str, *, yes: bool, openpath):
|
|
|
112
123
|
elif interaction.confirm("deploystatic?", default=True):
|
|
113
124
|
collectstatic_locally(stage, link=_staticfiles_link(context))
|
|
114
125
|
upload_collected_staticfiles(stage)
|
|
115
|
-
if
|
|
126
|
+
if skip_migrate:
|
|
127
|
+
echo.info("--skip-migrate: migrate をスキップしました。")
|
|
128
|
+
elif interaction.confirm("migrate?", default=True):
|
|
116
129
|
# handler 解決は migrate 実行が確定してから行う (management handler
|
|
117
130
|
# 未設定 stage で deploy 本体成功後に例外になり URL 表示へ到達しない
|
|
118
131
|
# のを防ぐ)
|
|
@@ -135,8 +148,14 @@ def _django_post_deploy(stage: str, *, yes: bool, openpath):
|
|
|
135
148
|
@click.option(
|
|
136
149
|
"--yes", "-y", is_flag=True, default=False, help="確認プロンプトをスキップ"
|
|
137
150
|
)
|
|
151
|
+
@click.option(
|
|
152
|
+
"--skip-migrate",
|
|
153
|
+
is_flag=True,
|
|
154
|
+
default=False,
|
|
155
|
+
help="migrate を実行しない (確認も出さない)。-y と併用可",
|
|
156
|
+
)
|
|
138
157
|
@removed_skip_check_existing
|
|
139
|
-
def promote(stage: str, commit_hash, openpath, yes):
|
|
158
|
+
def promote(stage: str, commit_hash, openpath, yes, skip_migrate):
|
|
140
159
|
"""build 済みの :<commit-hash> image へ stage を向けて deploy する (再ビルドなし)。
|
|
141
160
|
|
|
142
161
|
`pocket django build` で push した image に :<stage> タグを移し、インフラ/Lambda
|
|
@@ -154,7 +173,7 @@ def promote(stage: str, commit_hash, openpath, yes):
|
|
|
154
173
|
skip_frontend=False,
|
|
155
174
|
yes=yes,
|
|
156
175
|
)
|
|
157
|
-
_django_post_deploy(stage, yes=yes, openpath=openpath)
|
|
176
|
+
_django_post_deploy(stage, yes=yes, openpath=openpath, skip_migrate=skip_migrate)
|
|
158
177
|
|
|
159
178
|
|
|
160
179
|
@django.command()
|
|
@@ -26,6 +26,12 @@ from pocket_cli.resources.aws.builders.dockerignore import (
|
|
|
26
26
|
|
|
27
27
|
_MAX_LISTED = 10
|
|
28
28
|
|
|
29
|
+
# この process の build で警告した other-read 無しファイル ("path (mode)" 形式)。
|
|
30
|
+
# build ログに警告が埋もれて INIT 失敗まで気付けない実害があったため、deploy
|
|
31
|
+
# 終了時の再掲 (deploy_cli) と INIT 失敗エラーの原因提示 (lambdahandler) に使う。
|
|
32
|
+
# multi-container で同じ context を複数回 build しても重複しては積まない。
|
|
33
|
+
_warned_files: list[str] = []
|
|
34
|
+
|
|
29
35
|
# runtime が INIT フェーズで読む設定ファイル。other-read が無いまま COPY される
|
|
30
36
|
# と確実に INIT 失敗する (Rust runtime は pocket.toml を上方探索、Python runtime
|
|
31
37
|
# は pocket.runtime.toml を読む) ため、警告でなくエラーに昇格する。
|
|
@@ -57,9 +63,16 @@ def warn_files_without_world_read(context_dir: Path) -> list[str]:
|
|
|
57
63
|
unreadable = find_files_without_world_read(context_dir)
|
|
58
64
|
critical = [r for r in unreadable if Path(r).name in _INIT_CRITICAL_NAMES]
|
|
59
65
|
if unreadable:
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
with_mode = [
|
|
67
|
+
"%s (%o)" % (rel, os.stat(context_dir / rel).st_mode & 0o777)
|
|
68
|
+
for rel in unreadable
|
|
69
|
+
]
|
|
70
|
+
for entry in with_mode:
|
|
71
|
+
if entry not in _warned_files:
|
|
72
|
+
_warned_files.append(entry)
|
|
73
|
+
listed = ", ".join(with_mode[:_MAX_LISTED])
|
|
74
|
+
if len(with_mode) > _MAX_LISTED:
|
|
75
|
+
listed += " (他 %d 件)" % (len(with_mode) - _MAX_LISTED)
|
|
63
76
|
echo.warning(
|
|
64
77
|
"build context に other-read の無いファイルがあります (%d 件): %s。"
|
|
65
78
|
"Lambda の実行ユーザーは非 root のため、このまま image に COPY されると"
|
|
@@ -79,3 +92,28 @@ def warn_files_without_world_read(context_dir: Path) -> list[str]:
|
|
|
79
92
|
% ", ".join(critical)
|
|
80
93
|
)
|
|
81
94
|
return unreadable
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def warned_files_with_mode() -> list[str]:
|
|
98
|
+
"""この process の build で警告済みの other-read 無しファイル ("path (mode)")"""
|
|
99
|
+
return list(_warned_files)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def resummarize_world_read_warnings() -> None:
|
|
103
|
+
"""build 時の other-read 警告を deploy 終了時に再掲する。
|
|
104
|
+
|
|
105
|
+
build ログの途中に出る警告は大量の出力に埋もれて気付けず、INIT 失敗まで
|
|
106
|
+
到達してしまう実害があった (2026-08-26 受領 feedback)。deploy の最後に
|
|
107
|
+
ファイル名 + mode を再掲して、その場で chmod できるようにする。
|
|
108
|
+
"""
|
|
109
|
+
if not _warned_files:
|
|
110
|
+
return
|
|
111
|
+
listed = ", ".join(_warned_files[:_MAX_LISTED])
|
|
112
|
+
if len(_warned_files) > _MAX_LISTED:
|
|
113
|
+
listed += " (他 %d 件)" % (len(_warned_files) - _MAX_LISTED)
|
|
114
|
+
echo.warning(
|
|
115
|
+
"注意: build context に other-read の無いファイルがありました (%d 件): "
|
|
116
|
+
"%s。Dockerfile で `COPY --chmod` 等により正規化していない場合、Lambda の"
|
|
117
|
+
"非 root 実行ユーザーが読めず INIT フェーズで失敗します。"
|
|
118
|
+
"`chmod 644 <file>` で修正してください。" % (len(_warned_files), listed)
|
|
119
|
+
)
|
{magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/lambdahandler.py
RENAMED
|
@@ -12,6 +12,7 @@ from pydantic import BaseModel, Field
|
|
|
12
12
|
|
|
13
13
|
from pocket.resources.base import ResourceStatus
|
|
14
14
|
from pocket.utils import MANAGE_HANDLER_SUCCESS_SENTINEL
|
|
15
|
+
from pocket_cli.resources.aws.builders.context_check import warned_files_with_mode
|
|
15
16
|
|
|
16
17
|
if TYPE_CHECKING:
|
|
17
18
|
from pocket.context import LambdaHandlerContext
|
|
@@ -196,7 +197,7 @@ class LambdaHandler:
|
|
|
196
197
|
if message.startswith(report_prefix):
|
|
197
198
|
if not success_seen:
|
|
198
199
|
if _looks_like_init_failure("\n".join(printed)):
|
|
199
|
-
|
|
200
|
+
message = (
|
|
200
201
|
"Lambda が INIT フェーズで失敗しました "
|
|
201
202
|
"(Runtime.Unknown / INIT_REPORT ... Status: error)。"
|
|
202
203
|
"これはアプリの例外ではなく runtime 側の問題の可能性が"
|
|
@@ -211,9 +212,19 @@ class LambdaHandler:
|
|
|
211
212
|
"PermissionError になります。ログに PermissionError が"
|
|
212
213
|
"あれば該当ファイルを chmod 644 して再 deploy して"
|
|
213
214
|
"ください。"
|
|
215
|
+
)
|
|
216
|
+
detected = warned_files_with_mode()
|
|
217
|
+
if detected:
|
|
218
|
+
message += (
|
|
219
|
+
"今回の build では other-read の無いファイルを"
|
|
220
|
+
"検出済みです ((2) が濃厚): %s。"
|
|
221
|
+
% ", ".join(detected)
|
|
222
|
+
)
|
|
223
|
+
message += (
|
|
214
224
|
"アプリの traceback ではなく上の INIT_REPORT / "
|
|
215
225
|
"Runtime.Unknown 行を確認してください。"
|
|
216
226
|
)
|
|
227
|
+
raise ManagementCommandFailed(message)
|
|
217
228
|
raise ManagementCommandFailed(
|
|
218
229
|
"management command handler did not complete successfully "
|
|
219
230
|
"(no success marker before REPORT). "
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "magic-pocket-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.32.0"
|
|
4
4
|
description = "CLI and deploy tools for magic-pocket."
|
|
5
5
|
requires-python = ">=3.10"
|
|
6
6
|
dependencies = [
|
|
7
7
|
# lib は同 minor に束縛する。0.x では minor が breaking の単位のため、
|
|
8
8
|
# 上限なしだと cli を pin した消費者にも lib の破壊的変更が届いてしまう
|
|
9
|
-
"magic-pocket>=0.
|
|
9
|
+
"magic-pocket>=0.32.0,<0.33",
|
|
10
10
|
"click>=8.1.7",
|
|
11
11
|
"jinja2>=3.1.3",
|
|
12
12
|
"python-on-whales>=0.68.0",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/backup_common.py
RENAMED
|
File without changes
|
{magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/builders/__init__.py
RENAMED
|
File without changes
|
{magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/builders/codebuild.py
RENAMED
|
File without changes
|
{magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/builders/depot.py
RENAMED
|
File without changes
|
{magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/builders/docker.py
RENAMED
|
File without changes
|
|
File without changes
|
{magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/cloudformation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/resources/aws/stack_backed.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/cloudformation/vpc.yaml
RENAMED
|
File without changes
|
{magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/init/django-dotenv.env
RENAMED
|
File without changes
|
{magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/init/django-settings.py
RENAMED
|
File without changes
|
{magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/init/pocket.Dockerfile
RENAMED
|
File without changes
|
{magic_pocket_cli-0.31.2 → magic_pocket_cli-0.32.0}/pocket_cli/templates/init/pocket_simple.toml
RENAMED
|
File without changes
|