Skip to content

Commit

Permalink
Release Tiny Alpine 3.5 Docker Image (#24)
Browse files Browse the repository at this point in the history
* Add new Dockerfile

* Test custom build-harness

* Test 2-stage build process

* undo test

* fix path

* fix order of operations

* Rewrite to use docker for building

* remove language declaration

* escape $

* Fix vars

* Disable test

* fix test

* golang:1.8 test fixes

* golang:1.8 test fixes

* add group tpl

* Debug logging

* missing brace

* define log

* use gid for test

* fix test

* fix lint

* remove unused dockerfile

* add libc6-compat

* Export DOCKER_IMAGE_NAME

* add ca-certificates
  • Loading branch information
osterman authored and goruha committed May 23, 2017
1 parent 2997571 commit 111b440
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 109 deletions.
39 changes: 7 additions & 32 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,4 @@
sudo: required
language: go
go:
- 1.7.x
env:
global:
- DOCKER_IMAGE_NAME=cloudposse/github-authorized-keys
- RUN_TESTS=1
- TEST_GITHUB_API_TOKEN=${GITHUB_API_TOKEN}
- TEST_GITHUB_ORGANIZATION=${GITHUB_ORGANIZATION}
- TEST_GITHUB_TEAM=${GITHUB_TEAM}
- TEST_GITHUB_TEAM_ID=${GITHUB_TEAM_ID}
- TEST_GITHUB_USER=${GITHUB_USER}
services:
- docker

Expand All @@ -25,27 +13,16 @@ script:
- export TEST_ETCD_ENDPOINT=http://${ETCD_IP}:2379

- docker-compose -f docker-compose-test.yaml up -d
# setup testing environment for etcd
- make compose-up

- |-
make docker:build \
ARGS="RUN_TESTS \
TEST_GITHUB_API_TOKEN \
TEST_GITHUB_ORGANIZATION \
TEST_GITHUB_TEAM \
TEST_GITHUB_TEAM_ID \
TEST_GITHUB_USER \
TEST_ETCD_ENDPOINT"
# Also build packages for release
- make go:deps-dev
- make go:deps-build
- make go:deps
- make go:build-all
- ls -l release/
# cross-compile & run tests
- make ci

after_success:
# build a slim alpine image that ships only with the release binary
- make docker:build

after_success:
- make travis:docker-tag-and-push

deploy:
Expand All @@ -56,5 +33,3 @@ deploy:
skip_cleanup: true
on:
tags: true


48 changes: 7 additions & 41 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,44 +1,6 @@
FROM golang:1.7-alpine
FROM alpine:3.5

COPY ./ /go/src/github.com/cloudposse/github-authorized-keys

WORKDIR /go/src/github.com/cloudposse/github-authorized-keys

ARG RUN_TESTS=0
ARG TEST_GITHUB_API_TOKEN
ARG TEST_GITHUB_ORGANIZATION
ARG TEST_GITHUB_TEAM
ARG TEST_GITHUB_TEAM_ID
ARG TEST_GITHUB_USER
ARG TEST_ETCD_ENDPOINT

# We do tests on alpine so use alpine adduser flags

ENV TEST_LINUX_USER_ADD_TPL "adduser -D -s {shell} {username}"
ENV TEST_LINUX_USER_ADD_WITH_GID_TPL "adduser -D -s {shell} -G {group} {username}"
ENV TEST_LINUX_USER_ADD_TO_GROUP_TPL "adduser {username} {group}"
ENV TEST_LINUX_USER_DEL_TPL "deluser {username}"

ENV GIN_MODE=release

RUN set -ex \
&& apk add --no-cache --virtual .build-deps \
git \
make \
curl \
bash \
&& make init \
&& make go:deps-dev \
&& make go:lint \
&& make go:deps-build \
&& make go:deps \
&& ( [[ $RUN_TESTS -eq 0 ]] || make go:test; ) \
&& make go:build \
&& go-wrapper install \
&& rm -rf /go/src \
&& apk del .build-deps

WORKDIR $GOPATH
WORKDIR /

# For production run most common user add flags
#
Expand Down Expand Up @@ -69,10 +31,14 @@ ENV SYNC_USERS_INTERVAL=

ENV INTEGRATE_SSH=false


ENV LISTEN=":301"

# For production we run container with host network, so expose is just for testing and CI\CD
EXPOSE 301

RUN apk --update --no-cache add libc6-compat ca-certificates && \
ln -s /lib /lib64

COPY ./release/github-authorized-keys_linux_amd64 /usr/bin/github-authorized-keys

ENTRYPOINT ["github-authorized-keys"]
38 changes: 38 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,51 @@ RELEASE_ARCH += openbsd/386
RELEASE_ARCH += openbsd/amd64

APP := github-authorized-keys


COPYRIGHT_SOFTWARE := Github Authorized Keys
COPYRIGHT_SOFTWARE_DESCRIPTION := Use GitHub teams to manage system user accounts and authorized_keys

export DOCKER_IMAGE_NAME = cloudposse/$(APP)

include $(shell curl -so .build-harness "https://raw.githubusercontent.com/cloudposse/build-harness/master/templates/Makefile.build-harness"; echo .build-harness)

## Execute local deps
deps:
$(SELF) go:deps go:deps-dev go:deps-build

## Execute local build
build:
$(SELF) go:build

## Execute all targets
all:
$(SELF) go:deps-dev
$(SELF) go:deps-build
$(SELF) go:deps
$(SELF) go:lint
$(SELF) go:test
$(SELF) go:build-all

## Bring up docker compose environment
compose-up:
docker-compose -f docker-compose-test.yaml up -d

## Entrypoint for CI
ci:
@docker run \
-e GIN_MODE=release \
-e RUN_TESTS=1 \
-e LOG_LEVEL=debug \
-e TEST_GITHUB_API_TOKEN=$(GITHUB_API_TOKEN) \
-e TEST_GITHUB_ORGANIZATION=$(GITHUB_ORGANIZATION) \
-e TEST_GITHUB_TEAM=$(GITHUB_TEAM) \
-e TEST_GITHUB_TEAM_ID=$(GITHUB_TEAM_ID) \
-e TEST_GITHUB_USER=$(GITHUB_USER) \
-e TEST_LINUX_USER_ADD_TPL="adduser --shell {shell} {username}" \
-e TEST_LINUX_USER_ADD_WITH_GID_TPL="adduser --shell {shell} --gid {gid} {username}" \
-e TEST_LINUX_USER_ADD_TO_GROUP_TPL="adduser {username} {group}" \
-e TEST_LINUX_USER_DEL_TPL="deluser {username}" \
--volume=$$(pwd):/go/src/github.com/cloudposse/github-authorized-keys \
golang:1.8 make -C /go/src/github.com/cloudposse/github-authorized-keys all
@ls -l release/
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ Below are some of the settings which can be tweaked.
| Environment Variable | **Description** | **Default**
|--------------------------------|---------------------------------------------------------------------------------|-------------------------------------------------------------------------
| `LINUX_USER_ADD_TPL` | Command used to add a user to the system when no default group supplied. | `adduser {username} --disabled-password --force-badname --shell {shell}`
| `LINUX_USER_ADD_WITH_GID_TPL` | Command used to add a user to the system when a default primary group supplied. | `adduser {username} --disabled-password --force-badname --shell {shell} --group {group}`
| `LINUX_USER_ADD_WITH_GID_TPL` | Command used to add a user to the system when a default primary gid supplied . | `adduser {username} --disabled-password --force-badname --shell {shell} --gid {gid|group}`
| `LINUX_USER_ADD_TO_GROUP_TPL` | Command used to add the user to secondary groups | `adduser {username} {group}`
| `LINUX_USER_DEL_TPL` | Command used to delete a user from the system when removed the the team | `deluser {username}`
| `SSH_RESTART_TPL` | Command used to restart SSH when `INTEGRATE_SSH=true` | `/usr/sbin/service ssh force-reload`
Expand Down
39 changes: 19 additions & 20 deletions api/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ package api
import (
"errors"

"github.com/google/go-github/github"
"golang.org/x/oauth2"
log "github.com/Sirupsen/logrus"
"github.com/google/go-github/github"
"github.com/spf13/viper"
"golang.org/x/oauth2"
)

var (
Expand All @@ -36,7 +36,6 @@ var (

// ErrorGitHubNotFound - returned when github.com resource not found
ErrorGitHubNotFound = errors.New("Not found")

)

func init() {
Expand Down Expand Up @@ -69,7 +68,7 @@ func (c *GithubClient) GetTeam(name string, id int) (team *github.Team, err erro
err = nil

var opt = &github.ListOptions{
PerPage: viper.GetInt("github_api_max_page_size"),
PerPage: viper.GetInt("github_api_max_page_size"),
}

for {
Expand All @@ -78,13 +77,13 @@ func (c *GithubClient) GetTeam(name string, id int) (team *github.Team, err erro
if response.StatusCode != 200 {
err = ErrorGitHubAccessDenied
return
} else {
for _, localTeam := range teams {
if *localTeam.ID == id || *localTeam.Slug == name {
team = localTeam
// team found
return
}
}

for _, localTeam := range teams {
if *localTeam.ID == id || *localTeam.Slug == name {
team = localTeam
// team found
return
}
}

Expand Down Expand Up @@ -131,7 +130,7 @@ func (c *GithubClient) GetKeys(userName string) (keys []*github.Key, err error)
}

for {
items, response, local_err := c.client.Users.ListKeys(userName, opt)
items, response, localErr := c.client.Users.ListKeys(userName, opt)

logger.Debugf("Response: %v", response)
logger.Debugf("Response.StatusCode: %v", response.StatusCode)
Expand All @@ -147,8 +146,8 @@ func (c *GithubClient) GetKeys(userName string) (keys []*github.Key, err error)
return
}

if local_err != nil {
err = local_err
if localErr != nil {
err = localErr
return
}

Expand All @@ -165,7 +164,7 @@ func (c *GithubClient) GetKeys(userName string) (keys []*github.Key, err error)
func (c *GithubClient) GetTeamMembers(team *github.Team) (users []*github.User, err error) {
defer func() {
if r := recover(); r != nil {
users = make([]*github.User, 0)
users = make([]*github.User, 0)
err = ErrorGitHubConnectionFailed
}
}()
Expand All @@ -175,17 +174,17 @@ func (c *GithubClient) GetTeamMembers(team *github.Team) (users []*github.User,
PerPage: viper.GetInt("github_api_max_page_size"),
},
}

for {
members, resp, local_err := c.client.Organizations.ListTeamMembers(*team.ID, opt)
members, resp, localErr := c.client.Organizations.ListTeamMembers(*team.ID, opt)
if resp.StatusCode != 200 {
return nil, ErrorGitHubAccessDenied
}
if local_err != nil {
err = local_err
if localErr != nil {
err = localErr
return
}

users = append(users, members...)

if resp.LastPage == 0 {
Expand Down
3 changes: 3 additions & 0 deletions api/linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package api

import (
"bytes"
log "github.com/Sirupsen/logrus"
"os/exec"
"strings"

Expand Down Expand Up @@ -83,7 +84,9 @@ func (linux *Linux) Command(name string, params ...string) *exec.Cmd {

// TemplateCommand - creates command based on template and args with placeholders.
func (linux *Linux) TemplateCommand(template string, args map[string]interface{}) *exec.Cmd {
logger := log.WithFields(log.Fields{"class": "Linux", "method": "TemplateCommand"})
t := fasttemplate.New(template, "{", "}")
cmd := strings.Split(t.ExecuteString(args), " ")
logger.Debugf("Command: %v", cmd)
return linux.Command(cmd[0], cmd[1:]...)
}
22 changes: 11 additions & 11 deletions api/linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ package api

import (
"fmt"
model "github.com/cloudposse/github-authorized-keys/model/linux"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"os/user"
"strconv"
model "github.com/cloudposse/github-authorized-keys/model/linux"
)

var _ = Describe("Linux", func() {
Expand Down Expand Up @@ -89,7 +89,7 @@ var _ = Describe("Linux", func() {
)

BeforeEach(func() {
userName = model.NewUser("test", "", []string{"wheel", "root"}, "/bin/bash")
userName = model.NewUser("test", "", []string{"operator", "root"}, "/bin/bash")
linux = NewLinux("/")
})

Expand Down Expand Up @@ -184,14 +184,14 @@ var _ = Describe("Linux", func() {
Context("call with existing group", func() {
It("should return valid group", func() {
linux := NewLinux("/")
group, err := linux.groupLookup("wheel")
group, err := linux.groupLookup("operator")

Expect(err).To(BeNil())

Expect(group).NotTo(BeNil())

Expect(group.Gid).To(Equal("10"))
Expect(group.Name).To(Equal("wheel"))
Expect(group.Gid).To(Equal("37"))
Expect(group.Name).To(Equal("operator"))
})
})

Expand Down Expand Up @@ -230,14 +230,14 @@ var _ = Describe("Linux", func() {
Context("call with existing group", func() {
It("should return valid group", func() {
linux := NewLinux("/")
group, err := linux.groupLookup("10")
group, err := linux.groupLookup("37")

Expect(err).To(BeNil())

Expect(group).NotTo(BeNil())

Expect(group.Gid).To(Equal("10"))
Expect(group.Name).To(Equal("wheel"))
Expect(group.Gid).To(Equal("37"))
Expect(group.Name).To(Equal("operator"))
})
})

Expand Down Expand Up @@ -268,7 +268,7 @@ var _ = Describe("Linux", func() {
Context("call with existing group", func() {
It("should return true", func() {
linux := NewLinux("/")
isFound := linux.GroupExists("wheel")
isFound := linux.GroupExists("operator")
Expect(isFound).To(BeTrue())
})
})
Expand All @@ -294,10 +294,10 @@ var _ = Describe("Linux", func() {

Describe("userShell()", func() {
Context("call with existing user", func() {
It("should return /bin/ash", func() {
It("should return /bin/bash", func() {
linux := NewLinux("/")
shell := linux.userShell("root")
Expect(shell).To(Equal("/bin/ash"))
Expect(shell).To(Equal("/bin/bash"))
})
})
})
Expand Down
Loading

0 comments on commit 111b440

Please sign in to comment.