Skip to content

Commit

Permalink
Merge pull request #18 from commitdev/docker-http-generation
Browse files Browse the repository at this point in the history
Docker http generation
  • Loading branch information
Pritesh-Patel committed Oct 8, 2019
2 parents b09452c + 2303df3 commit 79c3ae4
Show file tree
Hide file tree
Showing 22 changed files with 228 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Expand Up @@ -58,6 +58,6 @@ COPY --from=builder /usr/local/bin /usr/local/bin
COPY --from=builder /usr/local/include /usr/local/include
COPY --from=builder /go/src/github.com/grpc-ecosystem/grpc-gateway ${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway
WORKDIR /project
RUN apk add --update --no-cache make bash curl git protobuf=${PROTOBUF_VERSION}-${ALPINE_PROTOBUF_VERSION_SUFFIX} && \
RUN apk add --update --no-cache make protobuf=${PROTOBUF_VERSION}-${ALPINE_PROTOBUF_VERSION_SUFFIX} && \
rm -rf /var/cache/apk/*
ENTRYPOINT ["sprout"]
10 changes: 10 additions & 0 deletions cmd/generate.go
Expand Up @@ -4,6 +4,10 @@ import (
"github.com/commitdev/sprout/config"
"github.com/commitdev/sprout/generate/golang"
"github.com/commitdev/sprout/generate/proto"
"github.com/commitdev/sprout/generate/docker"
"github.com/commitdev/sprout/generate/http"


"log"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -42,7 +46,13 @@ var generateCmd = &cobra.Command{
switch language {
case Go:
golang.Generate(Templator, cfg)
docker.GenerateGoAppDockerFile(Templator, cfg)

}

if cfg.Network.Http.Enabled {
http.GenerateHttpGW(Templator, cfg)
docker.GenerateGoHttpGWDockerFile(Templator, cfg)
}
},
}
Expand Down
Empty file.
11 changes: 11 additions & 0 deletions example/hello-world/docker/app/Dockerfile
@@ -0,0 +1,11 @@
FROM golang:1.12.6@sha256:83e8267be041b3ddf6a5792c7e464528408f75c446745642db08cfe4e8d58d18 AS build
WORKDIR /cache
COPY go.mod .
COPY . .
RUN go build -o hello-world

FROM alpine
RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
RUN apk update && apk add ca-certificates
COPY --from=build /cache/hello-world /app/
ENTRYPOINT /app/hello-world
10 changes: 10 additions & 0 deletions example/hello-world/docker/http/Dockerfile
@@ -0,0 +1,10 @@
FROM golang:1.12.6@sha256:83e8267be041b3ddf6a5792c7e464528408f75c446745642db08cfe4e8d58d18 AS build
WORKDIR /cache
COPY . .
RUN go build http/main.go -o hello-world-http

FROM alpine
RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
RUN apk update && apk add ca-certificates
COPY --from=build /cache/hello-world /app/
ENTRYPOINT /app/hello-world-http
4 changes: 2 additions & 2 deletions example/hello-world/hello-world-idl/Makefile
Expand Up @@ -42,9 +42,9 @@ generate-web:
cp -f -rv proto/Proto/* gen/web
rm -rf proto/proto proto/Proto
generate-http:
mkdir -p gen/http
mkdir -p gen/go
protoc ${PROTO_SOURCES} --grpc-gateway_out=logtostderr=true,paths=source_relative:proto --swagger_out=logtostderr=true:proto ./proto/health/*.proto
protoc ${PROTO_SOURCES} --grpc-gateway_out=logtostderr=true,paths=source_relative:proto --swagger_out=logtostderr=true:proto ./proto/helloworld/*.proto
cp -f -rv proto/proto/* gen/http
cp -f -rv proto/proto/* gen/go
rm -rf proto/proto

41 changes: 41 additions & 0 deletions example/hello-world/http/main.go
@@ -0,0 +1,41 @@
package main

import (
"log"
"context"
"net/http"

"github.com/grpc-ecosystem/grpc-gateway/runtime"
"google.golang.org/grpc"

health "github.com/yourrepo/hello-world-idl/gen/go/health"
helloworld "github.com/yourrepo/hello-world-idl/gen/go/helloworld"
)

func run(endpoint string, listening string) error {

ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()

mux := runtime.NewServeMux()
opts := []grpc.DialOption{grpc.WithInsecure()}
err := health.RegisterHealthHandlerFromEndpoint(ctx, mux, endpoint, opts)
err = helloworld.RegisterHelloworldHandlerFromEndpoint(ctx, mux, endpoint, opts)

if err != nil {
return err
}

return http.ListenAndServe(listening, mux)
}

func main() {
endpoint := "0.0.0.0:3000"
listening := "0.0.0.0:8080"
log.Printf("Starting http grpc gateway server on %v...", listening)

if err := run(endpoint, listening); err != nil {
log.Fatal(err)
}
}
18 changes: 18 additions & 0 deletions generate/docker/generate.go
@@ -0,0 +1,18 @@
package docker

import (
"github.com/commitdev/sprout/util"

"github.com/commitdev/sprout/config"
"github.com/commitdev/sprout/templator"
)

func GenerateGoAppDockerFile(templator *templator.Templator, config *config.SproutConfig) {
util.TemplateFileIfDoesNotExist("docker/app", "Dockerfile", templator.Docker.ApplicationDocker, config)
util.TemplateFileIfDoesNotExist("./", ".dockerignore", templator.Docker.DockerIgnore, config)

}

func GenerateGoHttpGWDockerFile(templator *templator.Templator, config *config.SproutConfig) {
util.TemplateFileIfDoesNotExist("docker/http", "Dockerfile", templator.Docker.HttpGatewayDocker, config)
}
12 changes: 12 additions & 0 deletions generate/http/generate.go
@@ -0,0 +1,12 @@
package http

import (
"github.com/commitdev/sprout/util"

"github.com/commitdev/sprout/config"
"github.com/commitdev/sprout/templator"
)

func GenerateHttpGW(templator *templator.Templator, config *config.SproutConfig) {
util.TemplateFileIfDoesNotExist("http", "main.go", templator.Go.GoHttpGW, config)
}
8 changes: 4 additions & 4 deletions generate/proto/generate.go
@@ -1,12 +1,12 @@
package proto

import (
"fmt"
"bytes"
"fmt"

"github.com/commitdev/sprout/util"
"github.com/commitdev/sprout/config"
"github.com/commitdev/sprout/templator"
"github.com/commitdev/sprout/util"
"log"
"os"
"os/exec"
Expand Down Expand Up @@ -80,10 +80,10 @@ func GenerateServiceProtobufFiles(templator *templator.Templator, cfg *config.Sp

f, err := os.Create(serviceProtoFilePath)

data:= struct {
data := struct {
*config.SproutConfig
ServiceName string
} {
}{
cfg,
s.Name,
}
Expand Down
1 change: 1 addition & 0 deletions go.sum
Expand Up @@ -27,6 +27,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/commitdev/sprout/example/hello-world v0.0.0-20190827182108-cfad4c3d94cc h1:zBLjQxkC2LT1e9eMs0I2k26NXXZVT/XGrnuqdAsFt3A=
github.com/commitdev/sprout/example/hello-world v0.0.0-20190827183525-9eeb1651f4f4 h1:pQw2XR8va971sW7QIX18I7FWft54TjLdQex5MHCcVtg=
github.com/commitdev/sprout/example/hello-world v0.0.0-20191006174419-73168768419f h1:zfmpI6udrSYU1Ly4YYqEvE3WyoGrgzqLgevS6FHWlsw=
github.com/commitdev/sprout/example/hello-world v0.0.0-20191007000403-b09452cbef06 h1:L6MAZtnpxfjj15iW3zllF3tVNjXaUB1qsNjMGISYRVI=
github.com/commitdev/sprout/example/hello-world-idl v0.0.0-20190910021125-8ac64211bb19 h1:ULmWBQ848cHxodGxtQWas0lWPAh/ZntpV1QsobbasMA=
github.com/commitdev/sprout/example/hello-world/hello-world-idl v0.0.0-20191006174419-73168768419f h1:yT3SIhGDFr+Pf7uW0wllWwp+HFeRvObO2s++6upn8g4=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
Expand Down
11 changes: 11 additions & 0 deletions templates/docker/dockerfile_app.tmpl
@@ -0,0 +1,11 @@
FROM golang:1.12.6@sha256:83e8267be041b3ddf6a5792c7e464528408f75c446745642db08cfe4e8d58d18 AS build
WORKDIR /cache
COPY go.mod .
COPY . .
RUN go build -o {{ .Name }}

FROM alpine
RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
RUN apk update && apk add ca-certificates
COPY --from=build /cache/{{ .Name }} /app/
ENTRYPOINT /app/{{ .Name }}
10 changes: 10 additions & 0 deletions templates/docker/dockerfile_http.tmpl
@@ -0,0 +1,10 @@
FROM golang:1.12.6@sha256:83e8267be041b3ddf6a5792c7e464528408f75c446745642db08cfe4e8d58d18 AS build
WORKDIR /cache
COPY . .
RUN go build http/main.go -o {{ .Name }}-http

FROM alpine
RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
RUN apk update && apk add ca-certificates
COPY --from=build /cache/{{ .Name }} /app/
ENTRYPOINT /app/{{ .Name }}-http
Empty file.
45 changes: 45 additions & 0 deletions templates/golang/http_gw.tmpl
@@ -0,0 +1,45 @@
package main

import (
"log"
"context"
"net/http"

"github.com/grpc-ecosystem/grpc-gateway/runtime"
"google.golang.org/grpc"

health "{{ $.GitRepo }}/{{ $.Name }}-idl/gen/go/health"
{{- range .Services}}
{{ .Name }} "{{ $.GitRepo }}/{{ $.Name }}-idl/gen/go/{{ .Name }}"
{{- end}}
)

func run(endpoint string, listening string) error {

ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()

mux := runtime.NewServeMux()
opts := []grpc.DialOption{grpc.WithInsecure()}
err := health.RegisterHealthHandlerFromEndpoint(ctx, mux, endpoint, opts)
{{- range .Services}}
err = {{ .Name }}.Register{{ .Name | Title }}HandlerFromEndpoint(ctx, mux, endpoint, opts)
{{- end}}

if err != nil {
return err
}

return http.ListenAndServe(listening, mux)
}

func main() {
endpoint := "0.0.0.0:{{ .Network.Grpc.Port }}"
listening := "0.0.0.0:{{ .Network.Http.Port }}"
log.Printf("Starting http grpc gateway server on %v...", listening)

if err := run(endpoint, listening); err != nil {
log.Fatal(err)
}
}
4 changes: 2 additions & 2 deletions templates/proto/makefile.tmpl
Expand Up @@ -56,12 +56,12 @@ generate-web:

{{- if .Network.Http.Enabled }}
generate-http:
mkdir -p gen/http
mkdir -p gen/go
protoc ${PROTO_SOURCES} --grpc-gateway_out=logtostderr=true,paths=source_relative:proto --swagger_out=logtostderr=true:proto ./proto/health/*.proto
{{- range .Services}}
protoc ${PROTO_SOURCES} --grpc-gateway_out=logtostderr=true,paths=source_relative:proto --swagger_out=logtostderr=true:proto ./proto/{{ .Name }}/*.proto
{{- end }}
cp -f -rv proto/proto/* gen/http
cp -f -rv proto/proto/* gen/go
rm -rf proto/proto
{{- end}}

30 changes: 30 additions & 0 deletions templator/templator.go
Expand Up @@ -6,12 +6,19 @@ import (
"text/template"
)

type DockerTemplator struct {
ApplicationDocker *template.Template
HttpGatewayDocker *template.Template
DockerIgnore *template.Template
}

type GoTemplator struct {
GoMain *template.Template
GoMod *template.Template
GoModIDL *template.Template
GoServer *template.Template
GoHealthServer *template.Template
GoHttpGW *template.Template
}

type Templator struct {
Expand All @@ -21,6 +28,7 @@ type Templator struct {
ProtoHealthTemplate *template.Template
ProtoServiceTemplate *template.Template
Go *GoTemplator
Docker *DockerTemplator
}

func NewTemplator(box *packr.Box) *Templator {
Expand All @@ -40,6 +48,7 @@ func NewTemplator(box *packr.Box) *Templator {
Go: NewGoTemplator(box),
Sprout: NewSproutTemplator(box),
GitIgnore: NewGitIgnoreTemplator(box),
Docker: NewDockerFileTemplator(box),
}
}

Expand All @@ -59,12 +68,16 @@ func NewGoTemplator(box *packr.Box) *GoTemplator {
goMainTemplateSource, _ := box.FindString("golang/main.tmpl")
goMainTemplate, _ := template.New("GoMainTemplate").Funcs(util.FuncMap).Parse(goMainTemplateSource)

goHttpTemplateSource, _ := box.FindString("golang/http_gw.tmpl")
goHttpTemplate, _ := template.New("GoHttpGWTemplate").Funcs(util.FuncMap).Parse(goHttpTemplateSource)

return &GoTemplator{
GoMain: goMainTemplate,
GoMod: goModTemplate,
GoModIDL: goModIDLTemplate,
GoServer: goServerTemplate,
GoHealthServer: goHealthServerTemplate,
GoHttpGW: goHttpTemplate,
}

}
Expand All @@ -81,3 +94,20 @@ func NewGitIgnoreTemplator(box *packr.Box) *template.Template {
template, _ := template.New("GitIgnore").Parse(templateSource)
return template
}

func NewDockerFileTemplator(box *packr.Box) *DockerTemplator {
appTemplateSource, _ := box.FindString("docker/dockerfile_app.tmpl")
appTemplate, _ := template.New("AppDockerfile").Parse(appTemplateSource)

httpTemplateSource, _ := box.FindString("docker/dockerfile_http.tmpl")
httpTemplate, _ := template.New("HttpDockerfile").Parse(httpTemplateSource)

ignoreTemplateSource, _ := box.FindString("docker/dockerignore.tmpl")
ignoreTemplate, _ := template.New("Dockerignore").Parse(ignoreTemplateSource)

return &DockerTemplator{
ApplicationDocker: appTemplate,
HttpGatewayDocker: httpTemplate,
DockerIgnore: ignoreTemplate,
}
}
20 changes: 20 additions & 0 deletions util/util.go
Expand Up @@ -3,6 +3,8 @@ package util
import (
"os"
"strings"
"fmt"
"log"
"text/template"
)

Expand All @@ -17,3 +19,21 @@ func CreateDirIfDoesNotExist(path string) error {
var FuncMap = template.FuncMap{
"Title": strings.Title,
}

func TemplateFileIfDoesNotExist(fileDir string, fileName string, template *template.Template, data interface{}) {
fullFilePath := fmt.Sprintf("%v/%v", fileDir, fileName)

if _, err := os.Stat(fullFilePath); os.IsNotExist(err) {
err := CreateDirIfDoesNotExist(fileDir)
f, err := os.Create(fullFilePath)
if err != nil {
log.Printf("Error creating file: %v", err)
}
err = template.Execute(f, data)
if err != nil {
log.Printf("Error templating: %v", err)
}
} else {
log.Printf("%v already exists. skipping.", fullFilePath)
}
}

0 comments on commit 79c3ae4

Please sign in to comment.