summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--README.md55
-rwxr-xr-xal32-mktorrent.sh176
-rw-r--r--magnet2feed.py30
4 files changed, 265 insertions, 0 deletions
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])