Skip to content

Commit

Permalink
Update to 5.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
bbayles committed Apr 30, 2021
1 parent dac72ed commit 8424718
Show file tree
Hide file tree
Showing 76 changed files with 988 additions and 1,631 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
ARCH ?= amd64
VERSION := 4.5.0
VERSION := 5.0.0

SCRIPTS_DIR := src/scripts
uPNA_DIR := src/uPNA
Expand All @@ -37,7 +37,7 @@ build:
make -C ${uPNA_DIR}

copy:
make -C ${SCRIPTS_DIR} vendor
make -C ${SCRIPTS_DIR} vendor clean
mkdir -p ${OBSRVBL_ROOT}/
echo ${VERSION} > ${OBSRVBL_ROOT}/version
mkdir -p ${OBSRVBL_ROOT}/pna/user/
Expand Down
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,25 @@ See [observable.net](https://observable.net) for more information about Observab

The following platforms are officially supported:

* [Ubuntu 16.04 and later](https://onstatic.s3.amazonaws.com/ona/master/ona-service_UbuntuXenial_amd64.deb)
* [RHEL 6 and compatible*](https://onstatic.s3.amazonaws.com/ona/master/ona-service_RHEL_6_x86_64.rpm)
* [Ubuntu 18.04 and later](https://onstatic.s3.amazonaws.com/ona/master/ona-service_UbuntuXenial_amd64.deb)
* [RHEL 7 and compatible](https://onstatic.s3.amazonaws.com/ona/master/ona-service_RHEL_7_x86_64.rpm)
* [RHEL 8 and compatible](https://onstatic.s3.amazonaws.com/ona/master/ona-service_RHEL_8_x86_64.rpm)
* [Raspberry Pi with Raspbian](https://onstatic.s3.amazonaws.com/ona/master/ona-service_RaspbianJessie_armhf.deb)
* [Docker](https://github.com/obsrvbl/ona/blob/master/images/docker/Dockerfile)

To install the latest version on 18.04 (recommended for physical and virtual machine installations):
To install the latest version on 20.04 (recommended for physical and virtual machine installations):

```
# wget https://onstatic.s3.amazonaws.com/ona/master/ona-service_UbuntuXenial_amd64.deb
# sudo apt install ./ona-service_UbuntuXenial_amd64.deb
$ wget https://onstatic.s3.amazonaws.com/ona/master/ona-service_UbuntuXenial_amd64.deb
$ sudo apt install ./ona-service_UbuntuXenial_amd64.deb
```

\* RHEL 6 and others will need `/usr/bin/python2.7` to point to a working Python 2.7 installation.
To monitor NetFlow traffic, you'll also need to install tools from the [CERT NetSA Security Suite](https://tools.netsa.cert.org/):

```
$ wget http://onstatic.s3.amazonaws.com/netsa-pkg.deb
$ sudo apt install ./netsa-pkg.deb
```

## Services

Expand Down
13 changes: 4 additions & 9 deletions images/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,13 @@ FROM ubuntu:18.04
LABEL maintainer="Observable Networks <[email protected]>"

# Install dependencies.
RUN apt-get update && apt-get install -y --fix-missing adduser curl net-tools libglib2.0-0 liblzo2-2 libltdl7 libpcap0.8 python2.7 sudo tcpdump zlib1g
RUN apt-get update && apt-get install -y curl

# Download and install the NetFlow receiver
RUN curl -L -O https://github.com/bbayles/netsa-pkg/releases/download/v0.1.12/netsa-pkg.deb
RUN dpkg -i netsa-pkg.deb

# Download and install ONA service
RUN curl -O https://s3.amazonaws.com/onstatic/ona/master/ona-service_UbuntuXenialContainer_amd64.deb
RUN dpkg -i ona-service_UbuntuXenialContainer_amd64.deb
RUN curl -L -O https://github.com/bbayles/netsa-pkg/releases/download/v0.1.15/netsa-pkg.deb
RUN curl -L -O https://s3.amazonaws.com/onstatic/ona/master/ona-service_UbuntuXenialContainer_amd64.deb
RUN apt install -y --fix-missing ./netsa-pkg.deb ./ona-service_UbuntuXenialContainer_amd64.deb

# Switch to the unprivileged user, set some local configuration, and start.

COPY run.sh /opt/obsrvbl-ona/run.sh
RUN chmod +x /opt/obsrvbl-ona/run.sh

Expand Down
39 changes: 23 additions & 16 deletions images/iso/build_iso.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash -ex
#!/bin/bash -x

# Copyright 2015 Observable Networks
#
Expand All @@ -21,13 +21,18 @@
# wrong.
#

RELEASE="${RELEASE:-18.04.5}"
RELEASE="${RELEASE:-20.04.1}"
ARCH="${ARCH:-amd64}"
VARIANT="${VARIANT:-legacy}"

UBUNTU="http://cdimage.ubuntu.com/ubuntu/releases"

DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)

fatal() {
echo "$@" >&2
exit 1
}

while getopts "f:a:r:" opt ; do
case $opt in
f) url="file://$(readlink -f $OPTARG)"
Expand All @@ -36,36 +41,38 @@ while getopts "f:a:r:" opt ; do
;;
r) RELEASE="$OPTARG"
;;
?) echo "invalid argument"
?) fatal "invalid argument"
;;
esac
done

ubuntu_name="ubuntu-${RELEASE}-server-${ARCH}.iso"
ona_name="ona-${RELEASE}-server-${ARCH}.iso"
ubuntu_url="${url:-${UBUNTU}/${RELEASE}/release/${ubuntu_name}}"
ubuntu_url="${url:-$($DIR/build_iso_helper $RELEASE $VARIANT)}"
test -n "$ubuntu_url" || fatal "failed getting Ubuntu ISO download URL"
ona_service_url="https://s3.amazonaws.com/onstatic/ona/master/ona-service_UbuntuXenial_amd64.deb"
netsa_pkg_url="https://onstatic.s3.amazonaws.com/netsa-pkg.deb"
netsa_pkg_url="http://onstatic.s3.amazonaws.com/netsa-pkg.deb"

shift $(($OPTIND-1))

test $EUID -ne 0 && sudo="sudo"
which mkisofs || (echo "missing mkisofs: $sudo apt-get install genisoimage" && false)
which isohybrid || (echo "missing isohybrid: $sudo apt-get install syslinux-utils" && false)
which mkisofs 1> /dev/null || fatal "missing mkisofs: $sudo apt-get install genisoimage"
which isohybrid 1> /dev/null || fatal "missing isohybrid: $sudo apt-get install syslinux-utils"

mkdir "$DIR"/working
test -f ${ubuntu_name} && cp ${ubuntu_name} working && echo "using local ${ubuntu_name}" || echo "downloading ${ubuntu_name}"
pushd "$DIR"/working
test -f ${ubuntu_name} || curl -L -o ${ubuntu_name} "${ubuntu_url}"
mkdir "$DIR"/working || fatal
(
set -e
cd "$DIR"/working
curl -L -o ${ubuntu_name} "${ubuntu_url}"
curl -L -o netsa-pkg.deb "${netsa_pkg_url}"
curl -L -o ona-service.deb "${ona_service_url}"
mkdir cdrom local
$sudo mount -o loop "${ubuntu_name}" cdrom
$sudo mount -o loop --read-only "${ubuntu_name}" cdrom
rsync -av --quiet cdrom/ local
$sudo cp ../preseed/* local/preseed/
$sudo cp -r ../ona local
$sudo cp -r netsa-pkg.deb local/ona/netsa-pkg.deb
$sudo cp -r ona-service.deb local/ona/ona-service.deb
$sudo cp netsa-pkg.deb local/ona/netsa-pkg.deb
$sudo cp ona-service.deb local/ona/ona-service.deb
$sudo cp ../isolinux/txt.cfg local/isolinux/txt.cfg
$sudo cp ../isolinux/grub.cfg local/boot/grub/grub.cfg
$sudo mkisofs -quiet -r -V "SWC Sensor Install CD" \
Expand All @@ -78,5 +85,5 @@ pushd "$DIR"/working
$sudo umount cdrom
$sudo chown $USER:$USER "../${ona_name}"
isohybrid "../${ona_name}"
popd
)
$sudo rm -rf "$DIR"/working
240 changes: 240 additions & 0 deletions images/iso/build_iso_helper
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
#!/usr/bin/env python
"""
Get the download URL for a Ubuntu Server ISO.
If successful:
- prints a URL to stdout
- exit status is 0
If unsuccessful:
- prints a traceback to stderr
- exit status is non-0
CLI usage examples:
$ ./build_iso_helper 20.04.1 subiquity
$ ./build_iso_helper 20.04.1 legacy
$ ./build_iso_helper --unittests
$ ./build_iso_helper --doctests
Real results as of December 2020:
>>> get_iso_url('20.04.1', subiquity=True)
'https://releases.ubuntu.com/20.04/ubuntu-20.04.1-live-server-amd64.iso'
>>> get_iso_url('20.04.1', subiquity=False)
'https://cdimage.ubuntu.com/ubuntu-legacy-server/releases/20.04.1/release/ubuntu-20.04.1-legacy-server-amd64.iso'
>>> get_iso_url('20.04.0', subiquity=True)
'https://old-releases.ubuntu.com/releases/20.04.0/ubuntu-20.04-live-server-amd64.iso'
>>> get_iso_url('16.04.7', subiquity=False)
'https://releases.ubuntu.com/16.04/ubuntu-16.04.7-server-amd64.iso'
>>> get_iso_url('18.04.5', subiquity=True)
'https://releases.ubuntu.com/18.04/ubuntu-18.04.5-live-server-amd64.iso'
>>> get_iso_url('18.04.5', subiquity=False)
'https://cdimage.ubuntu.com/ubuntu/releases/18.04.5/release/ubuntu-18.04.5-server-amd64.iso'
>>> get_iso_url('18.04.4', subiquity=False)
'https://old-releases.ubuntu.com/releases/18.04.4/ubuntu-18.04.4-server-amd64.iso'
>>> get_iso_url('20.99.0', True)
Traceback (most recent call last):
ValueError: no release found
>>> get_iso_url('16.04.7', True)
Traceback (most recent call last):
ValueError: no Subiquity release for this version
"""
from argparse import ArgumentParser, Action, SUPPRESS
from doctest import DocTestSuite
from unittest import TestCase, TextTestRunner, makeSuite
from unittest.mock import patch
from urllib.request import Request, build_opener, HTTPRedirectHandler
from urllib.error import URLError, HTTPError


class Version:
def __init__(self, major, minor, patch=None):
self.major = major
self.minor = minor
self._original_patch = patch
self.patch = patch or 0

@classmethod
def from_str(cls, s):
return cls(*(int(n) for n in s.split('.')))

def __str__(self):
return self.short if self._original_patch is None else self.long

@property
def short(self):
return f'{self.major}.{self.minor:>02}'

@property
def long(self):
return f'{self.major}.{self.minor:>02}.{self.patch}'

@property
def long_if_patch(self):
return self.patch and self.long or self.short


class DontFollowRedirects(HTTPRedirectHandler):
def redirect_request(self, *args, **kwargs):
pass


def head_status_code(url):
request = Request(url, method='HEAD')
try:
response = build_opener(DontFollowRedirects).open(request)
return response.status
except HTTPError as e:
return e.code
except URLError:
return None


def get_iso_url(version, subiquity: bool, arch='amd64'):
if isinstance(version, str):
v = Version.from_str(version)
elif isinstance(version, Version):
v = version
else:
raise TypeError(version)

if arch != 'amd64':
raise NotImplementedError('script only handles amd64 so far')

if v.major >= 20:
if subiquity:
urlpath = f'https://releases.ubuntu.com/{v.short}/'
isofile = f'ubuntu-{v.long_if_patch}-live-server-{arch}.iso'
else:
urlpath = (
'https://cdimage.ubuntu.com/ubuntu-legacy-server/releases'
f'/{v.long}/release/'
)
isofile = f'ubuntu-{v.long_if_patch}-legacy-server-{arch}.iso'
elif v.major >= 18:
if subiquity:
urlpath = f'https://releases.ubuntu.com/{v.short}/'
isofile = f'ubuntu-{v.long_if_patch}-live-server-{arch}.iso'
else:
urlpath = f'https://cdimage.ubuntu.com/ubuntu/releases/{v.long}/release/'
isofile = f'ubuntu-{v.long_if_patch}-server-{arch}.iso'
else:
if subiquity:
raise ValueError('no Subiquity release for this version')
else:
urlpath = f'https://releases.ubuntu.com/{v.short}/'
isofile = f'ubuntu-{v.long_if_patch}-server-{arch}.iso'

primary = urlpath + isofile
fallback1 = f'https://old-releases.ubuntu.com/releases/{v.long}/' + isofile
fallback2 = f'https://old-releases.ubuntu.com/releases/{v.short}/' + isofile
if head_status_code(primary) == 200:
return primary
if head_status_code(fallback1) == 200:
return fallback1
if head_status_code(fallback2) == 200:
return fallback2
if head_status_code('https://www.google.com') == 200:
raise ValueError('no release found')
else:
raise Exception('no network connectivity?')


class Tests(TestCase):
def test_version(self):
v = Version.from_str('20.04')
self.assertEqual(str(v), '20.04')
self.assertEqual(v.short, '20.04')
self.assertEqual(v.long, '20.04.0')
self.assertEqual(v.long_if_patch, '20.04')

v = Version.from_str('20.04.0')
self.assertEqual(str(v), '20.04.0')
self.assertEqual(v.short, '20.04')
self.assertEqual(v.long, '20.04.0')
self.assertEqual(v.long_if_patch, '20.04')

v = Version.from_str('20.04.1')
self.assertEqual(str(v), '20.04.1')
self.assertEqual(v.short, '20.04')
self.assertEqual(v.long, '20.04.1')
self.assertEqual(v.long_if_patch, '20.04.1')

def test_get_iso_url(self):
old = 'https://old-releases.ubuntu.com/releases'
releases = 'https://releases.ubuntu.com'
cd_legacy = 'https://cdimage.ubuntu.com/ubuntu-legacy-server/releases'

def fake_head_status_code(url):
if url in (
f'{cd_legacy}/20.04.1/release/ubuntu-20.04.1-legacy-server-amd64.iso',
f'{releases}/20.04/ubuntu-20.04.1-live-server-amd64.iso',
f'{old}/20.04.0/ubuntu-20.04-live-server-amd64.iso',
'https://www.google.com',
):
return 200
else:
return 999

with patch(f'{__name__}.head_status_code', fake_head_status_code):
self.assertEqual(
get_iso_url('20.04.1', True),
f'{releases}/20.04/ubuntu-20.04.1-live-server-amd64.iso',
)
self.assertEqual(
get_iso_url('20.04.1', False),
f'{cd_legacy}/20.04.1/release/ubuntu-20.04.1-legacy-server-amd64.iso',
)
self.assertEqual(
get_iso_url('20.04.0', True),
f'{old}/20.04.0/ubuntu-20.04-live-server-amd64.iso',
)
with self.assertRaises(ValueError):
get_iso_url('20.99.0', True)


class _TestAction(Action):
def __init__(self, option_strings, dest, default=SUPPRESS, help=None):
if dest == 'unittests':
self._suite = makeSuite(Tests)
elif dest == 'doctests':
self._suite = DocTestSuite()
else:
raise ValueError(dest)
super().__init__(
option_strings=option_strings, dest=dest, default=default, nargs=0, help=help
)

def __call__(self, parser, namespace, values, option_string=None):
TextTestRunner(verbosity=2).run(self._suite)
parser.exit()


def main():
parser = ArgumentParser()
parser.add_argument('version', help='e.g. "20.04.1"')
parser.add_argument(
'installer',
choices=['subiquity', 'legacy'],
help='ISO with the newer Subiquity installer or the older legacy installer',
)
parser.add_argument('--arch', default='amd64', help='default: "%(default)s"')
parser.add_argument('--unittests', action=_TestAction, help='run self-tests')
parser.add_argument(
'--doctests',
action=_TestAction,
help='test that the docstring examples are up-to-date',
)
args = parser.parse_args()
print(get_iso_url(args.version, args.installer == 'subiquity', args.arch))


if __name__ == '__main__':
main()
Loading

0 comments on commit 8424718

Please sign in to comment.