From 772389357c4f1bc34617c279aeef824107cecb62 Mon Sep 17 00:00:00 2001 From: Nicola Corna Date: Tue, 6 Jun 2017 08:27:09 +0200 Subject: [PATCH] Add DELETE_OLD_ZIPS and DELETE_OLD_DELTAS --- Dockerfile | 10 +++++-- src/build.sh | 6 +++++ src/clean_up.py | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 2 deletions(-) create mode 100755 src/clean_up.py diff --git a/Dockerfile b/Dockerfile index e0df7ce..927ef33 100644 --- a/Dockerfile +++ b/Dockerfile @@ -56,7 +56,7 @@ ENV DEBUG false # Clean artifacts output after each build ENV CLEAN_AFTER_BUILD true -# Provide root capabilities builtin inside the ROM ( see http://lineageos.org/Update-and-Build-Prep/ ) +# Provide root capabilities builtin inside the ROM (see http://lineageos.org/Update-and-Build-Prep/) ENV WITH_SU true # Provide a default JACK configuration in order to avoid out-of-memory issues @@ -76,9 +76,15 @@ ENV ZIP_SUBDIR false # permission only to the privileged apps) ENV SIGNATURE_SPOOFING "no" -# Generate delta files (saved in $ZIP_DIR/delta) +# Generate delta files ENV BUILD_DELTA false +# Delete old zips in $ZIP_DIR, keep only the N latest one (0 to disable) +ENV DELETE_OLD_ZIPS 0 + +# Delete old deltas in $DELTA_DIR, keep only the N latest one (0 to disable) +ENV DELETE_OLD_DELTAS 0 + # Create Volume entry points ############################ VOLUME $SRC_DIR diff --git a/src/build.sh b/src/build.sh index c4270c5..b21d08d 100755 --- a/src/build.sh +++ b/src/build.sh @@ -132,12 +132,18 @@ if ! [ -z "$DEVICE_LIST" ]; then echo ">> [$(date)] No previous build for $codename; using current build as base for the next delta" >> $DOCKER_LOG mkdir -p $SRC_DIR/delta_last/$codename/ find out/target/product/$codename -name 'lineage-*.zip' -exec cp {} $SRC_DIR/delta_last/$codename/ \; + if [ "$DELETE_OLD_DELTAS" -gt "0" ]; then + /usr/bin/python /root/clean_up.py -n $DELETE_OLD_DELTAS $DELTA_DIR + fi fi fi # Move produced ZIP files to the main OUT directory echo ">> [$(date)] Moving build artifacts for $codename to '$ZIP_DIR/$zipsubdir'" >> $DOCKER_LOG cd $SRC_DIR find out/target/product/$codename -name 'lineage-*.zip*' -exec mv {} $ZIP_DIR/$zipsubdir/ \; >&$DEBUG_LOG + if [ "$DELETE_OLD_ZIPS" -gt "0" ]; then + /usr/bin/python /root/clean_up.py -n $DELETE_OLD_ZIPS $ZIP_DIR + fi else echo ">> [$(date)] Failed build for $codename" >> $DOCKER_LOG fi diff --git a/src/clean_up.py b/src/clean_up.py new file mode 100755 index 0000000..78f4f33 --- /dev/null +++ b/src/clean_up.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# clean_up.py - Remove old Android builds or delta files +# Copyright (C) 2017 Niccolò Izzo +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from os import walk, remove +from os.path import basename +from re import compile +from datetime import datetime +from argparse import ArgumentParser + + +def clean_path(path, builds_to_keep): + files = [] + scandir = path[:-1] if path[-1] == "/" else path + for (dirpath, dirnames, filenames) in walk(scandir): + files.extend([dirpath+"/"+f for f in filenames]) + files_re = compile("lineage-[\d,.]+-[\d]+-[\w]+-[\w]+[.,\w]+") + build_files = [f for f in files if files_re.match(basename(f))] + build_re = compile("lineage-[\d,.]+-[\d]+-[\w]+-[\w]+") + builds = {} + # builds = {codename: {buildname: (date, [path, ...]), ...}, ...} + for f in build_files: + build_name = build_re.search(f).group(0) + token_list = build_name.split("/")[-1].split("-") + codename = token_list[4] + date = datetime.strptime(token_list[2], "%Y%m%d") + path = f + if codename not in builds: + builds[codename] = {build_name: (date, [path])} + elif build_name not in builds[codename]: + builds[codename][build_name] = (date, [path]) + else: + builds[codename][build_name][1].append(path) + # Clean up old builds + for codename, build in builds.items(): + build_list = list(build.values()) + build_list.sort(key=lambda b: b[0]) + n_builds = len(build_list) + if n_builds > builds_to_keep: + for b in build_list[0:n_builds-builds_to_keep]: + list(map(remove, b[1])) + + +def main(): + parser = ArgumentParser(description='Clean up old builds.') + parser.add_argument('paths', metavar='PATH', type=str, nargs='+', + help='a path to be cleaned') + parser.add_argument('-n', metavar='N_BUILDS', type=int, nargs='?', + default=3, help='select the number of builds to keep') + args = parser.parse_args() + for path in args.paths: + clean_path(path, args.n) + + +if __name__ == "__main__": + main()