diff options
Diffstat (limited to 'import-layers/yocto-poky/meta/lib/rootfspostcommands.py')
-rw-r--r-- | import-layers/yocto-poky/meta/lib/rootfspostcommands.py | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/import-layers/yocto-poky/meta/lib/rootfspostcommands.py b/import-layers/yocto-poky/meta/lib/rootfspostcommands.py new file mode 100644 index 000000000..4742e0613 --- /dev/null +++ b/import-layers/yocto-poky/meta/lib/rootfspostcommands.py @@ -0,0 +1,56 @@ +import os + +def sort_file(filename, mapping): + """ + Sorts a passwd or group file based on the numeric ID in the third column. + If a mapping is given, the name from the first column is mapped via that + dictionary instead (necessary for /etc/shadow and /etc/gshadow). If not, + a new mapping is created on the fly and returned. + """ + new_mapping = {} + with open(filename, 'rb+') as f: + lines = f.readlines() + # No explicit error checking for the sake of simplicity. /etc + # files are assumed to be well-formed, causing exceptions if + # not. + for line in lines: + entries = line.split(b':') + name = entries[0] + if mapping is None: + id = int(entries[2]) + else: + id = mapping[name] + new_mapping[name] = id + # Sort by numeric id first, with entire line as secondary key + # (just in case that there is more than one entry for the same id). + lines.sort(key=lambda line: (new_mapping[line.split(b':')[0]], line)) + # We overwrite the entire file, i.e. no truncate() necessary. + f.seek(0) + f.write(b''.join(lines)) + return new_mapping + +def remove_backup(filename): + """ + Removes the backup file for files like /etc/passwd. + """ + backup_filename = filename + '-' + if os.path.exists(backup_filename): + os.unlink(backup_filename) + +def sort_passwd(sysconfdir): + """ + Sorts passwd and group files in a rootfs /etc directory by ID. + Backup files are sometimes are inconsistent and then cannot be + sorted (YOCTO #11043), and more importantly, are not needed in + the initial rootfs, so they get deleted. + """ + for main, shadow in (('passwd', 'shadow'), + ('group', 'gshadow')): + filename = os.path.join(sysconfdir, main) + remove_backup(filename) + if os.path.exists(filename): + mapping = sort_file(filename, None) + filename = os.path.join(sysconfdir, shadow) + remove_backup(filename) + if os.path.exists(filename): + sort_file(filename, mapping) |