Bug 14822 - Inconsistent log when offline package is damaged and BB_NO_NETWORK is true
Summary: Inconsistent log when offline package is damaged and BB_NO_NETWORK is true
Status: RESOLVED OBSOLETE
Alias: None
Product: BitBake
Classification: Build System, Metadata & Runtime
Component: bitbake (show other bugs)
Version: unspecified
Hardware: x86 Multiple
: Medium normal
Target Milestone: 4.1
Assignee: Pavel Zhukov
QA Contact:
URL:
Whiteboard:
Depends on:
Blocks:
 
Reported: 2022-06-02 03:26 UTC by watson
Modified: 2022-06-16 15:48 UTC (History)
3 users (show)

See Also:
OS type for building Yocto: ---
Type of Regression: ---
Verified:
Documentation change: No (bug/feature does not impact docs)


Attachments
Contains log.do_fetch.0 and log.do_fetch.1 (5.58 KB, application/x-zip-compressed)
2022-06-02 03:26 UTC, watson
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description watson 2022-06-02 03:26:38 UTC
Created attachment 4871 [details]
Contains log.do_fetch.0 and log.do_fetch.1

---------------Summary---------------
If some packages on local machine for offline build is damaged, the log.do_fetch will change when running the same command.

---------------Details step to reproduce---------------
1. According to the instructions on https://docs.yoctoproject.org/dev-manual/common-tasks.html#replicating-a-build-offline, prepare an offline premirrors on the local machine, the path is <offline_downloads>.
2. Create a new build directory by `source oe-init-build-env <my_build_path>`. Make sure <my_build_path> is not under git repository, i.e. its ancestor diretories and itself does not contain .git directory.
3. Edit conf/local.conf in <my_build_path>. Add the following lines to the default one.
###############
BB_GENERATE_MIRROR_TARBALLS = "1"
INHERIT += "own-mirrors"
SOURCE_MIRROR_URL = "file://<offline_downloads>"
#The location where nativesdk comes from
UNINATIVE_URL = "file://<offline_downloads>/uninative/9bfc4c970495b3716b2f9e52c4df9f968c02463a9a95000f6657fbc3fde1f098/"
UNINATIVE_TARBALL = "x86_64-nativesdk-libc-3.6.tar.xz"
UNINATIVE_CHECKSUM[x86_64] = "9bfc4c970495b3716b2f9e52c4df9f968c02463a9a95000f6657fbc3fde1f098"
PREMIRRORS:prepend = "\
 git://.*/.* http://example.com/ \n \
 ftp://.*/.* http://example.com/ \n \
 http://.*/.* http://example.com/ \n \
 https://.*/.* http://example.com/ \n"
BB_NO_NETWORK = "1"
###############
4. Change the content of git2_github.com.besser82.libxcrypt.git.tar.gz in <offline_downloads> so that it is not a valid tar.gz format.
5. Run the command `bitbake core-image-minimal --runall=unpack`. The content of log.do_fetch is like log.do_fetch.0. This is some analysis for the log.
The download(self, urls=None) method of Fetch class calls m.try_premirror(ud, self.d) to check whether to try premirrors. Here, m is Git class type.  Because BB_FETCH_PREMIRRORONLY is false and downloads/git2/github.com.besser82.libxcrypt.git/ does not exist, try_premirror(self, ud, d) of Git class return true.
The download(self, urls=None) method of Fetch class calls the method try_mirrors(self, fetch, urldata, d, mirrors, check=False) of FetchMethod class because Git class dose not have try_mirrors().
The static method try_mirrors(fetch, d, origud, mirrors, check = False) is called.
The static method try_mirror_url(fetch, origud, ud, ld, check = False) is called.
In line 64, try_mirror_url() calls origud.method.download(origud, ld). Here, origud is Git class type. I add some log messages to debug this issue.
In line 65, the download(self, ud, d) method of Git class calls runfetchcmd("tar -xzf %s" % ud.fullmirror, d, workdir=ud.clonedir) to decompress the offline package.
In line 69~71, runfetchcmd() fails because the file is an invalid tar.gz format.
In line 73,  bb.fetch2.BBFetchException is thrown by origud.method.download().
The method try_mirror_url() in __init__.py calls ud.method.clean(ud, ld). Note that ud is Local class here, and origud is Git class.
The empty directory downloads/git2/github.com.besser82.libxcrypt.git/ will remain in <my_build_path>.

6. Run the command `bitbake core-image-minimal --runall=unpack` again. The content of log.do_fetch is like log.do_fetch.1. This is some analysis for the log.
The download(self, urls=None) method of Fetch class calls m.try_premirror(ud, self.d) to check whether to try premirrors. Here, m is Git class type.  Because BB_FETCH_PREMIRRORONLY is false and downloads/git2/github.com.besser82.libxcrypt.git/ already exist, try_premirror(self, ud, d) of Git class return false.
In line 8, the download(self, urls=None) method of Fetch class calls m.download(ud, self.d) of Git class to download from Git server.
In line 16~17, the download(self, urls=None) method of Fetch class calls m.clean(ud, self.d) to remove downloads/git2/github.com.besser82.libxcrypt.git/.

7. Repeat the command `bitbake core-image-minimal --runall=unpack`. The content of log.do_fetch for git2_github.com.besser82.libxcrypt.git.tar.gz will switch between log.do_fetch.0 and log.do_fetch.1.

---------------Simple conclusion---------------
Currently, the static method try_mirror_url(fetch, origud, ud, ld, check = False) just calls ud.method.clean() for exceptions. In my case, origud.method.download() is called and leaves an empty directory. And it affects the second command.
It may be necessary for try_mirror_url() to call origud.method.clean() if some exceptions is thrown by origud.method.download().
If I make such changes to try_mirror_url(), the log.do_fetch will be always like log.do_fetch.0.

Note:
- In step 2, it is important that the build directory <my_build_path> is not a descendant of a git repository. Otherwise, the behaviour will be different.
- In step 4, I just choose the package for my example. The behaviour is same if another package using Git protocol is chosen.
- In step 4, alternatively I could change the permission of the file git2_github.com.besser82.libxcrypt.git.tar.gz to un-readable.
- The use case is unusual. Although we should take care of the offline packages and keep them consistent, it is still possible to corrupt them by accident. The log file should help find the root cause.
Comment 1 Pavel Zhukov 2022-06-16 15:48:59 UTC
This was eventually fixed in https://git.openembedded.org/bitbake/commit/?id=b47ecab3e3aad5c5c376ec023aa82a51aa0f3b86

In current implementation fetcher will not try git commands if it sees fullmirror (even broken one). The flow fails with [1] in both cases.

[1]

gzip: stdin: not in gzip format
tar: Child returned status 1
tar: Error is not recoverable: exiting now