1. For BUILD folder, use host system's folder to avoid using
overlayFS. The reason is overlayFS causes makecheck to fail.
2. Add SYS_PTRACE to all docker instance requested by Alexey.
3. When docker instance is being created, add -t option
to fix make check hang in libarchive.
Change-Id: Id71992d5ea212c44d11b4c2083125223358d7819
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/3831
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Vinay Kulkarni <kulkarniv@vmware.com>
... | ... |
@@ -2,6 +2,7 @@ from PackageUtils import PackageUtils |
2 | 2 |
from Logger import Logger |
3 | 3 |
from ToolChainUtils import ToolChainUtils |
4 | 4 |
from CommandUtils import CommandUtils |
5 |
+from ChrootUtils import ChrootUtils |
|
5 | 6 |
import os.path |
6 | 7 |
import sys |
7 | 8 |
from constants import constants |
... | ... |
@@ -28,6 +29,17 @@ class BuildContainer(object): |
28 | 28 |
self.pkgBuildOptionFile = pkgBuildOptionFile |
29 | 29 |
|
30 | 30 |
def prepareBuildContainer(self, containerTaskName, packageName, isToolChainPackage=False): |
31 |
+ # Prepare an empty chroot environment to let docker use the BUILD folder. |
|
32 |
+ # This avoids docker using overlayFS which will cause make check failure. |
|
33 |
+ chrootName="build-"+packageName |
|
34 |
+ chrUtils = ChrootUtils(self.logName,self.logPath) |
|
35 |
+ returnVal,chrootID = chrUtils.createChroot(chrootName) |
|
36 |
+ if not returnVal: |
|
37 |
+ raise Exception("Unable to prepare build root") |
|
38 |
+ cmdUtils = CommandUtils() |
|
39 |
+ cmdUtils.runCommandInShell("mkdir -p " + chrootID + constants.topDirPath) |
|
40 |
+ cmdUtils.runCommandInShell("mkdir -p " + chrootID + constants.topDirPath + "/BUILD") |
|
41 |
+ |
|
31 | 42 |
containerID = None |
32 | 43 |
mountVols = { |
33 | 44 |
constants.prevPublishRPMRepo: {'bind': '/publishrpms', 'mode': 'ro'}, |
... | ... |
@@ -36,6 +48,7 @@ class BuildContainer(object): |
36 | 36 |
constants.rpmPath: {'bind': constants.topDirPath + "/RPMS", 'mode': 'rw'}, |
37 | 37 |
constants.sourceRpmPath: {'bind': constants.topDirPath + "/SRPMS", 'mode': 'rw'}, |
38 | 38 |
constants.logPath + "/" + self.logName: {'bind': constants.topDirPath + "/LOGS", 'mode': 'rw'}, |
39 |
+ chrootID + constants.topDirPath + "/BUILD": {'bind': constants.topDirPath + "/BUILD", 'mode': 'rw'} |
|
39 | 40 |
} |
40 | 41 |
|
41 | 42 |
containerName = containerTaskName |
... | ... |
@@ -50,21 +63,20 @@ class BuildContainer(object): |
50 | 50 |
try: |
51 | 51 |
self.logger.info("BuildContainer-prepareBuildContainer: Starting build container: " + containerName) |
52 | 52 |
#TODO: Is init=True equivalent of --sig-proxy? |
53 |
+ privilegedDocker = False |
|
54 |
+ cap_list = ['SYS_PTRACE'] |
|
53 | 55 |
if packageName in constants.listReqPrivilegedDockerForTest: |
54 |
- containerID = self.dockerClient.containers.run(self.buildContainerImage, |
|
55 |
- detach=True, |
|
56 |
- privileged=True, |
|
57 |
- name=containerName, |
|
58 |
- network_mode="host", |
|
59 |
- volumes=mountVols, |
|
60 |
- command="/bin/bash -l -c /wait.sh") |
|
61 |
- else: |
|
62 |
- containerID = self.dockerClient.containers.run(self.buildContainerImage, |
|
56 |
+ privilegedDocker = True |
|
57 |
+ |
|
58 |
+ containerID = self.dockerClient.containers.run(self.buildContainerImage, |
|
63 | 59 |
detach=True, |
60 |
+ cap_add=cap_list, |
|
61 |
+ privileged=privilegedDocker, |
|
64 | 62 |
name=containerName, |
65 | 63 |
network_mode="host", |
66 | 64 |
volumes=mountVols, |
67 | 65 |
command="/bin/bash -l -c /wait.sh") |
66 |
+ |
|
68 | 67 |
self.logger.debug("Started Photon build container for task " + containerTaskName |
69 | 68 |
+ " ID: " + containerID.short_id) |
70 | 69 |
if not containerID: |
... | ... |
@@ -72,7 +84,7 @@ class BuildContainer(object): |
72 | 72 |
except Exception as e: |
73 | 73 |
self.logger.debug("Unable to start Photon build container for task " + containerTaskName) |
74 | 74 |
raise e |
75 |
- return containerID |
|
75 |
+ return containerID, chrootID |
|
76 | 76 |
|
77 | 77 |
def findPackageNameFromRPMFile(self, rpmfile): |
78 | 78 |
rpmfile = os.path.basename(rpmfile) |
... | ... |
@@ -131,12 +143,13 @@ class BuildContainer(object): |
131 | 131 |
#should initialize a logger based on package name |
132 | 132 |
containerTaskName = "build-" + package |
133 | 133 |
containerID = None |
134 |
+ chrootID = None |
|
134 | 135 |
isToolChainPackage = False |
135 | 136 |
if package in constants.listToolChainPackages: |
136 | 137 |
isToolChainPackage = True |
137 | 138 |
destLogPath = constants.logPath + "/build-"+package |
138 | 139 |
try: |
139 |
- containerID = self.prepareBuildContainer(containerTaskName, package, isToolChainPackage) |
|
140 |
+ containerID, chrootID = self.prepareBuildContainer(containerTaskName, package, isToolChainPackage) |
|
140 | 141 |
if not os.path.isdir(destLogPath): |
141 | 142 |
cmdUtils = CommandUtils() |
142 | 143 |
cmdUtils.runCommandInShell("mkdir -p "+destLogPath) |
... | ... |
@@ -192,6 +205,10 @@ class BuildContainer(object): |
192 | 192 |
# Remove the container |
193 | 193 |
if containerID is not None: |
194 | 194 |
containerID.remove(force=True) |
195 |
+ # Remove the dummy chroot |
|
196 |
+ if chrootID is not None: |
|
197 |
+ chrUtils = ChrootUtils(self.logName,self.logPath) |
|
198 |
+ chrUtils.destroyChroot(chrootID) |
|
195 | 199 |
|
196 | 200 |
def findRunTimeRequiredRPMPackages(self, rpmPackage): |
197 | 201 |
listRequiredPackages = SPECS.getData().getRequiresForPackage(rpmPackage) |
... | ... |
@@ -615,7 +615,7 @@ class PackageUtils(object): |
615 | 615 |
rpmBuildCmd += ' --define \"%s\"' % macro |
616 | 616 |
rpmBuildCmd += " " + specFile |
617 | 617 |
rpmBuildCmd = "/bin/bash -l -c '" + rpmBuildCmd + " > " + rpmLogFile + " 2>&1'" |
618 |
- rpmBuildCmd = "docker exec " + str(containerID.short_id) + " " + rpmBuildCmd |
|
618 |
+ rpmBuildCmd = "docker exec -t " + str(containerID.short_id) + " " + rpmBuildCmd |
|
619 | 619 |
|
620 | 620 |
cmdUtils = CommandUtils() |
621 | 621 |
self.logger.info("Building rpm for package: " + package) |