Floci CodeBuild 本地模拟实践:存储状态 + Docker 真实构建执行全解析
【免费下载链接】flociLight, fluffy, and always free - The AWS Local Emulator alternative项目地址https://gitcode.com/gh_mirrors/fl/floci点击查看免费下载Floci 以 JSON 1.1 协议完整实现了 AWS CodeBuild API不仅提供项目、报告组、源码凭据等元数据的有状态管理还会在本地 Docker 环境中真实拉起容器执行 buildspec 中的各个构建阶段并将日志流式写入 CloudWatch Logs、把产物上传到模拟 S3。读完本文你将掌握 Floci CodeBuild 服务的 20 个 API 操作、构建执行的完整生命周期与源码级工作机制并能直接用 AWS CLI 在本地跑通一次真实的创建项目 → 启动构建 → 轮询状态 → 获取产物全流程。服务概览与协议基础传输协议与请求格式Floci 的 CodeBuild 服务遵循JSON 1.1协议客户端向模拟端点发送POST /请求并在X-Amz-Target头中携带CodeBuild_20161006.Action来指定具体操作。该分派逻辑由 CodeBuildJsonHandler.java 中的switch (action)完成每个 action 对应一个独立的处理方法未知 action 会返回InvalidAction错误。ARN 格式Floci 遵循真实 CodeBuild 的 ARN 规范在创建资源时通过AwsArnUtils.Arn.of(codebuild, region, account, ...)构造项目arn:aws:codebuild:region:account:project/name报告组arn:aws:codebuild:region:account:report-group/name源码凭据arn:aws:codebuild:region:account:token/type-uuid构建arn:aws:codebuild:region:account:build/project:uuidFloci 中实际为build/project:buildNumber其中源码凭据 ARN 的type取 serverType 的小写形式后接随机 UUID见 CodeBuildService.java。代码结构分层从源码结构看Floci 将 CodeBuild 服务拆为四层组件职责CodeBuildJsonHandler.javaJSON 1.1 协议层请求解析、action 分派、响应组装CodeBuildService.java有状态存储层项目/报告组/凭据/构建记录的增删改查与持久化CodeBuildRunner.java构建执行引擎Docker 容器调度、阶段执行、日志与产物处理BuildspecParser.javabuildspec YAML/JSON 解析器支持的 20 个操作Projects5 个操作操作说明CreateProject存储项目配置必填name、source.type、artifacts.type、environment、serviceRoleUpdateProject部分更新——只修改传入的字段DeleteProject按名称删除项目BatchGetProjects返回找到的项目与projectsNotFound列表ListProjects返回区域内所有项目名称CreateProject的校验在 CodeBuildService.java 中严格执行项目重名抛ResourceAlreadyExistsException缺少source.type、environment、serviceRole、artifacts.type均抛InvalidInputException项目名长度须在 2150 个字符之间。创建时还会写入默认值timeoutInMinutes默认 60、queuedTimeoutInMinutes默认 480、projectVisibility固定为PRIVATE。BatchGetProjects的查询支持按名称或 ARN两种标识匹配UpdateProject则逐字段判空后写入未传入的字段保持不变并自动刷新lastModified时间戳。Build Execution6 个操作操作说明StartBuild使用项目镜像拉起真实 Docker 容器依次执行 buildspec 各阶段INSTALL、PRE_BUILD、BUILD、POST_BUILD立即返回IN_PROGRESS状态的构建记录BatchGetBuilds返回构建当前状态轮询直至buildComplete为trueListBuilds返回区域内全部构建 ID按开始时间倒序最新在前ListBuildsForProject返回指定项目的构建 ID 列表StopBuild通知运行中的构建停止构建转入STOPPEDRetryBuild以已完成构建的同一配置启动新构建返回新构建记录Report Groups5 个操作操作说明CreateReportGroup存储报告组配置UpdateReportGroup按 ARN 部分更新DeleteReportGroup按 ARN 删除BatchGetReportGroups返回找到的报告组与reportGroupsNotFound列表ListReportGroups返回区域内全部报告组 ARNCreateReportGroup要求name与type必填重名按 ARN抛ResourceAlreadyExistsException新报告组状态固定为ACTIVE。Source Credentials3 个操作操作说明ImportSourceCredentials存储 serverType 与 authType按serverTypeauthType去重token 被接收但不返回ListSourceCredentials返回凭据元数据不含 tokenDeleteSourceCredentials按 ARN 删除源码凭据ImportSourceCredentials以serverType / authType作为逻辑键CodeBuildService.java同一组合默认覆盖旧凭据若传shouldOverwritefalse且已存在同组合凭据则抛ResourceAlreadyExistsException。token 字段仅被接收模型类中不暴露明文返回。Images1 个操作ListCuratedEnvironmentImages返回内置的 CodeBuild 标准镜像静态列表CodeBuildService.java覆盖两个平台AMAZON_LINUX_2aws/codebuild/amazonlinux2-x86_64-standard:5.0支持 JAVA、PYTHON、NODE_JSUBUNTUaws/codebuild/standard:7.0支持 JAVA、PYTHON、NODE_JSBuild 执行模型在 Docker 中真实构建这是 Floci CodeBuild 的核心能力。StartBuild调用 CodeBuildRunner.startBuild() 后构建会在虚拟线程中异步执行Thread.ofVirtual().start(...)API 立即返回IN_PROGRESS状态的构建记录这与真实 CodeBuild 的行为一致。一次构建的完整流程从 CodeBuildRunner.java 的runBuild可以看到完整执行链路Pulls 项目 Docker 镜像如public.ecr.aws/docker/library/alpine:latest并在本地创建临时工作目录启动容器入口命令为sh -c tail -f /dev/null保持存活以便后续逐个阶段用docker exec执行注入源码通过docker cpcopyArchiveToContainerCmd把工作目录打成 tar 归档拷入容器NO_SOURCE构建跳过此步执行 buildspec 阶段依次在容器内执行INSTALL→PRE_BUILD→BUILD→POST_BUILD流式输出日志到 CloudWatch Logs日志组为/aws/codebuild/project详见下文提取产物通过docker cpcopyArchiveFromContainerCmd把容器工作目录拷回本地若artifacts.typeS3则上传至模拟 S3标记构建完成状态为SUCCEEDED、FAILED或STOPPED源码注入与产物提取都走 Docker API 的归档拷贝端点tar 流不需要 bind mount因此 Floci 自身运行在 Docker 容器内Docker-in-Docker时同样工作正常。阶段状态机Floci 将构建拆分为与真实 CodeBuild 对齐的 11 个阶段BuildPhase每个阶段记录phaseType、phaseStatus、起止时间与耗时SUBMITTED → QUEUED → PROVISIONING → DOWNLOAD_SOURCE → INSTALL → PRE_BUILD → BUILD → POST_BUILD → UPLOAD_ARTIFACTS → FINALIZING → COMPLETED每个阶段通过beginPhase/completePhase/completePhaseWithError维护状态。几个值得注意的细节DOWNLOAD_SOURCE 阶段负责解析 buildspec优先使用buildspecOverride其次项目source.buildspec最后回退到工作目录中的buildspec.yml/buildspec.yaml三处都找不到时抛InvalidInputException见 CodeBuildRunner.java阶段短路若某个阶段失败exit code 非 0后续PRE_BUILD、BUILD阶段会被标记为SUCCEEDED空跑跳过skipPhase但POST_BUILD总是执行除非容器被停止超时控制每个阶段以sh -e -c脚本形式执行超时时间取timeoutInMinutes默认 60 分钟超时后阶段失败并返回Phase timed out after N minutes阶段失败信息会以COMMAND_EXECUTION_ERROR状态码写入阶段上下文错误消息截断至 1024 字符且输出末尾 512 字符会被拼入错误说明便于排查任何未捕获异常会让构建进入FAULT状态并在COMPLETED阶段记录FAULT_ERROR上下文StopBuild 与 RetryBuild 的实现StopBuildCodeBuildRunner.java采用双通道机制先置位stopFlags中的AtomicBoolean让各阶段在下一个检查点优雅退出再调用dockerClient.stopContainerCmd强制停止容器5 秒超时。构建随后通过finishStopped转为STOPPED。RetryBuildCodeBuildService.java会复用原构建的 buildspecOverride、环境、产物配置与超时时间重新走一遍StartBuild逻辑并分配新的 buildNumber 与构建记录。构建 ID 与持久化构建 ID 形如projectName:buildNumberbuildNumber 由account:region:projectName维度的计数器分配且计数器本身是持久化的写入codebuild-build-counters.json重启后仍能保持递增CodeBuildService.java。构建记录本身是运行时状态不持久化重启后丢失。Floci 关闭时stopManagedContainers实现ContainerTeardown接口会清理所有在途构建的容器避免产生孤儿容器。Buildspec 支持Floci 通过 BuildspecParser.java 解析项目内嵌的buildspec.yml或buildspecOverride提供的构建规范支持 YAML 与 JSON版本 0.2。解析结果结构如下version: 0.2 env: variables: # 普通环境变量 KEY: value parameter-store: # 从模拟 SSM 读取参数 MY_PARAM: /my/param secrets-manager: # 从模拟 Secrets Manager 读取密钥 MY_SECRET: my-secret-id phases: install: commands: [] pre_build: commands: [] build: commands: [] post_build: commands: [] artifacts: files: [] base-directory: # 默认 $CODEBUILD_SRC_DIR discard-paths: false name: packaging: ZIP type: 支持的字段汇总phases——install、pre_build、build、post_build各阶段命令列表artifacts.files—— 要收集的文件模式列表支持**/*通配、具体文件名与路径模式artifacts.base-directory—— 产物收集的基准目录默认$CODEBUILD_SRC_DIRenv.variables/env.parameter-store/env.secrets-manager—— 三类环境变量来源见下文artifacts缺省时类型默认为NO_ARTIFACTS、打包方式默认为ZIP、discard-paths默认为falseBuildspecParser.java。环境变量注入机制CodeBuildRunner.buildEnvListCodeBuildRunner.java为容器注入了一套完整的环境变量与真实 CodeBuild 对齐变量值CODEBUILD_BUILD_ID构建 ID如my-project:1CODEBUILD_BUILD_ARN构建 ARNCODEBUILD_BUILD_NUMBER构建序号CODEBUILD_BUILD_IMAGE构建镜像CODEBUILD_INITIATORuserCODEBUILD_SRC_DIR/codebuild/output/src/src容器内工作目录CODEBUILD_LOG_PATHCloudWatch Logs 日志流名AWS_DEFAULT_REGION/AWS_REGION请求所在区域AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEYtest/testAWS_ENDPOINT_URL指向 Floci 自身端点见下文此外还依次合并buildspec 的env.variables→ SSM 参数通过ssmService.getParameter解析parameter-store→ Secrets Manager 密钥通过secretsManagerService.getSecretValue解析secrets-manager→ 项目级environment.environmentVariables→ 构建级 override 变量。SSM/密钥解析失败只记录 debug 日志不影响构建执行。AWS_ENDPOINT_URL的解析CodeBuildRunner.java考虑了运行环境差异Floci 在容器内运行时使用内嵌 DNS 后缀与端口在宿主机直接运行时则指向http://host.docker.internal:port。这意味着构建容器内的 AWS CLI/SDK 可以直接访问 Floci 的其他模拟服务S3、SSM、Secrets Manager 等形成完整的本地集成环境。Artifact Upload产物上传到模拟 S3当artifacts.typeS3时收集到的文件会被上传到配置的 S3 桶CodeBuildRunner.java。关键行为桶必须已存在通过 S3 服务的CreateBucket创建Floci 不会自动建桶S3 中的对象路径与产物基准目录下的相对路径一致即baseDir.relativize(file)打包方式packagingZIP时打包为artifactName.zipartifactName 默认project-buildNumberpackagingNONE时逐文件上传路径处理discard-pathstrue时只保留文件名丢弃目录结构否则保留相对路径位置解析artifacts.location格式为bucket或bucket/prefixprefix 会拼入对象键文件匹配collectFiles**/*或**收集全部文件不含通配符的模式按直接路径解析其余模式用PathMatcher的 glob 语法匹配无匹配文件时记 warning 日志并跳过上传上传失败不会导致构建失败仅将UPLOAD_ARTIFACTS阶段标记为FAILED构建最终状态仍取决于 buildspec 阶段结果产物从容器取回本地时Floci 会剥离docker cp归档中的顶层目录并做路径穿越防护target.startsWith(destDir)校验源码 zip 解压时同样有 zip slip 防护。Configuration配置项CodeBuild 服务的开关配置位于 EmulatorConfig.java变量默认值说明FLOCI_SERVICES_CODEBUILD_ENABLEDtrue启用或禁用该服务FLOCI_SERVICES_CODEBUILD_DOCKER_NETWORK无构建容器使用的 Docker 网络名可选传给ContainerSpec.withDockerNetwork存储层方面CodeBuild 使用StorageBackedMap做持久化CodeBuildService.java涉及四份数据文件codebuild-projects.json、codebuild-report-groups.json、codebuild-source-credentials.json、codebuild-build-counters.json。存储的mode与flushIntervalMs默认 5000ms同样可通过FLOCI_STORAGE_CODEBUILD_*系列配置调整。CLI Examples本地实战演练以下命令以--endpoint-url http://localhost:4566指向 Floci 模拟端点可直接在安装了 AWS CLI 的机器上运行。# 1. 创建带 S3 产物的项目 aws --endpoint-url http://localhost:4566 codebuild create-project \ --name my-project \ --source typeNO_SOURCE \ --artifacts typeS3,locationmy-bucket \ --environment typeLINUX_CONTAINER,imagepublic.ecr.aws/docker/library/alpine:latest,computeTypeBUILD_GENERAL1_SMALL \ --service-role arn:aws:iam::000000000000:role/codebuild-role # 2. 先用 S3 服务建好产物桶Floci 不会自动建桶 aws --endpoint-url http://localhost:4566 s3api create-bucket --bucket my-bucket # 3. 使用内联 buildspec 启动构建 aws --endpoint-url http://localhost:4566 codebuild start-build \ --project-name my-project \ --buildspec-override version: 0.2 phases: build: commands: - echo hello output.txt artifacts: files: - output.txt # 4. 轮询直至完成 aws --endpoint-url http://localhost:4566 codebuild batch-get-builds --ids build-id # 5. 列出全部构建 aws --endpoint-url http://localhost:4566 codebuild list-builds # 6. 查看内置的标准镜像列表 aws --endpoint-url http://localhost:4566 codebuild list-curated-environment-images构建期间可以随时执行stop-build终止完成后可用get-object从my-bucket取回output.txt或my-project-n.zip产物。若项目中存在buildspec.yml且source.type为S3Floci 会在DOWNLOAD_SOURCE阶段从模拟 S3 拉取 zip 源码并解压解压同样带 zip slip 防护此时无需--buildspec-override。测试与验证Floci 仓库为 CodeBuild 服务配备了完整的测试体系src/test/java/io/github/hectorvent/floci/services/codebuild/CodeBuildServiceTest.java—— 服务层单元测试覆盖项目/报告组/凭据的 CRUD 与校验规则CodeBuildServicePersistenceTest.java—— 验证存储持久化行为重启后状态恢复、计数器保持递增CodeBuildIntegrationTest.java—— 端到端集成测试验证StartBuild→ 轮询 → 产物回读的完整链路此外CodeBuild 还被 CloudFormation 与 CodePipeline 复用CodeBuildCfnProvisioner.java支持 CloudFormation 资源AWS::CodeBuild::Project的声明式创建对应测试位于 CodeBuildCfnProvisionerTest.javaCodePipeline 流水线中的构建动作也由该服务承接。这意味着你在本地可以串联CloudFormation 建项目 → CodePipeline 触发构建 → 产物落 S3的完整 CI/CD 链路。小结Floci 的 CodeBuild 模拟并非简单的状态桩而是存储状态 真实执行的双层设计CodeBuildService负责项目、报告组、源码凭据与构建记录的持久化状态管理CodeBuildRunner通过 Docker API 在本地真实运行 buildspec 各阶段并打通了 CloudWatch Logs、S3、SSM、Secrets Manager 等多个模拟服务。对于希望在本地复现 CodeBuild 行为、调试 CI/CD 流水线或进行 SDK/工具链兼容性测试的开发者这一实现提供了与真实 AWS 高度对齐的 API 面与执行语义。赞分享【免费下载链接】flociLight, fluffy, and always free - The AWS Local Emulator alternative项目地址https://gitcode.com/gh_mirrors/fl/floci点击查看免费下载相关推荐你的Windows电脑还在手动折腾这款神器让你告别繁琐系统管理你的Windows电脑还在手动折腾这款神器让你告别繁琐系统管理 还记得上次重装系统后面对几十个软件安装包时的绝望吗或是为了关闭某个恼人的系统提示不得不翻ILLA Builder状态管理方案从本地存储到全局状态ILLA Builder状态管理方案从本地存储到全局状态 在现代Web应用开发中状态管理是构建复杂交互界面的核心挑战之一。ILLA Builder作为一款支低代码前端应用Redux Thunk与安全存储加密本地状态的最佳实践Redux Thunk与安全存储加密本地状态的最佳实践 痛点直击你的Redux状态安全吗 还在将用户认证令牌、支付信息等敏感数据明文存储在Redux状态中前端上一篇Docker和Kubernetes安全加固方案10个关键防护策略下一篇3步打造你的智能网页自动化管家用Browser-Use告别重复操作创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →