Adds Bazel Rules for building/pushing docker images

Change-Id: If08c1cff4b1bc01a8fcf297c14e4d1c20cdbe263
Google-Bug-Id: 119838739
Signed-Off-By: Avi Kondareddy <avikr@google.com>
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d3b4b44
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+# ignore bazel generated files
+bazel-*
diff --git a/BUILD.bazel b/BUILD.bazel
new file mode 100644
index 0000000..f2937c1
--- /dev/null
+++ b/BUILD.bazel
@@ -0,0 +1,42 @@
+load(
+    "@io_bazel_rules_docker//container:container.bzl",
+    "container_image",
+    "container_push",
+)
+load("@debs//file:packages.bzl", "packages")
+load("//:debs.bzl", "get_dep_list")
+
+# build container using kunit.sh and latest kunitconfig from gerrit
+container_image(
+    name = "kunit",
+    base = "@debian_base//image",
+    debs = [packages[x] for x in get_dep_list()],
+    directory = "/",
+    entrypoint = "/kunit.sh",
+    files = [
+        "kunit.sh",
+        "@kunitconfig_repo//:kunitconfig",
+    ],
+    mode = "777",
+    repository = "kunit-presubmit/kunit",
+)
+
+container_push(
+    name = "push_kunit",
+    format = "Docker",
+    image = ":kunit",
+    registry = "gcr.io",
+    repository = "kunit-presubmit/kunit",
+    tag = "latest",
+)
+
+# build test container using latest kunit source
+container_image(
+    name = "kunit_test",
+    base = ":kunit",
+    directory = "/kunit/linux",
+    env = {"ARTIFACTS": "kunit/artifacts"},
+    repository = "kunit-presubmit/test",
+    tars = ["@kunit_repo//:files"],
+    workdir = "/kunit/linux",
+)
diff --git a/README.md b/README.md
index 3c1af5c..063ef63 100644
--- a/README.md
+++ b/README.md
@@ -31,17 +31,70 @@
 container are solved in the deployment configuration discussed below under "Prow
 Job Specification".
 
-TODO(avikr@google.com): generalize for users using docker registry
+To build and push, you can either use Bazel or Docker:
 
-To build and push, you must have [Docker](
-https://docs.docker.com/install/linux/docker-ce/debian/) and [Google Cloud SDK](
-https://cloud.google.com/sdk/install) installed locally. Make sure to enable
+### Bazel
+
+Bazel allows building/pushing without dependence on docker and automates
+using latest kunitconfig in build. As Bazel enforces deterministic
+builds, all debian packages depended on are listed in [debs.bzl](debs.bzl), and
+based off the snapshot specified in the *dpkg_src* rule in
+[WORKSPACE](WORKSPACE).
+
+#### Update
+
+The direct dependencies needed are:
+* build-essential
+* bc
+* m4
+* flex
+* bison
+* python3
+
+If recursive dependancies change in future snapshots, [debs.bzl](debs.bzl) must
+be manually updated with a list of all dependancies.
+A simple solution:
+
+```shell
+# run interactive shell in latest debian image
+docker run -it --rm debian
+
+# install direct dependancies
+apt install build-essential bc m4 flex bison python3
+
+# generate list of all required dependancies recursively
+apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts \
+--no-breaks --no-replaces --no-enhances --no-pre-depends \
+build-essential bc m4 flex bison python3 | grep "^\w" | sort -u
+```
+
+The snapshot used can be updated as specified in the
+[distroless package manager bazel rules](
+https://github.com/GoogleContainerTools/distroless/tree/master/package_manager).
+
+#### Use
+
+```shell
+# build prowjob image
+bazel build :kunit
+
+# push to configured repo
+bazel run :push_kunit
+
+# build test image with kunit source and add to local docker
+bazel run :kunit_test
+
+# need docker to run, results to stdout
+docker run --privileged --tmpfs /dev/shm:exec kunit-presubmit/test:kunit_test
+```
+
+### Docker
+
+You must have [Docker](https://docs.docker.com/install/linux/docker-ce/debian/)
+Make sure to enable
 [sudoless docker](https://docs.docker.com/install/linux/linux-postinstall/)
 (fixes gcr push
-authentication problems). You will need to enable gcloud authentication first to
-push with `gcloud auth configure-docker`.
-
-TODO(avikr@google.com): replace with bazel build
+authentication problems).
 
 Now to build and push image :
 
@@ -82,6 +135,14 @@
 the UML Kernel in an entrypoint script works as intended but fails in an
 interactive shell.
 
+### Registry
+
+By default, we have configured our install to use Google Container Registry.
+This requires installing [Google Cloud SDK](
+https://cloud.google.com/sdk/install) and configuring with project to push to.
+If using docker to push, you will need to enable gcloud authentication first to
+push with `gcloud auth configure-docker`.
+
 ## Prow Job Specification
 
 Prow Jobs are detailed at
diff --git a/WORKSPACE b/WORKSPACE
new file mode 100644
index 0000000..9c92879
--- /dev/null
+++ b/WORKSPACE
@@ -0,0 +1,93 @@
+workspace(name = "prow_presubmit")
+
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load(
+    "@bazel_tools//tools/build_defs/repo:git.bzl",
+    "git_repository",
+    "new_git_repository",
+)
+
+# import container build/push rules
+http_archive(
+    name = "io_bazel_rules_docker",
+    sha256 = "29d109605e0d6f9c892584f07275b8c9260803bf0c6fcb7de2623b2bedc910bd",
+    strip_prefix = "rules_docker-0.5.1",
+    urls = ["https://github.com/bazelbuild/rules_docker/archive/v0.5.1.tar.gz"],
+)
+
+# pull latest kunitconfig
+new_git_repository(
+    name = "kunitconfig_repo",
+    branch = "kunit/alpha/master",
+    build_file_content = """
+exports_files(["kunitconfig"])
+    """,
+    remote = "https://kunit.googlesource.com/kunitconfig",
+)
+
+# pull latest kunit source for testing
+new_git_repository(
+    name = "kunit_repo",
+    branch = "kunit/alpha/master",
+    build_file_content = """
+load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar")
+
+pkg_tar(
+    name = "files",
+    srcs = glob(["**"]),
+    strip_prefix = ".",
+    visibility = ["//visibility:public"],
+)
+    """,
+    remote = "https://kunit.googlesource.com/linux",
+)
+
+# setting container rules / base images needed
+load(
+    "@io_bazel_rules_docker//container:container.bzl",
+    "container_pull",
+    container_repositories = "repositories",
+)
+
+container_repositories()
+
+container_pull(
+    name = "debian_base",
+    registry = "index.docker.io",
+    repository = "library/debian",
+)
+
+# rules for installing packages from debian snapshot
+git_repository(
+    name = "distroless",
+    branch = "master",
+    remote = "https://github.com/GoogleContainerTools/distroless",
+)
+
+load(
+    "@distroless//package_manager:package_manager.bzl",
+    "package_manager_repositories",
+    "dpkg_src",
+    "dpkg_list",
+)
+
+package_manager_repositories()
+
+load("//:debs.bzl", "get_dep_list")
+
+dpkg_src(
+    name = "uml",
+    arch = "amd64",
+    distro = "stretch",
+    sha256 = "a0c5a8906ac6ad010535cca152df43411d0e5db1790f6d0e4106bbdf96f3ef0f",
+    snapshot = "20181121T102052Z",
+    url = "http://snapshot.debian.org/archive",
+)
+
+dpkg_list(
+    name = "debs",
+    packages = get_dep_list(),
+    sources = [
+        "@uml//file:Packages.json",
+    ],
+)
diff --git a/debs.bzl b/debs.bzl
new file mode 100644
index 0000000..aec39ca
--- /dev/null
+++ b/debs.bzl
@@ -0,0 +1,101 @@
+# recursive deps for
+#   - build-essential
+#   - bc
+#   - m4
+#   - flex
+#   - bison
+#   - python3
+# calculated using apt-cache depends in a base debian-stretch container
+# see README.md under Bazel - Update for details on how to update
+
+def get_dep_list():
+    return [
+        "bc",
+        "binutils",
+        "bison",
+        "build-essential",
+        "bzip2",
+        "cdebconf",
+        "cpp",
+        "cpp-6",
+        "debconf",
+        "dh-python",
+        "dpkg",
+        "dpkg-dev",
+        "flex",
+        "g++",
+        "g++-6",
+        "gcc",
+        "gcc-6",
+        "gcc-6-base",
+        "guile-2.0-libs",
+        "install-info",
+        "libasan3",
+        "libatomic1",
+        "libbison-dev",
+        "libbz2-1.0",
+        "libc-dev-bin",
+        "libc6",
+        "libc6-dev",
+        "libcc1-0",
+        "libcilkrts5",
+        "libdb5.3",
+        "libdebian-installer4",
+        "libdpkg-perl",
+        "libexpat1",
+        "libffi6",
+        "libgc1c2",
+        "libgcc-6-dev",
+        "libgcc1",
+        "libgdbm3",
+        "libgmp10",
+        "libgomp1",
+        "libisl15",
+        "libitm1",
+        "liblsan0",
+        "libltdl7",
+        "liblzma5",
+        "libmpc3",
+        "libmpdec2",
+        "libmpfr4",
+        "libmpx2",
+        "libncurses5",
+        "libncursesw5",
+        "libnewt0.52",
+        "libpcre3",
+        "libperl5.24",
+        "libpython3-stdlib",
+        "libpython3.5-minimal",
+        "libpython3.5-stdlib",
+        "libquadmath0",
+        "libreadline7",
+        "libselinux1",
+        "libsigsegv2",
+        "libslang2",
+        "libsqlite3-0",
+        "libssl1.1",
+        "libstdc++-6-dev",
+        "libstdc++6",
+        "libtextwrap1",
+        "libtinfo5",
+        "libtsan0",
+        "libubsan0",
+        "libunistring0",
+        "linux-libc-dev",
+        "m4",
+        "make",
+        "make-guile",
+        "mime-support",
+        "patch",
+        "perl",
+        "perl-base",
+        "perl-modules-5.24",
+        "python3",
+        "python3-minimal",
+        "python3.5",
+        "python3.5-minimal",
+        "readline-common",
+        "tar",
+        "xz-utils",
+        "zlib1g",
+    ]