[
  {
    "path": ".circleci/config.yml",
    "content": "version: 2\njobs:\n  build:\n    machine: true\n    steps:\n      - checkout\n\n      - run:\n          name: Run Shellcheck\n          command: |\n            make shellcheck\n\n      - run:\n          name: Create SD image\n          command: |\n            VERSION=${CIRCLE_TAG} make sd-image\n\n      - run:\n          name: Prepare artifacts\n          command: |\n            mkdir -p output\n            cp hypriotos*zip* output/\n\n      - store_artifacts:\n          path: /home/circleci/project/output\n\n      - deploy:\n          name: Deploy\n          command: |\n            if [ \"$CIRCLE_TAG\" != \"\" ]; then\n              curl -sSL https://github.com/tcnksm/ghr/releases/download/v0.5.4/ghr_v0.5.4_linux_amd64.zip -o ghr.zip\n              unzip ghr.zip\n              if [[ $CIRCLE_TAG = *\"rc\"* ]]; then\n                pre=-prerelease\n              fi\n              ./ghr $pre -u hypriot $CIRCLE_TAG output/\n            fi\n\nworkflows:\n  version: 2\n  build_and_deploy:\n    jobs:\n      - build:\n          filters:\n            tags:\n              only: /.*/\n"
  },
  {
    "path": ".dockerignore",
    "content": "*.img\n*.img.zip\n*.img.zip.sha256\n*.tar.gz\n*.tar.gz.sha256\n.vagrant/\nresources/\n"
  },
  {
    "path": ".gitignore",
    "content": "*.img\n*.img.zip\n*.img.zip.sha256\n*.tar.gz\n*.tar.gz.sha256\n.vagrant/\nresources/\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM hypriot/image-builder:latest\n\nENV HYPRIOT_OS_VERSION=v2.1.0 \\\n    RAW_IMAGE_VERSION=v0.3.1\n\n#Note that the checksums and build timestamps only apply when fetching missing\n#artifacts remotely is enabled to validate downloaded remote artifacts\nENV FETCH_MISSING_ARTIFACTS=true \\\n    ROOT_FS_ARTIFACT=rootfs-arm64-debian-$HYPRIOT_OS_VERSION.tar.gz \\\n    KERNEL_ARTIFACT=4.19.58-hypriotos-v8.tar.gz \\\n    BOOTLOADER_ARTIFACT=rpi-bootloader.tar.gz \\\n    RAW_IMAGE_ARTIFACT=rpi-raw.img.zip \\\n    DOCKER_ENGINE_VERSION=\"5:18.09.7~3-0~debian-stretch\" \\\n    CONTAINERD_IO_VERSION=\"1.2.6-3\" \\\n    DOCKER_COMPOSE_VERSION=\"1.23.1\" \\\n    DOCKER_MACHINE_VERSION=\"0.16.1\" \\\n    KERNEL_VERSION=\"4.19.58\" \\\n    ROOTFS_TAR_CHECKSUM=\"4437ac3ab8278a4a3994aa9aa36f0f00bc409f80ebdffef23a141dfc0286ecb0\" \\\n    RAW_IMAGE_CHECKSUM=\"ccff10498fb45fb76c6064988fb01b3543adfdb70ee7e5fb04b51885573684a6\" \\\n    BOOTLOADER_BUILD=\"20190713-140339\" \\\n    KERNEL_BUILD=\"20190715-111025\"\n\nRUN apt-get update && \\\n    DEBIAN_FRONTEND=noninteractive apt-get install -y \\\n    binfmt-support \\\n    qemu \\\n    qemu-user-static \\\n    --no-install-recommends && \\\n    rm -rf /var/lib/apt/lists/*\n\nADD https://github.com/gruntwork-io/fetch/releases/download/v0.1.0/fetch_linux_amd64 /usr/local/bin/fetch\nRUN chmod +x /usr/local/bin/fetch\n\nCOPY builder/ /builder/\n\n# build sd card image\nCMD /builder/build.sh\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2017-2019 Dieter Reuter\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "Makefile",
    "content": "VERSION ?= dirty\n\ndefault: build\n\nbuild:\n\tVERSION=${VERSION} docker build -t image-builder-rpi64 .\n\nsd-image: build\n\tVERSION=${VERSION} docker run --rm --privileged -v $(shell pwd):/workspace -v /boot:/boot -v /lib/modules:/lib/modules -e CIRCLE_TAG -e VERSION image-builder-rpi64\n\nshell: build\n\tVERSION=${VERSION} docker run -ti --privileged -v $(shell pwd):/workspace -v /boot:/boot -v /lib/modules:/lib/modules -e CIRCLE_TAG -e VERSION image-builder-rpi64 bash\n\ntest:\n\tVERSION=${VERSION} docker run --rm --privileged -v $(shell pwd):/workspace -v /boot:/boot -v /lib/modules:/lib/modules -e CIRCLE_TAG -e VERSION image-builder-rpi64 bash -c \"unzip /workspace/hypriotos-rpi64-${VERSION}.img.zip && rspec --format documentation --color /workspace/builder/test/*_spec.rb\"\n\nshellcheck:\n\tVERSION=${VERSION} docker run --rm -v $(shell pwd):/workspace koalaman/shellcheck:v0.7.0 /workspace/builder/build.sh /workspace/builder/chroot-script.sh /workspace/builder/files/etc/firstboot.d/10-resize-rootdisk\n\nvagrant:\n\tvagrant up\n\ndocker-machine: vagrant\n\tdocker-machine create -d generic \\\n\t  --generic-ssh-user $(shell vagrant ssh-config | grep ' User ' | cut -d ' ' -f 4) \\\n\t  --generic-ssh-key $(shell vagrant ssh-config | grep IdentityFile | cut -d ' ' -f 4) \\\n\t  --generic-ip-address $(shell vagrant ssh-config | grep HostName | cut -d ' ' -f 4) \\\n\t  --generic-ssh-port $(shell vagrant ssh-config | grep Port | cut -d ' ' -f 4) \\\n\t  image-builder-rpi64\n\ntest-integration: test-integration-image test-integration-docker\n\ntest-integration-image:\n\tdocker run --rm -ti -v $(shell pwd)/builder/test-integration:/serverspec:ro -e BOARD uzyexe/serverspec:2.24.3 bash -c \"rspec --format documentation --color spec/hypriotos-image\"\n\ntest-integration-docker:\n\tdocker run --rm -ti -v $(shell pwd)/builder/test-integration:/serverspec:ro -e BOARD uzyexe/serverspec:2.24.3 bash -c \"rspec --format documentation --color spec/hypriotos-docker\"\n\ntag:\n\tgit tag ${TAG}\n\tgit push origin ${TAG}\n"
  },
  {
    "path": "README.md",
    "content": "# image-builder-rpi64\n[![CircleCI](https://circleci.com/gh/DieterReuter/image-builder-rpi64.svg?style=svg)](https://circleci.com/gh/DieterReuter/image-builder-rpi64)\n\n**Warning:** This SD image will not work on a Raspberry Pi 4B !!! \n\nThis repo builds the SD card image with HypriotOS for the Raspberry Pi 3 in 64bit.\nYou can find released versions of the SD card image here in the GitHub\nreleases page. To build this SD card image we have to\n\n * take the files for the root filesystem from [`os-rootfs`](https://github.com/hypriot/os-rootfs)\n * take the empty raw filesystem from [`image-builder-raw`](https://github.com/hypriot/image-builder-raw) with the two partitions\n * add Hypriot's Debian repos\n * install the Raspberry Pi kernel from [`rpi64-kernel`](https://github.com/dieterreuter/rpi64-kernel)\n * install Docker tools Docker Engine, Docker Compose and Docker Machine\n\nHere is an example how all the GitHub repos play together:\n\n![Architecture](http://blog.hypriot.com/images/hypriotos-xxx/hypriotos_buildpipeline.jpg)\n\n## Contributing\n\nYou can contribute to this repo by forking it and sending us pull requests.\nFeedback is always welcome!\n\nYou can build the SD card image locally with Vagrant.\n\n### Setting up build environment\n\nMake sure you have [vagrant](https://docs.vagrantup.com/v2/installation/) and [docker-machine](https://docs.docker.com/machine/install-machine/) installed.\nThen run the following command to create the Vagrant box and the Docker Machine\nconnection. The Vagrant box is needed as a vanilla boot2docker VM is not able to\nrun guestfish inside. Use `export VAGRANT_DEFAULT_PROVIDER=virtualbox` to\nstrictly create a VirtualBox VM.\n\n```bash\nmake docker-machine\n```\n\nNow set the Docker environments to this new docker machine:\n\n```bash\neval $(docker-machine env image-builder-rpi64)\n```\n\n### Build the SD card image\n\nFrom here you can just make the SD card image. The output will be written and\ncompressed to `hypriotos-rpi64-dirty.img.zip`.\n\n```bash\nmake sd-image\n```\n\n### Run Serverspec tests\n\nTo test the compressed SD card image with [Serverspec](http://serverspec.org)\njust run the following command. It will expand the SD card image in a Docker\ncontainer and run the Serverspec tests in `builder/test/` folder against it.\n\n```bash\nmake test\n```\n\n### Run integration tests\n\nNow flash the SD card image and boot up a Raspberry Pi. Run the [Serverspec](http://serverspec.org) integration tests in `builder/test-integration/`\nfolder against your Raspberry Pi. Set the environment variable `BOARD` to the\nIP address or host name of your running Raspberry Pi.\n\n```bash\nflash hypriotos-rpi64-dirty.img.zip\nBOARD=black-pearl.local make test-integration\n```\n\nThis test works with any Docker Machine, so you do not need to create the\nVagrant box.\n\n## Deployment\n\nFor maintainers of this project you can release a new version and deploy the\nSD card image to GitHub releases with\n\n```bash\nTAG=v0.0.1 make tag\n```\n\nAfter that open the GitHub release of this version and fill it with relevant\nchanges and links to resolved issues.\n\n\n## License\n\nMIT License\n\nCopyright (c) 2017-2019 Dieter Reuter\n"
  },
  {
    "path": "Vagrantfile",
    "content": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\nENV['VAGRANT_DEFAULT_PROVIDER'] = 'virtualbox'\n\nVagrant.configure(2) do |config|\n  config.vm.box = \"bento/ubuntu-16.04\"\n\n  config.vm.network \"forwarded_port\", guest: 2376, host: 2376, auto_correct: true\n  config.vm.synced_folder \".\", \"#{`pwd`.chomp}\"\n\n  config.vm.provider \"vmware_fusion\" do |v|\n    # Customize the amount of memory on the VM:\n    v.memory = \"2048\"\n  end\n\n  config.vm.provider \"virtualbox\" do |vb|\n    # Customize the amount of memory on the VM:\n    vb.memory = \"2048\"\n  end\n\n  config.vm.provision \"shell\", inline: <<-SHELL\n     sudo apt update\n     sudo apt install --yes apt-transport-https ca-certificates curl software-properties-common\n     curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -\n     sudo add-apt-repository \"deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable\"\n     sudo apt-get update\n     sudo apt-get install -y docker-ce\n  SHELL\nend\n"
  },
  {
    "path": "builder/build.sh",
    "content": "#!/bin/bash -e\nset -x\n# This script should be run only inside of a Docker container\nif [ ! -f /.dockerenv ]; then\n  echo \"ERROR: script works only in a Docker container!\"\n  exit 1\nfi\n\n### setting up some important variables to control the build process\n\n# place to store our created sd-image file\nBUILD_RESULT_PATH=\"/workspace\"\n\n# place to build our sd-image\nBUILD_PATH=\"/build\"\n\nROOTFS_TAR=${ROOT_FS_ARTIFACT}\nROOTFS_TAR_PATH=\"${BUILD_RESULT_PATH}/${ROOTFS_TAR}\"\n\n# Show CIRCLE_TAG in Circle builds\necho CIRCLE_TAG=\"${CIRCLE_TAG}\"\n\n# name of the sd-image we gonna create\nHYPRIOT_IMAGE_VERSION=${VERSION:=\"dirty\"}\nHYPRIOT_IMAGE_NAME=\"hypriotos-rpi64-${HYPRIOT_IMAGE_VERSION}.img\"\nexport HYPRIOT_IMAGE_VERSION\n\n# create build directory for assembling our image filesystem\nrm -rf ${BUILD_PATH}\nmkdir ${BUILD_PATH}\n\n# download our base root file system\nif [ ! -f \"${ROOTFS_TAR_PATH}\" ]; then\n  if [ \"$FETCH_MISSING_ARTIFACTS\" == \"true\" ]; then\n    wget -q -O \"${ROOTFS_TAR_PATH}\" \"https://github.com/hypriot/os-rootfs/releases/download/${HYPRIOT_OS_VERSION}/${ROOTFS_TAR}\"\n  else\n    echo \"Missing artifact ${ROOT_FS_ARTIFACT}\"\n    exit 255\n  fi\nfi\n\nif [ \"$FETCH_MISSING_ARTIFACTS\" == \"true\" ]; then\n  # verify checksum of our root filesystem\n  echo \"${ROOTFS_TAR_CHECKSUM} ${ROOTFS_TAR_PATH}\" | sha256sum -c -\nfi\n\n# extract root file system\ntar xf \"${ROOTFS_TAR_PATH}\" -C \"${BUILD_PATH}\"\n\n# extract/add additional files\nFILENAME=/workspace/$BOOTLOADER_ARTIFACT\nif [ ! -f \"$FILENAME\" ]; then\n  if [ \"$FETCH_MISSING_ARTIFACTS\" == \"true\" ]; then\n    fetch --repo=\"https://github.com/DieterReuter/rpi-bootloader\" --tag=\"v$BOOTLOADER_BUILD\" --release-asset=\"rpi-bootloader.tar.gz.sha256\" /workspace\n    fetch --repo=\"https://github.com/DieterReuter/rpi-bootloader\" --tag=\"v$BOOTLOADER_BUILD\" --release-asset=\"rpi-bootloader.tar.gz\" /workspace\n  else\n    echo \"Missing artifact ${BOOTLOADER_ARTIFACT}\"\n    exit 255\n  fi\nfi\ntar -xf \"$FILENAME\" -C \"${BUILD_PATH}\"\n\nFILENAME=/workspace/$KERNEL_ARTIFACT\nif [ ! -f \"$FILENAME\" ]; then\n  if [ \"$FETCH_MISSING_ARTIFACTS\" == \"true\" ]; then\n    fetch --repo=\"https://github.com/DieterReuter/rpi64-kernel\" --tag=\"v$KERNEL_BUILD\" --release-asset=\"$KERNEL_VERSION-hypriotos-v8.tar.gz.sha256\" /workspace\n    fetch --repo=\"https://github.com/DieterReuter/rpi64-kernel\" --tag=\"v$KERNEL_BUILD\" --release-asset=\"$KERNEL_VERSION-hypriotos-v8.tar.gz\" /workspace\n  else\n    echo \"Missing artifact ${KERNEL_ARTIFACT}\"\n    exit 255\n  fi\nfi\ntar -xf \"$FILENAME\" -C \"${BUILD_PATH}\"\n\n# register qemu-aarch64 with binfmt\n# to ensure that binaries we use in the chroot\n# are executed via qemu-aarch64\nupdate-binfmts --enable qemu-aarch64\n\n# set up mount points for the pseudo filesystems\nmkdir -p ${BUILD_PATH}/{proc,sys,dev/pts}\n\nmount -o bind /dev ${BUILD_PATH}/dev\nmount -o bind /dev/pts ${BUILD_PATH}/dev/pts\nmount -t proc none ${BUILD_PATH}/proc\nmount -t sysfs none ${BUILD_PATH}/sys\n\n# modify/add image files directly\n# e.g. root partition resize script\ncp -R /builder/files/* ${BUILD_PATH}/\n\n# make our build directory the current root\n# and install the Rasberry Pi firmware, kernel packages,\n# docker tools and some customizations\nchroot ${BUILD_PATH} /bin/bash < /builder/chroot-script.sh\n\n# unmount pseudo filesystems\numount -l ${BUILD_PATH}/dev/pts\numount -l ${BUILD_PATH}/dev\numount -l ${BUILD_PATH}/proc\numount -l ${BUILD_PATH}/sys\n\n# package image filesytem into two tarballs - one for bootfs and one for rootfs\n# ensure that there are no leftover artifacts in the pseudo filesystems\nrm -rf ${BUILD_PATH:?}/{dev,sys,proc}/*\n\ntar -czf /image_with_kernel_boot.tar.gz -C ${BUILD_PATH}/boot .\ndu -sh ${BUILD_PATH}/boot\nrm -Rf ${BUILD_PATH:?}/boot\ntar -czf /image_with_kernel_root.tar.gz -C ${BUILD_PATH} .\ndu -sh ${BUILD_PATH}\nls -alh /image_with_kernel_*.tar.gz\n\nRAW_IMAGE=${RAW_IMAGE_ARTIFACT%.*}\n# download the ready-made raw image for the RPi\nif [ ! -f \"${BUILD_RESULT_PATH}/${RAW_IMAGE_ARTIFACT}\" ]; then\n  if [ \"$FETCH_MISSING_ARTIFACTS\" == \"true\" ]; then\n    wget -q -O \"${BUILD_RESULT_PATH}/${RAW_IMAGE_ARTIFACT}\" \"https://github.com/hypriot/image-builder-raw/releases/download/${RAW_IMAGE_VERSION}/${RAW_IMAGE}.zip\"\n  else\n    echo \"Missing artifact ${RAW_IMAGE_ARTIFACT}\"\n    exit 255\n  fi\nfi\n\nif [ \"$FETCH_MISSING_ARTIFACTS\" == \"true\" ]; then\n  # verify checksum of the ready-made raw image\n  echo \"${RAW_IMAGE_CHECKSUM} ${BUILD_RESULT_PATH}/${RAW_IMAGE_ARTIFACT}\" | sha256sum -c -\nfi\n\nunzip -p \"${BUILD_RESULT_PATH}/${RAW_IMAGE}\" > \"/${HYPRIOT_IMAGE_NAME}\"\n\n# create the image and add root base filesystem\nguestfish -a \"/${HYPRIOT_IMAGE_NAME}\"<<_EOF_\n  run\n  #import filesystem content\n  mount /dev/sda2 /\n  tar-in /image_with_kernel_root.tar.gz / compress:gzip\n  mkdir /boot\n  mount /dev/sda1 /boot\n  tar-in /image_with_kernel_boot.tar.gz /boot compress:gzip\n_EOF_\n\n# ensure that the travis-ci user can access the sd-card image file\numask 0000\n\n# compress image\nzip \"${BUILD_RESULT_PATH}/${HYPRIOT_IMAGE_NAME}.zip\" \"${HYPRIOT_IMAGE_NAME}\"\ncd ${BUILD_RESULT_PATH} && sha256sum \"${HYPRIOT_IMAGE_NAME}.zip\" > \"${HYPRIOT_IMAGE_NAME}.zip.sha256\" && cd -\n\n# # test sd-image that we have built\n# VERSION=${HYPRIOT_IMAGE_VERSION} rspec --format documentation --color ${BUILD_RESULT_PATH}/builder/test\n"
  },
  {
    "path": "builder/chroot-script.sh",
    "content": "#!/bin/bash\nset -ex\n\nKEYSERVER=\"ha.pool.sks-keyservers.net\"\n\nfunction clean_print(){\n  local fingerprint=\"${2}\"\n  local func=\"${1}\"\n\n  nospaces=${fingerprint//[:space:]/}\n  tolowercase=${nospaces,,}\n  KEYID_long=${tolowercase:(-16)}\n  KEYID_short=${tolowercase:(-8)}\n  if [[ \"${func}\" == \"fpr\" ]]; then\n    echo \"${tolowercase}\"\n  elif [[ \"${func}\" == \"long\" ]]; then\n    echo \"${KEYID_long}\"\n  elif [[ \"${func}\" == \"short\" ]]; then\n    echo \"${KEYID_short}\"\n  elif [[ \"${func}\" == \"print\" ]]; then\n    if [[ \"${fingerprint}\" != \"${nospaces}\" ]]; then\n      printf \"%-10s %50s\\n\" fpr: \"${fingerprint}\"\n    fi\n    # if [[ \"${nospaces}\" != \"${tolowercase}\" ]]; then\n    #   printf \"%-10s %50s\\n\" nospaces: $nospaces\n    # fi\n    if [[ \"${tolowercase}\" != \"${KEYID_long}\" ]]; then\n      printf \"%-10s %50s\\n\" lower: \"${tolowercase}\"\n    fi\n    printf \"%-10s %50s\\n\" long: \"${KEYID_long}\"\n    printf \"%-10s %50s\\n\" short: \"${KEYID_short}\"\n    echo \"\"\n  else\n    echo \"usage: function {print|fpr|long|short} GPGKEY\"\n  fi\n}\n\n\nfunction get_gpg(){\n  GPG_KEY=\"${1}\"\n  KEY_URL=\"${2}\"\n\n  clean_print print \"${GPG_KEY}\"\n  GPG_KEY=$(clean_print fpr \"${GPG_KEY}\")\n\n  if [[ \"${KEY_URL}\" =~ ^https?://* ]]; then\n    echo \"loading key from url\"\n    KEY_FILE=temp.gpg.key\n    wget -q -O \"${KEY_FILE}\" \"${KEY_URL}\"\n  elif [[ -z \"${KEY_URL}\" ]]; then\n    echo \"no source given try to load from key server\"\n#    gpg --keyserver \"${KEYSERVER}\" --recv-keys \"${GPG_KEY}\"\n    apt-key adv --keyserver \"${KEYSERVER}\" --recv-keys \"${GPG_KEY}\"\n    return $?\n  else\n    echo \"keyfile given\"\n    KEY_FILE=\"${KEY_URL}\"\n  fi\n\n  FINGERPRINT_OF_FILE=$(gpg --with-fingerprint --with-colons \"${KEY_FILE}\" | grep fpr | rev |cut -d: -f2 | rev)\n\n  if [[ ${#GPG_KEY} -eq 16 ]]; then\n    echo \"compare long keyid\"\n    CHECK=$(clean_print long \"${FINGERPRINT_OF_FILE}\")\n  elif [[ ${#GPG_KEY} -eq 8 ]]; then\n    echo \"compare short keyid\"\n    CHECK=$(clean_print short \"${FINGERPRINT_OF_FILE}\")\n  else\n    echo \"compare fingerprint\"\n    CHECK=$(clean_print fpr \"${FINGERPRINT_OF_FILE}\")\n  fi\n\n  if [[ \"${GPG_KEY}\" == \"${CHECK}\" ]]; then\n    echo \"key OK add to apt\"\n    apt-key add \"${KEY_FILE}\"\n    rm -f \"${KEY_FILE}\"\n    return 0\n  else\n    echo \"key invalid\"\n    exit 1\n  fi\n}\n\n## examples:\n# clean_print {print|fpr|long|short} {GPGKEYID|FINGERPRINT}\n# get_gpg {GPGKEYID|FINGERPRINT} [URL|FILE]\n\n# device specific settings\nHYPRIOT_DEVICE=\"Raspberry Pi 3 64bit\"\n\n# set up /etc/resolv.conf\nDEST=$(readlink -m /etc/resolv.conf)\nexport DEST\nmkdir -p \"$(dirname \"${DEST}\")\"\necho \"nameserver 8.8.8.8\" > \"${DEST}\"\n\n# # set up hypriot rpi repository for rpi specific kernel- and firmware-packages\n# PACKAGECLOUD_FPR=418A7F2FB0E1E6E7EABF6FE8C2E73424D59097AB\n# PACKAGECLOUD_KEY_URL=https://packagecloud.io/gpg.key\n# get_gpg \"${PACKAGECLOUD_FPR}\" \"${PACKAGECLOUD_KEY_URL}\"\n\n###arm64: not used for now\n# echo 'deb https://packagecloud.io/Hypriot/rpi/debian/ jessie main' > /etc/apt/sources.list.d/hypriot.list\n\n# # set up hypriot schatzkiste repository for generic packages\n# echo 'deb [arch=armhf] https://packagecloud.io/Hypriot/Schatzkiste/debian/ jessie main' >> /etc/apt/sources.list.d/hypriot.list\n\n# RPI_ORG_FPR=CF8A1AF502A2AA2D763BAE7E82B129927FA3303E RPI_ORG_KEY_URL=http://archive.raspberrypi.org/debian/raspberrypi.gpg.key\n# get_gpg \"${RPI_ORG_FPR}\" \"${RPI_ORG_KEY_URL}\"\n\n# echo 'deb [arch=armhf] http://archive.raspberrypi.org/debian/ jessie main' | tee /etc/apt/sources.list.d/raspberrypi.list\n\n# # make sure, we can use dedicated armhf packages\n# dpkg --add-architecture armhf\n# sed -i 's/deb http/deb [arch=arm64] http/g' /etc/apt/sources.list\n# sed -i 's/deb-src http/deb-src [arch=arm64] http/g' /etc/apt/sources.list\n\n# reload package sources\napt-get update\napt-get upgrade -y\n\n# # install WiFi firmware packages (same as in Raspbian)\n# apt-get install -y \\\n#   firmware-atheros \\\n#   firmware-brcm80211 \\\n#   firmware-libertas \\\n#   firmware-ralink \\\n#   firmware-realtek\n\n#+++for now copy files statically from ./builder/files/lib/firmware/brcm\n# # install WiFi firmware for internal RPi3 WiFi module\n# mkdir -p /lib/firmware/brcm\n# curl -sSL https://github.com/RPi-Distro/firmware-nonfree/raw/master/brcm/brcmfmac43430-sdio.bin > /lib/firmware/brcm/brcmfmac43430-sdio.bin\n#---\n\n# install kernel- and firmware-packages\n# apt-get install -y \\\n#   \"raspberrypi-kernel=${KERNEL_BUILD}\" \\\n#   \"raspberrypi-bootloader=${KERNEL_BUILD}\" \\\n#   \"libraspberrypi0=${KERNEL_BUILD}\" \\\n#   \"libraspberrypi-dev=${KERNEL_BUILD}\" \\\n#   \"libraspberrypi-bin=${KERNEL_BUILD}\"\n\n# enable serial console\nprintf \"# Spawn a getty on Raspberry Pi serial line\\nT0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100\\n\" >> /etc/inittab\n\n# boot/cmdline.txt\necho \"dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 cgroup_enable=cpuset cgroup_enable=memory swapaccount=1 elevator=deadline fsck.repair=yes rootwait console=ttyAMA0,115200 net.ifnames=0\" > /boot/cmdline.txt\n# \" net.ifnames=0\" is neccessary for Debian Stretch: see https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/\n\n# create a default boot/config.txt file (details see http://elinux.org/RPiconfig)\necho \"\n# enable UART console on GPIO pins\nenable_uart=1\nhdmi_force_hotplug=1\n\" > boot/config.txt\n\n# echo \"# camera settings, see http://elinux.org/RPiconfig#Camera\n# start_x=1\n# disable_camera_led=1\n# gpu_mem=128\n# \" >> boot/config.txt\n\necho \"# setting for maximum memory, gpu_mem to minimum 16M, camera off\nstart_x=0\ngpu_mem=16\n\" >> boot/config.txt\n\n# # /etc/modules\n# echo \"snd_bcm2835\n# \" >> /etc/modules\n\n# create /etc/fstab\necho \"\nproc /proc proc defaults 0 0\n/dev/mmcblk0p1 /boot vfat defaults 0 0\n/dev/mmcblk0p2 / ext4 defaults,noatime 0 1\n\" > /etc/fstab\n\n# run resize script on first boot (phase 1)\nmv /sbin/init /sbin/init.bak\nln -s /sbin/resizefs /sbin/init\n\n# as the Pi does not have a hardware clock we need a fake one\napt-get install -y \\\n  --no-install-recommends \\\n  fake-hwclock\n\n# install packages for managing wireless interfaces\napt-get install -y \\\n  --no-install-recommends \\\n  wpasupplicant \\\n  wireless-tools \\\n  ethtool \\\n  crda\n\n# # add firmware and packages for managing bluetooth devices\n# apt-get install -y \\\n#   --no-install-recommends \\\n#   bluetooth \\\n#   pi-bluetooth\napt-get install -y \\\n  --no-install-recommends \\\n  bluetooth\n\n# ensure compatibility with Docker install.sh, so `raspbian` will be detected correctly\napt-get install -y \\\n  --no-install-recommends \\\n  lsb-release\n\n# install cloud-init and its required dependencies\napt-get install -y \\\n  --no-install-recommends \\\n  cloud-init \\\n  dirmngr \\\n  less\n\nmkdir -p /var/lib/cloud/seed/nocloud-net\nln -s /boot/user-data /var/lib/cloud/seed/nocloud-net/user-data\nln -s /boot/meta-data /var/lib/cloud/seed/nocloud-net/meta-data\n\n# enable Docker Engine experimental features\nmkdir -p /etc/docker/\necho '{\n  \"experimental\": true\n}\n' > /etc/docker/daemon.json\n\n# set up Docker APT repository and install official Docker CE packages\n# see: https://docs.docker.com/install/linux/docker-ce/debian/\n#\n# Install packages to allow apt to use a repository over HTTPS:\napt-get install -y \\\n  --no-install-recommends \\\n  apt-transport-https \\\n  ca-certificates \\\n  curl \\\n  gnupg2 \\\n  software-properties-common\n# Add Docker’s official GPG key:\ncurl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -\n# Verify fingerprint of Docker’s official GPG key:\napt-key fingerprint 0EBFCD88\n# Set up set the stable Docker repository:\nadd-apt-repository \\\n   \"deb [arch=arm64] https://download.docker.com/linux/debian \\\n   $(lsb_release -cs) \\\n   stable\"\n# Install Docker CE\napt-get update\napt-get install -y \\\n  --no-install-recommends \\\n  docker-ce=\"${DOCKER_ENGINE_VERSION}\" \\\n  docker-ce-cli=\"${DOCKER_ENGINE_VERSION}\" \\\n  containerd.io=\"${CONTAINERD_IO_VERSION}\"\n\n# install Docker Machine directly from GitHub releases\ncurl -sSL \"https://github.com/docker/machine/releases/download/v${DOCKER_MACHINE_VERSION}/docker-machine-Linux-aarch64\" \\\n  > /usr/local/bin/docker-machine\nchmod +x /usr/local/bin/docker-machine\n\n# install bash completion for Docker Machine\ncurl -sSL \"https://raw.githubusercontent.com/docker/machine/v${DOCKER_MACHINE_VERSION}/contrib/completion/bash/docker-machine.bash\" -o /etc/bash_completion.d/docker-machine\n\n# install Docker Compose via pip\napt-get install -y \\\n  --no-install-recommends \\\n  python\ncurl -sSL https://bootstrap.pypa.io/get-pip.py | python\npip install docker-compose==\"${DOCKER_COMPOSE_VERSION}\"\n\n# install bash completion for Docker Compose\ncurl -sSL \"https://raw.githubusercontent.com/docker/compose/${DOCKER_COMPOSE_VERSION}/contrib/completion/bash/docker-compose\" -o /etc/bash_completion.d/docker-compose\n\necho \"Installing rpi-serial-console script\"\nwget -q https://raw.githubusercontent.com/lurch/rpi-serial-console/master/rpi-serial-console -O usr/local/bin/rpi-serial-console\nchmod +x usr/local/bin/rpi-serial-console\n\n# cleanup APT cache and lists\napt-get clean\nrm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*\n\nif [ \"$FETCH_MISSING_ARTIFACTS\" == \"true\" ]; then\n# set device label and version number\ncat <<EOF >> /etc/os-release\nHYPRIOT_BOOTLOADER_BUILD=\"${BOOTLOADER_BUILD}\"\nHYPRIOT_KERNEL_BUILD=\"${KERNEL_BUILD}\"\nHYPRIOT_KERNEL_VERSION=\"${KERNEL_VERSION}\"\nHYPRIOT_DEVICE=\"$HYPRIOT_DEVICE\"\nHYPRIOT_IMAGE_VERSION=\"$HYPRIOT_IMAGE_VERSION\"\nEOF\nelse\ncat <<EOF >> /etc/os-release\nHYPRIOT_KERNEL_VERSION=\"${KERNEL_VERSION}\"\nHYPRIOT_DEVICE=\"$HYPRIOT_DEVICE\"\nHYPRIOT_IMAGE_VERSION=\"$HYPRIOT_IMAGE_VERSION\"\nEOF\nfi\ncp /etc/os-release /boot/os-release\n"
  },
  {
    "path": "builder/files/boot/meta-data",
    "content": ""
  },
  {
    "path": "builder/files/boot/user-data",
    "content": "#cloud-config\n# vim: syntax=yaml\n#\n\n# The current version of cloud-init in the Hypriot rpi-64 is 0.7.9\n# When dealing with cloud-init, it is SUPER important to know the version\n# I have wasted many hours creating servers to find out the module I was trying to use wasn't in the cloud-init version I had\n# Documentation: http://cloudinit.readthedocs.io/en/0.7.9/index.html\n\n# Set your hostname here, the manage_etc_hosts will update the hosts file entries as well\nhostname: black-pearl\nmanage_etc_hosts: true\n\n# You could modify this for your own user information\nusers:\n  - name: pirate\n    gecos: \"Hypriot Pirate\"\n    sudo: ALL=(ALL) NOPASSWD:ALL\n    shell: /bin/bash\n    groups: users,docker,video\n    plain_text_passwd: hypriot\n    lock_passwd: false\n    ssh_pwauth: true\n    chpasswd: { expire: false }\n\n# # Set the locale of the system\n# locale: \"en_US.UTF-8\"\n\n# # Set the timezone\n# # Value of 'timezone' must exist in /usr/share/zoneinfo\n# timezone: \"America/Los_Angeles\"\n\n# # Update apt packages on first boot\n# package_update: true\n# package_upgrade: true\n# package_reboot_if_required: true\npackage_upgrade: false\n\n# # Install any additional apt packages you need here\n# packages:\n#  - ntp\n\n# # WiFi connect to HotSpot\n# # - use `wpa_passphrase SSID PASSWORD` to encrypt the psk\n# write_files:\n#   - content: |\n#       allow-hotplug wlan0\n#       iface wlan0 inet dhcp\n#       wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf\n#       iface default inet dhcp\n#     path: /etc/network/interfaces.d/wlan0\n#   - content: |\n#       ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev\n#       update_config=1\n#       network={\n#       ssid=\"YOUR_WIFI_SSID\"\n#       psk=\"YOUR_WIFI_PASSWORD\"\n#       proto=RSN\n#       key_mgmt=WPA-PSK\n#       pairwise=CCMP\n#       auth_alg=OPEN\n#       }\n#     path: /etc/wpa_supplicant/wpa_supplicant.conf\n\n# These commands will be ran once on first boot only\nruncmd:\n  # Pickup the hostname changes\n  - 'systemctl restart avahi-daemon'\n\n#  # Activate WiFi interface\n#  - 'ifup wlan0'\n"
  },
  {
    "path": "builder/files/etc/apt/preferences.d/hypriot",
    "content": "# ensure that only Hypriot kernel packages get installed\n\nPackage: linux-headers-*-hypriotos*\nPin: origin packagecloud.io/hypriot/schatzkiste\nPin-Priority: 1001\n\nPackage: libraspberrypi*\nPin: origin packagecloud.io/hypriot/schatzkiste\nPin-Priority: 1001\n\nPackage: raspberrypi-bootloader\nPin: origin packagecloud.io/hypriot/schatzkiste\nPin-Priority: 1001\n"
  },
  {
    "path": "builder/files/etc/apt/preferences.d/raspberrypi",
    "content": "# ensure that the correct firmware packages from the \n# Raspberry Pi Foundation get installed\n# those packages are usually the most recent ones\n\nPackage: firmware-*\nPin: origin archive.raspberrypi.org\nPin-Priority: 1001\n"
  },
  {
    "path": "builder/files/etc/firstboot.d/10-resize-rootdisk",
    "content": "#!/bin/bash\nset -ex\n\n# resize script phase 2\n\nif ! [ -h /dev/disk/by-label/root ]; then\n  echo \"/dev/disk/by-label/root does not exist or is not a symlink. Don't know how to expand\"\n  return 0\nfi\n\nROOT_PART=$(readlink /dev/disk/by-label/root)\n/sbin/resize2fs \"$ROOT_PART\"\n"
  },
  {
    "path": "builder/files/etc/skel/.bash_prompt",
    "content": "# @gf3’s Sexy Bash Prompt, inspired by “Extravagant Zsh Prompt”\n# Shamelessly copied from https://github.com/gf3/dotfiles\n\ndefault_username='unknown'\nOSNAME=\"HypriotOS: \"\nOSTYPE=\"Embedded\"\nPROMPTCHAR='\\$'\n\n# determine OS type\nif [ \"$(uname -s)\" = Darwin ]; then\n  OSNAME=\"OSX: \"\n  OSTYPE=\"Desktop\"\n  #PROMPTCHAR=\"🐳 \"\nelif [ \"$(cat /etc/os-release | grep ^NAME= | cut -d\\\" -f2)\" = Ubuntu ]; then\n  OSNAME=\"Ubuntu: \"\n  OSTYPE=\"Desktop\"\n  #PROMPTCHAR=\"🐳 \"\nelif [ \"$(uname -m)\" = armv6l ]; then\n  OSNAME=\"HypriotOS/armv6: \"\nelif [ \"$(uname -m)\" = armv7l ]; then\n  OSNAME=\"HypriotOS/armv7: \"\nelif [ \"$(uname -m)\" = aarch64 ]; then\n  OSNAME=\"HypriotOS/arm64: \"\nelse\n  OSNAME=\"HypriotOS: \"\nfi\n\nif [[ $COLORTERM = gnome-* && $TERM = xterm ]] && infocmp gnome-256color >/dev/null 2>&1; then\n  export TERM=gnome-256color\nelif infocmp xterm-256color >/dev/null 2>&1; then\n  export TERM=xterm-256color\nfi\n\nif tput setaf 1 &> /dev/null; then\n  tput sgr0\n  if [[ $(tput colors) -ge 256 ]] 2>/dev/null; then\n    BLUE=$(tput setaf 4)\n    MAGENTA=$(tput setaf 9)\n    ORANGE=$(tput setaf 172)\n    GREEN=$(tput setaf 70)\n    PURPLE=$(tput setaf 141)\n  else\n    BLUE=$(tput setaf 4)\n    MAGENTA=$(tput setaf 5)\n    ORANGE=$(tput setaf 3)\n    GREEN=$(tput setaf 2)\n    PURPLE=$(tput setaf 1)\n\n  fi\n  BOLD=$(tput bold)\n  RESET=$(tput sgr0)\n  else\n    BLUE=\"\\033[1;34m\"\n    MAGENTA=\"\\033[1;31m\"\n    ORANGE=\"\\033[1;33m\"\n    GREEN=\"\\033[1;32m\"\n    PURPLE=\"\\033[1;35m\"\n    BOLD=\"\"\n    RESET=\"\\033[m\"\n  fi\n\n\nfunction git_info() {\n  # check if we're in a git repo\n  git rev-parse --is-inside-work-tree &>/dev/null || return\n\n  # quickest check for what branch we're on\n  branch=$(git symbolic-ref -q HEAD | sed -e 's|^refs/heads/||')\n\n  # check if it's dirty (via github.com/sindresorhus/pure)\n  dirty=$(test -z \"$(git status --porcelain)\" || echo -e \"*\")\n\n  echo \"$RESET$BOLD on $PURPLE$branch$dirty\"\n}\n\n# Only show username/host if not default\nfunction usernamehost() {\n  if [ \"$USER\" != $default_username ]; then\n    echo \"${BLUE}${OSNAME}${MAGENTA}$USER${RESET}${BOLD}@${ORANGE}$HOSTNAME${RESET}${BOLD} in \";\n  else\n    echo \"${BLUE}${OSNAME}\";\n  fi\n}\n\n# iTerm Tab and Title Customization and prompt customization\n# http://sage.ucsc.edu/xtal/iterm_tab_customization.html\n\n# Put the string \" [bash]   hostname::/full/directory/path\"\n# in the title bar using the command sequence\n# \\[\\e]2;[bash]   \\h::\\]$PWD\\[\\a\\]\n\n# Put the penultimate and current directory\n# in the iterm tab\n# \\[\\e]1;\\]$(basename $(dirname $PWD))/\\W\\[\\a\\]\n\n\n# show git info only on macOS/Ubuntu Desktop systems, don't slow down on ARM/Embedded devices\nif [ \"$OSTYPE\" = \"Desktop\" ]; then\n  PS1=\"\\[\\e]2;$PWD\\[\\a\\]\\[\\e]1;\\]$(basename \"$(dirname \"$PWD\")\")/\\W\\[\\a\\]${BOLD}$(usernamehost)\\[$GREEN\\]\\w\\$(git_info)\\[$RESET\\]\\[$BOLD\\]\\n${PROMPTCHAR} \\[$RESET\\]\"\nelse\n  PS1=\"\\[\\e]2;$PWD\\[\\a\\]\\[\\e]1;\\]$(basename \"$(dirname \"$PWD\")\")/\\W\\[\\a\\]${BOLD}$(usernamehost)\\[$GREEN\\]\\w\\[$RESET\\]\\[$BOLD\\]\\n${PROMPTCHAR} \\[$RESET\\]\"\nfi\n"
  },
  {
    "path": "builder/files/etc/skel/.bashrc",
    "content": "# ~/.bashrc: executed by bash(1) for non-login shells.\n\n# Note: PS1 and umask are already set in /etc/profile. You should not\n# need this unless you want different defaults for root.\n# PS1='${debian_chroot:+($debian_chroot)}\\h:\\w\\$ '\n# umask 022\n\n# You may uncomment the following lines if you want `ls' to be colorized:\nexport LS_OPTIONS='--color=auto'\neval \"`dircolors`\"\nalias ls='ls $LS_OPTIONS'\n# alias ll='ls $LS_OPTIONS -l'\n# alias l='ls $LS_OPTIONS -lA'\n#\n# Some more alias to avoid making mistakes:\n# alias rm='rm -i'\n# alias cp='cp -i'\n# alias mv='mv -i'\n"
  },
  {
    "path": "builder/files/etc/systemd/system/hciuart.service",
    "content": "[Unit]\nDescription=Configure Bluetooth Modems connected by UART\nConditionPathIsDirectory=/proc/device-tree/soc/gpio@7e200000/bt_pins\nBefore=bluetooth.service\nAfter=dev-ttyAMA0.device\n\n[Service]\nType=forking\nExecStart=/usr/bin/hciattach /dev/ttyAMA0 bcm43xx 921600 noflow -\n\n[Install]\nWantedBy=multi-user.target\n"
  },
  {
    "path": "builder/files/etc/udev/rules.d/10-wlan-powersave-off.rules",
    "content": "KERNEL==\"wlan*\", ACTION==\"add\", RUN+=\"/sbin/iwconfig wlan0 power off\"\n"
  },
  {
    "path": "builder/files/etc/udev/rules.d/75-persistent-net-generator.rules",
    "content": "# These rules generate rules to keep network interface names unchanged\n# across reboots and write them to /etc/udev/rules.d/70-persistent-net.rules.\n\n# variables used to communicate:\n#   MATCHADDR\t\tMAC address used for the match\n#   MATCHID\t\tbus_id used for the match\n#   MATCHDRV\t\tdriver name used for the match\n#   MATCHIFTYPE\t\tinterface type match\n#   COMMENT\t\tcomment to add to the generated rule\n#   INTERFACE_NAME\trequested name supplied by external tool\n#   INTERFACE_NEW\tnew interface name returned by rule writer\n\nACTION!=\"add\",\t\t\t\tGOTO=\"persistent_net_generator_end\"\nSUBSYSTEM!=\"net\",\t\t\tGOTO=\"persistent_net_generator_end\"\n\n# ignore the interface if a name has already been set\nNAME==\"?*\",\t\t\t\tGOTO=\"persistent_net_generator_end\"\n\n# new predictable network interface naming scheme\n# http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/\nIMPORT{cmdline}=\"net.ifnames\"\nENV{net.ifnames}==\"1\",\t\t\tGOTO=\"persistent_net_generator_end\"\n\n# device name whitelist\nKERNEL!=\"ath*|msh*|ra*|sta*|ctc*|lcs*|hsi*\", \\\n\t\t\t\t\tGOTO=\"persistent_net_generator_end\"\n\n# ignore Xen virtual interfaces\nSUBSYSTEMS==\"xen\",\t\t\tGOTO=\"persistent_net_generator_end\"\n\n# ignore UML virtual interfaces\nDRIVERS==\"uml-netdev\",\t\t\tGOTO=\"persistent_net_generator_end\"\n\n# ignore \"secondary\" raw interfaces of the madwifi driver\nKERNEL==\"ath*\", ATTRS{type}==\"802\",\tGOTO=\"persistent_net_generator_end\"\n\n# ignore \"secondary\" monitor interfaces of mac80211 drivers\nKERNEL==\"wlan*\", ATTRS{type}==\"803\",\tGOTO=\"persistent_net_generator_end\"\n\n# by default match on the MAC address and interface type\nENV{MATCHADDR}=\"$attr{address}\"\nENV{MATCHIFTYPE}=\"$attr{type}\"\n\n# match interface dev_id\nATTR{dev_id}==\"?*\", ENV{MATCHDEVID}=\"$attr{dev_id}\"\n\n# These vendors are known to violate the local MAC address assignment scheme\n# Interlan, DEC (UNIBUS or QBUS), Apollo, Cisco, Racal-Datacom\nENV{MATCHADDR}==\"02:07:01:*\", GOTO=\"globally_administered_whitelist\"\n# 3Com\nENV{MATCHADDR}==\"02:60:60:*\", GOTO=\"globally_administered_whitelist\"\n# 3Com IBM PC; Imagen; Valid; Cisco; Apple\nENV{MATCHADDR}==\"02:60:8c:*\", GOTO=\"globally_administered_whitelist\"\n# Intel\nENV{MATCHADDR}==\"02:a0:c9:*\", GOTO=\"globally_administered_whitelist\"\n# Olivetti\nENV{MATCHADDR}==\"02:aa:3c:*\", GOTO=\"globally_administered_whitelist\"\n# CMC Masscomp; Silicon Graphics; Prime EXL\nENV{MATCHADDR}==\"02:cf:1f:*\", GOTO=\"globally_administered_whitelist\"\n# Prominet Corporation Gigabit Ethernet Switch\nENV{MATCHADDR}==\"02:e0:3b:*\", GOTO=\"globally_administered_whitelist\"\n# BTI (Bus-Tech, Inc.) IBM Mainframes\nENV{MATCHADDR}==\"02:e6:d3:*\", GOTO=\"globally_administered_whitelist\"\n# Novell 2000\nENV{MATCHADDR}==\"52:54:4c:*\", GOTO=\"globally_administered_whitelist\"\n# Realtec\nENV{MATCHADDR}==\"52:54:ab:*\", GOTO=\"globally_administered_whitelist\"\n# Kingston Technologies\nENV{MATCHADDR}==\"e2:0c:0f:*\", GOTO=\"globally_administered_whitelist\"\n\n\n# ignore interfaces with locally administered or null MAC addresses\n# and VMWare, Hyper-V, KVM, Virtualbox and Xen virtual interfaces\nENV{MATCHADDR}==\"?[2367abef]:*\",\tENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"00:00:00:00:00:00\",\tENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"00:0c:29:*|00:50:56:*|00:05:69:*|00:1C:14:*\", \\\n\t\t\t\t\tENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"00:15:5d:*\",\t\tENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"52:54:00:*|54:52:00:*\", ENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"08:00:27:*\",\t\tENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"00:16:3e:*\",\t\tENV{MATCHADDR}=\"\"\n\n# ignore Windows Azure Hyper-V virtual interfaces\nENV{MATCHADDR}==\"00:03:ff:*\", ENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"00:0d:3a:*\", ENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"00:1d:d8:*\", ENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"00:12:5a:*\", ENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"00:17:fa:*\", ENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"00:22:48:*\", ENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"00:25:ae:*\", ENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"00:50:f2:*\", ENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"28:18:78:*\", ENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"50:1a:c5:*\", ENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"60:45:bd:*\", ENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"7c:1e:52:*\", ENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"7c:ed:8d:*\", ENV{MATCHADDR}=\"\"\nENV{MATCHADDR}==\"dc:b4:c4:*\", ENV{MATCHADDR}=\"\"\n\n# ignore Ravello virtual interfaces\nENV{MATCHADDR}==\"2c:c2:60:*\", ENV{MATCHADDR}=\"\"\n\nLABEL=\"globally_administered_whitelist\"\n\n# ibmveth interfaces have stable locally administered MAC addresses\nSUBSYSTEMS==\"ibmveth\",\t\t\tENV{MATCHADDR}=\"$attr{address}\"\n\n# S/390 interfaces are matched only by id\nSUBSYSTEMS==\"ccwgroup\", \\\n\tENV{MATCHDRV}=\"$driver\", ENV{MATCHID}=\"$id\", \\\n\tENV{MATCHADDR}=\"\", ENV{MATCHDEVID}=\"\"\n\n# terminate processing if there are not enough conditions to create a rule\nENV{MATCHADDR}==\"\", ENV{MATCHID}==\"\", ENV{INTERFACE_NAME}==\"\", \\\n\t\t\t\t\tGOTO=\"persistent_net_generator_end\"\n\n\n# provide nice comments for the generated rules\nSUBSYSTEMS==\"pci\", \\\n ENV{COMMENT}=\"PCI device $attr{vendor}:$attr{device}\"\nSUBSYSTEMS==\"pcmcia\", \\\n ENV{COMMENT}=\"PCMCIA device $attr{card_id}:$attr{manf_id}\"\nSUBSYSTEMS==\"usb\", \\\n ENV{COMMENT}=\"USB device 0x$attr{idVendor}:0x$attr{idProduct}\"\nSUBSYSTEMS==\"ccwgroup\", \\\n ENV{COMMENT}=\"S/390 device at $id\"\nSUBSYSTEMS==\"ibmveth\", \\\n ENV{COMMENT}=\"LPAR virtual device at $id\"\nSUBSYSTEMS==\"ieee1394\", \\\n ENV{COMMENT}=\"Firewire device $attr{host_id}\"\nENV{COMMENT}==\"\", \\\n ENV{COMMENT}=\"Unknown $env{SUBSYSTEM} device ($env{DEVPATH})\"\nATTRS{driver}==\"?*\", \\\n ENV{COMMENT}=\"$env{COMMENT} ($attr{driver})\"\n\n\n# ignore interfaces without a driver link like bridges and VLANs, otherwise\n# generate and write the rule\nDRIVERS==\"?*\", IMPORT{program}=\"write_net_rules\"\n\n# rename the interface if requested\nENV{INTERFACE_NEW}==\"?*\", NAME=\"$env{INTERFACE_NEW}\"\n\nLABEL=\"persistent_net_generator_end\"\n\n"
  },
  {
    "path": "builder/files/etc/udev/rules.d/99-com.rules",
    "content": "SUBSYSTEM==\"gpio*\", PROGRAM=\"/bin/sh -c 'chown -R root:gpio /sys/class/gpio && chmod -R 770 /sys/class/gpio; chown -R root:gpio /sys/devices/virtual/gpio && chmod -R 770 /sys/devices/virtual/gpio; chown -R root:gpio /sys/devices/platform/soc/*.gpio/gpio && chmod -R 770 /sys/devices/platform/soc/*.gpio/gpio'\"\nSUBSYSTEM==\"input\", GROUP=\"input\", MODE=\"0660\"\nSUBSYSTEM==\"i2c-dev\", GROUP=\"i2c\", MODE=\"0660\"\nSUBSYSTEM==\"spidev\", GROUP=\"spi\", MODE=\"0660\"\nSUBSYSTEM==\"bcm2835-gpiomem\", GROUP=\"gpio\", MODE=\"0660\"\n"
  },
  {
    "path": "builder/files/lib/firmware/brcm/brcmfmac43430-sdio.txt",
    "content": "# NVRAM file for BCM943430WLSELG\n# 2.4 GHz, 20 MHz BW mode\n\n# The following parameter values are just placeholders, need to be updated.\nmanfid=0x2d0\nprodid=0x0726\nvendid=0x14e4\ndevid=0x43e2\nboardtype=0x0726\nboardrev=0x1202\nboardnum=22\nmacaddr=00:90:4c:c5:12:38\nsromrev=11\nboardflags=0x00404201\nboardflags3=0x08000000\nxtalfreq=37400\n#xtalfreq=19200\nnocrc=1\nag0=255\naa2g=1\nccode=ALL\n\npa0itssit=0x20\nextpagain2g=0\n\n#PA parameters for 2.4GHz, measured at CHIP OUTPUT\npa2ga0=-168,7161,-820\nAvVmid_c0=0x0,0xc8\ncckpwroffset0=5\n\n# PPR params\nmaxp2ga0=84\ntxpwrbckof=6\ncckbw202gpo=0\nlegofdmbw202gpo=0x66111111\nmcsbw202gpo=0x77711111\npropbw202gpo=0xdd\n\n# OFDM IIR :\nofdmdigfilttype=18\nofdmdigfilttypebe=18\n# PAPD mode:\npapdmode=1\npapdvalidtest=1\npacalidx2g=32\npapdepsoffset=-36\npapdendidx=61\n\nil0macaddr=00:90:4c:c5:12:38\nwl0id=0x431b\n\ndeadman_to=0xffffffff\n# muxenab: 0x1 for UART enable, 0x2 for GPIOs, 0x8 for JTAG\nmuxenab=0x1\n# CLDO PWM voltage settings - 0x4 - 1.1 volt\n#cldo_pwm=0x4\n\n#VCO freq 326.4MHz\nspurconfig=0x3 \n"
  },
  {
    "path": "builder/files/lib/firmware/brcm/brcmfmac43455-sdio.txt",
    "content": "# Cloned from bcm94345wlpagb_p2xx.txt \n# NVRAMRev=$Rev: 498373 $\nsromrev=11\nvendid=0x14e4\ndevid=0x43ab\nmanfid=0x2d0\nprodid=0x06e4\nmacaddr=00:90:4c:c5:12:38\n#macaddr=b8:27:eb:74:f2:6c\nnocrc=1\nboardtype=0x6e4\nboardrev=0x1304\n\n#XTAL 37.4MHz\nxtalfreq=37400\n\nbtc_mode=1\n#------------------------------------------------------\n#boardflags: 5GHz eTR switch by default\n#            2.4GHz eTR switch by default\n#            bit1 for btcoex\nboardflags=0x00480201\nboardflags2=0x40800000\nboardflags3=0x48200100\nphycal_tempdelta=15\nrxchain=1\ntxchain=1\naa2g=1\naa5g=1\ntssipos5g=1\ntssipos2g=1\nfemctrl=0\nAvVmid_c0=1,165,2,100,2,100,2,100,2,100\npa2ga0=-129,6525,-718\npa2ga1=-149,4408,-601\npa5ga0=-185,6836,-815,-186,6838,-815,-184,6859,-815,-184,6882,-818\npa5ga1=-202,4285,-574,-201,4312,-578,-196,4391,-586,-201,4294,-575\nitrsw=1\npdoffsetcckma0=2\npdoffset2gperchan=0,-2,1,0,1,0,1,1,1,0,0,-1,-1,0\npdoffset2g40ma0=16\npdoffset40ma0=0x8888\npdoffset80ma0=0x8888\nextpagain5g=2\nextpagain2g=2\ntworangetssi2g=1\ntworangetssi5g=1\n# LTECX flags\n# WCI2\nltecxmux=0\nltecxpadnum=0x0504\nltecxfnsel=0x22\nltecxgcigpio=0x32\n\nmaxp2ga0=80\nofdmlrbw202gpo=0x0022\ndot11agofdmhrbw202gpo=0x4442\nmcsbw202gpo=0x98444422\nmcsbw402gpo=0x98444422\nmaxp5ga0=82,82,82,82\nmcsbw205glpo=0xb9555000\nmcsbw205gmpo=0xb9555000\nmcsbw205ghpo=0xb9555000\nmcsbw405glpo=0xb9555000\nmcsbw405gmpo=0xb9555000\nmcsbw405ghpo=0xb9555000\nmcsbw805glpo=0xb9555000\nmcsbw805gmpo=0xb9555000\nmcsbw805ghpo=0xb9555000\n\nswctrlmap_2g=0x00000000,0x00000000,0x00000000,0x010000,0x3ff\nswctrlmap_5g=0x00100010,0x00200020,0x00200020,0x010000,0x3fe\nswctrlmapext_5g=0x00000000,0x00000000,0x00000000,0x000000,0x3\nswctrlmapext_2g=0x00000000,0x00000000,0x00000000,0x000000,0x3\n\nvcodivmode=1\ndeadman_to=481500000\n\ned_thresh2g=-54\ned_thresh5g=-54\neu_edthresh2g=-54\neu_edthresh5g=-54\nldo1=4\nrawtempsense=0x1ff\ncckPwrIdxCorr=3\ncckTssiDelay=150\nofdmTssiDelay=150\ntxpwr2gAdcScale=1\ntxpwr5gAdcScale=1\ndot11b_opts=0x3aa85\ncbfilttype=1\nfdsslevel_ch11=6\n"
  },
  {
    "path": "builder/files/sbin/resizefs",
    "content": "#!/bin/sh\n\nmount -t proc proc /proc\nmount -t sysfs sys /sys\nmount -t tmpfs tmp /run\nmount / -o remount,rw\n\nPART_START=$(cat /sys/block/mmcblk0/mmcblk0p2/start)\n\necho \"Modifying partition table\"\nfdisk -u /dev/mmcblk0 <<EOF\np\nd\n2\nn\np\n2\n$PART_START\n\np\nw\nEOF\necho \"Partition table changed. rebooting\"\nrm /sbin/init /sbin/resizefs\nmv /sbin/init.bak /sbin/init\necho 1 > /proc/sys/kernel/sysrq\nmount / -o remount,ro\nsync\necho b > /proc/sysrq-trigger\n"
  },
  {
    "path": "builder/test/image_spec.rb",
    "content": "require_relative 'spec_helper'\n\ndescribe \"SD card image\" do\n  it \"exists\" do\n    image_file = file(image_path)\n    expect(image_file).to exist\n  end\n\n  context \"Partition table\" do\n    let(:stdout) { run(\"list-filesystems\").stdout }\n\n    it \"has two partitions\" do\n      partitions = stdout.split(/\\r?\\n/)\n      expect(partitions.size).to be 2\n    end\n\n    it \"has a boot-partition with a vfat filesystem\" do\n      expect(stdout).to contain('sda1: vfat')\n    end\n\n    it \"has a root-partition with a ext4 filesystem\" do\n      expect(stdout).to contain('sda2: ext4')\n    end\n  end\n\n  context \"Binary dpkg\" do\n    let(:stdout) { run_mounted(\"file-architecture /usr/bin/dpkg\").stdout }\n\n    it \"is compiled for ARM aarch64 architecture\" do\n      expect(stdout).to contain('aarch64')\n    end\n  end\n\n  context \"/etc/fstab\" do\n    let(:stdout) { run_mounted(\"cat /etc/fstab\").stdout }\n\n    it \"has a vfat boot entry\" do\n      expect(stdout).to contain('/dev/mmcblk0p1 /boot vfat')\n    end\n\n    it \"has a ext4 root entry\" do\n      expect(stdout).to contain('/dev/mmcblk0p2 / ext4')\n    end\n  end\n\n  context \"Docker systemd service file\" do\n    let(:stdout) { run_mounted(\"cat /lib/systemd/system/docker.service\").stdout }\n\n    it \"Docker Engine is installed\" do\n      expect(stdout).to contain(\"/usr/bin/dockerd\")\n    end\n  end\nend\n"
  },
  {
    "path": "builder/test/os-release_spec.rb",
    "content": "require_relative 'spec_helper'\n\ndescribe \"Root filesystem\" do\n  let(:stdout) { run_mounted(\"cat /etc/os-release\").stdout }\n\n  it \"is based on debian\" do\n    expect(stdout).to contain('debian')\n  end\n\n  it \"is debian version stretch\" do\n    expect(stdout).to contain('stretch')\n  end\n\n  it \"is a HypriotOS\" do\n    expect(stdout).to contain('HypriotOS')\n  end\n\n  it \"has a HYPRIOT_OS= entry\" do\n    expect(stdout).to contain('^HYPRIOT_OS=')\n  end\n  it \"has a HYPRIOT_OS_VERSION= entry\" do\n    expect(stdout).to contain('^HYPRIOT_OS_VERSION=')\n  end\n  it \"has a HYPRIOT_DEVICE= entry\" do\n    expect(stdout).to contain('^HYPRIOT_DEVICE=')\n  end\n  it \"has a HYPRIOT_IMAGE_VERSION= entry\" do\n    expect(stdout).to contain('^HYPRIOT_IMAGE_VERSION=')\n  end\n\n  it \"is for architecure 'HYPRIOT_OS=\\\"HypriotOS/arm64\\\"'\" do\n    expect(stdout).to contain('^HYPRIOT_OS=\"HypriotOS/arm64\"$')\n  end\n\n  it \"is for device 'HYPRIOT_DEVICE=\\\"Raspberry Pi 3 64bit\\\"'\" do\n    expect(stdout).to contain('^HYPRIOT_DEVICE=\"Raspberry Pi 3 64bit\"$')\n  end\n\n  it \"uses os-rootfs version 'HYPRIOT_OS_VERSION=\\\"v2.1.0\\\"'\" do\n    expect(stdout).to contain('^HYPRIOT_OS_VERSION=\"v2.1.0\"$')\n  end\n\n  if ENV.fetch('CIRCLE_TAG','') != ''\n    it \"is not dirty\" do\n      expect(stdout).not_to contain('dirty')\n    end\n  end\nend\n"
  },
  {
    "path": "builder/test/spec_helper.rb",
    "content": "require 'serverspec'\nset :backend, :exec\n\ndef image_path\n  return \"hypriotos-rpi64-#{ENV['VERSION']}.img\"\nend\n\ndef run( cmd )\n  return command(\"guestfish add #{image_path} : run : #{cmd}\")\nend\n\ndef run_mounted( cmd )\n  return run(\"mount /dev/sda2 / : #{cmd}\")\nend\n"
  },
  {
    "path": "builder/test-integration/.bundle/config",
    "content": "---\nBUNDLE_PATH: vendor/bundle\nBUNDLE_DISABLE_SHARED_GEMS: '1'\nBUNDLE_BIN: bin\n"
  },
  {
    "path": "builder/test-integration/.gitignore",
    "content": "bin/\nvendor/\n"
  },
  {
    "path": "builder/test-integration/.rspec",
    "content": "--color\n--format documentation\n"
  },
  {
    "path": "builder/test-integration/.ruby-version",
    "content": "2.0.0\n"
  },
  {
    "path": "builder/test-integration/Gemfile",
    "content": "# A sample Gemfile\nsource \"https://rubygems.org\"\n\ngem \"serverspec\"\n"
  },
  {
    "path": "builder/test-integration/README.md",
    "content": "# HypriotOS serverspec tests\n\nTo test the SD card image for the Raspberry Pi use this [Serverspec](http://serverspec.org) tests. See the [Serverspec Docs](http://serverspec.org/resource_types.html) for more details what you can test with it.\n\n## Preparation\n\n1. Flash the SD card image\n2. Put the SD card into your Raspberry Pi\n3. Power on the Raspberry Pi\n4. Retrieve the host name or IP address to reach the Pi\n\n## Install Serverspec\n\nYou need ruby and bundle installed. Then you can install the dependencies locally with\n\n```bash\nbundle install\n```\n\n## Run tests\n\nSet the `BOARD` environment variable to the host name or\nIP address of your Pi. The user name for the test is `root`.\n\n### Remove previous fingerpint\n\nYou normally have to remove the fingerprint of a previously tested Hypriot Pi.\nUse the hostname or the IP address of your Raspberry Pi.\n\n```bash\nssh-keygen -R black-pearl.local\n```\n\n### Run basic SD image tests\n\nNow run the basic SD card image tests. This tests if docker is up and running and the image has everything as we expect it.\n\n```bash\nBOARD=black-pearl.local bin/rspec spec/hypriotos-image\n```\n\n### Run full docker test\n\nNow run a full docker test. This does a full cycle with `docker pull` and `docker run` to see that everything works fine.\n\n```\nBOARD=black-pearl.local bin/rspec spec/hypriotos-docker\n```\n"
  },
  {
    "path": "builder/test-integration/Rakefile",
    "content": "require 'rake'\nrequire 'rspec/core/rake_task'\n\ntask :spec    => 'spec:all'\ntask :default => :spec\n\nnamespace :spec do\n  targets = []\n  Dir.glob('./spec/*').each do |dir|\n    next unless File.directory?(dir)\n    targets << File.basename(dir)\n  end\n\n  task :all     => targets\n  task :default => :all\n\n  targets.each do |target|\n    desc \"Run serverspec tests to #{target}\"\n    RSpec::Core::RakeTask.new(target.to_sym) do |t|\n      ENV['TARGET_HOST'] = target\n      t.pattern = \"spec/#{target}/*_spec.rb\"\n    end\n  end\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-docker/docker-busybox-httpd_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe command('docker pull hypriot/rpi-busybox-httpd:0.1.0') do\n  its(:exit_status) { should eq 0 }\nend\n\ndescribe command('docker run -t --rm hypriot/rpi-busybox-httpd:0.1.0 busybox') do\n  its(:stdout) { should match /BusyBox v1.20.2/ }\n  its(:exit_status) { should eq 0 }\nend\n\ndescribe command('docker run -t --rm hypriot/rpi-busybox-httpd:0.1.0 busybox httpd') do\n  its(:exit_status) { should eq 0 }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-docker/docker-compose_spec.rb.off",
    "content": "require 'spec_helper'\n\ndescribe command('rm -rf rpi-node-haproxy-example && git clone https://github.com/hypriot/rpi-node-haproxy-example') do\n  its(:exit_status) { should eq 0 }\nend\n\ndescribe command('cd rpi-node-haproxy-example && docker-compose up -d') do\n  its(:exit_status) { should eq 0 }\nend\n\ndescribe command('cd rpi-node-haproxy-example && docker-compose ps') do\n  its(:stdout) { should match /rpinodehaproxyexample_haproxy_1   bash \\/haproxy-start   Up/ }\n  its(:stdout) { should match /rpinodehaproxyexample_weba_1      node index.js         Up/ }\n  its(:stdout) { should match /rpinodehaproxyexample_webb_1      node index.js         Up/ }\n  its(:stdout) { should match /rpinodehaproxyexample_webc_1      node index.js         Up/ }\n  its(:exit_status) { should eq 0 }\nend\n\ndescribe command('curl http://localhost') do\n  its(:stdout) { should match /Hello from Node.js container/ }\n  its(:exit_status) { should eq 0 }\nend\n\ndescribe command('cd rpi-node-haproxy-example && docker-compose kill') do\n  its(:exit_status) { should eq 0 }\nend\n\ndescribe command('cd rpi-node-haproxy-example && docker-compose ps') do\n  its(:stdout) { should match /rpinodehaproxyexample_haproxy_1   bash \\/haproxy-start   Exit 137/ }\n  its(:stdout) { should match /rpinodehaproxyexample_weba_1      node index.js         Exit 137/ }\n  its(:stdout) { should match /rpinodehaproxyexample_webb_1      node index.js         Exit 137/ }\n  its(:stdout) { should match /rpinodehaproxyexample_webc_1      node index.js         Exit 137/ }\n  its(:exit_status) { should eq 0 }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-docker/docker-node_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe command('docker pull hypriot/rpi-node:0.12.0') do\n  its(:exit_status) { should eq 0 }\nend\n\ndescribe command('docker run -t --rm hypriot/rpi-node:0.12.0 node --version') do\n  its(:stdout) { should match /v0.12.0/ }\n#  its(:stderr) { should match /^$/ }\n  its(:exit_status) { should eq 0 }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/base/bootfiles_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe file('/boot/bcm2710-rpi-3-b.dtb') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/boot/bootcode.bin') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/boot/cmdline.txt') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/boot/config.txt') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/boot/fixup.dat') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/boot/kernel8.img') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/boot/COPYING.linux') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/boot/LICENCE.broadcom') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/boot/overlays') do\n  it { should be_directory }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/boot/start.elf') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/base/device_tree_spec.rb",
    "content": "require 'spec_helper'\n\n# /proc/device-tree is only present if device-tree works\ndescribe file('/proc/device-tree') do\n  it { should be_symlink }\n  it { should be_linked_to '/sys/firmware/devicetree/base' }\n  it { should be_mode 777 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/proc/device-tree/model') do\n  it { should be_file }\n  it { should be_mode 444 }\n  it { should be_owned_by 'root' }\n  its(:content) { should match /Raspberry Pi 3 Model B/ }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/base/kernel_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe command('uname -r') do\n  its(:stdout) { should match /4.19.58-hypriotos-v8/ }\n  its(:exit_status) { should eq 0 }\nend\n\ndescribe file('/lib/modules/4.19.58-hypriotos-v8/kernel') do\n  it { should be_directory }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/base/packages_spec.rb",
    "content": "describe package('curl') do\n  it { should be_installed }\nend\n\ndescribe package('wget') do\n  it { should be_installed }\nend\n\ndescribe package('bash-completion') do\n  it { should be_installed }\nend\n\ndescribe package('htop') do\n  it { should be_installed }\nend\n\ndescribe package('occi') do\n  it { should_not be_installed }\nend\n\ndescribe package('usbutils') do\n  it { should be_installed }\nend\n\ndescribe package('lsb-release') do\n  it { should be_installed }\nend\n\ndescribe package('wpasupplicant') do\n  it { should be_installed }\nend\n\ndescribe package('wireless-tools') do\n  it { should be_installed }\nend\n\ndescribe 'for bluetooth-support' do\n  describe package('bluetooth') do\n    it { should be_installed }\n  end\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/base/release_spec.rb",
    "content": "describe file('/etc/hypriot_release') do\n  it { should_not be_file }\nend\n\ndescribe file('/etc/os-release') do\n  it { should be_file }\n  it { should be_owned_by 'root' }\n  its(:content) { should contain /ID=debian/ }\n  its(:content) { should match /HYPRIOT_OS=\"HypriotOS\\/arm64\"/ }\n  its(:content) { should match /HYPRIOT_OS_VERSION=\"v2.1.0\"/ }\n  its(:content) { should match /HYPRIOT_DEVICE=\"Raspberry Pi 3 64bit\"/ }\n  its(:content) { should match /HYPRIOT_IMAGE_VERSION=/ }\nend\n\ndescribe file('/boot/os-release') do\n  it { should be_file }\n  it { should be_owned_by 'root' }\n  its(:content) { should contain /ID=debian/ }\n  its(:content) { should match /HYPRIOT_OS=\"HypriotOS\\/arm64\"/ }\n  its(:content) { should match /HYPRIOT_OS_VERSION=\"v2.1.0\"/ }\n  its(:content) { should match /HYPRIOT_DEVICE=\"Raspberry Pi 3 64bit\"/ }\n  its(:content) { should match /HYPRIOT_IMAGE_VERSION=/ }\nend\n\ndescribe file('/etc/motd') do\n  it { should be_file }\n  it { should be_owned_by 'root' }\n  its(:content) { should match /HypriotOS \\(Debian GNU\\/Linux 9\\)/ }\nend\n\ndescribe file('/etc/issue') do\n  it { should be_file }\n  it { should be_owned_by 'root' }\n  its(:content) { should match /HypriotOS \\(Debian GNU\\/Linux 9\\)/ }\nend\n\ndescribe file('/etc/issue.net') do\n  it { should be_file }\n  it { should be_owned_by 'root' }\n  its(:content) { should match /HypriotOS \\(Debian GNU\\/Linux 9\\)/ }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/base/rpi3_bluetooth_spec.rb",
    "content": "# only test for built-in bluetooth support if we are on the Raspberry Pi 3\ncpu_info = command('cat /proc/cpuinfo').stdout\n\nif cpu_info.include?('a02082') or cpu_info.include?('a22082')\n  describe \"RPi 3: bluetooth support\" do\n    describe command('hciconfig') do\n      its(:stdout) { should contain /hci0/ }\n      its(:stdout) { should contain /UP RUNNING/ }\n    end\n  end\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/base/rpi3_wifi_spec.rb",
    "content": "# only test for built-in bluetooth support if we are on the Raspberry Pi 3\ncpu_info = command('cat /proc/cpuinfo').stdout\n\nif cpu_info.include?('a02082') or cpu_info.include?('a22082')\n  describe \"RPi 3B: built-in wifi works\" do\n    describe command('ifconfig -a') do\n      its(:stdout) { should contain /wlan0/ }\n    end\n\n    describe command('ethtool -i wlan0') do\n      its(:stdout) { should contain /driver: brcmfmac/ }\n      its(:stdout) { should contain /version: 7.45.98.38/ }\n      its(:stdout) { should contain /firmware-version: 01-e58d219f/ }\n    end\n  end\nend\n\ndescribe \"RPi 3B: built-in wifi firmware is installed\" do\n  describe file('/lib/firmware/brcm/brcmfmac43430-sdio.bin') do\n    it { should be_file }\n    it { should be_mode 644 }\n    it { should be_owned_by 'root' }\n  end\n\n  describe file('/lib/firmware/brcm/brcmfmac43430-sdio.txt') do\n    it { should be_file }\n    it { should be_mode 644 }\n    it { should be_owned_by 'root' }\n  end\nend\n\ndescribe \"RPi 3B: built-in wifi works\" do\n  describe command('ifconfig -a') do\n    its(:stdout) { should contain /wlan0/ }\n  end\n\n  wifi_info = command('ethtool -i wlan0').stdout\n  if wifi_info.include?('version: 7.45.98.38')\n    describe command('ethtool -i wlan0') do\n      its(:stdout) { should contain /driver: brcmfmac/ }\n      its(:stdout) { should contain /version: 7.45.98.38/ }\n      its(:stdout) { should contain /firmware-version: 01-e58d219f/ }\n    end\n  end\nend\n\ndescribe \"RPi 3B+: built-in wifi firmware is installed\" do\n  describe file('/lib/firmware/brcm/brcmfmac43455-sdio.bin') do\n    it { should be_file }\n    it { should be_mode 644 }\n    it { should be_owned_by 'root' }\n  end\n\n  describe file('/lib/firmware/brcm/brcmfmac43455-sdio.txt') do\n    it { should be_file }\n    it { should be_mode 644 }\n    it { should be_owned_by 'root' }\n  end\nend\n\ndescribe \"RPi 3B+: built-in wifi works\" do\n  describe command('ifconfig -a') do\n    its(:stdout) { should contain /wlan0/ }\n  end\n\n  wifi_info = command('ethtool -i wlan0').stdout\n  if wifi_info.include?('version: 7.45.154')\n    describe command('ethtool -i wlan0') do\n      its(:stdout) { should contain /driver: brcmfmac/ }\n      its(:stdout) { should contain /version: 7.45.154/ }\n      its(:stdout) { should contain /firmware-version: 01-4fbe0b04/ }\n    end\n  end\nend"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/base/serial_base.rb",
    "content": "describe command('ps -ax') do\n  its(:stdout) { should match /getty -L ttyAMA0 115200 vt100/ }\nend\n\ndescribe file('/etc/inittab') do\n  it { should be_file }\n  it { should be_mode 644 }\n  it { should be_owned_by 'root' }\n  its(:content) { should match /^T0:23:respawn:\\/sbin\\/getty -L ttyAMA0 115200 vt100/ }\nend\n\ndescribe file('/usr/bin/rpi-serial-console') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/base/users_spec.rb",
    "content": "describe user('root') do\n  it { should exist }\n  it { should have_home_directory '/root' }\n  it { should have_login_shell '/bin/bash' }\nend\n\ndescribe group('docker') do\n  it { should exist }\nend\n\ndescribe user('pirate') do\n  it { should exist }\n  it { should have_home_directory '/home/pirate' }\n  it { should have_login_shell '/bin/bash' }\n  it { should belong_to_group 'docker' }\n  it { should belong_to_group 'video' }\nend\n\ndescribe file('/etc/sudoers') do\n  it { should be_file }\n  it { should be_mode 440 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/etc/sudoers.d') do\n  it { should be_directory }\n  it { should be_mode 750 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/root/.bashrc') do\n  it { should be_file }\n  it { should be_mode 644 }\n  it { should be_owned_by 'root' }\nend\ndescribe file('/root/.bash_prompt') do\n  it { should be_file }\n  it { should be_mode 644 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/home/pirate/.bashrc') do\n  it { should be_file }\n  it { should be_mode 644 }\n  it { should be_owned_by 'pirate' }\nend\ndescribe file('/home/pirate/.bash_prompt') do\n  it { should be_file }\n  it { should be_mode 644 }\n  it { should be_owned_by 'pirate' }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/cloud-init_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe package('cloud-init') do\n  it { should be_installed }\nend\n\ndescribe file('/boot/user-data') do\n  it { should be_file }\n  its(:content) { should match /hostname: / }\nend\n\ndescribe file('/boot/meta-data') do\n  it { should be_file }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/cmdline_kernel_spec.rb",
    "content": "describe file('/boot/cmdline.txt') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\n  its(:content) { should match /dwc_otg.lpm_enable=0/ }\n  its(:content) { should match /console=tty1/ }\n  its(:content) { should match /root=\\/dev\\/mmcblk0p2/ }\n  its(:content) { should match /rootfstype=ext4/ }\n  its(:content) { should match /cgroup_enable=cpuset/ }\n  its(:content) { should match /cgroup_enable=memory/ }\n  its(:content) { should match /swapaccount=1/ }\n  its(:content) { should match /elevator=deadline/ }\n  its(:content) { should match /fsck.repair=yes/ }\n  its(:content) { should match /rootwait/ }\n  its(:content) { should match /console=ttyAMA0,115200/ }\n  its(:content) { should match /net.ifnames=0/ }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/cmdline_serial_spec.rb",
    "content": "describe file('/boot/cmdline.txt') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\n  its(:content) { should match /console=tty1/ }\n  its(:content) { should match /console=ttyAMA0,115200/ }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/config_txt_spec.rb",
    "content": "describe file('/boot/config.txt') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\n  its(:content) { should match /^enable_uart=1/ }\n  its(:content) { should match /^hdmi_force_hotplug=1/ }\n  its(:content) { should match /^start_x=0/ }\n  its(:content) { should match /^gpu_mem=16/ }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/docker-compose_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe file('/usr/local/bin/docker-compose') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe command('docker-compose --version') do\n  its(:stdout) { should match /1.23.1/m }\n  its(:exit_status) { should eq 0 }\nend\n\ndescribe file('/etc/bash_completion.d/docker-compose') do\n  it { should be_file }\n  it { should be_mode 644 }\n  it { should be_owned_by 'root' }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/docker-machine_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe file('/usr/local/bin/docker-machine') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe command('docker-machine --version') do\n  its(:stdout) { should match /0.16.1/m }\n  its(:exit_status) { should eq 0 }\nend\n\ndescribe file('/etc/bash_completion.d/docker-machine') do\n  it { should be_file }\n  it { should be_mode 644 }\n  it { should be_owned_by 'root' }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/docker_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe package('docker-ce') do\n  it { should be_installed }\nend\n\ndescribe command('dpkg -l docker-ce') do\n  its(:stdout) { should match /ii  docker-ce/ }\n  its(:stdout) { should match /5:18.09.7~3-0~debian/ }\n  its(:stdout) { should match /arm64/ }\n  its(:exit_status) { should eq 0 }\nend\n\ndescribe command('dpkg -l docker-ce-cli') do\n  its(:stdout) { should match /ii  docker-ce-cli/ }\n  its(:stdout) { should match /5:18.09.7~3-0~debian/ }\n  its(:stdout) { should match /arm64/ }\n  its(:exit_status) { should eq 0 }\nend\n\ndescribe command('dpkg -l containerd.io') do\n  its(:stdout) { should match /ii  containerd.io/ }\n  its(:stdout) { should match /1.2.6-3/ }\n  its(:stdout) { should match /arm64/ }\n  its(:exit_status) { should eq 0 }\nend\n\ndescribe file('/usr/bin/docker') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/usr/bin/docker-init') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/usr/bin/docker-proxy') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/usr/bin/dockerd') do\n  it { should be_file }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/usr/bin/dockerd-ce') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/usr/bin/containerd') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/usr/bin/containerd-shim') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/lib/systemd/system/docker.socket') do\n  it { should be_file }\n  it { should be_mode 644 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/var/run/docker.sock') do\n  it { should be_socket }\n  it { should be_mode 660 }\n  it { should be_owned_by 'root' }\n  it { should be_grouped_into 'docker' }\nend\n\ndescribe file('/etc/default/docker') do\n  it { should be_file }\n  it { should be_mode 644 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/var/lib/docker') do\n  it { should be_directory }\n  it { should be_mode 711 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/var/lib/docker/overlay2') do\n  it { should be_directory }\n  it { should be_mode 700 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe command('docker -v') do\n  its(:stdout) { should match /Docker version 18.09.7, build/ }\n  its(:exit_status) { should eq 0 }\nend\n\ndescribe command('docker info') do\n  its(:stdout) { should match /Storage Driver: overlay2/ }\n  its(:exit_status) { should eq 0 }\nend\n\ndescribe interface('lo') do\n  it { should exist }\nend\n\ndescribe interface('docker0') do\n  it { should exist }\nend\n\ndescribe service('docker') do\n  it { should be_enabled }\n  it { should be_running }\nend\n\ndescribe command('grep docker /var/log/syslog') do\n  its(:stdout) { should match /Daemon has completed initialization/ }\n  its(:exit_status) { should eq 0 }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/filesystems_spec.rb",
    "content": "Specinfra::Runner.run_command('modprobe btrfs')\ndescribe kernel_module('btrfs') do\n  it { should be_loaded }\nend\n\nSpecinfra::Runner.run_command('modprobe overlay')\ndescribe kernel_module('overlay') do\n  it { should be_loaded }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/hypriot-list_spec.rb",
    "content": "require 'spec_helper'\n\n# describe file('/etc/apt/sources.list.d/hypriot.list') do\n#   it { should be_file }\n#   it { should be_mode 644 }\n#   it { should be_owned_by 'root' }\n#   it { should contain 'deb https://packagecloud.io/Hypriot/Schatzkiste/debian/ jessie main' }\n# end\n\ndescribe package('apt-transport-https') do\n  it { should be_installed }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/kernel_config_spec.rb",
    "content": "Specinfra::Runner.run_command('modprobe configs')\n\ndescribe command('zcat /proc/config.gz') do\n  its(:stdout) { should match /CONFIG_KPROBES=y/ }\n  #its(:stdout) { should match /CONFIG_UPROBES=y/ }\n  its(:stdout) { should match /CONFIG_HAVE_KPROBES=y/ }\n  its(:stdout) { should match /CONFIG_EVENT_TRACING=y/ }\n  #its(:stdout) { should match /CONFIG_KPROBE_EVENT=y/ }\n  #its(:stdout) { should match /CONFIG_UPROBE_EVENT=y/ }\n  #its(:stdout) { should match /CONFIG_PROBE_EVENTS=y/ }\n  its(:stdout) { should match /CONFIG_FTRACE=y/ }\n  #its(:stdout) { should match /CONFIG_FTRACE_SYSCALLS=y/ }\n  its(:stdout) { should match /CONFIG_DYNAMIC_FTRACE=y/ }\n  its(:stdout) { should match /CONFIG_HAVE_DYNAMIC_FTRACE=y/ }\n  #its(:stdout) { should match /CONFIG_BCM2708_VCHIQ=y/ }\n  its(:stdout) { should match /CONFIG_HW_RANDOM_BCM2835=y/ }\n  # Docker specific kernel settings (see https://github.com/docker/docker/blob/master/contrib/check-config.sh)\n  ## Generally Necessary:\n  its(:stdout) { should match /CONFIG_NAMESPACES=y/ }\n  its(:stdout) { should match /CONFIG_NET_NS=y/ }\n  its(:stdout) { should match /CONFIG_PID_NS=y/ }\n  its(:stdout) { should match /CONFIG_IPC_NS=y/ }\n  its(:stdout) { should match /CONFIG_UTS_NS=y/ }\n  #its(:stdout) { should match /CONFIG_DEVPTS_MULTIPLE_INSTANCES=y/ }\n  its(:stdout) { should match /CONFIG_CGROUPS=y/ }\n  its(:stdout) { should match /CONFIG_CGROUP_CPUACCT=y/ }\n  its(:stdout) { should match /CONFIG_CGROUP_DEVICE=y/ }\n  its(:stdout) { should match /CONFIG_CGROUP_FREEZER=y/ }\n  its(:stdout) { should match /CONFIG_CGROUP_SCHED=y/ }\n  its(:stdout) { should match /CONFIG_CPUSETS=y/ }\n  its(:stdout) { should match /CONFIG_MEMCG=y/ }\n  its(:stdout) { should match /CONFIG_KEYS=y/ }\n  its(:stdout) { should match /CONFIG_VETH=m/ }\n  its(:stdout) { should match /CONFIG_BRIDGE=m/ }\n  its(:stdout) { should match /CONFIG_BRIDGE_NETFILTER=m/ }\n  its(:stdout) { should match /CONFIG_NF_NAT_IPV4=m/ }\n  its(:stdout) { should match /CONFIG_IP_NF_FILTER=m/ }\n  its(:stdout) { should match /CONFIG_IP_NF_TARGET_MASQUERADE=m/ }\n  its(:stdout) { should match /CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m/ }\n  its(:stdout) { should match /CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m/ }\n  its(:stdout) { should match /CONFIG_NF_NAT=m/ }\n  its(:stdout) { should match /CONFIG_NF_NAT_NEEDED=y/ }\n  its(:stdout) { should match /CONFIG_POSIX_MQUEUE=y/ }\n  ## Optional Features:\n  its(:stdout) { should match /CONFIG_USER_NS=y/ }\n  its(:stdout) { should match /CONFIG_SECCOMP=y/ }\n  its(:stdout) { should match /CONFIG_CGROUP_PIDS=y/ }\n  its(:stdout) { should match /CONFIG_MEMCG_SWAP=y/ }\n  its(:stdout) { should match /CONFIG_MEMCG_SWAP_ENABLED=y/ }\n  #its(:stdout) { should match /CONFIG_MEMCG_KMEM=y/ }\n  its(:stdout) { should match /CONFIG_BLK_CGROUP=y/ }\n  its(:stdout) { should match /CONFIG_BLK_DEV_THROTTLING=y/ }\n  its(:stdout) { should match /CONFIG_IOSCHED_CFQ=y/ }\n  its(:stdout) { should match /CONFIG_CFQ_GROUP_IOSCHED=y/ }\n  its(:stdout) { should match /CONFIG_CGROUP_PERF=y/ }\n  #its(:stdout) { should match /CONFIG_CGROUP_HUGETLB=y/ }\n  its(:stdout) { should match /CONFIG_NET_CLS_CGROUP=m/ }\n  its(:stdout) { should match /CONFIG_CGROUP_NET_PRIO=y/ }\n  its(:stdout) { should match /CONFIG_CFS_BANDWIDTH=y/ }\n  its(:stdout) { should match /CONFIG_FAIR_GROUP_SCHED=y/ }\n  its(:stdout) { should match /CONFIG_RT_GROUP_SCHED=y/ }\n  its(:stdout) { should match /CONFIG_IP_VS=m/ }\n  #its(:stdout) { should match /CONFIG_EXT3_FS=y/ }\n  #its(:stdout) { should match /CONFIG_EXT3_FS_XATTR=y/ }\n  #its(:stdout) { should match /CONFIG_EXT3_FS_POSIX_ACL=y/ }\n  #its(:stdout) { should match /CONFIG_EXT3_FS_SECURITY=y/ }\n  its(:stdout) { should match /CONFIG_EXT4_FS=y/ }\n  its(:stdout) { should match /CONFIG_EXT4_FS_POSIX_ACL=y/ }\n  its(:stdout) { should match /CONFIG_EXT4_FS_SECURITY=y/ }\n  ## Network Drivers:\n  its(:stdout) { should match /CONFIG_VXLAN=m/ }\n  its(:stdout) { should match /CONFIG_XFRM_ALGO=y/ }\n  its(:stdout) { should match /CONFIG_XFRM_USER=y/ }\n  its(:stdout) { should match /CONFIG_IPVLAN=m/ }\n  its(:stdout) { should match /CONFIG_MACVLAN=m/ }\n  its(:stdout) { should match /CONFIG_DUMMY=m/ }\n  ## Storage Drivers:\n  #its(:stdout) { should match /CONFIG_AUFS_FS=m/ }\n  its(:stdout) { should match /CONFIG_BTRFS_FS=m/ }\n  its(:stdout) { should match /CONFIG_BLK_DEV_DM=m/ }\n  its(:stdout) { should match /CONFIG_DM_THIN_PROVISIONING=m/ }\n  its(:stdout) { should match /CONFIG_OVERLAY_FS=m/ }\n  its(:exit_status) { should eq 0 }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/kernel_modules_spec.rb",
    "content": "Specinfra::Runner.run_command('modprobe snd_bcm2835')\n\n# describe kernel_module('snd_bcm2835') do\n#   it { should be_loaded }\n# end\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/openvswitch_spec.rb",
    "content": "Specinfra::Runner.run_command('modprobe openvswitch')\nSpecinfra::Runner.run_command('modprobe vxlan')\nSpecinfra::Runner.run_command('modprobe gre')\n\ndescribe kernel_module('openvswitch') do\n  it { should be_loaded }\nend\n\ndescribe kernel_module('vxlan') do\n  it { should be_loaded }\nend\n\ndescribe kernel_module('gre') do\n  it { should be_loaded }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/raspberrypi-list_spec.rb",
    "content": "require 'spec_helper'\n\n# describe file('/etc/apt/sources.list.d/raspberrypi.list') do\n#   it { should be_file }\n#   it { should be_mode 644 }\n#   it { should be_owned_by 'root' }\n#   it { should contain 'deb http://archive.raspberrypi.org/debian/ jessie main' }\n# end\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/serial_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe file('/usr/local/bin/rpi-serial-console') do\n  it { should be_file }\n  it { should be_mode 755 }\n  it { should be_owned_by 'root' }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/hypriotos-image/udev_spec.rb",
    "content": "require 'spec_helper'\n\ndescribe file('/etc/udev/rules.d/99-com.rules') do\n  it { should be_file }\n  it { should be_mode 644 }\n  it { should be_owned_by 'root' }\nend\n\ndescribe file('/etc/udev/rules.d/75-persistent-net-generator.rules') do\n  it { should be_file }\n  it { should be_mode 644 }\n  it { should be_owned_by 'root' }\nend\n"
  },
  {
    "path": "builder/test-integration/spec/spec_helper.rb",
    "content": "require 'serverspec'\nrequire 'net/ssh'\n\nset :backend, :ssh\n\nhost = ENV['BOARD']\nunless host\n  fail \"No BOARD env with the target address given!\"\nend\nport = ENV['PORT']\n\noptions = Net::SSH::Config.for(host)\n\noptions[:user] ||= 'pirate'\noptions[:password] ||= 'hypriot'\nif port\n  options[:port] = port\nend\n\nset :host,        options[:host_name] || host\nset :ssh_options, options\n"
  }
]