Add license analysis vagrantfile 69/116469/6
authorAlexander Mazuruk <a.mazuruk@samsung.com>
Thu, 17 Dec 2020 16:13:45 +0000 (17:13 +0100)
committerMorgan Richomme <morgan.richomme@orange.com>
Mon, 4 Jan 2021 07:29:18 +0000 (07:29 +0000)
Usage in README.rst

This Vagrantfile is intended for single image analysis.

Issue-ID: INT-1735

Signed-off-by: Alexander Mazuruk <a.mazuruk@samsung.com>
Change-Id: Ief45804d216a9a50777491c2cf7a8088133e5a3b

test/legal/docker_license_analysis/Dockerfile.sample [new file with mode: 0644]
test/legal/docker_license_analysis/README.rst [new file with mode: 0644]
test/legal/docker_license_analysis/Vagrantfile [new file with mode: 0644]
test/legal/docker_license_analysis/tools/analysis.sh [new file with mode: 0755]

diff --git a/test/legal/docker_license_analysis/Dockerfile.sample b/test/legal/docker_license_analysis/Dockerfile.sample
new file mode 100644 (file)
index 0000000..851f92d
--- /dev/null
@@ -0,0 +1,2 @@
+FROM scratch
+RUN echo "This is dummy image."
diff --git a/test/legal/docker_license_analysis/README.rst b/test/legal/docker_license_analysis/README.rst
new file mode 100644 (file)
index 0000000..71a4a33
--- /dev/null
@@ -0,0 +1,80 @@
+#####################################
+License Analysis of Docker Containers
+#####################################
+
+Vagrantfile that includes tern + scancode for performing dynamic license analysis
+of docker containers. It takes either a Dockerfile or image name to analyse.
+
+
+*********
+Reasoning
+*********
+
+While there are tools supporting ONAP development that perform license analysis
+and produce SBoM, they do it via static static analysis. When base image
+introduces licensing issue we will have no way to know from those tools.
+Additionally, the tools performing those static analysis require special access
+rights which only few people have. This Vagrant box is meant to be run as close
+to Docker build as possible to give feedback directly to developers.
+
+It has been placed in a VM due to following reasons:
+
+- reproducibility
+- tern requires:
+
+    * access to /dev/fuse
+    * access to docker.sock
+
+Due to the above requirements, running in Docker would require:
+
+  * running container in --privileged mode
+  * passing host's /dev/fuse to the container
+  * passing host's docker.sock to the container
+
+Running it in VM creates new instances of both which should alleviate security
+issues that could be present when running on host/docker
+
+
+***************
+Getting started
+***************
+
+Prerequisites
+=============
+
+`Vagrant <https://www.vagrantup.com/downloads>`_
+
+
+Running
+=======
+
+Dockerfile analysis
+-------------------
+
+Substitute the DOCKER_FILE_ANALYSE value with location of the Dockerfile
+you want to analyse::
+
+  DOCKER_FILE_ANALYSE="/path/to/Dockerfile" vagrant up
+
+Please mind that the Docker on the VM needs to be able to download the base
+image for analysis to take place.
+
+Docker image analysis
+---------------------
+
+
+Substitute the DOCKER_IMAGE_ANALYSE value with your image of choice::
+
+  DOCKER_IMAGE_ANALYSE="debian:buster" vagrant up
+
+Please mind that the Docker on the VM needs to be able to download the image
+for analysis to take place.
+
+Gathering results
+=================
+
+::
+
+  vagrant ssh-config > ssh-config
+  scp -F ssh-config default:~/ternvenv/report-scancode.json report-scancode.json
+
diff --git a/test/legal/docker_license_analysis/Vagrantfile b/test/legal/docker_license_analysis/Vagrantfile
new file mode 100644 (file)
index 0000000..f1123ff
--- /dev/null
@@ -0,0 +1,107 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+VM_MEMORY = 2 * 1024
+VM_CPUS = 2
+VM_DISK = 128
+VM_STORAGE_POOL = "default"
+VM_USER = "vagrant"
+
+# Dockerfile to analyse
+DOCKER_FILE = ENV["DOCKER_FILE_ANALYSE"] || "Dockerfile.sample"
+DOCKER_FILE_PATH = "/home/vagrant/ternvenv/Dockerfile"
+# Docker image to analyse (in form of "debian:latest").
+# Takes precedence over DOCKER_FILE
+DOCKER_IMAGE = ENV['DOCKER_IMAGE_ANALYSE']
+
+$install_docker= <<-SCRIPT
+  apt-get update
+  apt-get install --yes \
+    apt-transport-https \
+    ca-certificates \
+    curl \
+    gnupg-agent \
+    software-properties-common
+  curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
+  add-apt-repository \
+   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
+   $(lsb_release -cs) \
+   stable"
+  apt-get update
+  apt-get install --yes \
+    docker-ce docker-ce-cli containerd.io
+  groupadd -f docker
+  usermod -a -G docker $USER
+SCRIPT
+
+$install_python = <<-SCRIPT
+  # TODO: currently scancode locks us to python3.6, they are currently
+  # (10 Dec 2020) updating so check in a while
+  add-apt-repository ppa:deadsnakes/ppa
+  apt-get update
+  apt-get install --yes \
+    python3.6 libpython3.6-dev python3-pip python3.6-venv python3-setuptools\
+    python3-apt \
+    attr bzip2 xz-utils zlib1g libxml2-dev libxslt1-dev \
+    findutils git gnupg2 tar util-linux
+  update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 1
+  update-alternatives --set python3 /usr/bin/python3.6
+  pip3 install --upgrade pip
+SCRIPT
+
+$install_tern = <<-SCRIPT
+  cd /home/$USER
+  python3 -m venv ternvenv
+  cd ternvenv
+  source bin/activate
+  pip3 install --upgrade pip
+  pip3 install --no-cache-dir tern scancode-toolkit[full]
+SCRIPT
+
+Vagrant.configure("2") do |config|
+  config.vm.box = "generic/ubuntu2004"
+  config.vm.hostname = "vagrant"
+
+  config.vm.provider :virtualbox do |v|
+    v.name = config.vm.hostname
+    v.memory = VM_MEMORY
+    v.cpus = VM_CPUS
+  end
+
+  config.vm.provider :libvirt do |v|
+    v.memory = VM_MEMORY
+    v.cpus = VM_CPUS
+    v.machine_virtual_size = VM_DISK
+    v.storage_pool_name = VM_STORAGE_POOL
+  end
+
+  config.vm.synced_folder '.', '/vagrant', disabled: true
+
+  config.vm.provision "install_docker", type: "shell" do |s|
+    s.privileged = true
+    s.env = {"DEBIAN_FRONTEND" => "noninteractive", "USER":VM_USER}
+    s.inline = $install_docker
+    s.reset = true
+  end
+
+  config.vm.provision "install_python", type: "shell" do |s|
+    s.privileged = true
+    s.env = {"DEBIAN_FRONTEND" => "noninteractive"}
+    s.inline = $install_python
+  end
+
+  config.vm.provision "install_tern", type: "shell" do |s|
+    s.privileged = false
+    s.env = {"USER":VM_USER}
+    s.inline = $install_tern
+  end
+
+  # Add the Dockerfile for analysis to the Vagrant box
+  config.vm.provision "file", source: DOCKER_FILE, destination: DOCKER_FILE_PATH
+
+  config.vm.provision "license_analysis", type: "shell" do |s|
+    s.privileged = false
+    s.env = {"IMAGE":DOCKER_IMAGE, "FILE":DOCKER_FILE_PATH}
+    s.path = "tools/analysis.sh"
+  end
+end
diff --git a/test/legal/docker_license_analysis/tools/analysis.sh b/test/legal/docker_license_analysis/tools/analysis.sh
new file mode 100755 (executable)
index 0000000..a667ce6
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/env sh
+# Analysis is run twice to populate tern cache:
+# https://github.com/tern-tools/tern/issues/818
+
+TERNVENV="${TERNVENV:-$HOME/ternvenv}"
+
+if [ -d "$TERNVENV" ]; then
+  cd $TERNVENV
+  if [ -f bin/activate ]; then
+    . bin/activate
+  else
+    echo "Tern virtual environment is not initialized!" >&2;
+    exit 1
+  fi
+else
+  echo "Ternenv directory not found, if it is not in $HOME/ternvenv set the \$TERNVENV to your location." >&2;
+  exit 1
+fi
+
+if [ -n "$IMAGE" ]; then
+  echo 'Running Docker Image analysis'
+  tern report -f json -o /dev/null -i "$IMAGE"
+  tern report -f json -o report-scancode.json -x scancode -i "$IMAGE"
+elif [ -f "$FILE" ]; then
+  echo 'Running Dockerfile analysis'
+  tern report -f json -o /dev/null -d $FILE
+  tern report -f json -o report-scancode.json -x scancode -d $FILE
+else
+  echo "\$IMAGE is not set and \$FILE does not point to a file." >&2;
+fi
+