This repository has been archived on 2023-02-19. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-buildbot/master_unpack.py
Sergey Sharybin adbc6ebcea Commit local changes from server made by Brecht
Never, ever, ever such situation should happen.

From reading the change it seems it's related on making
it possible to build releases from the buildbot.
2019-11-08 09:24:53 +01:00

231 lines
7.4 KiB
Python

# ##### BEGIN GPL LICENSE BLOCK #####
#
# 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 2
# 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, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# Runs on Buildbot master, to unpack incoming unload.zip into latest
# builds directory and remove older builds.
# <pep8 compliant>
import argparse
import os
import shutil
import sys
import time
import zipfile
DOWNLOAD_DIR = "/data/www/vhosts/builder.blender.org/webroot/download/"
# Parse package filename to extract branch and platform
class Package:
def __init__(self, zipname):
self.zipname = zipname
self.filename = os.path.basename(zipname)
self.platform = self._get_platform(self.filename)
self.branch = self._get_branch(self.filename)
self.version = self._get_version(self.filename)
# extension stripping
def _strip_extension(self, filename):
extensions = '.zip', '.tar', '.bz2', '.xz', '.gz', '.tgz', '.tbz', '.exe'
for ext in extensions:
if filename.endswith(ext):
filename = filename[:-len(ext)]
return filename
# extract platform from package name
def _get_platform(self, filename):
# name is blender-version-platform.extension. we want to get the
# platform out, but there may be some variations, so we fiddle a
# bit to handle current and hopefully future names
filename = self._strip_extension(filename)
filename = self._strip_extension(filename)
tokens = filename.split("-")
platforms = ('osx', 'mac', 'bsd',
'win', 'linux', 'source',
'irix', 'solaris', 'mingw')
platform_tokens = []
found = False
for i, token in enumerate(tokens):
if not found:
for platform in platforms:
if platform in token.lower():
found = True
break
if found:
platform_tokens += [token]
return '-'.join(platform_tokens)
def _get_version(self, filename):
tokens = filename.split("-")
use_next_token = False
for token in tokens:
if use_next_token:
return token
elif token == "blender":
use_next_token = True
return ""
def _get_branch(self, filename):
tokens = filename.split("-")
branch = ""
for token in tokens:
if token == "blender":
return branch
if branch == "":
branch = token
else:
branch = branch + "-" + token
return ""
def get_download_dir(branch):
if not branch or branch == 'master':
directory = DOWNLOAD_DIR
elif branch == 'experimental-build':
directory = os.path.join(DOWNLOAD_DIR, "experimental")
else:
directory = os.path.join(DOWNLOAD_DIR, branch)
os.makedirs(directory, exist_ok=True)
os.chmod(directory, 0o755)
return directory
def open_zipfile(filename):
# Open zip file
if not os.path.exists(filename):
sys.stderr.write("File %r not found.\n" % filename)
sys.exit(1)
try:
return zipfile.ZipFile(filename, "r")
except Exception as ex:
sys.stderr.write('Failed to open zip file: %s\n' % str(ex))
sys.exit(1)
def get_zipfile_packages(zipfile):
# List packages in zip file
packages = [Package(zipname) for zipname in zipfile.namelist()]
if len(packages) == 0:
sys.stderr.write('Empty zip file\n')
sys.exit(1)
return packages
def get_branch_platform(packages):
# Extract branch and platform names
branch = packages[0].branch
platform = packages[0].platform
version = packages[0].version
if platform == '':
sys.stderr.write('Failed to detect platform ' +
'from package: %r\n' % packages[0].filename)
sys.exit(1)
for package in packages:
if package.branch != branch or package.platform != platform or package.version != version:
sys.stderr.write('All packages in the zip file must have the same branch and platform\n')
sys.exit(1)
return branch, platform, version
def extract_zipfile_packages(zipfile, packages, branch):
# Extract packages from zip file
directory = get_download_dir(branch)
for package in packages:
filepath = os.path.join(directory, package.filename)
try:
zf = zipfile.open(package.zipname)
f = open(filepath, "wb")
shutil.copyfileobj(zf, f)
os.chmod(filepath, 0o644)
zf.close()
except Exception as ex:
sys.stderr.write('Failed to unzip package: %s\n' % str(ex))
sys.exit(1)
def remove_replaced_packages(branch, platform, version, new_packages):
# Remove other files from the same platform and branch that are replaced
# by the new packages.
directory = get_download_dir(branch)
for filename in os.listdir(directory):
package = Package(filename)
if package.platform == platform and package.branch == branch and package.version == version:
is_new_package = False
for new_package in new_packages:
if package.filename == new_package.filename:
is_new_package = True
if not is_new_package:
try:
print("Removing older package version", filename)
os.remove(os.path.join(directory, filename))
except Exception as ex:
sys.stderr.write('Failed to remove replaced package: %s\n' % str(ex))
def remove_old_packages():
# Remove any branch packages that are 100 days or older.
cutoff_time = time.time() - 100 * 86400
for dirname in os.listdir(DOWNLOAD_DIR):
dirpath = os.path.join(DOWNLOAD_DIR, dirname)
if not os.path.isdir(dirpath):
continue
for filename in os.listdir(dirpath):
filepath = os.path.join(dirpath, filename)
if not os.path.isfile(filepath):
continue
file_mtime = os.stat(filepath).st_mtime
if file_mtime < cutoff_time:
try:
print("Removing old branch build", filename)
os.remove(filepath)
except Exception as ex:
sys.stderr.write('Failed to remove old package: %s\n' % str(ex))
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('filename')
args = parser.parse_args()
with open_zipfile(args.filename) as zipfile:
packages = get_zipfile_packages(zipfile)
branch, platform, version = get_branch_platform(packages)
extract_zipfile_packages(zipfile, packages, branch)
remove_replaced_packages(branch, platform, version, packages)
remove_old_packages()