From 49595c6649ad0483c4468cdb8db7f5cc148e2971 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Tue, 29 Aug 2017 17:17:25 +0200 Subject: [PATCH] Initial commit --- .gitignore | 2 + build_deb | 118 +++++++ config | 38 +++ daily_build | 151 +++++++++ distributions | 28 ++ init.sh | 10 + keys/.gitkeep | 0 package_helpers.sh | 60 ++++ pbuilder/build-sources | 30 ++ pbuilder/images/.gitkeep | 0 pbuilder/repos/.gitkeep | 0 rebuildd/build-binaries | 64 ++++ rebuildd/get-sources | 10 + rebuildd/upload-binaries | 101 ++++++ repo/include-changes | 22 ++ repo/move-to-incoming | 26 ++ repo/process-include | 46 +++ sendxmpp | 702 +++++++++++++++++++++++++++++++++++++++ ynh-build | 105 ++++++ 19 files changed, 1513 insertions(+) create mode 100644 .gitignore create mode 100755 build_deb create mode 100644 config create mode 100755 daily_build create mode 100644 distributions create mode 100644 init.sh create mode 100644 keys/.gitkeep create mode 100644 package_helpers.sh create mode 100755 pbuilder/build-sources create mode 100644 pbuilder/images/.gitkeep create mode 100644 pbuilder/repos/.gitkeep create mode 100755 rebuildd/build-binaries create mode 100755 rebuildd/get-sources create mode 100755 rebuildd/upload-binaries create mode 100755 repo/include-changes create mode 100755 repo/move-to-incoming create mode 100755 repo/process-include create mode 100755 sendxmpp create mode 100755 ynh-build diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..587035d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +pbuilder/images/* +keys/* diff --git a/build_deb b/build_deb new file mode 100755 index 0000000..7ff9f91 --- /dev/null +++ b/build_deb @@ -0,0 +1,118 @@ +#!/bin/bash + +# Default options values +## Either building source in a chroot env or not +BUILD_SRC_LOCALLY=false + +## Debian distribution to use +CODENAME= +DISTRIBUTION= + +# Global and environment variables +source /home/vinaigrette/config +export DEBSIGN_KEYID +export DEBFULLNAME +export DEBEMAIL + +usage() +{ +cat << EOF +Usage: `basename $0` [options] DIR + +ARGUMENTS: + DIR Root directory of the package to build + +OPTIONS: + -c CODENAME Debian codename target + (one of: $AVAILABLE_CODENAMES) + -d COMPONENT Repository component to put package in + (one of: $AVAILABLE_COMPONENTS) + -l Build sources locally (without pbuilder) + -h Print this help +EOF +exit +} + +# Parse options +while getopts :c:d:lh option; do + case "$option" in + c) + CODENAME=$OPTARG + ;; + d) + DISTRIBUTION=$OPTARG + ;; + l) + BUILD_SRC_LOCALLY=true + ;; + h) + usage + ;; + :) + echo "Option -$OPTARG requires an argument" + exit 1 + ;; + \?) + echo "-$OPTARG: invalid option" + exit 1 + ;; + esac +done + +shift $((OPTIND-1)) + +# Parse DIR argument +if [ $# -ne 1 ]; then + echo -e "Error: Missing DIR argument\n" + usage +fi +PKG_DIR=$(readlink -fn $1) +ROOT_DIR=$(readlink -fn ${PKG_DIR}/../) + +# Retrieve package info +cd $PKG_DIR +package=$(dpkg-parsechangelog | awk '/^Source: / {print $2}') +version=$(dpkg-parsechangelog | awk '/^Version: / {print $2}') +distribution=$(dpkg-parsechangelog | awk '/^Distribution: / {print $2}') + +# Set and validate codename & distribution +if [ -z "$CODENAME" ]; then + CODENAME=$DEFAULT_CODENAME +elif ! [[ $AVAILABLE_CODENAMES =~ ^(.* |)$CODENAME( .*|)$ ]]; then + echo "Unmanaged codename '$CODENAME'" + exit 1 +fi +if [ -z "$DISTRIBUTION" ]; then + extract_codename_distribution $distribution || exit 1 +fi + +changes_file=${ROOT_DIR}/${package}_${version}_source.changes + +echo "Building source package of ${package}_${version}..." +if $BUILD_SRC_LOCALLY; then + debuild -S -sa > /dev/null +else + img="${PBUILDER_IMAGES}/amd64/${CODENAME}.tgz" + sudo pbuilder execute --bindmounts ${ROOT_DIR} \ + --basetgz ${img} -- ${BUILD_SOURCES} $PKG_DIR +fi +if [ $? -ne 0 ] || [ ! -f ${changes_file} ]; then + echo "An error occured while building source package" + exit 1 +fi + +echo "Adding ${package}_${version} to ${CODENAME}/${DISTRIBUTION}..." +$INCLUDE_CHANGES $CODENAME $DISTRIBUTION $changes_file +if [ $? -ne 0 ]; then + echo "An error occured while including source package" + exit 1 +fi + +#echo "Process incoming in repository..." +#sudo reprepro -V -b $REPO_DIR processincoming incoming +#if [ $? -ne 0 ]; then +# echo "An error occured while processing incoming" +# exit 1 +#fi + +echo "Build will start soon. See http://rebuild.yunohost.org" diff --git a/config b/config new file mode 100644 index 0000000..4603a53 --- /dev/null +++ b/config @@ -0,0 +1,38 @@ +#!/bin/bash + +DEBSIGN_KEYID=59A3E6FF +DEBFULLNAME="YunoHost Contributors" +DEBEMAIL="contrib@yunohost.org" + +HOME_VINAIGRETTE="/home/vinaigrette" +GIT_REPOS="$HOME_VINAIGRETTE/repos/" +BUILD_DEB="$HOME_VINAIGRETTE/build_deb" + +PBUILDER_HOME="$HOME_VINAIGRETTE/pbuilder/" +PBUILDER_IMAGES="$PBUILDER_HOME/images/" +PBUILDER_RESULTS="$PBUILDER_HOME/results/" +DAILY_PACKAGES="$PBUILDER_HOME/packages/" + +BUILD_SOURCES="$PBUILDER_HOME/build-sources" +INCLUDE_CHANGES="$HOME_VINAIGRETTE/repo/include-changes" + +REPO_DIR=/var/www/repo/debian +PATATE_REPO_DIR=/var/www/repo/patate + + + + +AVAILABLE_CODENAMES="wheezy jessie stretch" +DEFAULT_CODENAME="jessie" + +AVAILABLE_COMPONENTS="old-stable stable testing unstable extra" +DEFAULT_COMPONENT="unstable" + +AVAILABLE_ARCH="amd64 i386 armhf" +DEFAULT_ARCH="amd64" + + + + +DEPS="pbuilder reprepro" +DEPS="dpkg-parsechangelog pbuilder mk-build-deps debuild debclean reprepo sendxmpp" diff --git a/daily_build b/daily_build new file mode 100755 index 0000000..e191294 --- /dev/null +++ b/daily_build @@ -0,0 +1,151 @@ +#!/bin/bash + +# Global and environment variables +source /home/vinaigrette/config +export DEBSIGN_KEYID +export DEBFULLNAME +export DEBEMAIL + +# Default options values +## Either building source in a chroot env or not +BUILD_SRC_LOCALLY=false +## Either force package build if there is no update or not +FORCE=false +## Final version of the package +VERSION="$(date +%Y.%m.%d)+$(date +%H%M)" +## Repository branch to checkout +BRANCH=unstable + +# Global and environment variables +DISTRIBUTION="unstable" +CODENAME="jessie" + + +usage() +{ +cat << EOF +Usage: `basename $0` [options] + +OPTIONS: + -p PACKAGE Package name to build + -v VERSION Package version to set (default: $VERSION) + -b BRANCH Branch to use (default: $BRANCH) + -f Force package building + -l Build sources locally + -h Print this help +EOF +exit +} + +# Parse options +while getopts ":fhlb:v:p:" option; do + case $option in + f) + FORCE=true + ;; + l) + BUILD_SRC_LOCALLY=true + ;; + v) + VERSION=$OPTARG + ;; + b) + BRANCH=$OPTARG + ;; + p) + REQUIRED_PACKAGE=$OPTARG + ;; + h) + usage + ;; + :) + echo "Option -$OPTARG requires an argument" + exit 1 + ;; + \?) + echo "-$OPTARG: invalid option" + exit 1 + ;; + esac +done + +cd $DAILY_PACKAGES + +# Find packages to build +if [ -n "$REQUIRED_PACKAGE" ]; then + NEW_PACKAGES=$REQUIRED_PACKAGE +else + NEW_PACKAGES=$(find . -maxdepth 1 -mindepth 1 -type d | cut -d '/' -f2 | grep -v SSOwat | sort) + if [ ! -n "$NEW_PACKAGES" ]; then + exit 1 + fi +fi + +PKG_TO_BUILD=0 + +for package in $NEW_PACKAGES; do + cd $DAILY_PACKAGES/$package + + echo "---------------------------------------------" + echo "Selected package: ${package}" + + # Fetch and update package from origin + echo "Looking for changes from git..." + git fetch origin + git checkout $BRANCH + if ! $FORCE && [ -z "$(git log $BRANCH..origin/$BRANCH)" ]; then + echo "Local sources already up-to-date" + continue + fi + git pull origin $BRANCH + + echo "Updating changelog to version ${VERSION}" + rm -f debian/changelog.dch + cp debian/changelog debian/changelog.old + dch --package $package -v "${VERSION}" -D ${DISTRIBUTION} --force-distribution "Daily build." -b > /dev/null 2>&1 + + changes_file=${DAILY_PACKAGES}/${package}_${VERSION}_source.changes + + echo "Building source package of ${package}_${VERSION}..." + if $BUILD_SRC_LOCALLY; then + debuild -S -sa > /dev/null + else + sudo pbuilder execute --bindmounts ${DAILY_PACKAGES} --basetgz /var/cache/pbuilder/images/amd64/${CODENAME}.tgz -- /usr/local/bin/pbuilder/build-sources ${DAILY_PACKAGES}/${package} + fi + if [ $? -ne 0 ] || [ ! -f ${changes_file} ]; then + echo "An error occured while building source package ${package}" + exit 1 + fi + + echo "Adding ${package}_${VERSION} to ${CODENAME}/${DISTRIBUTION}..." +# /usr/local/bin/repo/move-to-incoming "../${package}_${VERSION}_source.changes" + /usr/local/bin/repo/include-changes $CODENAME $DISTRIBUTION $changes_file + RET=$? + + # Do not save in changelog + cp debian/changelog.old debian/changelog + rm debian/changelog.old + + if [ $RET -ne 0 ]; then + echo "An error occured while building source package ${package}" + else + PKG_TO_BUILD+=1 + fi +done + +if [ $PKG_TO_BUILD -eq 0 ]; then + echo "Nothing to build" + exit 1 +fi + +#echo "Process incoming in repository..." +#sudo reprepro -C $DISTRIBUTION -V -b $REPO_DIR processincoming yunohost +#if [ $? -ne 0 ]; then +# echo "An error occured while processing incoming" +# exit 1 +#fi + +#echo "Update packages local database..." +#sudo apt-get update > /dev/null 1>&1 + +echo "Build will start soon. See http://rebuild.yunohost.org" diff --git a/distributions b/distributions new file mode 100644 index 0000000..a1d68b3 --- /dev/null +++ b/distributions @@ -0,0 +1,28 @@ +Origin: YunoHost +Label: YunoHost for Jessie +Suite: stable +Codename: jessie +Version: 8.0 +Architectures: i386 amd64 armel armhf source +Components: stable testing unstable extra +AlsoAcceptFor: jessie-stable jessie-testing jessie-unstable stable testing unstable +Update: jessie-stable jessie-testing +Description: YunoHost repository for Debian Jessie +SignWith: 59A3E6FF +Tracking: all includechanges keepsources +Log: logfile + --changes --via=include /home/vinaigrette/repo/process-include + +Origin: YunoHost +Label: YunoHost for Stretch +Suite: testing +Codename: stretch +Version: 9.0 +Architectures: i386 amd64 armel armhf source +Components: stable testing unstable extra +AlsoAcceptFor: stretch-stable stretch-testing stretch-unstable stable testing unstable +Description: YunoHost repository for Debian Stretch +SignWith: 59A3E6FF +Tracking: all includechanges keepsources +Log: logfile + --changes --via=include /home/vinaigrette/repo/process-include diff --git a/init.sh b/init.sh new file mode 100644 index 0000000..08c903d --- /dev/null +++ b/init.sh @@ -0,0 +1,10 @@ +cd /home/vinaigrette/repos/ +git clone https://github.com/yunohost/yunohost +git clone https://github.com/yunohost/yunohost-admin +git clone https://github.com/yunohost/ssowat +git clone https://github.com/yunohost/moulinette + +mkdir -p /var/www/repo/debian/conf/ +cp distributions /var/www/repo/debian/conf/ + + diff --git a/keys/.gitkeep b/keys/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/package_helpers.sh b/package_helpers.sh new file mode 100644 index 0000000..1db9ec6 --- /dev/null +++ b/package_helpers.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +# Get Files entries from a given .changes or .dsc file +get_files() +{ + file=$(readlink -fn $1) + echo $(awk '/^Files:/,EOF' $file | gawk '/^ [a-z0-9]{32} / {print $5}') +} + +# Get Distribution entry from a given .changes or .dsc file +get_distribution() +{ + file=$(readlink -fn $1) + echo $(awk '/^Distribution:/ {print $2}' $file) +} + +# Get Architecture entry from a given .changes or .dsc file +get_architecture() +{ + file=$(readlink -fn $1) + echo $(awk '/^Architecture:/ {print $2}' $file) +} + +# Extract Debian codename and YunoHost distribution if present. +# It should be something like wheezy-stable +extract_codename_distribution() +{ + if [[ $1 = *-* ]]; then + [[ $1 = "old-stable" ]] && return 0 + + i=0 + for p in `echo "$1" | tr "-" "\n"`; do + case $i in + 0) + if [[ $p =~ ^wheezy|jessie$ ]]; then + CODENAME=$p + else + echo "invalid Debian codename $p" + return 1 + fi + ;; + 1) + if [[ $p =~ ^stable|testing|unstable$ ]]; then + DISTRIBUTION=$p + else + echo "invalid distribution $p" + return 2 + fi + ;; + *) + echo "unexpected string '$p' (i=$i)" + return 3 + esac + i=`expr $i + 1` + done + elif ! [[ $1 =~ ^stable|testing|unstable$ ]]; then + echo "invalid distribution '$1'" + return 4 + fi +} diff --git a/pbuilder/build-sources b/pbuilder/build-sources new file mode 100755 index 0000000..3518d44 --- /dev/null +++ b/pbuilder/build-sources @@ -0,0 +1,30 @@ +#!/bin/bash + +PKG_PATH=$1 + +apt-get -q update + +VERSION=$(sed 's/\..*//' /etc/debian_version) +if [[ "$VERSION" == '7' ]]; then + apt-get -q -y -t wheezy-backports install devscripts +fi + +cd $PKG_PATH + +echo \ +"******************************************************************************" +echo "Installing build-dependencies..." + +mk-build-deps -i -r -t "apt-get --no-install-recommends -y" \ + || (echo "Error." && exit 1) +rm -f *build-deps*_all.deb + +echo \ +"******************************************************************************" +echo "Creating source package..." + +# Creating source package without signing it +debuild -S -sa -uc + +# Be sure to clean directory +debclean diff --git a/pbuilder/images/.gitkeep b/pbuilder/images/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/pbuilder/repos/.gitkeep b/pbuilder/repos/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/rebuildd/build-binaries b/rebuildd/build-binaries new file mode 100755 index 0000000..cf7e8ac --- /dev/null +++ b/rebuildd/build-binaries @@ -0,0 +1,64 @@ +#!/bin/bash + +codename=$1 +package=$2 +version=$3 +arch=$4 + +source /home/vinaigrette/repo/config +source /home/vinaigrette/package_helpers.sh + +# Build only binary-only limited to architecture dependent packages +DEBBUILDOPTS="-B" + +if [[ $arch == $DEFAULT_ARCH ]]; then + # Build architecture independent packages too + DEBBUILDOPTS="-b" +elif [[ $arch == all ]]; then + # Build architecture independent packages too on default arch + arch=$DEFAULT_ARCH + DEBBUILDOPTS="-b" +fi + +# Retrieve the number of processors +if [ -x /usr/bin/getconf ]; then + JOBS=`getconf _NPROCESSORS_CONF` +else + JOBS=1 +fi + +echo \ +"******************************************************************************" +echo "Starting building..." + +# Format needed pbuilder arguments +DEBBUILDOPTS="$DEBBUILDOPTS -j$JOBS" +DSC_FILE="${package}_${version}.dsc" +BASE_TGZ="/var/cache/pbuilder/images/${arch}/${codename}.tgz" +EXTRA_OPTS=() + +# Use specific conf for nodejs builds +if [[ $package =~ ^yunohost-admin$ ]]; then + base_tgz="/var/cache/pbuilder/images/${arch}/${codename}-nodejs.tgz" + if [[ -f ${base_tgz} ]]; then + echo "+ using nodejs environment..." + BASE_TGZ=${base_tgz} + fi +fi + +case $arch in + armhf) + pbuilder build --debbuildopts "${DEBBUILDOPTS}" \ + --configfile /etc/pbuilder/rc.d/armhf \ + --basetgz $BASE_TGZ "${EXTRA_OPTS[@]}" $DSC_FILE + exit_code=$? + ;; + + amd64|i386) + pbuilder build --debbuildopts "${DEBBUILDOPTS}" \ + --basetgz $BASE_TGZ "${EXTRA_OPTS[@]}" $DSC_FILE + exit_code=$? + ;; +esac + +exit $exit_code diff --git a/rebuildd/get-sources b/rebuildd/get-sources new file mode 100755 index 0000000..eb555c7 --- /dev/null +++ b/rebuildd/get-sources @@ -0,0 +1,10 @@ +#!/bin/bash + +codename=$1 +package=$2 +version=$3 + +sudo apt-get update > /dev/null 1>&1 +#apt-get -q --download-only --only-source -t $codename \ +apt-get -q --download-only --only-source \ + source ${package}=${version} diff --git a/rebuildd/upload-binaries b/rebuildd/upload-binaries new file mode 100755 index 0000000..1dc2cae --- /dev/null +++ b/rebuildd/upload-binaries @@ -0,0 +1,101 @@ +#!/bin/bash -p + +codename=$1 +package=$2 +version=$3 +arch=$4 +job=$5 + +source /home/vinaigrette/config +source /home/vinaigrette/package_helpers.sh +XMPP_BOT_KEY=$(cat /home/vinaigrette/keys/xmppbotkey) + +# Repository codename to add package to +CODENAME= + +# Either adding package to rpi repo or not +ADD_TO_RPI=false + +# Architecture independent packages are built on default arch +ARCH=$arch +[[ $arch == all ]] && ARCH=$DEFAULT_ARCH + +# Resulting changes file +CHANGES_FILE=$PBUILDER_RESULTS/${package}_${version}_${ARCH}.changes + +# Retrieve distribution/component +DISTRIBUTION=$(get_distribution $CHANGES_FILE) + +# Attempt to extract Debian codename from Distribution +extract_codename_distribution $DISTRIBUTION || exit 1 +[ -z "$CODENAME" ] && CODENAME=$1 + +# Add to rpi +#if [[ $4 == all ]] && [[ $DISTRIBUTION != unstable ]]; then +# ADD_TO_RPI=true +#fi + +# Retrieving component from source package +get_source_component() { + reprepro -b $REPO_DIR -T dsc --list-max 1 --list-format '${$component}' \ + listfilter $CODENAME "\$Source (==${package}), \$SourceVersion (==${version})" +} +COMPONENT=$(get_source_component) +if [ -z "$COMPONENT" ]; then + echo "Unable to retrieve source package component" + exit 1 +fi + +# Add to patate - soon-deprecated repo +ADD_TO_PATATE=false +if [[ $arch == all ]] && [[ $COMPONENT == "old-stable" ]]; then + ADD_TO_PATATE=true +fi + +echo \ +"******************************************************************************" +echo "Adding binary package..." + +include_to() { + # Include changes to the given repo (waiting 1m max) + echo "Adding to ${1}/$COMPONENT..." + reprepro --waitforlock 6 -b $REPO_DIR -C $COMPONENT include $1 \ + $CHANGES_FILE > /dev/null 1>&1 || return 1 +} +include_to_patate() { + echo "Adding to soon-deprecated repository in megusta..." + reprepro --waitforlock 6 -b $PATATE_REPO_DIR include megusta \ + $CHANGES_FILE > /dev/null 1>&1 || return 1 +} + +status=0 +if include_to $CODENAME ; then + if $ADD_TO_RPI; then + include_to "${CODENAME}/rpi" || status=1 + fi +else + status=1 +fi +if $ADD_TO_PATATE; then + include_to_patate || status=2 +fi + +if [ $status -eq 0 ]; then + # Clean pbuilder results + for f in $(get_files $CHANGES_FILE); do + rm -f /var/cache/pbuilder/result/$f + done +fi + + +# Send notification on xmpp dev room + +export HOME=$HOME_PBUILDER + +xmpp_msg="[rebuildd] Completed build of ${package}/${version} in ${COMPONENT} for ${CODENAME}/${arch}. See http://rebuild.yunohost.org/job/${job}" + +echo -n "$xmpp_msg" \ + | sendxmpp -u gitbot -j im.yunohost.org -p $XMPP_BOT_KEY \ + -c dev@conference.yunohost.org -r GitBot + +exit $status diff --git a/repo/include-changes b/repo/include-changes new file mode 100755 index 0000000..22baab9 --- /dev/null +++ b/repo/include-changes @@ -0,0 +1,22 @@ +#!/bin/bash + +codename=$1 +distribution=$2 +changes_file=$3 + +source /home/vinaigrette/config +source /home/vinaigrette/package_helpers.sh + +sudo reprepro -C $distribution -V -b $REPO_DIR include $codename $changes_file +RET=$? + +# Cleaning files +if [ $RET -eq 0 ]; then + dir=$(cd `dirname $changes_file` && pwd) + for f in $(get_files ${changes_file}); do + ! [[ $f =~ \.orig\.tar\.(gz|xz)$ ]] && sudo rm -f ${dir}/$f + done + sudo rm -f $changes_file +fi + +exit $RET diff --git a/repo/move-to-incoming b/repo/move-to-incoming new file mode 100755 index 0000000..6aa648c --- /dev/null +++ b/repo/move-to-incoming @@ -0,0 +1,26 @@ +#!/bin/bash + +changes_file=$1 + +source /home/vinaigrette/repo/config +source /home/vinaigrette/package_helpers.sh + +INCOMING_DIR=${REPO_DIR}/incoming + +# Retrieve changes file directory +dir=$(cd `dirname $changes_file` && pwd) + +# Move file to incoming directory +for f in $(get_files ${changes_file}); do + if [[ $f =~ \.orig\.tar\.(gz|xz)$ ]]; then + echo "* Copying ${f}..." + sudo cp ${dir}/${f} $INCOMING_DIR + else + echo "* Moving ${f}..." + sudo mv ${dir}/${f} $INCOMING_DIR + fi +done + +# Move changes file too +echo "* Moving $(basename ${changes_file})..." +sudo mv ${changes_file} $INCOMING_DIR diff --git a/repo/process-include b/repo/process-include new file mode 100755 index 0000000..fe932c9 --- /dev/null +++ b/repo/process-include @@ -0,0 +1,46 @@ +#!/bin/bash + +action=$1 +codename=$2 +package=$3 +version=$4 +changes_file=$5 + +source /usr/local/lib/helpers/debian/package.sh + +MAIL="rebuildd@yunohost.org" + +# Only care about packages being added +if [[ $action != accepted ]]; then + exit 1 +fi + +# Only care about source packages +arch=$(get_architecture $changes_file) +if [[ $arch != source ]]; then + exit 0 +fi + +# Retrieve the .dsc file +dsc_file=$(dirname ${changes_file})/${package}_${version}.dsc +if [ ! -f $dsc_file ]; then + echo "Unable to find the .dsc file" + exit 1 +fi + +# Retrieve architecture from the .dsc +arch=$(awk '/^Architecture: / {print $2}' ${dsc_file}) +if [[ $arch =~ -?any ]]; then + source /etc/default/rebuildd + + # Add all architectures supported by rebuildd + arch=$ARCHS +fi + +# Kick off the job +for a in $arch; do + # package_name package_version priority dist_name arch mail + echo "$package $version 1 $codename $a $MAIL" | sudo rebuildd-job add +done + +exit 0 diff --git a/sendxmpp b/sendxmpp new file mode 100755 index 0000000..b78fbc2 --- /dev/null +++ b/sendxmpp @@ -0,0 +1,702 @@ +#!/usr/bin/perl -w + +eval 'exec /usr/bin/perl -w -S $0 ${1+"$@"}' +if 0; # not running under some shell + +# +# script to send message using xmpp (aka jabber), +# somewhat resembling mail(1) +# +# Author: Dirk-Jan C. Binnema +# Maintainer: Lubomir Host 'rajo' +# Copyright (c) 2004 - 2005 Dirk-Jan C. Binnema +# Copyright (c) 2006 - 2009 Lubomir Host 'rajo' +# +# Homepage: http://sendxmpp.platon.sk +# +# Released under the terms of the GNU General Public License v2 +# +# $Platon: sendxmpp/sendxmpp,v 1.22 2010-10-03 19:36:35 rajo Exp $ +# $Id: $ + +use Authen::SASL qw(Perl); # authentication broken if Authen::SASL::Cyrus module installed +use Net::XMPP; +use Getopt::Long; +use strict; + +use open ':utf8'; +use open ':std'; + +# subroutines decls +sub xmpp_login($$$$$$$$$); +sub xmpp_send ($$$$); +sub xmpp_send_raw_xml($$); +sub xmpp_send_message($$$$$$); +sub xmpp_send_chatroom_message($$$$$); +sub xmpp_logout($); +sub xmpp_check_result; +sub parse_cmdline(); +sub error_exit; +sub debug_print; +sub read_config_file($); +sub push_hash($$); +sub terminate(); +sub main(); + +my # MakeMaker +$VERSION = [ q$Revision: 1.22 $ =~ m/(\S+)\s*$/g ]->[0]; +my $RESOURCE = 'sendxmpp'; +my $VERBOSE = 0; +my $DEBUG = 0; +# http://tools.ietf.org/html/rfc3921#section-2 section 2.1.1 - Types of Message +my @suppported_message_types = qw( chat error groupchat headline ); +my $message_type = 'chat'; # default message type + +# start! +&main; + +# +# main: main routine +# +sub main () { + + my $cmdline = parse_cmdline(); + + $| = 1; # no output buffering + + $DEBUG = 1 if ($$cmdline{'debug'}); + $VERBOSE = 1 if ($$cmdline{'verbose'}); + + my $config = read_config_file ($$cmdline{'file'}) + unless ($$cmdline{'jserver'} && $$cmdline{'username'} && $$cmdline{'password'}); + + # login to xmpp + my $cnx = xmpp_login ($$cmdline{'jserver'} || $$config{'jserver'}, + $$cmdline{'port'} || $$config{'port'} || ($$cmdline{'ssl'} ? 5223 : 5222), + $$cmdline{'username'} || $$config{'username'}, + $$cmdline{'password'} || $$config{'password'}, + $$cmdline{'component'}|| $$config{'component'}, + $$cmdline{'resource'}, + $$cmdline{'tls'}, + $$cmdline{'ssl'}, + $$cmdline{'debug'}) + or error_exit("cannot login: $!"); + + + # read message from STDIN or or from -m/--message parameter + if (!$$cmdline{interactive}) { + + # the non-interactive case + my $txt; + my $message = $$cmdline{'message'}; + if ($message) { + open (MSG, "<$message") + or error_exit ("cannot open message file '$message': $!"); + while () { $txt .= $_ }; + close(MSG); + } + else { + $txt .= $_ while (); + } + + xmpp_send ($cnx,$cmdline,$config,$txt); + + } else { + # the interactive case, read stdin line by line + + # deal with TERM + $main::CNX = $cnx; + $SIG{INT}=\&terminate; + + # line by line... + while () { + chomp; + xmpp_send ($cnx,$cmdline,$config,$_); + } + } + + xmpp_logout($cnx); + exit 0; +} + + + +# +# read_config_file: read the configuration file +# input: filename +# output: hash with 'user', 'jserver' and 'password' keys +# +sub read_config_file ($) { + + # check permissions + my $cfg_file = shift; + error_exit ("cannot read $cfg_file: $!") + unless (-r $cfg_file); + my $owner = (stat _ )[4]; + error_exit ("you must own $cfg_file") + unless ($owner == $>); + my $mode = (stat _ )[2] & 07777; + error_exit ("$cfg_file must not be accessible by others") + if ($mode & 0077); + + open (CFG,"<$cfg_file") + or error_exit("cannot open $cfg_file for reading: $!"); + + my %config; + my $line = 0; + while () { + + ++$line; + + next if (/^\s*$/); # ignore empty lines + next if (/^\s*\#.*/); # ignore comment lines + + #s/\#.*$//; # ignore comments in lines + + # Hugo van der Kooij has account with '#' as username + if (/([\.\w_#-]+)@([-\.\w:;]+)\s+(\S+)\s*(\S+)?$/) { + %config = ( + 'username' => $1, + 'jserver' => $2, + 'port' => 0, + 'password' => $3, + 'component' => $4, + ); + + } + else { + close CFG; + error_exit ("syntax error in line $line of $cfg_file"); + } + + # account with weird port number + if ($config{'jserver'} =~ /(.*):(\d+)/) { + $config{'jserver'} = $1; + $config{'port'} = $2; + } + + # account with specific connection host + if ($config{'jserver'} =~ /(.*);([-\.\w]+)/) { + $config{'jserver'} = $2; + $config{'username'} .= "\@$1" unless $config{'component'}; + } + } + + close CFG; + + error_exit ("no correct config found in $cfg_file") + unless (scalar(%config)); + + if ($DEBUG || $VERBOSE) { + while (my ($key,$val) = each %config) { + debug_print ("config: '$key' => '$val'"); + } + } + + return \%config; +} + + + +# +# parse_cmdline: parse commandline options +# output: hash with commandline options +# +sub parse_cmdline () { + + usage() unless (scalar(@ARGV)); + + my ($subject,$file,$resource,$jserver,$port,$username,$password,$component, + $message, $chatroom, $headline, $debug, $tls, $ssl, $interactive, $help, $raw, $verbose); + my $res = GetOptions ('subject|s=s' => \$subject, + 'file|f=s' => \$file, + 'resource|r=s' => \$resource, + 'jserver|j=s' => \$jserver, + 'component|o=s' => \$component, + 'username|u=s' => \$username, + 'password|p=s' => \$password, + 'message|m=s' => \$message, + 'headline|l' => \$headline, + 'message-type=s' => \$message_type, + 'chatroom|c' => \$chatroom, + 'tls|t' => \$tls, + 'ssl|e' => \$ssl, + 'interactive|i' => \$interactive, + 'help|usage|h' => \$help, + 'debug|d' => \$debug, + 'raw|w' => \$raw, + 'verbose|v' => \$verbose); + usage () if ($help); + + my @rcpt = @ARGV; + + if (defined($raw) && scalar(@rcpt) > 0) { + error_exit("You must give a recipient or --raw (but not both)"); + } + if ($raw && $subject) { + error_exit("You cannot specify a subject in raw XML mode"); + } + if ($raw && $chatroom) { + error_exit("The chatroom option is pointless in raw XML mode"); + } + + if ($message && $interactive) { + error_exit("Cannot have both -m (--message) and -i (--interactive)"); + } + + if (scalar(grep { $message_type eq $_ } @suppported_message_types) == 0) { + error_exit("Unsupported message type '$message_type'"); + } + + if ($ssl && $tls) { + error_exit("Connect securely wether using -e (--ssl) or -t (--tls)"); + } + + if ($headline) { + # --headline withouth --message-type + if ($message_type eq 'message') { + $message_type = 'headline' + } + else { + error_exit("Options --headline and --message-type are mutually exclusive"); + } + } + + if ($jserver && $jserver =~ /(.*):(\d+)/) { + $jserver = $1; + $port = $2; + } + + my %dict = ('subject' => ($subject or ''), + 'message' => ($message or ''), + 'resource' => ($resource or $RESOURCE), + 'jserver' => ($jserver or ''), + 'component' => ($component or ''), + 'port' => ($port or 0), + 'username' => ($username or ''), + 'password' => ($password or ''), + 'chatroom' => ($chatroom or 0), + 'message-type' => $message_type, + 'interactive' => ($interactive or 0), + 'tls' => ($tls or 0), + 'ssl' => ($ssl or 0), + 'debug' => ($debug or 0), + 'verbose' => ($verbose or 0), + 'raw' => ($raw or 0), + 'file' => ($file or ($ENV{'HOME'}.'/.sendxmpprc')), + 'recipient' => \@rcpt); + + if ($DEBUG || $VERBOSE) { + while (my ($key,$val) = each %dict) { + debug_print ("cmdline: '$key' => '$val'"); + } + } + + return \%dict; +} + + +# +# xmpp_login: login to the xmpp (jabber) server +# input: hostname,port,username,password,resource,tls,ssl,debug +# output: an XMPP connection object +# +sub xmpp_login ($$$$$$$$$) { + + my ($host, $port, $user, $pw, $comp, $res, $tls, $ssl, $debug) = @_; + my $cnx = new Net::XMPP::Client(debuglevel=>($debug?2:0)); + error_exit "could not create XMPP client object: $!" + unless ($cnx); + + my @res; + my $arghash = { + hostname => $host, + port => $port, + tls => $tls, + ssl => $ssl, + connectiontype => 'tcpip', + componentname => $comp + }; + + delete $arghash->{port} unless $port; + if ($arghash->{port}) { + @res = $cnx->Connect(%$arghash); + error_exit ("Could not connect to '$host' on port $port: $@") unless @res; + } else { + @res = $cnx->Connect(%$arghash); + error_exit ("Could not connect to server '$host': $@") unless @res; + } + + xmpp_check_result("Connect",\@res,$cnx); + + if ($comp) { + my $sid = $cnx->{SESSION}->{id}; + $cnx->{STREAM}->{SIDS}->{$sid}->{hostname} = $comp + } + + @res = $cnx->AuthSend(#'hostname' => $host, + 'username' => $user, + 'password' => $pw, + 'resource' => $res); + xmpp_check_result('AuthSend',\@res,$cnx); + + return $cnx; +} + + + + +# +# xmmp_send: send the message, determine from cmdline +# whether it's to individual or chatroom +# +sub xmpp_send ($$$$) { + + my ($cnx, $cmdline, $config, $txt) = @_; + + unless ($$cmdline{'chatroom'}) { + unless ($$cmdline{'raw'}) { + map { + xmpp_send_message ($cnx, + $_, #$$cmdline{'recipient'}, + $$cmdline{'component'} || $$config{'component'}, + $$cmdline{'subject'}, + $$cmdline{'message-type'}, + $txt) + } @{$$cmdline{'recipient'}}; + } + else { + xmpp_send_raw_xml ($cnx, $txt); + } + } + else { + map { + xmpp_send_chatroom_message ($cnx, + $$cmdline{'resource'}, + $$cmdline{'subject'}, + $_, # $$cmdline{'recipient'}, + $txt) + } @{$$cmdline{'recipient'}}; + } +} + + + +# +# xmpp_send_raw_xml: send a raw XML packet +# input: connection,packet +# +sub xmpp_send_raw_xml ($$) { + + my ($cnx,$packet) = @_; + + # for some reason, Send does not return anything + $cnx->Send($packet); + xmpp_check_result('Send',0,$cnx); +} + + +# +# xmpp_send_message: send a message to some xmpp user +# input: connection,recipient,subject,msg +# +sub xmpp_send_message ($$$$$$) { + + my ($cnx, $rcpt, $comp, $subject, $message_type, $msg) = @_; + + # for some reason, MessageSend does not return anything + # mimeit01@xmpp.hs-esslingen.de: if $comp IS set, AND the rcpt DOESN'T contain an @, then @comp is added + $cnx->MessageSend('to' => $rcpt . ( ($comp && index($rcpt, "@") == -1) ? "\@$comp" : '' ), + 'type' => $message_type, + 'subject' => $subject, + 'body' => $msg); + + xmpp_check_result('MessageSend',0,$cnx); +} + + +# +# xmpp_send_chatroom_message: send a message to a chatroom +# input: connection,resource,subject,recipient,message +# +sub xmpp_send_chatroom_message ($$$$$) { + + my ($cnx,$resource,$subject,$rcpt,$msg) = @_; + + # set the presence + my $pres = new Net::XMPP::Presence; + my $res = $pres->SetTo("$rcpt/$resource"); + + $cnx->Send($pres); + + # create/send the message + my $groupmsg = new Net::XMPP::Message; + $groupmsg->SetMessage(to => $rcpt, + body => $msg, + type => 'groupchat'); + + $res = $cnx->Send($groupmsg); + xmpp_check_result ('Send',$res,$cnx); + + # leave the group + $pres->SetPresence (Type=>'unavailable',To=>$rcpt); +} + + +# +# xmpp_logout: log out from the xmpp server +# input: connection +# +sub xmpp_logout($) { + + # HACK + # messages may not be received if we log out too quickly... + sleep 1; + + my $cnx = shift; + $cnx->Disconnect(); + xmpp_check_result ('Disconnect',0); # well, nothing to check, really +} + + + +# +# xmpp_check_result: check the return value from some xmpp function execution +# input: text, result, [connection] +# +sub xmpp_check_result +{ + my ($txt, $res, $cnx)=@_; + + error_exit ("Error '$txt': result undefined") + unless (defined $res); + + # res may be 0 + if ($res == 0) { + debug_print "$txt"; + # result can be true or 'ok' + } + elsif ((@$res == 1 && $$res[0]) || $$res[0] eq 'ok') { + debug_print "$txt: " . $$res[0]; + # otherwise, there is some error + } + else { + my $errmsg = $cnx->GetErrorCode() || '?'; + error_exit ("Error '$txt': " . join (': ',@$res) . "[$errmsg]", $cnx); + } +} + + +# +# terminate; exit the program upon TERM sig reception +# +sub terminate () { + debug_print "caught TERM"; + xmpp_logout($main::CNX); + exit 0; +} + + +# +# debug_print: print the data if defined and DEBUG || VERBOSE is TRUE +# input: [array of strings] +# +sub debug_print { + print STDERR "sendxmpp: " . (join ' ', @_) . "\n" + if (@_ && ($DEBUG ||$VERBOSE)); +} + + +# +# error_exit: print error message and exit the program +# logs out if there is a connection +# input: error, [connection] +# +sub error_exit { + + my ($err,$cnx) = @_; + print STDERR "$err\n"; + xmpp_logout ($cnx) + if ($cnx); + + exit 1; +} + + +# +# usage: print short usage message and exit +# +sub usage () { + + print STDERR + "sendxmpp version $VERSION\n" . + "Copyright (c) 2004 - 2005 Dirk-Jan C. Binnema\n" . + "Copyright (c) 2006 - 2007 Lubomir Host 'rajo'\n" . + "usage: sendxmpp [options] [ ...]\n" . + "or refer to the the sendxmpp manpage\n"; + + exit 0; +} + + +# +# the fine manual +# +=pod + +=head1 NAME + +sendxmpp - send xmpp messages from the commandline. + +=head1 SYNOPSIS + +sendxmpp [options] [ ...] + +sendxmpp --raw [options] + +=head1 DESCRIPTION + +sendxmpp is a program to send XMPP (Jabber) messages from the commandline, not +unlike L. Messages can be sent both to individual recipients and chatrooms. + +=head1 OPTIONS + +=over + +=item B<-f>,B<--file> I + +Use I configuration file instead of F<~/.sendxmpprc> + +=item B<-u>,B<--username> I + +Use I instead of the one in the configuration file + +=item B<-p>,B<--password> I + +Use I instead of the one in the configuration file + +=item B<-j>,B<--jserver> I + +Use jabber I instead of the one in the configuration file. + +=item B<-o>,B<--component> I + +Use componentname in connect call. Seems needed for Google talk. + +=item B<-r>,B<--resource> I + +Use resource I for the sender [default: 'sendxmpp']; when sending to a chatroom, this determines the 'alias' + +=item B<-t>,B<--tls> + +Connect securely, using TLS + +=item B<-e>,B<--ssl> + +Connect securely, using SSL + +=item B<-l>,B<--headline> + +Backward compatibility option. You should use B<--message-type=headline> instead. Send a headline type message (not stored in offline messages) + +=item B<--messages-type> + +Set type of message. Supported types are: B. Default message type is B. Headline type message can be set also with B<--headline> option, see B<--headline> + +=item B<-c>,B<--chatroom> + +Send the message to a chatroom + +=item B<-s>,B<--subject> I + +Set the subject for the message to I [default: '']; when sending to a chatroom, this will set the subject for the chatroom + +=item B<-m>,B<--message> I + +Read the message from I (a file) instead of stdin + +=item B<-i>,B<--interactive> + +Work in interactive mode, reading lines from stdin and sending the one-at-time + +=item B<-w>,B<--raw> + +Send raw XML message to jabber server + +=item B<-v>,B<--verbose> + +Give verbose output about what is happening + +=item B<-h>,B<--help>,B<--usage> + +Show a 'Usage' message + +=item B<-d>,B<--debug> + +Show debugging info while running. B: This will include passwords etc. so be careful with the output! + +=back + +=head1 CONFIGURATION FILE + +You may define a 'F<~/.sendxmpprc>' file with the necessary data for your +xmpp-account, with a line of the format: + +=over + +I@I I I + +=back + +e.g.: + + # my account + alice@jabber.org secret + +('#' and newlines are allowed like in shellscripts). You can add a I (or IP address) if it is different from the I part of your JID: + + # account with specific connection host + alice@myjabberserver.com;foo.com secret + +You can also add a I if it is not the standard XMPP port: + + # account with weird port number + alice@myjabberserver.com:1234 secret + +Of course, you may also mix the two: + + # account with a specific host and port + alice@myjabberserver.com;foo.com:1234 secret + +B: for your security, sendxmpp demands that the configuration +file is owned by you and readable only to you (permissions 600). + +=head1 EXAMPLE + + $ echo "hello bob!" | sendxmpp -s hello someone@jabber.org + + or to send to a chatroom: + + $ echo "Dinner Time" | sendxmpp -r TheCook --chatroom test2@conference.jabber.org + + or to send your system logs somewhere, as new lines appear: + + $ tail -f /var/log/syslog | sendxmpp -i sysadmin@myjabberserver.com + + NOTE: be careful not the overload public jabber services + +=head1 SEE ALSO + +Documentation for the L module + +The jabber homepage: L + +The sendxmpp homepage: L + +=head1 AUTHOR + +sendxmpp has been written by Dirk-Jan C. Binnema , and uses +the L modules written by Ryan Eatmon. Current maintainer is +Lubomir Host 'rajo' , L + +=cut diff --git a/ynh-build b/ynh-build new file mode 100755 index 0000000..b99649c --- /dev/null +++ b/ynh-build @@ -0,0 +1,105 @@ +#!/bin/bash + +source /home/vinaigrette/config + +# ##### # +# Usage # +# ##### # + +usage() { + echo " +Usage: + `basename $0` + +Arguments: + moulinette, yunohost, yunohost-admin or SSOwat + testing or stable + jessie or stretch + x.y.z (ex: 2.6.1) +" +} + +if [[ $1 == "-h" ]]; then + usage + exit 0 +fi + +# ################# # +# Check user inputs # +# ################# # + +## Project +if [[ $1 =~ ^yunohost|yunohost-admin|moulinette|SSOwat$ ]]; then + PROJECT=$1 +else + echo "Invalid project $1" + usage + exit 1 +fi + +## Branch +if [[ $2 =~ ^testing|stable$ ]]; then + BRANCH=$2 +else + echo "Invalid branch $2" + usage + exit 2 +fi + +# Distribution +if [[ $3 =~ ^jessie|stretch$ ]]; then + DISTRIB=$3 +else + echo "Invalid distribution $3" + usage + exit 3 +fi + +# Version +VERSION=$4 +echo $VERSION +if [ -z "$VERSION" ]; then + echo "Invalid version $VERSION" + usage + exit 4 +fi + +# Sum up configuration +echo "## #################################################### ##" +echo "## Building $PROJECT $BRANCH release - $VERSION version" +echo "## #################################################### ##" + +# Update project's repository +echo "" +echo "## Updating $GIT_REPOS/$PROJECT repository ..." +cd $GIT_REPOS/$PROJECT +git fetch --quiet +git fetch --tags --quiet +git checkout $BRANCH --quiet +git pull origin $BRANCH --quiet + +# Check if tag really exists +if git rev-parse "debian/$VERSION" >/dev/null 2>&1; then + TAG="debian/$VERSION" +else + echo "Invalid version $VERSION (there's no debian/$VERSION tag in the git repo !)" + usage + exit +fi + + +# Create temporary folder +TMP_FOLDER=$(mktemp -d) + +# Extract git archive a desired tag +echo "" +echo "## Exporting in $TMP_FOLDER ..." +git archive $TAG --format=tar | tar -x -C $TMP_FOLDER + +# Build Debian package +echo "" +echo "## Building Debian package ..." +echo "" +cd $TMP_FOLDER +$BUILD_DEB -d $BRANCH -c $DISTRIB . +