Workspace Cloning / Sharing in Jenkins

博客提供了关于Hudson工作区克隆与共享的相关链接,包括http://lwandersonmusings.blogspot.com/2011/06/workspace-cloning-sharing-in-hudson.html ,还注明转载自https://www.cnblogs.com/flysun0311/p/3548138.html 。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 http://lwandersonmusings.blogspot.com/2011/06/workspace-cloning-sharing-in-hudson.html

 

What's inside...
Huge workspace (6GB) + long build time (6 hours) + many post-build steps (17) = huge consumption of resources. Replicate the build? Share the workspace? Clone the workspace? Clone and share the workspace?  


Background
Recently I was challenged with the opportunity to convert a large project (1,600,000+ LOC) from a commercial build system to Hudson as part of an enterprise-wide effort of a client to standardize their build environment. Without getting into the details of the project itself, one of the greatest challenges was overcoming the size of the source code repository as well as the length of the integration build, 6GB and 6 hours, respectively. The entire build process, including post-build scanning and reporting (Findbugs, Fortify, etc.) took over 12 hours.
 
One of the primary objectives of this particular conversion was to reduce the time for overall throughput of the build process. An additional requirement was the publication of Sonar analysis reports for management consumption. And since each sub-project is autonomous in the reporting scheme, we needed to run the Sonar analysis on each of the 16 sub-projects as well.


Let's get started...
I started by adding 17 steps to the build job, one for each sub-project as well as one for the entire project as a whole. But we were experiencing intermittent errors in the Sonar analysis steps which basically aborted the entire process. And aborting the entire process meant no publication of build statistics, etc., to the Hudson dashboard even though the build itself was completing successfully.


Share the workspace...
So we decided to create individual Hudson jobs for each of the Sonar analysis steps so that if one analysis step (job) failed, the others would run. And more importantly, the build job itself would complete publishing its code coverage and test results reports to the Hudson dashboards. But since we didn’t want to propagate a 6GB workspace for each of the 17 Sonar analysis jobs, not to mention the time required to repeatedly download the 1.6M LOC, we decided to use the ‘Custom workspace’ Advanced Project configuration option to point back to the main build job’s Hudson workspace. It worked. 


All well and good… so we thought.
And now the nightly build process was taking 14 hours. Granted Sonar analysis was added to the process, but one of the goals was to reduce the overall throughput time, not increase it. And with the implementation of the 17 additional Sonar analysis jobs that are required to run on the same slave because of re-using the main build’s Hudson workspace, we needed to “pin” all the jobs to the same slave. Even though I was testing this prototype process on a single slave, we wanted the capability to run this process on any slave of a Hudson master that was equipped to handle the build. We also wanted the capability to distribute the workload of the 17 Sonar analysis jobs across the slaves, effectively reducing the overall build process throughput time.


Zip and copy...
So my next challenge was to develop an architecture that would solve two problems that were introduced by the new implementation; namely, increased overall throughput, and pinning all jobs to a single slave. First I experimented with zipping up the workspace in a post-build step of the main build, archiving it, and then in the downstream Sonar analysis job, using the ‘Copy artifacts from another project’ build step to bring it into the workspace and then a build step to unzip it.
 
The main build job would sometimes fail zipping up the huge workspace. But most often the downstream job would fail either retrieving the archive across the network or unzipping the archive because it was sometimes corrupted (probably from the download failing). It was very error prone and inconsistent, presumably because of the huge workspace. I experimented with the CopyArchiverCopy ArtifactCopy Data to Workspace, and Copy to Slave plug-ins, but I finally abandoned the zip-and-copy idea never getting the entire process to run successfully from start to finish.


Ok, how about cloning?
I then discovered the Clone Workspace SCM plug-in that, in theory, would allow us to run the main integration build on any capable slave, clone its workspace, and then run the downstream jobs on any other capable slave using the ‘cloned’ workspace. Essentially, this was the same as my zip-archive-unzip process, but all supported through a Hudson plug-in, not via a hacked-up process.
 
After installing the plug-in, I reconfigured the main integration build job to utilize the ‘Archive for Clone Workspace SCM’ Post-Build action specifying ‘Most Recent Not Failed Build’:
 
This insures the workspace is not archived if the build fails preventing wasted space since the downstream job is not triggered if the build fails. When the archiver finishes archiving the workspace successfully, it automatically deletes the previous workspace archive.
 
I then reconfigured each of the downstream analysis jobs to specify the ‘Clone Workspace’ Source Code Management configuration option also specifying the ‘Most Recent Not Failed Build’ criteria to match the parent job specification:
 
But… the proverbial good news, bad news. 
The good news is that it recreates the workspace of the upstream job in the pre-build process as the Hudson workspace of the downstream job prior to running any build steps. The workspace of the downstream job is identical to the workspace of the main build upstream job. The bad news is that it recreates the workspace of the upstream job in the pre-build process as the Hudson workspace of the downstream job prior to running any build steps. (Yes- that’s not a typo- they are the same.)
 
Even though we consider it temporary (it is replaced on each execution of the downstream job), the workspace cannot be automatically removed when the job is finished remaining on the slave tying up valuable disk storage. We attempted to use the ‘CleanUp all other workspaces on the same slavegroup’ Hudson Build Environment option, but it did not do what we expected. 
 
So now we had a new challenge. Even though we could now run the 17 downstream jobs independently of the main build job, i.e., on any capable slave, we added another problem to the list; lack of disk storage. In propagating the 6GB workspace 17 times, we had quickly consumed all available disk space on the slave. And in the future when we intend to utilize more than one slave, we could potentially have 18 6GB workspaces on each slave.

Ok, how about cloning AND sharing?
 
After a sudden stroke of brilliance (he said sarcastically), I finally came up with what would be our final solution. While implementing, revising, and testing it, I kept asking myself, “Why didn’t I think of this before?” It was a relatively simple solution, combining both previously thought-of theories, using the ‘Custom workspace’ Advanced Project option as well as the Clone Workspace SCM plug-in. The challenge was fine-tuning it so it would work.
 
To test my new architecture I was given three slaves that we prepared identically capable of running the main integration build. I created three Hudson jobs, one for each of the three slaves, to create a custom workspace using the cloned workspace of the main build job. The important difference between this configuration and the configuration of the previous Sonar analysis jobs that were also using the cloned workspace from the main integration build is that the workspace of each of these three jobs, which we call the ‘unarchive’ jobs for clarity, is a custom workspace named identically in each of the jobs. This is key. It is not a Hudson-created workspace (which contains the name of the job) as with the previous Sonar analysis jobs.
 
Each of the jobs, each pinned to a single slave, creates aX:\Hudson\workspace\AcmeMainProject as a custom workspace. The custom workspace is specified in the Advanced Project Options section:
 
After the three unarchive jobs have finished executing, each of the slaves has an identically named workspace with identical content.
 
I then reconfigured each of the downstream Sonar analysis jobs to use the workspace created by the unarchive jobs, X:\Hudson\workspace\AcmeMainProject, as a custom workspace and replaced the ‘Clone workspace’ SCM option with ‘None’. The result is that any of the analysis jobs can run on any of the three slaves since each of the three slaves has an identical workspace at theX:\Hudson\workspace\AcmeMainProject location.


Some final tuning...
After some trial and error and understanding that Hudson groups all jobs to be triggered alphabetically before triggering them regardless of how they are grouped in the triggering job, I finally developed an architecture of cascading jobs that would give us the capability we needed with a relatively minimal amount of disk storage as well as reduced the overall throughput time.
 
The main build job runs the 6-hour Ant build to produce the artifacts of the project. Upon successful completion, a single downstream job is triggered. That single downstream job does nothing more than trigger the three unarchive jobs as well as a fourth ‘trigger’ job. Using the combination of job names and job priorities, the three unarchive jobs run first, one on each capable slave, creating the custom workspace on each slave. The trigger job runs next because of a lower priority, on any of the slaves, and also does nothing more than trigger the 17 Sonar analysis jobs, the Findbugs job, and the Fortify analysis job. The downstream jobs are then released and run in alphabetical sequence within priority on any of the three slaves.
 
Using the Priority Sorter plug-in, I assigned declining priorities to the jobs reflecting the sequence in which they must run: 100 for the unarchive jobs, 75 to the trigger job, 50 to the Sonar analysis jobs, and 25 to the Findbugs and Fortify analysis jobs.
 
 
This guarantees that if all or any one of the slaves are(is) not available (either offline or another job is running on the slave) when the unarchive jobs are triggered, the unarchive jobs will execute prior to any of the downstream analysis jobs when the slave(s) again become(s) available.
 
So what was the bottom line, you ask?
Stem to stern including archiving and unarchiving the cloned workspace, the total throughput time of the entire build process (when all three slaves are available) was reduced from over 14 hours to just over 8 hours. Not only did we reduce the overall throughput time, we also reduced the total disk storage required by sharing the cloned workspaces.
 
Mission accomplished.

转载于:https://www.cnblogs.com/flysun0311/p/3548138.html

<think>好的,我现在需要解决用户的问题:在Docker构建过程中出现COPY失败,提示文件未找到,具体涉及到Jenkinsjenkins_home、workspace、target目录,可能与.dockerignore文件排除有关。用户还提到了Jenkins的安装和Docker相关操作。 首先,我得分析可能的原因。COPY失败通常有几个常见原因:源文件路径不正确、Docker构建上下文的问题、.dockerignore排除了需要的文件,或者文件确实不存在于构建上下文中。 用户提到Jenkins相关目录,比如jenkins_home、workspace,可能用户是在构建一个包含Jenkins数据的镜像,或者在构建过程中需要复制Jenkins工作空间中的文件。例如,用户可能在Dockerfile中使用COPY指令复制Jenkins工作目录下的target文件(比如Java项目的构建输出),但构建时提示文件不存在。 接下来,我需要考虑Docker的构建上下文。当运行docker build时,Docker客户端会将当前目录(构建上下文)发送给Docker守护进程。所有COPY指令的源路径都是相对于这个上下文的。如果用户的Dockerfile不在Jenkins的工作目录,或者构建上下文没有包含所需的文件,就会导致文件找不到。 另外,检查.dockerignore文件是否排除了target目录或其他必要文件。有时候,.dockerignore可能会忽略某些目录,导致COPY失败。 还需要确认在运行docker build时的上下文路径是否正确。例如,如果Jenkins的工作空间在/workspace/jenkins_home,而Dockerfile位于该目录下,用户应该在该目录下运行docker build -t image_name .。如果Dockerfile在其他位置,可能需要调整源路径或使用适当的构建上下文。 此外,用户可能在使用Docker卷挂载了jenkins_home,例如引用中的命令:-v /workspace/jenkins_home:/var/jenkins_home。这意味着Jenkins的数据存储在宿主机的/workspace/jenkins_home中。如果用户希望在构建镜像时复制宿主机上的这些文件,需要确保构建上下文包含这些路径,或者Dockerfile中的COPY指令正确指向这些位置。但需要注意,如果构建上下文不包含这些路径,即使宿主机上有文件,Docker也无法访问它们,因为构建时只能使用上下文内的文件。 可能的解决步骤包括: 1. 确认Dockerfile中COPY指令的源路径是否正确,相对于构建上下文。 2. 检查.dockerignore文件是否排除了必要的文件或目录。 3. 确保构建上下文包含需要复制的文件,即运行docker build时的当前目录是否正确。 4. 检查Jenkins的工作空间路径是否正确,文件是否确实存在。 5. 如果文件位于宿主机的挂载卷中,确保构建上下文包含该卷路径,或者调整Dockerfile的位置和COPY指令。 例如,假设用户的项目结构在Jenkins的工作空间是/workspace/jenkins_home/workspace/project,其中包含Dockerfile和target目录。用户应该在project目录下运行docker build,这样构建上下文就包含了target目录。Dockerfile中的COPY指令应为COPY target/app.jar /app/,这样就能正确复制。 如果用户使用了.dockerignore文件,其中可能有类似target/的排除项,这会导致COPY失败,需要检查并修改.dockerignore。 另外,用户可能在Dockerfile中使用了绝对路径,例如COPY /workspace/jenkins_home/workspace/project/target/app.jar /app/,这会导致错误,因为Docker的COPY指令不能使用绝对路径,必须使用相对于构建上下文的路径。 总结起来,用户需要检查构建上下文、COPY指令的路径、.dockerignore文件,并确认文件实际存在的位置是否在构建上下文中。</think>### 解决Docker构建中COPY失败(文件未找到)的步骤 #### 1. **确认构建上下文与路径正确性** - Docker的`COPY`指令只能复制**构建上下文内的文件**。构建上下文由`docker build`命令的最后一个参数指定(例如`docker build -t image_name .`中的`.`表示当前目录)。 - **示例问题**:若`Dockerfile`位于`/workspace/jenkins_home`,而需要复制的文件在`/workspace/jenkins_home/target`中,应确保执行构建命令时所在目录包含`target`目录。否则需调整路径或构建上下文[^2]。 #### 2. **检查`.dockerignore`文件** - 如果存在`.dockerignore`文件,可能排除了`target`或`workspace`目录。例如以下配置会忽略`target`目录: ```plaintext # .dockerignore示例(错误配置) target/ ``` - **解决方法**:移除相关排除规则,或添加例外(如`!target/app.jar`)[^3]。 #### 3. **验证文件实际存在性** - 在构建前,通过命令确认文件是否存在于构建上下文中: ```bash # 进入构建上下文目录 cd /workspace/jenkins_home ls -l target/app.jar # 检查目标文件是否存在 ``` - **注意**:如果文件由Jenkins构建生成(如Java项目的`target`目录),需确保构建步骤已成功执行。 #### 4. **调整Dockerfile中的COPY指令** - **错误示例**:使用绝对路径或错误相对路径: ```dockerfile COPY /var/jenkins_home/workspace/project/target/app.jar /app/ # 错误! ``` - **正确示例**:假设构建上下文为`/workspace/jenkins_home`,且文件位于`workspace/project/target`: ```dockerfile COPY workspace/project/target/app.jar /app/ ``` #### 5. **处理挂载卷与宿主机路径** - 如果使用`-v`挂载了Jenkins目录(如`-v /workspace/jenkins_home:/var/jenkins_home`),需注意: - Docker构建时**无法直接访问容器内挂载的文件**,必须通过宿主机路径操作。 - 确保宿主机上的`/workspace/jenkins_home`中存在所需文件。 --- ### 完整解决方案示例 假设项目结构如下: ```plaintext /workspace/jenkins_home ├── Dockerfile └── workspace/project └── target/app.jar ``` **步骤:** 1. 进入构建上下文目录: ```bash cd /workspace/jenkins_home ``` 2. 检查`.dockerignore`是否排除`workspace`或`target`。 3. 编写正确的`Dockerfile`: ```dockerfile FROM openjdk:11 COPY workspace/project/target/app.jar /app/app.jar CMD ["java", "-jar", "/app/app.jar"] ``` 4. 执行构建: ```bash docker build -t myapp . ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值