Azure DevOps自托管运行器工作目录自动清理失败问题
问题场景
使用Azure DevOps自托管运行器执行测试流水线,已配置workspace: clean: all期望每次流水线启动前清理工作目录,但实际触发时频繁出现权限拒绝错误,提示无法访问前一次运行生成的__pycache__目录下的文件。手动SSH到运行器清理目录后首次运行正常,第二次运行又因遗留文件失败。
原始流水线配置
name: $(Date:yyyyMMdd)$(Rev:.r) trigger: none pr: - master - main - release* pool: name: sonarcube-agents variables: AZURE_SUBSCRIPTION: testsub-dev IMAGE_NAME: $(Build.DefinitionName) SOURCE_DIRECTORY: $(System.DefaultWorkingDirectory) #specifying resources #test change to trigger 15 jobs: - job: BuildAndTest displayName: 'Build and Test Job' steps: - script: | echo "Running on self-hosted agent" echo "Step 1: Checking out the repository" displayName: 'Checkout Code' - checkout: self #clean: true # more steps here that run the tests and generate some files # in the working directory. we run some docker containers and # run unit tests. at end of pipeline we are left with new # files which are reports of qa tests. I do stop all # containers and delete all images and volumes as you can see. # make test cmd triggers a Makefile which does most of the work. # (start all containers, run tests, and generate the test reports etc) - script: | echo "lets run tests" make test echo "end of tests #" echo "*********" echo "**********" echo "lets clean up \n lets stop containers" docker stop $(docker ps -aq) echo "lets clean up \n lets remove all images and containers" yes | docker system prune -a echo "check if anything still - docker ps -a" docker ps -a echo "check all volumes: " docker volume ls -qf dangling=true echo "remove all docker volumes" docker volume remove $(docker volume ls -qf dangling=true) displayName: runtestswithmakefile # here I am trying to remove all the extra files but it does not help. - script: | shopt -s dotglob rm -rf * workspace: # Workspace options on the agent. clean: all
错误信息
##[error]One or more errors occurred. (One or more errors occurred. (Access to the path '/data/vsts-agent/workspace/1/s/pycache/app.cpython-39.pyc' is denied.)) (One or more errors occurred. (Access to the path '/data/vsts-agent/workspace/1/s/migrations/pycache/env.cpython-39.pyc' is denied.)) (Access to the path '/data/vsts-agent/workspace/1/s/pycache/app.cpython-39.pyc' is denied.) (Access to the path '/data/vsts-agent/workspace/1/s/migrations/pycache/env.cpython-39.pyc' is denied.)
解决方法
1. 修正流水线配置语法错误
原始配置存在两处关键语法问题:
workspace: clean: all被错误放置在steps层级下,需移至job级别才能生效。- 测试脚本的
- script块缩进错误,脱离了BuildAndTestjob的步骤列表,导致执行顺序混乱。 - 开启
checkout步骤的clean: true,确保代码检出时自动清理目录。
修正后的核心配置片段:
jobs: - job: BuildAndTest displayName: 'Build and Test Job' workspace: # 移到job级别生效 clean: all steps: - script: | echo "Running on self-hosted agent" echo "Step 1: Checking out the repository" displayName: 'Checkout Code' - checkout: self clean: true # 启用检出时清理 - script: | echo "lets run tests" make test echo "end of tests #" echo "*********" echo "**********" echo "lets clean up \n lets stop containers" docker stop $(docker ps -aq) echo "lets clean up \n lets remove all images and containers" yes | docker system prune -a --volumes # 添加--volumes彻底清理卷 echo "check if anything still - docker ps -a" docker ps -a echo "check all volumes: " docker volume ls -qf dangling=true echo "remove all docker volumes" docker volume remove $(docker volume ls -qf dangling=true) displayName: runtestswithmakefile
2. 处理Python缓存文件权限问题
__pycache__文件由Docker容器内的用户创建,其UID/GID可能与自托管运行器系统用户不一致,导致权限拒绝。解决方式二选一:
- 在流水线末尾添加sudo清理缓存目录:
- script: | sudo rm -rf __pycache__/ migrations/__pycache__/ displayName: 'Clean up Python Cache Files' - 在
make test的Docker启动命令中,指定容器运行用户为当前运行器用户,确保文件权限一致:# Makefile中docker run示例 docker run -u $(id -u):$(id -g) -v $(PWD):/app your-image make test-in-container
3. 调整清理步骤顺序
将所有清理操作放在测试步骤之后,确保流水线结束前彻底清除生成文件,避免遗留权限问题。
内容的提问来源于stack exchange,提问作者Deepak

