mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
relase: make github operations perfect
This commit is contained in:
committed by
Ciro Santilli
parent
b2238daee3
commit
60f0e98644
61
README.adoc
61
README.adoc
@@ -293,7 +293,7 @@ If you really want to develop semiconductors, your only choice is to join an uni
|
|||||||
|
|
||||||
==== About the QEMU Buildroot setup
|
==== About the QEMU Buildroot setup
|
||||||
|
|
||||||
link:https://en.wikipedia.org/wiki/Buildroot[Buildroot] is a set of `make` scripts that downloads from source and compiles compatible versions of:
|
link:https://en.wikipedia.org/wiki/Buildroot[Buildroot] is a set of Make scripts that download and compile from source compatible versions of:
|
||||||
|
|
||||||
* GCC
|
* GCC
|
||||||
* Linux kernel
|
* Linux kernel
|
||||||
@@ -553,7 +553,7 @@ Some times it works with the host QEMU:
|
|||||||
sudo apt-get install qemu-system-x86
|
sudo apt-get install qemu-system-x86
|
||||||
git clone https://github.com/cirosantilli/linux-kernel-module-cheat
|
git clone https://github.com/cirosantilli/linux-kernel-module-cheat
|
||||||
cd linux-kernel-module-cheat
|
cd linux-kernel-module-cheat
|
||||||
./download-latest-release
|
./release-download-latest
|
||||||
unzip lkmc-*.zip
|
unzip lkmc-*.zip
|
||||||
./run --prebuilt
|
./run --prebuilt
|
||||||
....
|
....
|
||||||
@@ -9404,22 +9404,7 @@ vim "$(./getvar --arch arm run_cmd_file)"
|
|||||||
./"$(./getvar --arch arm run_cmd_file)"
|
./"$(./getvar --arch arm run_cmd_file)"
|
||||||
....
|
....
|
||||||
|
|
||||||
Next, you will also want to give the relevant images to save them time. Zip the images with:
|
Next, you will also want to give the relevant images to save them time, see: <<zip-img>>.
|
||||||
|
|
||||||
....
|
|
||||||
./build-all -G
|
|
||||||
./zip-img
|
|
||||||
....
|
|
||||||
|
|
||||||
Source: link:zip-img[]
|
|
||||||
|
|
||||||
This generates a zip file:
|
|
||||||
|
|
||||||
....
|
|
||||||
out/lkmc-*.zip
|
|
||||||
....
|
|
||||||
|
|
||||||
which you can then upload somewhere, e.g. GitHub release assets as in https://github.com/cirosantilli/linux-kernel-module-cheat/releases/tag/test-replay-arm
|
|
||||||
|
|
||||||
Finally, do a clone of the relevant repository out of tree and reproduce the bug there, to be 100% sure that it is an actual upstream bug, and to provide developers with the cleanest possible commands.
|
Finally, do a clone of the relevant repository out of tree and reproduce the bug there, to be 100% sure that it is an actual upstream bug, and to provide developers with the cleanest possible commands.
|
||||||
|
|
||||||
@@ -10338,7 +10323,7 @@ This can be used to check the determinism of:
|
|||||||
* <<norandmaps>>
|
* <<norandmaps>>
|
||||||
* <<qemu-record-and-replay>>
|
* <<qemu-record-and-replay>>
|
||||||
|
|
||||||
==== Releases
|
==== Release
|
||||||
|
|
||||||
This is not yet super stable, but one day maybe this script will automatically do a release:
|
This is not yet super stable, but one day maybe this script will automatically do a release:
|
||||||
|
|
||||||
@@ -10348,8 +10333,46 @@ This is not yet super stable, but one day maybe this script will automatically d
|
|||||||
|
|
||||||
Source: link:release[].
|
Source: link:release[].
|
||||||
|
|
||||||
|
When ready, that script should:
|
||||||
|
|
||||||
|
* build
|
||||||
|
* test
|
||||||
|
* package with <<release-zip>>
|
||||||
|
* upload to GitHub with link:release-create-github[]
|
||||||
|
|
||||||
This should in particular enable to easily update <<prebuilt>>.
|
This should in particular enable to easily update <<prebuilt>>.
|
||||||
|
|
||||||
|
===== release-zip
|
||||||
|
|
||||||
|
Create a zip containing all files required for <<prebuilt>>
|
||||||
|
|
||||||
|
....
|
||||||
|
./build-all -G
|
||||||
|
./release-zip
|
||||||
|
....
|
||||||
|
|
||||||
|
Source: link:release-zip[]
|
||||||
|
|
||||||
|
This generates a zip file:
|
||||||
|
|
||||||
|
....
|
||||||
|
echo "$(./getvar release_zip_file)"
|
||||||
|
....
|
||||||
|
|
||||||
|
which you can then upload somewhere.
|
||||||
|
|
||||||
|
For example, you can create or update a GitHub release and upload automatically with:
|
||||||
|
|
||||||
|
....
|
||||||
|
git push
|
||||||
|
printf "$GITHUB_TOKEN" > "$(./getvar github_token_file)"
|
||||||
|
./release-upload
|
||||||
|
....
|
||||||
|
|
||||||
|
Source: link:release-upload[]
|
||||||
|
|
||||||
|
TODO: generalize that so that people can upload to their forks.
|
||||||
|
|
||||||
=== Fairy tale
|
=== Fairy tale
|
||||||
|
|
||||||
____
|
____
|
||||||
|
|||||||
46
common.py
46
common.py
@@ -6,6 +6,7 @@ import copy
|
|||||||
import datetime
|
import datetime
|
||||||
import glob
|
import glob
|
||||||
import imp
|
import imp
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
@@ -15,10 +16,10 @@ import stat
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
import urllib
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
this = sys.modules[__name__]
|
this = sys.modules[__name__]
|
||||||
|
|
||||||
# Default paths.
|
|
||||||
root_dir = os.path.dirname(os.path.abspath(__file__))
|
root_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
data_dir = os.path.join(root_dir, 'data')
|
data_dir = os.path.join(root_dir, 'data')
|
||||||
p9_dir = os.path.join(data_dir, '9p')
|
p9_dir = os.path.join(data_dir, '9p')
|
||||||
@@ -34,8 +35,7 @@ extract_vmlinux = os.path.join(linux_src_dir, 'scripts', 'extract-vmlinux')
|
|||||||
qemu_src_dir = os.path.join(submodules_dir, 'qemu')
|
qemu_src_dir = os.path.join(submodules_dir, 'qemu')
|
||||||
parsec_benchmark_src_dir = os.path.join(submodules_dir, 'parsec-benchmark')
|
parsec_benchmark_src_dir = os.path.join(submodules_dir, 'parsec-benchmark')
|
||||||
ccache_dir = os.path.join('/usr', 'lib', 'ccache')
|
ccache_dir = os.path.join('/usr', 'lib', 'ccache')
|
||||||
|
github_token_file = os.path.join(data_dir, 'github-token')
|
||||||
# Other default variables.
|
|
||||||
arch_map = {
|
arch_map = {
|
||||||
'a': 'arm',
|
'a': 'arm',
|
||||||
'A': 'aarch64',
|
'A': 'aarch64',
|
||||||
@@ -44,6 +44,9 @@ arch_map = {
|
|||||||
arches = [arch_map[k] for k in arch_map]
|
arches = [arch_map[k] for k in arch_map]
|
||||||
gem5_cpt_prefix = '^cpt\.'
|
gem5_cpt_prefix = '^cpt\.'
|
||||||
sha = subprocess.check_output(['git', '-C', root_dir, 'log', '-1', '--format=%H']).decode().rstrip()
|
sha = subprocess.check_output(['git', '-C', root_dir, 'log', '-1', '--format=%H']).decode().rstrip()
|
||||||
|
release_dir = os.path.join(this.out_dir, 'release')
|
||||||
|
release_zip_file = os.path.join(this.release_dir, 'lkmc-{}.zip'.format(this.sha))
|
||||||
|
github_repo_id = 'cirosantilli/linux-kernel-module-cheat'
|
||||||
config_file = os.path.join(data_dir, 'config')
|
config_file = os.path.join(data_dir, 'config')
|
||||||
if os.path.exists(config_file):
|
if os.path.exists(config_file):
|
||||||
config = imp.load_source('config', config_file)
|
config = imp.load_source('config', config_file)
|
||||||
@@ -189,6 +192,39 @@ def get_toolchain_tool(tool):
|
|||||||
global this
|
global this
|
||||||
return glob.glob(os.path.join(this.host_bin_dir, '*-buildroot-*-{}'.format(tool)))[0]
|
return glob.glob(os.path.join(this.host_bin_dir, '*-buildroot-*-{}'.format(tool)))[0]
|
||||||
|
|
||||||
|
def github_make_request(
|
||||||
|
authenticate=False,
|
||||||
|
data=None,
|
||||||
|
extra_headers=None,
|
||||||
|
path='',
|
||||||
|
subdomain='api',
|
||||||
|
url_params=None,
|
||||||
|
**extra_request_args
|
||||||
|
):
|
||||||
|
global this
|
||||||
|
if extra_headers is None:
|
||||||
|
extra_headers = {}
|
||||||
|
headers = {'Accept': 'application/vnd.github.v3+json'}
|
||||||
|
headers.update(extra_headers)
|
||||||
|
if authenticate:
|
||||||
|
with open(this.github_token_file, 'r') as f:
|
||||||
|
token = f.read().rstrip()
|
||||||
|
headers['Authorization'] = 'token ' + token
|
||||||
|
if url_params is not None:
|
||||||
|
path += '?' + urllib.parse.urlencode(url_params)
|
||||||
|
request = urllib.request.Request(
|
||||||
|
'https://' + subdomain + '.github.com/repos/' + github_repo_id + path,
|
||||||
|
headers=headers,
|
||||||
|
data=data,
|
||||||
|
**extra_request_args
|
||||||
|
)
|
||||||
|
response_body = urllib.request.urlopen(request).read().decode()
|
||||||
|
if response_body:
|
||||||
|
_json = json.loads(response_body)
|
||||||
|
else:
|
||||||
|
_json = {}
|
||||||
|
return _json
|
||||||
|
|
||||||
def log_error(msg):
|
def log_error(msg):
|
||||||
print('error: {}'.format(msg), file=sys.stderr)
|
print('error: {}'.format(msg), file=sys.stderr)
|
||||||
|
|
||||||
@@ -340,7 +376,7 @@ def run_cmd(
|
|||||||
#signal.signal(signal.SIGPIPE, sigpipe_old)
|
#signal.signal(signal.SIGPIPE, sigpipe_old)
|
||||||
return proc.returncode
|
return proc.returncode
|
||||||
|
|
||||||
def setup(parser, **extra_args):
|
def setup(parser):
|
||||||
'''
|
'''
|
||||||
Parse the command line arguments, and setup several variables based on them.
|
Parse the command line arguments, and setup several variables based on them.
|
||||||
Typically done after getting inputs from the command line arguments.
|
Typically done after getting inputs from the command line arguments.
|
||||||
|
|||||||
30
release
30
release
@@ -1,31 +1,27 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
'''
|
||||||
|
https://upload.com/cirosantilli/linux-kernel-module-cheat#release
|
||||||
|
'''
|
||||||
|
|
||||||
import imp
|
import imp
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
import common
|
import common
|
||||||
zip_img = imp.load_source('zip_img', os.path.join(common.root_dir, 'zip-img'))
|
release_zip = imp.load_source('release_zip', os.path.join(common.root_dir, 'release-zip'))
|
||||||
|
release_upload = imp.load_source('release_upload', os.path.join(common.root_dir, 'release-upload'))
|
||||||
|
|
||||||
|
# TODO factor those out so we don't redo the same thing multiple times.
|
||||||
|
# subprocess.check_call([os.path.join(common.root_dir, 'test')])
|
||||||
|
# subprocess.check_call([os.path.join(common.root_dir, ''bench-all', '-A', '-u'])
|
||||||
|
|
||||||
subprocess.check_call([os.path.join(common.root_dir, 'test')])
|
|
||||||
# A clean release requires a full rebuild unless we hack it :-(
|
# A clean release requires a full rebuild unless we hack it :-(
|
||||||
# We can't just use our curent build as it contains packages we've
|
# We can't just use our curent build as it contains packages we've
|
||||||
# installed in random experiments. And with EXT2: we can't easily
|
# installed in random experiments. And with EXT2: we can't easily
|
||||||
# know what the smallest root filesystem size is and use it either...
|
# know what the smallest root filesystem size is and use it either...
|
||||||
# https://stackoverflow.com/questions/47320800/how-to-clean-only-target-in-buildroot
|
# https://stackoverflow.com/questions/47320800/how-to-clean-only-target-in-buildroot
|
||||||
subprocess.check_call([os.path.join(common.root_dir, 'build-all')])
|
subprocess.check_call([os.path.join(common.root_dir, 'build-all')])
|
||||||
zip_img.main()
|
release_zip.main()
|
||||||
tag = 'sha-{}'.format(common.sha)
|
subprocess.check_call(['git', 'push'])
|
||||||
subprocess.check_call(['git', 'tag', '-f', tag])
|
release_upload.main()
|
||||||
subprocess.check_call(['git', 'push', '--tags'])
|
|
||||||
# TODO
|
|
||||||
# - https://stackoverflow.com/questions/41022470/curl-request-to-add-file-to-github-release
|
|
||||||
# - https://stackoverflow.com/questions/38627115/upload-files-to-github-directory-using-github-api
|
|
||||||
# upload_basename = 'images-{}.zip'.format(common.sha)
|
|
||||||
#curl "https://api.github.com/repos/cirosantilli/linux-kernel-module-cheat/releases/tags/${tag}/assets?access_token=$(cat data/access_token)&tag_name=${upload_basename}" \
|
|
||||||
# --header 'Content-Type: application/zip' \
|
|
||||||
# --upload-file "${common_out_dir}/${upload_basename}" \
|
|
||||||
# -H 'Accept: application/vnd.github.v3+json' \
|
|
||||||
# -X POST \
|
|
||||||
#;
|
|
||||||
subprocess.check_call(['./bench-all', '-A', '-u'])
|
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Download the latest release from GitHub:
|
Usage: https://github.com/cirosantilli/linux-kernel-module-cheat#prebuilt
|
||||||
|
|
||||||
|
Implementation:
|
||||||
https://stackoverflow.com/questions/24987542/is-there-a-link-to-github-for-downloading-a-file-in-the-latest-release-of-a-repo/50540591#50540591
|
https://stackoverflow.com/questions/24987542/is-there-a-link-to-github-for-downloading-a-file-in-the-latest-release-of-a-repo/50540591#50540591
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import json
|
|
||||||
import urllib.request
|
import urllib.request
|
||||||
|
|
||||||
_json = json.loads(urllib.request.urlopen(urllib.request.Request(
|
import common
|
||||||
'https://api.github.com/repos/cirosantilli/linux-kernel-module-cheat/releases',
|
|
||||||
headers={'Accept' : 'application/vnd.github.full+json"text/html'}
|
_json = common.github_make_request(path='/releases')
|
||||||
)).read())
|
|
||||||
asset = _json[0]['assets'][0]
|
asset = _json[0]['assets'][0]
|
||||||
urllib.request.urlretrieve(asset['browser_download_url'], asset['name'])
|
urllib.request.urlretrieve(asset['browser_download_url'], asset['name'])
|
||||||
78
release-upload
Executable file
78
release-upload
Executable file
@@ -0,0 +1,78 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
'''
|
||||||
|
Usage: https://github.com/cirosantilli/linux-kernel-module-cheat#release-zip
|
||||||
|
|
||||||
|
Implementation:
|
||||||
|
|
||||||
|
* https://stackoverflow.com/questions/5207269/how-to-release-a-build-artifact-asset-on-github-with-a-script/52354732#52354732
|
||||||
|
* https://stackoverflow.com/questions/38153418/can-someone-give-a-python-requests-example-of-uploading-a-release-asset-in-githu/52354681#52354681
|
||||||
|
'''
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import urllib.error
|
||||||
|
|
||||||
|
import common
|
||||||
|
|
||||||
|
def main():
|
||||||
|
repo = common.github_repo_id
|
||||||
|
tag = 'sha-{}'.format(common.sha)
|
||||||
|
upload_path = common.release_zip_file
|
||||||
|
|
||||||
|
# Check the release already exists.
|
||||||
|
try:
|
||||||
|
_json = common.github_make_request(path='/releases/tags/' + tag)
|
||||||
|
except urllib.error.HTTPError as e:
|
||||||
|
if e.code == 404:
|
||||||
|
release_exists = False
|
||||||
|
else:
|
||||||
|
raise e
|
||||||
|
else:
|
||||||
|
release_exists = True
|
||||||
|
release_id = _json['id']
|
||||||
|
|
||||||
|
# Create release if not yet created.
|
||||||
|
if not release_exists:
|
||||||
|
_json = common.github_make_request(
|
||||||
|
authenticate=True,
|
||||||
|
data=json.dumps({
|
||||||
|
'tag_name': tag,
|
||||||
|
'name': tag,
|
||||||
|
'prerelease': True,
|
||||||
|
}).encode(),
|
||||||
|
path='/releases'
|
||||||
|
)
|
||||||
|
release_id = _json['id']
|
||||||
|
|
||||||
|
asset_name = os.path.split(upload_path)[1]
|
||||||
|
|
||||||
|
# Clear the prebuilts for a upload.
|
||||||
|
_json = common.github_make_request(
|
||||||
|
path=('/releases/' + str(release_id) + '/assets'),
|
||||||
|
)
|
||||||
|
for asset in _json:
|
||||||
|
if asset['name'] == asset_name:
|
||||||
|
_json = common.github_make_request(
|
||||||
|
authenticate=True,
|
||||||
|
path=('/releases/assets/' + str(asset['id'])),
|
||||||
|
method='DELETE',
|
||||||
|
)
|
||||||
|
break
|
||||||
|
|
||||||
|
# Upload the prebuilt.
|
||||||
|
with open(upload_path, 'br') as myfile:
|
||||||
|
content = myfile.read()
|
||||||
|
_json = common.github_make_request(
|
||||||
|
authenticate=True,
|
||||||
|
data=content,
|
||||||
|
extra_headers={'Content-Type': 'application/zip'},
|
||||||
|
path=('/releases/' + str(release_id) + '/assets'),
|
||||||
|
subdomain='uploads',
|
||||||
|
url_params={'name': asset_name},
|
||||||
|
)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
'''
|
||||||
|
https://github.com/cirosantilli/linux-kernel-module-cheat#release-zip
|
||||||
|
'''
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import zipfile
|
import zipfile
|
||||||
@@ -7,10 +11,10 @@ import zipfile
|
|||||||
import common
|
import common
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
outfile = os.path.join(common.out_dir, 'lkmc-{}.zip'.format(common.sha))
|
os.makedirs(common.release_dir, exist_ok=True)
|
||||||
if os.path.exists(outfile):
|
if os.path.exists(common.release_zip_file):
|
||||||
os.unlink(outfile)
|
os.unlink(common.release_zip_file)
|
||||||
zipf = zipfile.ZipFile(outfile, 'w', zipfile.ZIP_DEFLATED)
|
zipf = zipfile.ZipFile(common.release_zip_file, 'w', zipfile.ZIP_DEFLATED)
|
||||||
for arch in common.arches:
|
for arch in common.arches:
|
||||||
common.setup(common.get_argparse(default_args={'arch': arch}))
|
common.setup(common.get_argparse(default_args={'arch': arch}))
|
||||||
zipf.write(common.qcow2_file, arcname=os.path.relpath(common.qcow2_file, common.root_dir))
|
zipf.write(common.qcow2_file, arcname=os.path.relpath(common.qcow2_file, common.root_dir))
|
||||||
Reference in New Issue
Block a user