Skip to content

Commit

Permalink
Script fetchs releases of supported distributions
Browse files Browse the repository at this point in the history
  • Loading branch information
wblankenship committed Jun 3, 2016
1 parent 036dbbe commit dd3517f
Show file tree
Hide file tree
Showing 4 changed files with 304 additions and 0 deletions.
190 changes: 190 additions & 0 deletions tools/get_releases.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
#!/usr/bin/env bash

# When something returns an error code, abort the script
set -e

##################
# Get Script Dir #
##################

# Here we are going to get the directory this script lives in, allowing us to
# find other scripts in this directory that we depend on. This method is
# resiliant to softlinking.

SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"

# $DIR now contains the directory this script lives in

######################
# Define Global Vars #
######################

get_docker_tags="$DIR/get_releases/get_docker_releases.js"

###########################
# Define Helper Functions #
###########################

# error is used to print a message to stderr followed by instructions on how
# to use this script. It then exits the application with an error code
error () {
echo "$1" 1>&2
help
exit 1
}

# help simply prints the instructions for using this script
help () {
echo "USAGE: ./get_releases.sh DIST" 1>&2
echo "" 1>&2
echo " This script gathers supported releases from the NodeSource" 1>&2
echo " Node.js binary distributions and cross references them against" 1>&2
echo " the image tags supported by Docker Hub." 1>&2
echo "" 1>&2
echo " DIST determines which Linux OS Distribution we are gathering" 1>&2
echo " supported releases of, and can be one of the following:" 1>&2
echo " - fedora" 1>&2
echo " - centos" 1>&2
echo " - debian" 1>&2
echo " - ubuntu" 1>&2
echo "" 1>&2
}

#########################################
# Define Logic Functions For NodeSource #
#########################################

# Note: for all of the following distributions, we leave out checking iojs.
# This is for two reasons:
# 1) It simplifies logic
# 2) The iojs repos didn't introduce any new releases

# NodeSource Debian Based Distributions
# Note: this lumps Ubuntu and Debian into the same group. This is safe because
# none of the release names overlap
get_ns_deb () {
URLS=(
"https://deb.nodesource.com/node/pool/main/n/nodejs/"
"https://deb.nodesource.com/node_0.12/pool/main/n/nodejs/"
"https://deb.nodesource.com/node_4.x/pool/main/n/nodejs/"
"https://deb.nodesource.com/node_5.x/pool/main/n/nodejs/"
"https://deb.nodesource.com/node_6.x/pool/main/n/nodejs/"
)

DISTS=$(
for url in ${URLS[@]}; do
curl ${url} 2>/dev/null \
| grep -o ">nodejs_.*1nodesource1~.*\.deb" \
| sed 's/>nodejs_.*-1nodesource1~//' \
| sed 's/1.*deb//'
done
)

echo "$DISTS" | sort | uniq
}

# NodeSource Fedora Based Distributions
get_ns_fedora () {
URLS=(
"https://rpm.nodesource.com/pub/fc/"
"https://rpm.nodesource.com/pub_0.12/fc/"
"https://rpm.nodesource.com/pub_4.x/fc/"
"https://rpm.nodesource.com/pub_5.x/fc/"
"https://rpm.nodesource.com/pub_6.x/fc/"
)

DISTS=$(
for url in "${URLS[@]}"; do
curl ${url} 2>/dev/null \
| grep -o '>[0-9][0-9]' \
| sed 's/>//'
done
)

echo "$DISTS" | sort | uniq
}

# NodeSource Centos Based Distributions
get_ns_centos () {
URLS=(
"https://rpm.nodesource.com/pub/el/"
"https://rpm.nodesource.com/pub_0.12/el/"
"https://rpm.nodesource.com/pub_4.x/el/"
"https://rpm.nodesource.com/pub_5.x/el/"
"https://rpm.nodesource.com/pub_6.x/el/"
)

DISTS=$(
for url in "${URLS[@]}"; do
curl ${url} 2>/dev/null \
| grep -o '>[0-9]' \
| sed 's/>//'
done
)

echo "$DISTS" | sort | uniq
}

# Compare two lists to find common strings
comp () {
COMMON=""
for ns in $1; do
for docker in $2; do
if [ "$ns" == "$docker" ]; then
COMMON="$COMMON $ns"
fi
done
done

# Remove the first space of the string and return the list
echo "$COMMON" | sed 's/^ //'
}

############################
# Begin Main Program Logic #
############################

# Ensure we were passed 1 arguments
if [ "$#" -ne 1 ]; then
error "Invalid number of arguments"
fi

# Determine which distribution we are being asked about
case "$1" in
fedora)
NS=$(get_ns_fedora)
DOCKER=$($get_docker_tags fedora)
TAGS=$(comp "$NS" "$DOCKER")
echo $TAGS
;;
centos)
NS=$(get_ns_centos)
DOCKER=$($get_docker_tags centos)
TAGS=$(comp "$NS" "$DOCKER")
echo $TAGS
;;
debian)
NS=$(get_ns_deb)
DOCKER=$($get_docker_tags debian)
TAGS=$(comp "$NS" "$DOCKER")
echo $TAGS
;;
ubuntu)
NS=$(get_ns_deb)
DOCKER=$($get_docker_tags ubuntu)
TAGS=$(comp "$NS" "$DOCKER")
echo $TAGS
;;
*)
error "Invalid distribution name"
esac

# Return success if we didn't encounter an error
exit 0

4 changes: 4 additions & 0 deletions tools/get_releases/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
get_releases
============

Scripts supporting get_releases.sh
104 changes: 104 additions & 0 deletions tools/get_releases/get_docker_releases.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/usr/bin/env nodejs

/*****************
* Bring in deps *
*****************/

var request = require('request')
var async = require('async')

/***************************
* Define Helper Functions *
***************************/

function error(msg) {
console.error(msg)
help()
process.exit(1)
}

function help() {
var msg = `USAGE: ./get_docker_releases.js DIST
This script gathers supported tags from the Docker image specified by DIST.
DIST corresponds to a valid, NodeSource supported, Linux Distribution and
can be one of the following:
- fedora
- centos
- debian
- ubuntu
`
console.error(msg)
}

/**********************
* Main Program Logic *
**********************/

if(process.argv.length !== 3) {
error("Incorrect number of arguments")
}

// Cache arg to avoid array lookup everywhere
var dist = process.argv[2]

// Ensure dist is a valid string
switch(dist) {
case 'fedora':
case 'centos':
case 'debian':
case 'ubuntu':
break
default:
// Everything that wasn't defined in the cases above is invalid. The switch
// may seem unnatural here, but it was a lot cleaner than an if statement
error('Invalid distribution')
break
}


// Continue asking for more tags until the Docker Hub tells us we have them all
// next acts as our async do-while termination condition, when there are no
// more tags, next will be set to null and the loop will terminate.
var next = `https://registry.hub.docker.com/v2/repositories/library/${dist}/tags`
var tags = []

async.whilst(
function check () {
return next != null
},
function getTags (cb) {
request(next, function fetchedTags (e, resp, body) {
// If the request failed, we have nothing left to do. Eventually this
// could be made to be more resiliant to network hiccups
if(e) {
exit(e.message)
}

// Attempt to make sense of the response, if we can't convert it to JSON
// or the response doesn't include the values we were expecting, then
// we will exit the application
try {
body = JSON.parse(body)
} catch(e) {
exit(e.message)
}
// The next URL we need to grab will be given to us by Docker Hub
next = body.next
// Append the names of the images that were returned by Docker Hub to the
// tags array. This may be confusing without understanding how the Docker
// Hub returns information. Try taking the URL above and plugging it into
// a webbrowser to explore the format
tags = tags.concat(body.results.map( (v) => v.name))
cb()
})
},
function gotTags () {
// Once we reache here, we have finished compiling our list of tags.
// Note: there is no chance of encountering an error since we never call
// the callback with an error condition. When an error was encountered
// above, the application would log it and exit.
console.log(tags.join('\n'))
}
)
6 changes: 6 additions & 0 deletions tools/get_releases/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"dependencies": {
"async": "1.5.2",
"request": "2.72.0"
}
}

0 comments on commit dd3517f

Please sign in to comment.