Giter VIP home page Giter VIP logo

image-builder's Introduction

image-builder

Quality Gate Status

Image builder contains components needed to build images within the SODALITE platform. It encapsulates

How to use image-builder

Examples

Every example is in two forms: json (for REST API) and yaml (for image-builder TOSCA template).

GIT

The simplest option for building docker images is to provide git repository with app code and dockerfile.

{
  "source": {
    "git_repo": {
      "url": "https://github.com/mihaTrajbaric/generic_repo.git"
    }
  },
  "target": {
    "images": [
      {
        "image": "repository/git",
        "tag": "latest"
      }
    ],
    "registry": {
      "url": "docker.io",
      "username": "user",
      "password": "password"
    }
  }
}

Image builder will assume repository contains Dockerfile in repo's root dir of default branch and will use it for workdir during building process. It will build image with tag test_image:latest, which will be pushed to arbitrary OCI image registry.

Additional options

Additional options for git mode include:

  • git authentication
  • version (branch name, tag name, HEAD)
  • Name or relative path of dockerfile (default: Dockerfile)
  • workdir (default: . )
{
  "source": {
    "git_repo": {
      "url": "https://github.com/mihaTrajbaric/generic-repo-2",
      "version": "HEAD",
      "username": "git_username",
      "password": "git_password_or_token",
      "dockerfile": "docker_dir/Dockerfile",
      "workdir": "code_dir"
    }
  },
  "target": {
    "images": [
      {
        "image": "repository/git",
        "tag": "additional_options"
      }
    ],
    "registry": {
      "url": "docker.io",
      "username": "user",
      "password": "password"
    }
  }
}

Dockerfile

No build context

Image builder can build image from standalone dockerfile without any build context.

{
  "source": {
    "dockerfile": {
      "url": "https://raw.githubusercontent.com/mihaTrajbaric/image-builder-test-files/master/no_context/Dockerfile"
    }
  },
  "target": {
    "images": [
      {
        "image": "repository/no_context",
        "tag": "latest"
      }
    ],
    "registry": {
      "url": "docker.io",
      "username": "user",
      "password": "password"
    }
  }
}

Build context

Image builder can add arbitrary git repository for build context. It will insert dockerfile into root dir of repository.

{
  "source": {
    "dockerfile": {
      "url": "https://raw.githubusercontent.com/mihaTrajbaric/image-builder-test-files/master/python_build_context/Dockerfile"
    },
    "build_context": {
      "url": "https://github.com/mihaTrajbaric/generic_docker_build_context.git"
    }
  },
  "target": {
    "images": [
      {
        "image": "repository/build-context",
        "tag": "latest"
      }
    ],
    "registry": {
      "url": "docker.io",
      "username": "user",
      "password": "password"
    }
  }
}

Additional options

Additional options for dockerfile mode:

  • url authentication
  • build_context options
    • git authentication
    • subdir (relative path inside repo where build must be run)
{
  "source": {
    "dockerfile": {
      "url": "https://raw.githubusercontent.com/mihaTrajbaric/image-builder-test-files/master/no_context/Dockerfile"
      "username": "username",
      "password": "password_or_token"
    },
    "build_context": {
      "subdir": "no_context",
      "url": "https://github.com/mihaTrajbaric/image-builder-test-files",
      "username": "git_username",
      "password": "git_password"
    }
  },
  "target": {
    "images": [
      {
        "image": "repository/subdir_context",
        "tag": "latest"
      }
    ],
    "registry": {
      "url": "docker.io",
      "username": "user",
      "password": "password"
    }
  }
}

Image variants

This mode enables image builder to build more variants of single docker image. Image variants are built by overloading the base container image, which is injected dynamically at build-time by the image builder, both for single and multi-stage builds. No modifications to the Dockerfile are required.

This mode works in combination with any of other modes (dockerfile, git, tar).

Following example will produce two images. image_variants:latest will be built with default base image (specified in Dockerfile), while image_variants:python-3.8 will be built on top of python:3.8-alpine.

{
  "source": {
    "git_repo": {
      "url": "https://github.com/mihaTrajbaric/generic_repo.git"
    }
  },
  "target": {
    "images": [
      {
        "image": "repository/image_variants",
        "tag": "latest"
      },
      {
        "image": "repository/image_variants",
        "tag": "python-3.8",
        "base": "python:3.8-alpine"
      }
    ],
    "registry": {
      "url": "docker.io",
      "username": "user",
      "password": "password"
    }
  }
}

Multi-arch build

Image builder is capable of building images for multiple architectures leveraging docker buildx.

Following example will produce multiple variants of single image.

{
  "source": {
    "git_repo": {
      "url": "https://github.com/mihaTrajbaric/generic_repo.git"
    }
  },
  "target": {
    "images": [
      {
        "image": "repository/platforms",
        "tag": "latest",
        "platforms": [
          "linux/amd64",
          "linux/386",
          "linux/arm64",
          "linux/ppc64le",
          "linux/s390x",
          "linux/arm/v7",
          "linux/arm/v6"
          ]
      }
    ],
    "registry": {
      "url": "docker.io",
      "username": "user",
      "password": "password"
    }
  }
}  

Platforms are defined on per-image basis, so every image variant can target different set of platforms:

{
  "source": {
    "git_repo": {
      "url": "https://github.com/mihaTrajbaric/generic_repo.git"
    }
  },
  "target": {
    "images": [
      {
        "image": "repository/image_variants_platforms",
        "tag": "latest",
        "platforms": [
          "linux/amd64",
          "linux/386",
          "linux/arm64",
          "linux/ppc64le",
          "linux/s390x",
          "linux/arm/v7",
          "linux/arm/v6"
        ]
      },
      {
        "image": "repository/image_variants_platforms",
        "tag": "python-3.8",
        "base": "python:3.8-alpine",
        "platforms": [
          "linux/amd64",
          "linux/arm64",
          "linux/arm/v7",
          "linux/arm/v6"
        ]
      }
    ],
    "registry": {
      "url": "docker.io",
      "username": "user",
      "password": "password"
    }
  }
}

Converting json to yaml

Image builder can run as REST API with JSON build params or as TOSCA template with YAML build_params. Conversion can be done with json_to_yaml.py. Examples are in both formats.

REST API

Openapi spec

Image Builder REST API is build using Openapi specification.

Prerequisites

- Ubuntu 20.04
- python 3.8 or newer

Config

PostgreSQL connection

Rest API is using PostgreSQL database. It is deployed with REST API as part of docker-compose template and TOSCA template. REST API can be configured to connect to any PostgreSQL instance by following environmental variables:

  • IMAGEBUILDER_DATABASE_IP=[database_ip]
  • IMAGEBUILDER_DATABASE_PORT=[database_port]
  • IMAGEBUILDER_DATABASE_NAME=[database_name]
  • IMAGEBUILDER_DATABASE_USER=[database_username]
  • IMAGEBUILDER_DATABASE_PASSWORD=[database_password]
  • IMAGEBUILDER_DATABASE_TIMEOUT=[database_timeout], optional

PostgreSQL can be run as docker container.

OAuth

Image Builder REST API uses OAuth 2.0 for authentication.

It can be overridden by setting AUTH_API_KEY env var in image-builder-api container to key_name of choice. This key must be added to request as -H "X-API-Key: [key_name]"

Local run

To run locally, use docker compose or local TOSCA template with compliant orchestrator. It was tested with opera==0.6.6. Note that if you deploy image-builder with docker-compose, multi-arch prerequisites need to be installed and configured.

Script installation

In order to proceed with local docker installation use deploy_local.sh script (for Ubuntu Linux distribution) that checks and installs all components required for deployment (pip, xOpera, Ansible Roles, etc), provides means for setting up input variables necessary for deployment and starts the deployment itself.

Remote deploy

REST API can be deployed remotely using TOSCA template with compliant orchestrator, for instance xOpera.

Steps before deploy

  1. Install pip packages:

    python3 -m pip install opera[openstack]==0.6.6 docker

  2. Install ansible-playbooks:

    ansible-galaxy install -r image-builder-rest-blueprint/requirements.yml --force

  3. Clone SODALITE iac-modules (Release 3.4.1):

    git clone -b 3.5.0 https://github.com/SODALITE-EU/iac-modules.git image-builder-rest-blueprint/openstack/modules

  4. Copy image-builder TOSCA library

    cp -r image-builder-rest-blueprint/library/ image-builder-rest-blueprint/openstack/library/

  5. Generate TLS certificate and key files

    openssl genrsa -out image-builder-rest-blueprint/openstack/modules/docker/artifacts/ca.key 4096
    openssl req -new -x509 -key image-builder-rest-blueprint/openstack/modules/docker/artifacts/ca.key -out image-builder-rest-blueprint/openstack/modules/docker/artifacts/ca.crt
    cp image-builder-rest-blueprint/openstack/modules/docker/artifacts/ca.key image-builder-rest-blueprint/openstack/modules/misc/tls/artifacts/ca.key
    cp image-builder-rest-blueprint/openstack/modules/docker/artifacts/ca.crt image-builder-rest-blueprint/openstack/modules/misc/tls/artifacts/ca.crt

Sample JSON payloads

Sample JSON payloads to be used with /build/ endpoint can be found in build-params/JSON_(API).

Python client

Convenient Python client (Python 3.8) can send json payload and waits for the response (see client.py).

docker-image-definition

docker-image-definition is a TOSCA blueprint, based on tosca_simple_yaml_1_3.

Running using xOpera

Within SODALITE platform, it is executed with xOpera orchestrator. If using xOpera 0.6.6 via CLI:

opera deploy -i inputs.yaml docker_image_definition.yaml

Running using the image builder CLI

It is also possible to run the image builder in a self-contained container using a CLI convenience wrapper:

$ image-builder-cli.sh <input.yaml>

Building the image builder CLI

By default, the included image-builder-cli.sh script will use the sodaliteh2020/image-builder-cli image. If developing the image builder locally, local versions of the CLI container can be built with the supplied Dockerfile:

$ cd REST_API && docker build -t <your tag> -f Dockerfile-cli .

you will then need to fix up the image name in the image-builder-cli.sh script to use your local image.

build_params for docker-image-definition

docker-image-definition needs build_params in YAML format, which can be converted from json.

image-builder's People

Contributors

alexmaslenn avatar dradx avatar mihatrajbaric avatar pmundt avatar snyk-bot avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

pmundt

image-builder's Issues

Support for Singularity image building

Similarly to Docker images building, we should provide a means for building Singularity images with ability to push the images either into public Singularity Hub or private Singularity registry that would be deployed in the testbed. This is needed for other SODALITE services, such as MODAK, and HPC use cases. An example of a Singularity definition file can be found here.

Multi-arch image support

Since the beginning, we have required multi-arch containers from the image builder. At present, it is limited to the host architecture of wherever the ansible docker plugin is invoked, which we have been using as a workaround for building arm64 images in our Edge testbed. An additional consideration is the creation of the image manifest which is able to provide resolutions to different architecture image variants in the container registry.

As we are now aiming to have increased integration in Y3, it's no longer possible to work around this limitation, and it will need to be addressed directly in the image builder.

Both of these issues are addressable through the use of docker buildx, however, the last time we looked at this there was no direct support in the Ansible docker plugin, and so it was decided to temporarily shelve this discussion and revisit later in the project. The upstream community has, unfortunately, not already taken care of this for us in the meantime. Presumably, the easiest solution would now be to extend the existing Docker Ansible plugin to support the buildx extensions directly.

I am happy to support this work, but do not presently have the spare cycles to implement this myself.

Poor test coverage

At the moment, tests cover just basic API functionality (endpoints user and auth) and fail to test core image-builder engine.

Dockerfile not built relative to git tree path

In trying to build a simple image with the image builder, there seems to be a problem with the working directory of the builder not being pivoted to the cloned git tree. This generates a build failure when we need to COPY files relative to the cloned tree:

                {
                    "hosts": {
                        "opera": {
                            "_ansible_no_log": false,
                            "action": "docker_image",
                            "changed": false,
                            "failed": true,
                            "invocation": {
                                "module_args": {
                                    "api_version": "auto",
                                    "archive_path": null,
                                    "build": {
                                        "args": null,
                                        "cache_from": null,
                                        "container_limits": null,
                                        "dockerfile": null,
                                        "etc_hosts": null,
                                        "http_timeout": null,
                                        "network": null,
                                        "nocache": false,
                                        "path": "/home/image_builder/5959f0d2-fcaa-59ab-aeae-e2e16d45179c",
                                        "pull": true,
                                        "rm": true,
                                        "target": null,
                                        "use_config_proxy": null
                                    },
                                    "buildargs": null,
                                    "ca_cert": null,
                                    "client_cert": null,
                                    "client_key": null,
                                    "container_limits": null,
                                    "debug": false,
                                    "docker_host": "unix://var/run/docker.sock",
                                    "dockerfile": null,
                                    "force": null,
                                    "force_absent": false,
                                    "force_source": true,
                                    "force_tag": false,
                                    "http_timeout": null,
                                    "load_path": null,
                                    "name": "adaptant/edgetpu-exporter",
                                    "nocache": false,
                                    "path": null,
                                    "pull": null,
                                    "push": true,
                                    "repository": "docker.io/adaptant/edgetpu-exporter:latest",
                                    "rm": true,
                                    "source": "build",
                                    "ssl_version": null,
                                    "state": "present",
                                    "tag": "latest",
                                    "timeout": 60,
                                    "tls": false,
                                    "tls_hostname": "localhost",
                                    "use_tls": null,
                                    "validate_certs": false
                                }
                            },
                            "msg": "Error building adaptant/edgetpu-exporter - code: None, message: COPY failed: stat /var/lib/docker/tmp/docker-builder229831268/go.mod: no such file or directory, logs: ['Step 1/11 : FROM golang as builder', '\\n', ' ---> 00d970a31ef2\\n', 'Step 2/11 : ENV GO111MODULE=on', '\\n', ' ---> Using cache\\n', ' ---> 05bf77a42124\\n', 'Step 3/11 : WORKDIR /app', '\\n', ' ---> Using cache\\n', ' ---> 419cfb13a115\\n', 'Step 4/11 : COPY go.mod .', '\\n']"
                        }
                    },
                    "task": {
                        "duration": {
                            "end": "2020-07-04T15:23:23.285719Z",
                            "start": "2020-07-04T15:23:20.348292Z"
                        },
                        "id": "834b0bfa-0d98-0ec5-0dee-000000000018",
                        "name": "Build image and push it"
                    }
                }

Poor documentation

Besides JSON payloads and sample TOSCA inputs, there is not any real documentation on image-builder usage, which can lead to confusion

Dockerfile inside build_context

Image builder dockerfile mode expects Dockerfile to be provided with source_url (or source.url in TOSCA) param, which can then be inserted into build context (arbitrary git repo). This 2-component approach was introduced to support snow-uc, with code in one repo and dockerfiles in another repo.

Since most projects have Dockerfile in its own git repository, image-builder could provide a simpler way, without specifying two separate URLs for dockerfile and build context/

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.