Running a local docker registry

Why would you want to run a local registry?

  • If you are using vagrant to mimic your qa/staging/prod environments and want to make sure you run the same host OS
  • If you want to test multi-host deployments with Rancher, Kubernetes, Mesos or any other orchestration framework

Without a local registry every time a new docker host is provisioned all the images need to be pulled from the remote registry, this might not be a huge issue, but depending on how many services you run it could take some time to re-download all the images. By having a local registry caching all the images it makes sure you can provision ready to use environments very quickly.

To run the registry there are a few steps

Create configuration file

version: 0.1  
log:  
  level: debug
  formatter: text
http:  
  secret: secret
  addr: :5000
storage:  
  cache:
    blobdescriptor: inmemory
  filesystem:
    rootdirectory: /var/lib/registry
proxy:  
  remoteurl: https://registry-1.docker.io

It is possible to override the settings of the config file via environment variables by using the SECTION_SECTION_... format, eg; STORAGE_CACHE_FILESYSTEM=/path
However, it is recommended to drive the configuration of the registry via a file instead of environment variables.
Settings worth mentioning:

  • storage_filesystem_rootdirectory - where to storage the image layers and repositories
  • proxy - enables a registry to be configured as a pull through cache

The official docs describe the configuration settings in more details.

Create compose file

version: '2'  
services:  
  registry:
    image: registry:2.4
    ports:
      - "5000:5000"
      - "5001:5001"
    volumes:
      - /data/registry:/var/lib/registry
    command:
      serve /var/lib/registry/config.yml
    networks:
      default:
        aliases:
          - registry.local

Bring the registry up

docker-compose up -d  

Verify the registry is online

curl -I localhost:5000  

List the repositories

curl localhost:5000/v2/_catalog  

It should come back as an empty array

{
    "repositories": []
}

Configure docker daemon to use the local registry

Where to change the configuration will depend on the distro you are using, but in any case, make sure the docker daemon is started with the following attributes:

Pull MySQL image

docker pull mysql:latest  

Verify the image has been cached

curl localhost:5000/v2/_catalog  

The MySQL repo should be present in the list

{
    "repositories": [
        "library/mysql",
    ]
}

List the image tags

curl localhost:5000/v2/library/mysql/tags/list  

Should list all the available tags for the image

{
    "name": "library/mysql",
    "tags": [
        "5.5.40",
        "5.5.41",
        "5.5.42",
        "5.5.43",
        "5.5.44",
        "5.5.45",
        "5.5.46",
        "5.5.47",
        "5.5.48",
        "5.5.49",
        "5.5.50",
        "5.5.51",
        "5.5.52",
        "5.5",
        "5.6.17",
        "5.6.20",
        "5.6.21",
        "5.6.22",
        "5.6.23",
        "5.6.24",
        "5.6.25",
        "5.6.26",
        "5.6.27",
        "5.6.28",
        "5.6.29",
        "5.6.30",
        "5.6.31",
        "5.6.32",
        "5.6.33",
        "5.6",
        "5.7.10",
        "5.7.11",
        "5.7.12",
        "5.7.13",
        "5.7.14",
        "5.7.15",
        "5.7.4-m14",
        "5.7.4",
        "5.7.5-m15",
        "5.7.5",
        "5.7.6-m16",
        "5.7.6",
        "5.7.7-rc",
        "5.7.7",
        "5.7.8-rc",
        "5.7.8",
        "5.7.9",
        "5.7",
        "5",
        "latest"
    ]
}

Configuring Jersey Servlet Container on Embedded Tomcat

One of the ways of configuring a Jersey Servlet Container on Tomcat is via a web.xml file.
For example, typically the following web.xml file is used where a Servlet and its mappings are defined:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>  
<web-app xmlns="http://java.sun.com/xml/ns/javaee"  
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <servlet>
        <servlet-name>API</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>

        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.app.v2.RestApplication</param-value>
        </init-param>

    </servlet>
    <servlet-mapping>
        <servlet-name>API</servlet-name>
        <url-pattern>/api/*</url-pattern>
    </servlet-mapping>
</web-app>  

When starting an embedded version of Tomcat the same Jersey Servlet that was defined in the XML file can be defined via code:

    RestApplication restApplication = new RestApplication();
    ServletContainer servletContainer = new ServletContainer(restApplication);
    Tomcat.addServlet(ctx, "api", servletContainer);
    ctx.addServletMapping("/api/*", "hubble-api");

There are three steps involved in configuring Jersey:

Tomcat Embedded Server Configuration

Tomcat initially started as a web server container, meaning that one Tomcat server could host several web applications. With the popularity of languages such as Ruby and Node growing and frameworks like rails and express becoming very popular for web applications the new pattern of embedding the web server as part of the application itself removing the need of any external dependencies became very common.
Even though this feature is not very well documented, Tomcat does support an embedded configuration.

Below is an example of converting a standard server.xml to an embedded server.

<?xml version='1.0' encoding='utf-8'?>

<Server port="8010" shutdown="SHUTDOWN">  
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

    <Service name="Catalina">

        <Connector port="8080"
                   protocol="org.apache.coyote.http11.Http11NioProtocol"
                   compression="on"
                   compressableMimeType="application/json"
                   connectionTimeout="5000"
                   maxThreads="50"
                   minSpareThreads="50"
                   redirectPort="9410" />

        <Engine name="Catalina" defaultHost="localhost">

            <Host name="localhost"  appBase="webapps"
                  unpackWARs="true" autoDeploy="false">

            </Host>
        </Engine>
    </Service>

</Server>  

The main components defined in the XML file are:

  • Server
  • Listeners
  • Service
  • Connector
  • Engine
  • Host

When configuring an embedded Tomcat, the xml file listed above can be converted to java code as follows:

Tomcat tomcat = new Tomcat();  
Path tempPath = Files.createTempDirectory("tomcat-base-dir");  
tomcat.setBaseDir(tempPath.toString());

// Configure connector
Connector connector = new Connector();  
connector.setPort(8080);  
connector.setProtocol(Http11NioProtocol.class.getName());  
connector.setProperty("maxThreads", "100");  
connector.setProperty("minSpareThreads", "100");  
connector.setProperty("compression", "on");  
connector.setProperty("compressableMimeType", "application/json");  
connector.setProperty("connectionTimeout", "8000");  
tomcat.getService().addConnector(connector);  
tomcat.setConnector(connector);

// Configure tomcat life cycle listeners
JreMemoryLeakPreventionListener jreMemoryLeakPreventionListener = new JreMemoryLeakPreventionListener();  
GlobalResourcesLifecycleListener globalResourcesLifecycleListener = new GlobalResourcesLifecycleListener();  
ThreadLocalLeakPreventionListener threadLocalLeakPreventionListener = new ThreadLocalLeakPreventionListener();  
VersionLoggerListener versionLoggerListener = new VersionLoggerListener();  
tomcat.getServer().addLifecycleListener(jreMemoryLeakPreventionListener);  
tomcat.getServer().addLifecycleListener(globalResourcesLifecycleListener);  
tomcat.getServer().addLifecycleListener(threadLocalLeakPreventionListener);  
tomcat.getServer().addLifecycleListener(versionLoggerListener);

// Create web context
File webContentFolder = Files.createTempDirectory("default-doc-base").toFile();  
StandardContext ctx = (StandardContext) tomcat.addWebapp("", webContentFolder.getAbsolutePath());

// Disable jar scanner for better start up performance
StandardJarScanFilter jarScanFilter = (StandardJarScanFilter) ctx.getJarScanner().getJarScanFilter();  
jarScanFilter.setTldSkip("*");

tomcat.start();  
tomcat.getServer().await();  

*It is important to set both the default Tomcat connector as well as the service connector the application will use. By default, Tomcat configures an HTTP/1.1 connector listening on port 8080, so if only the service connector is set Tomcat will try to load both connectors at once.

Golang Reflection and Interfaces

Before diving into interfaces and reflection I want to give a bit of a background on the use case I had to apply them to.

Manage Struct metadata as form of JSON components

In most data designs data is still relational. Non Relational databases have their use case but when dealing with Account-User Management, RBAC and other relational data models a relational database still is the best tool of choice.
In an iterative development process all columns of a table might not be known before hand and having a framework to quickly iterate on top becomes very handy. For example; instead of having to add new columns to a table the concept of a JSON component column can be used where data points that are not searched can be stored in a JSON string, which allows for the data model to be defined at the application level. Projects like OpenStack and Rancher already follow that strategy.
UPDATE: MySQL version 5.7.8 introduced native support for JSON: https://dev.mysql.com/doc/refman/5.7/en/json.html

Implementing JSON components in Go

A StructTag can be used to define which attributes should be stored in the JSON component.
When persisting the struct to the database the component attributes would be added to the JSON Components string and only the Components string would be persisted to the database.

type Stack struct {  
    StringComponent string  `json:"stringComponent,omitempty" genesis:"component"`
    IntComponent    int `json:"intComponent,omitempty" genesis:"component"`
    BoolComponent   bool    `json:"boolComponent,omitempty" genesis:"component"`
    FloatComponent  float64 `json:"floatComponent,omitempty" genesis:"component"`
    Components  string
}

First attempt at Reflection

At first I created a method in the Stack type which would iterate over all its attributes and build up a JSON string based on the attributes that were tagged with the component StructTag

func (s *Stack) prep() {  
    components := map[string]interface{}{}
    fields := reflect.TypeOf(s).Elem()
    values := reflect.ValueOf(s).Elem()
    for i := 0; i < fields.NumField(); i++ {
        field := fields.Field(i)
        value := values.Field(i)
        if isComponent(field) {
            components[field.Name] = value.Interface()
        }
    }
    c, err := json.Marshal(components)
    if err != nil {
        fmt.Printf("Error creating components JSON object %v\n", err.Error())
    }
    jsonString := string(c[:])
    s.Components = jsonString
}

Go Playground sample

The main problem with the approach listed above is that the prep method is tied to the Stack struct and other structs can't reuse it.

Second attempt at Reflection

Instead of calling prep as a struct method, by making Prep a public function then any struct can be provided as an argument and the method will take care of building the JSON component string via reflection.

func Prep(obj interface{}) {  
    components := map[string]interface{}{}
    fields := reflect.TypeOf(obj).Elem()
    values := reflect.ValueOf(obj).Elem()
    for i := 0; i < fields.NumField(); i++ {
        field := fields.Field(i)
        value := values.Field(i)
        if isComponent(field) {
            components[field.Name] = value.Interface()
        }
    }
    c, err := json.Marshal(components)
    if err != nil {
        fmt.Printf("Error creating components JSON object %v\n", err.Error())
    }
    jsonString := string(c[:])
     values.FieldByName("Components").SetString(jsonString)
}

Go Playground sample

Some important points to keep in mind:

  • Go has static and underlying types
  • Difference between Types and Kinds:
    • A Kind represents the specific kind of type that a Type represents.
    • In other words, a Kind is the underlying type and the Type is the static type
    • Example: http://play.golang.org/p/jAczBqbx0a

Even though the obj argument is an empty interface, its Kind at runtime will be of Pointer and its Type of *Stack (or whatever struct is passed in)
That is important to understand since to manipulate struct fields with reflection you need to have a Struct Kind.
For example; the following statement would panic:

reflect.ValueOf(obj).NumField()  

or

reflect.ValueOf(obj).Field(0)  

Accessing a Struct from a Pointer

Initially this might seem a bit alien, however, I like to relate to how you can deference pointers in C.
In C you can use the -> notation to access the values a pointer points to:

#include<stdio.h>

struct Stack {  
  int x;
};

int main(void) {  
  struct Stack s; 
  struct Stack *p;
  p = &s;
  s.x = 1;
  printf("s.x %d\n", s.x); // 1
  printf("&s %p\n", &s); // address of s
  printf("p %p\n", p); // address of s
  printf("&p %p\n", &p); // address of pointer
  printf("*p.x %d\n", p->x); // 1
  return 0;
}

In Golang the concept is similar but the syntax is a bit different. You can use the Elem() method which returns the value the interface contains. In the case of a pointer it will return the object that is being referenced to.

reflect.ValueOf(obj).Elem()  

and since the pointer is pointing to a Struct the Field method can be utilized

reflect.ValueOf(obj).Elem().NumField()  
reflect.ValueOf(obj).Elem().Field(0)

Configuring H2 database for JUnit Tests with OpenJPA

When it comes time to write unit tests for an application most likely then not there will be a scenario where the tests would have to communicate to a database backend. However, using the main database of the application during the unit tests run can pollute and corrupt the data so the recommended approach is to use a dedicated database just for the tests.

Provisioning and maintaining a full database like MySQL or PostgreSQL can have a bit of an overhead. For that regards the most suited database for unit tests is H2

The area where H2 excels is that it can be provisioned before the test suite run starts and at the end removed it since it is a in memory database.

Below are the steps necessary for configuring a OpenJPA Entity Manager Factory using the H2 driver:

Add maven dependency

<dependency>  
      <groupId>com.h2database</groupId>
      <artifactId>h2</artifactId>
      <version>1.4.191</version>
      <scope>test</scope>
</dependency>  

Create Data Source

PoolConfiguration props = new PoolProperties();  
props.setUsername("test");  
props.setPassword("");  
props.setUrl("jdbc:h2:~/test");  
props.setDriverClassName("org.h2.Driver");  
dataSource = new DataSource();  
dataSource.setPoolProperties(props);  

Create Entity Manager Factory

Properties jpaProps = new Properties();  
jpaProps.put("openjpa.ConnectionFactory", dataSource);  
jpaProps.put("openjpa.Log", "log4j");  
jpaProps.put("openjpa.ConnectionFactoryProperties", "true");  
entityManagerFactory = Persistence.createEntityManagerFactory("myfactory", jpaProps);