Skip to content

Instantly share code, notes, and snippets.

@sujaypillai
Created February 23, 2017 17:33
Show Gist options
  • Save sujaypillai/5dd29e1b8cc80265f90c31bf86cbef5f to your computer and use it in GitHub Desktop.
Save sujaypillai/5dd29e1b8cc80265f90c31bf86cbef5f to your computer and use it in GitHub Desktop.
package main
import (
"golang.org/x/net/context"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/cli/command"
"github.com/docker/docker/client"
"fmt"
"os"
)
var (
err error
appName string
)
// Keep constants with sensitive information in one place
const (
DefaultServer = "registry.gitlab.com"
Username = "xxxxx"
Password = "xxxxx"
)
// App struct holds information about the app that should be launched
// with auth and docker client info
type App struct {
Name string
Client *client.Client
AuthConfig types.AuthConfig
AuthConfigEncoded string
Config container.ContainerCreateCreatedBody
}
func registryAuthentication(image string) types.RequestPrivilegeFunc {
return func() (string, error) {
authConfig := types.AuthConfig{
Username: Username,
Password: Password,
ServerAddress: DefaultServer,
}
base64config, err := command.EncodeAuthToBase64(authConfig)
if err != nil {
return "", err
}
return base64config, nil
}
}
// Initialize application from environment variable
func (app *App) Initialize() error {
app.Client, err = client.NewEnvClient()
return err
}
// Prepare auth registry for usage
func (app *App) PrepareRegistry() error {
app.AuthConfig = types.AuthConfig{
Username: Username,
Password: Password,
ServerAddress: DefaultServer,
}
resp, err := app.Client.RegistryLogin(context.Background(), app.AuthConfig)
if err != nil {
panic(err)
}
fmt.Println("Status:\t", resp.Status)
if resp.IdentityToken != "" {
app.AuthConfig.IdentityToken = resp.IdentityToken
}
app.AuthConfigEncoded, err = command.EncodeAuthToBase64(app.AuthConfig)
return err
}
func (app *App) ImagePull() error {
opts := types.ImagePullOptions{
RegistryAuth: app.AuthConfigEncoded,
PrivilegeFunc: registryAuthentication(app.Name),
}
_, err := app.Client.ImagePull(context.Background(), DefaultServer + "magnus/atom", opts)
if err != nil {
return err
}
return nil
}
func (app *App) ImageIsLoaded() bool {
result, err := app.Client.ImageSearch(context.Background(), app.Name, types.ImageSearchOptions{Limit: 1})
if err != nil {
panic(err)
}
if len(result) != 0 {
return true
}
return false
}
// Create config for container
func (app *App) ContainerCreate() error {
// Wait for image to be pulled
for !app.ImageIsLoaded() {
app.Config, err = app.Client.ContainerCreate(
context.Background(),
&container.Config{Image: app.Name},
&container.HostConfig{},
&network.NetworkingConfig{},
"")
return err
}
return nil
}
// Launch container with the `App.Name`
func (app *App) ContainerStart() error {
return app.Client.ContainerStart(context.Background(), app.Config.ID, types.ContainerStartOptions{})
}
// Launch app
func (app *App) Start() {
err = app.Initialize()
if err != nil {
panic(err)
}
err = app.PrepareRegistry()
if err != nil {
panic(err)
}
err = app.ImagePull()
if err != nil {
panic(err)
}
err = app.ContainerCreate()
if err != nil {
panic(err)
}
err = app.ContainerStart()
if err != nil {
panic(err)
}
}
func main() {
if len(os.Args) > 1 {
appName = os.Args[1]
app := App{Name: "magnus/" + appName}
app.Start()
fmt.Sprintln("Launched", appName)
} else {
fmt.Println("Please, provide app name")
}
}
@richmondwang
Copy link

do you know how we can mount files in ContainerCreate?

@AlexRuzin
Copy link

It's possible to do bind mounts using HostConfig:
hostConfig := &container.HostConfig{
Mounts: []mount.Mount{
{
Type: mount.TypeBind,
Source: mountLoc,
Target: "/var/lib/mysql",
},
},
[...]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment