index : releng | |
Archlinux32 release engineering | gitolite user |
summaryrefslogtreecommitdiff |
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | README.md | 55 | ||||
-rwxr-xr-x | al32-mktorrent.sh | 176 | ||||
-rw-r--r-- | magnet2feed.py | 30 |
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c82b53a --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.iso* +*sums +*.rss +.idea diff --git a/README.md b/README.md new file mode 100644 index 0000000..0de8b0e --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +# al32-mktorrent + +Torrent creation script for [ArchLinux32](https://archlinux32.org), with upload +capabilities via `scp` and to [hefur](https://github.com/abique/hefur). + +The latest torrents are hosted on [static.dopsi.ch](https://static.dopsi.ch/al32/) +along with the RSS feeds (for [i686](https://static.dopsi.ch/al32/feed_i686.rss) and +[dual](https://static.dopsi.ch/al32/feed_dual.rss)). + +## Usage + + al32-mktorrent.sh [ -d date ] [ -w webdir ] [ -t hefurdir ] [ arch... ] + +If no `arch` is specified both `i686` and `dual` will be generated. +If no `date` is specified, the script will prompt for a date during the process. +If `hefurdir` or `webdir` is not specified no file will be uploaded to +the corresponding server. + +## Features + + * [X] Torrent creation + * [X] Create a torrent file per architecture + * [X] Obtain the latest mirrorlist + * [X] Check mirrors for ISO availability + * [X] Download ISO + * [X] Check ISO + * [X] Create both torrent files at once + * [X] Create a magnet link per architecture + * [ ] Torrent upload + * [X] Upload the torrent file to a web server via SSH + * [X] Upload the torrent file to a torrent tracker via SSH + * [ ] Upload the torrent to transmission-server + * [ ] Inform the world of the new torrent file + * [X] Add the magnet link to a RSS feed + * [X] Upload the new RSS feed to the server + * [ ] Send an email to the arch-ports list + +## License + +> 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 <http://www.gnu.org/licenses/>. + +## Author + +Copyright (c) 2017 Simon Doppler (dopsi) diff --git a/al32-mktorrent.sh b/al32-mktorrent.sh new file mode 100755 index 0000000..6c01aff --- /dev/null +++ b/al32-mktorrent.sh @@ -0,0 +1,176 @@ +# 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 <http://www.gnu.org/licenses/>. + +#! /bin/bash +set -euo pipefail + +function join_by { local IFS="$1"; shift; echo "$*"; } + +usage () { + echo "Usage: $0 [-d date] [-w webdir] [-t hefurdir] [arch...]" +} + +fg_green="\033[32m" +fg_red="\033[31m" +fg_blue="\033[34m" +fg_reset="\033[0m" +fg_bold="\033[1m" + +MIRRORLIST_FILE="https://raw.githubusercontent.com/archlinux32/packages/master/core/pacman-mirrorlist/mirrorlist" + +function cleanup () { + echo -n -e "$fg_reset${fg_bold}Cleaning up directory...$fg_reset " + rm -f ./*.sig ./*.torrent ./*.rss sha512sums +} + +function create_torrent_for_arch () { + declare -a available_mirrors + mirrorlist="$(curl "$MIRRORLIST_FILE" 2>/dev/null | grep Server | cut -d '=' -f 2 | sed -e 's/\s//g;s_$arch/$repo_archisos/_')" + + if [ "$#" -eq 0 ] ; then + echo "No architecture specified, selecting 'i686'" + arch="i686" + elif [ "$#" -eq 1 ] ; then + echo "Selecting architecture '$1'" + arch="$1" + else + usage + echo "Too many arguments, exiting" >&2 + exit 1 + fi + + iso_string="archlinux-$iso_date-$arch.iso" + + for i in $mirrorlist ; do + echo -n -e "$fg_reset${fg_bold}Checking $fg_reset$fg_blue$i$fg_reset " + curl --connect-timeout 10 -g "$i" 2>/dev/null | grep -q "$iso_string" && ( + echo -e "$fg_reset${fg_green}OK$fg_reset" + ) || ( echo -e "$fg_reset${fg_red}Failed$fg_reset" ; false ) || continue + available_mirrors=(${available_mirrors[@]} "$i") + done + + echo "${#available_mirrors[@]} mirrors available" + + + if [ ! -f "$iso_string" ] ; then + echo -e "$fg_reset${fg_bold}Downloading iso...$fg_reset" + curl -O "${available_mirrors[0]}$iso_string" + else + echo -e "$fg_reset${fg_bold}Reusing already downloaded iso...$fg_reset" + fi + + + echo -e "$fg_reset${fg_bold}Downloading verification files...$fg_reset" + curl -O "${available_mirrors[0]}$iso_string.sig" + curl -O "${available_mirrors[0]}sha512sums" + + echo -n -e "$fg_reset${fg_bold}Checking PGP signature...$fg_reset " + gpg --verify "$iso_string.sig" "$iso_string" || exit 100 + echo -e "$fg_reset${fg_green}OK" + + echo -e "$fg_reset${fg_bold}Checking SHA512 sums...$fg_reset" + sha512sum --ignore-missing --check sha512sums || exit 101 + + echo -e "$fg_reset${fg_bold}Create torrent file...$fg_reset" + if [ -f "$iso_string.torrent" ] ; then + rm "$iso_string.torrent" + fi + mktorrent --announce=http://archlinux32.org:6969/announce --web-seed="$(join_by ',' "${available_mirrors[@]}")" "$iso_string" + + echo -e "$fg_reset${fg_bold}Create magnet link...$fg_reset" + magnet_link="$(transmission-show --magnet "$iso_string.torrent")" + echo "$magnet_link" + + echo -e "$fg_reset${fg_bold}Create RSS feed files...$fg_reset" + python "${0%/*}/magnet2feed.py" "$magnet_link" "$iso_date" +} + +function upload_file_to_remote_dir { + if [ -f "$1" ] && [ -n "$2" ] ; then + echo -e "$fg_reset${fg_bold}Uploading file$fg_reset ${fg_blue}$1$fg_reset ${fg_bold}to$fg_reset ${fg_blue}$1$fg_reset $fg_bold...$fg_reset" + scp "$1" "$2" + fi +} + +### Check for if required programs are present + +which mktorrent 2>&1 >/dev/null || ( + echo "Missing mktorrent" + exit 1 +) + +python -c "import feedgenerator" 2>/dev/null || ( + echo "Missing python module feedgenerator" + exit 1 +) + +which transmission-show 2>&1 >/dev/null || ( + echo "Missing transmission-show" + exit 1 +) + +### Actual program + +declare -a architectures=("i686" "dual") +iso_date='' +web_dir='' +hefur_dir='' + +while getopts "d:w:t:h" o; do + case "${o}" in + d) + iso_date=${OPTARG} + ;; + t) + hefur_dir=${OPTARG} + ;; + w) + web_dir=${OPTARG} + ;; + h) + usage + exit + ;; + *) + echo "$0: unknown option ${o}" >&2 + usage + ;; + esac +done +shift $((OPTIND-1)) + +if [ "$#" -gt 0 ] ; then + architectures=($@) +fi + +[ -z "$iso_date" ] && read -r -p "Date of the ISO: " iso_date + +cleanup + +for a in "${architectures[@]}" ; do + create_torrent_for_arch "$a" +done + +for a in "${architectures[@]}" ; do + torrent_filename="archlinux-$iso_date-$a.iso.torrent" + if [ -n "$web_dir" ] ; then + feed_filename="feed_$a.rss" + upload_file_to_remote_dir "$torrent_filename" "$web_dir" + upload_file_to_remote_dir "$feed_filename" "$web_dir" + fi + if [ -n "$hefur_dir" ] ; then + upload_file_to_remote_dir "$torrent_filename" "$hefur_dir" + fi +done + +# vim: set ts=4 sw=4: diff --git a/magnet2feed.py b/magnet2feed.py new file mode 100644 index 0000000..5dc767f --- /dev/null +++ b/magnet2feed.py @@ -0,0 +1,30 @@ +from feedgenerator import Rss201rev2Feed +import sys +from os.path import basename + +feed_url = 'https://static.dopsi.ch/al32/feed_{arch}.rss' +architectures = ['i686', 'dual'] + + +def main(link, date): + for arch in architectures: + feed = Rss201rev2Feed(title='ArchLinux32 torrent download feed ({arch} ISO)'.format(arch=arch), + link=feed_url, + description="A torrent feed to download the latest ArchLinux32 {arch} iso".format( + arch=arch + ), + language='en') + + feed.add_item(title='ArchLinux32 {arch} {date}'.format(arch=arch, date=date), + link=link, + description='ArchLinux32 {arch} {date}'.format(arch=arch, date=date)) + + with open(basename(feed_url).format(arch=arch), mode='w') as feed_file: + feed.write(feed_file, 'utf-8') + + +if __name__ == '__main__': + if len(sys.argv) != 3: + print('Error: {cmd} magnet date'.format(cmd=sys.argv[0])) + + main(link=sys.argv[1], date=sys.argv[2]) |