Move tar_fix from Python to Only Bash

This commit is contained in:
Jesus 2023-09-24 10:45:51 +08:00
parent d199f5a255
commit 6f292fc47a
No known key found for this signature in database
GPG Key ID: E607CE7149F4D71C
3 changed files with 57 additions and 103 deletions

View File

@ -10,16 +10,14 @@ Hyperbola Docker images.
Usage
======
- `git clone` this repository.
- `git clone` this repository and move to directory where you have cloned it.
- `cd` to a directory where you have cloned it.
- Generate bootstrap image with [hyperbola-bootstrap](https://git.sr.ht/~heckyel/hyperbola-bootstrap)
- Generate bootstrap image with [hyperbola-bootstrap](https://git.sr.ht/~heckyel/hyperbola-bootstrap) or download file from [archive.fridu.us](https://archive.fridu.us/hyperbola/iso/)
- Converter hyperbola-bootstrap to bootstrap image valid for docker
```console
$ python3 tar_fix.py --input=hyperbola-bootstrap.tar.gz --output=bootstrap.tar.gz
$ bash tar_fix.sh --input=hyperbola-bootstrap.tar.gz --output=bootstrap.tar.gz
```
- Make sure you have my `Dockerfile`, `.dockerignore` and the `bootstrap.tar.gz` in one directory.
@ -30,12 +28,6 @@ Usage
$ docker build --tag hyperbola:0.4 -f Dockerfile-Hyperbola-v04 .
```
or for Hyperbola Milky Way v0.3
```console
$ docker build --tag hyperbola:0.3 -f Dockerfile-Hyperbola-v03 .
```
License
=======

View File

@ -1,92 +0,0 @@
#!/usr/bin/env python3
import tarfile
import os
class Tarball:
def __init__(self, infile, outfile):
self.infile = infile
self.outfile = outfile
def drop_lead_comp(self):
"""Removes leading path component (top-level dir)
from input tar file."""
with tarfile.open(self.infile) as tarin, tarfile.open(self.outfile, 'w:gz') as tarout:
# Identify common top-level dir for all tarball
# components, and proceed if it's set.
lead_comp_name = os.path.commonpath(tarin.getnames())
if lead_comp_name:
prefix_len = len(lead_comp_name + '/')
# Remove top-level dir (eg. "root.x86_64" or "root.i686"
# in Hyperbola bootstrap tarballs) from the archive.
tarin.members.remove(tarin.getmember(lead_comp_name))
for m in tarin.members:
# Drop top-level dir prefix in all tarball
# component's paths.
m.path = m.path[prefix_len:]
# If component is a link, don't fetch its content.
# There's no point to that, and it helps avoiding
# KeyError("linkname 'something' not found") on "broken"
# symlinks, which are perfectly normal in a
# root FS tarball. And for hard links, the link
# target needs to be stripped of the prefix same as
# the file name.
if m.linkname:
if m.islnk():
m.linkname = m.linkname[prefix_len:]
tarout.addfile(m)
else:
tarout.addfile(m, tarin.extractfile(m))
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(
description="Remove leading path component from input tarball contents and save "
"the result in output tarball.", add_help=False)
group = parser.add_argument_group("Arguments")
group.add_argument("--help", action='store_true',
help="Show this help message and exit.")
args = parser.parse_known_args()
group.add_argument("--input", metavar='PATH', dest='infile',
type=str, help="Input tar[.gz/xz/bz2] file path.",
required=True)
group.add_argument("--output", metavar='PATH', dest='outfile',
type=str, help="Output tar.gz file path.",
required=True)
if args[0].help:
parser.exit(parser.print_help())
else:
args = parser.parse_args()
tarball = Tarball(args.infile, args.outfile)
tarball.drop_lead_comp()
# An error handling attempt I would like to remember. Note to self: it skips symlinks altogether.
#
# # Handle broken symlinks. They are perfectly normal in a root fs tarball, but tarfile module is not
# # prepared for that. Trying hard not to catch anything other than "linkname 'something' not found".
# try:
# # Write each modified component to output tarball.
# tarout.addfile(m, tarin.extractfile(m))
#
# except KeyError as error:
# if "linkname '" and "' not found" in str(error):
# print("Warning: the input tarball contains a dead symlink: '%s' to non-existent '%s'. No "
# "biggy, but you might want to know. It will be included in the output tarball as it "
# "is. Proceeding..." % (m.name, m.linkname), file=sys.stderr)
# else:
# raise
# And a compound list for all tar members:
#
# [m.path[prefix_len:] for m in tarin.members]

54
tar_fix.sh Normal file
View File

@ -0,0 +1,54 @@
#!/bin/bash
set -e
usage() {
echo "Uso: bash $0 --input=<archivo_entrada> --output=<archivo_salida>"
exit 1
}
printf '%b%s%b%s%b\n' '\e[1;32m' '==> ' '\e[0m\033[1m' 'Get the current directory path...' '\e[m'
current_dir=$(pwd)
# Check arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--input=*)
input_file="${1#*=}"
shift
;;
--output=*)
output_file="${1#*=}"
shift
;;
*)
usage
;;
esac
done
if [ -z "$input_file" ] || [ -z "$output_file" ]; then
usage
fi
printf '%b%s%b%s%b\n' '\e[1;32m' '==> ' '\e[0m\033[1m' 'Unzip the input file to a temporary directory...' '\e[m'
temp_dir=$(mktemp -d)
tar -xzvf "$input_file" -C "$temp_dir" || echo "Info: some tar failed, but the script will continue."
printf '%b%s%b%s%b\n' '\e[1;32m' '==> ' '\e[0m\033[1m' 'Rename files ending in .pacnew...' '\e[m'
find "$temp_dir" -type f -name "*.pacnew" -exec sh -c 'mv -f "$1" "${1%.pacnew}"' _ {} \;
printf '%b%s%b%s%b\n' '\e[1;32m' '==> ' '\e[0m\033[1m' 'Copy the contents of 'x86_64' to the root...' '\e[m'
rsync -a "$temp_dir/x86_64/" "$temp_dir/"
printf '%b%s%b%s%b\n' '\e[1;32m' '==> ' '\e[0m\033[1m' 'Delete the x86_64 directory using doas (requires privileges)...' '\e[m'
doas rm -rf "$temp_dir/x86_64"
printf '%b%s%b%s%b\n' '\e[1;32m' '==> ' '\e[0m\033[1m' "Make $output_file..." '\e[m'
(cd "$temp_dir" && tar -czvf "$current_dir/$output_file" *)
printf '%b%s%b%s%b\n' '\e[1;32m' '==> ' '\e[0m\033[1m' 'Clean the temporary directory using doas (requires privileges)...' '\e[m'
doas rm -rf "$temp_dir"
echo "The file $output_file has been successfully created! <3"