From a01c7955fb8028c1c46569ece00167ecdee10f8b Mon Sep 17 00:00:00 2001 From: Tim Olbrich Date: Mon, 11 May 2020 14:46:47 +0200 Subject: [PATCH] #2 inital builder. Directory of BuildContext and Project are statically at the moment --- ...harbourrocks_harbour_cmd_harbour_build.xml | 16 +++ cmd/harbour-build/app/cmd.go | 44 ++++++++ cmd/harbour-build/main.go | 14 +++ go.mod | 11 +- go.sum | 29 +++++ pkg/harbourbuild/builder.go | 103 ++++++++++++++++++ pkg/harbourbuild/configuration/config.go | 28 +++++ pkg/harbourbuild/handler/build.go | 41 +++++++ pkg/harbourbuild/models/buildjob.go | 7 ++ pkg/harbourbuild/models/buildrequest.go | 7 ++ pkg/harbourbuild/redis/builder.go | 7 ++ pkg/harbourbuild/server.go | 46 ++++++++ pkg/httphandler/traits/http.go | 2 +- pkg/registry/models/repositories.go | 2 +- pkg/registry/models/tags.go | 2 +- 15 files changed, 355 insertions(+), 4 deletions(-) create mode 100644 .idea/runConfigurations/go_build_github_com_harbourrocks_harbour_cmd_harbour_build.xml create mode 100644 cmd/harbour-build/app/cmd.go create mode 100644 cmd/harbour-build/main.go create mode 100644 pkg/harbourbuild/builder.go create mode 100644 pkg/harbourbuild/configuration/config.go create mode 100644 pkg/harbourbuild/handler/build.go create mode 100644 pkg/harbourbuild/models/buildjob.go create mode 100644 pkg/harbourbuild/models/buildrequest.go create mode 100644 pkg/harbourbuild/redis/builder.go create mode 100644 pkg/harbourbuild/server.go diff --git a/.idea/runConfigurations/go_build_github_com_harbourrocks_harbour_cmd_harbour_build.xml b/.idea/runConfigurations/go_build_github_com_harbourrocks_harbour_cmd_harbour_build.xml new file mode 100644 index 0000000..4a2ea95 --- /dev/null +++ b/.idea/runConfigurations/go_build_github_com_harbourrocks_harbour_cmd_harbour_build.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cmd/harbour-build/app/cmd.go b/cmd/harbour-build/app/cmd.go new file mode 100644 index 0000000..b2a4764 --- /dev/null +++ b/cmd/harbour-build/app/cmd.go @@ -0,0 +1,44 @@ +package app + +import ( + "github.com/harbourrocks/harbour/pkg/harbourbuild" + "github.com/harbourrocks/harbour/pkg/harbourbuild/configuration" + "github.com/harbourrocks/harbour/pkg/logconfig" + "github.com/harbourrocks/harbour/pkg/redisconfig" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +func NewBuildServerCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "harbour-builder", + Long: "The habour.rocks build server manages the building of projects for the registry", + RunE: func(cmd *cobra.Command, args []string) error { + + // load builder config + s := configuration.ParseViperConfig() + + // configure logging + l := logconfig.ParseViperConfig() + logconfig.ConfigureLog(l) + + logrus.Info("Harbour Builder configured") + + // test redis connection + redisconfig.TestConnection(s.Redis) + + return harbourbuild.RunBuildServer(s) + }, + } + + return cmd +} + +func init() { + cobra.OnInitialize(initCobra) +} + +func initCobra() { + viper.AutomaticEnv() +} diff --git a/cmd/harbour-build/main.go b/cmd/harbour-build/main.go new file mode 100644 index 0000000..ac1d16f --- /dev/null +++ b/cmd/harbour-build/main.go @@ -0,0 +1,14 @@ +package main + +import ( + "github.com/harbourrocks/harbour/cmd/harbour-build/app" + "os" +) + +func main() { + cmd := app.NewBuildServerCommand() + + if err := cmd.Execute(); err != nil { + os.Exit(1) + } +} diff --git a/go.mod b/go.mod index 01e4522..08f748c 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,21 @@ module github.com/harbourrocks/harbour go 1.13 require ( + github.com/Microsoft/go-winio v0.4.14 // indirect + github.com/containerd/containerd v1.3.4 // indirect github.com/coreos/go-oidc v2.2.1+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible + github.com/docker/distribution v2.7.1+incompatible // indirect + github.com/docker/docker v17.12.0-ce-rc1.0.20200406100148-5a685dc7e4e3+incompatible + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.4.0 // indirect github.com/go-redis/redis/v7 v7.2.0 github.com/graphql-go/graphql v0.7.9 + github.com/jhoonb/archivex v0.0.0-20180718040744-0488e4ce1681 + github.com/opencontainers/go-digest v1.0.0-rc1 // indirect + github.com/opencontainers/image-spec v1.0.1 // indirect github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect - github.com/sirupsen/logrus v1.2.0 + github.com/sirupsen/logrus v1.4.1 github.com/spf13/cobra v0.0.7 github.com/spf13/viper v1.4.0 github.com/stretchr/testify v1.5.1 // indirect diff --git a/go.sum b/go.sum index 51aefdd..a58f6f8 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -10,6 +12,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/containerd/containerd v1.3.4 h1:3o0smo5SKY7H6AJCmJhsnCjR2/V2T8VmiHt7seN2/kI= +github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk= @@ -24,6 +28,16 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo= +github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v17.12.0-ce-rc1.0.20200406100148-5a685dc7e4e3+incompatible h1:8K7rm+mlO7mi7Sw99gvBrGVqMiPuiyHS8J3ulTn5stc= +github.com/docker/docker v17.12.0-ce-rc1.0.20200406100148-5a685dc7e4e3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -34,6 +48,7 @@ github.com/go-redis/redis/v7 v7.2.0 h1:CrCexy/jYWZjW0AyVoHlcJUeZN19VWlbepTh1Vq6d github.com/go-redis/redis/v7 v7.2.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -56,6 +71,8 @@ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jhoonb/archivex v0.0.0-20180718040744-0488e4ce1681 h1:EiEjLram6Y0WXygV4WyzKmTr3XaR4CD3tvjdTrsk3cU= +github.com/jhoonb/archivex v0.0.0-20180718040744-0488e4ce1681/go.mod h1:GN1Mg/uXQ6qwXA0HypnUO3xlcQJS9/y68EsHNeuuRa4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= @@ -81,9 +98,16 @@ github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= +github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU= @@ -102,6 +126,8 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= @@ -157,6 +183,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -172,8 +199,10 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/harbourbuild/builder.go b/pkg/harbourbuild/builder.go new file mode 100644 index 0000000..ae817f6 --- /dev/null +++ b/pkg/harbourbuild/builder.go @@ -0,0 +1,103 @@ +package harbourbuild + +import ( + "context" + "fmt" + "github.com/docker/docker/api/types" + "github.com/docker/docker/client" + "github.com/harbourrocks/harbour/pkg/harbourbuild/models" + "github.com/jhoonb/archivex" + l "github.com/sirupsen/logrus" + "os" +) + +type Builder struct { + jobChan chan models.BuildJob + cli *client.Client + ctx context.Context +} + +func NewBuilder(jobChan chan models.BuildJob) (Builder, error) { + var builder Builder + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + return builder, err + } + + builder = Builder{jobChan: jobChan, cli: cli, ctx: ctx} + return builder, nil +} + +func (b Builder) Start() { + go func() { + for { + select { + case job := <-b.jobChan: + b.buildImage(job) + } + } + }() +} + +func (b Builder) buildImage(job models.BuildJob) { + l.Trace("Create Build Context") + buildCtx, err := b.createBuildContext(job.Request.Project) + if err != nil { + l.WithError(err).Error("Failed to create build context") + return + } + + defer b.cleanUpAfterBuild(buildCtx) + + l.Trace("Create Build Options") + opt := types.ImageBuildOptions{ + Tags: job.Request.Tags, + Dockerfile: job.Request.Dockerfile, + } + + l.Trace("Build Image") + _, err = b.cli.ImageBuild(b.ctx, buildCtx, opt) + if err != nil { + l.WithError(err).Error("Failed to build image") + return + } +} + +func (b Builder) cleanUpAfterBuild(buildContext *os.File) { + l.Trace("Cleaning up") + err := buildContext.Close() + err = os.Remove(buildContext.Name()) + if err != nil { + l.WithError(err).Error("Error while cleaning up build context") + return + } +} + +//TODO Communicate with Harbour SCM in order to receive the path to the project-files +func (b Builder) getProjectPath(project string) (string, error) { + // Just returns a demo path + return fmt.Sprintf("./test/repos/%s", project), nil +} + +func (b Builder) createBuildContext(project string) (*os.File, error) { + + buildContext := fmt.Sprintf("./test/buildcontext/%s.tar", project) + projectPath, err := b.getProjectPath(project) + if err != nil { + l.WithError(err).Error("Failed to receive the project files") + return nil, err + } + + tar := new(archivex.TarFile) + err = tar.Create(buildContext) + err = tar.AddAll(projectPath, false) + err = tar.Close() + + dockerBuildCtx, err := os.Open(buildContext) + if err != nil { + return nil, err + } + + return dockerBuildCtx, nil +} diff --git a/pkg/harbourbuild/configuration/config.go b/pkg/harbourbuild/configuration/config.go new file mode 100644 index 0000000..c8b028c --- /dev/null +++ b/pkg/harbourbuild/configuration/config.go @@ -0,0 +1,28 @@ +package configuration + +import ( + "github.com/harbourrocks/harbour/pkg/auth" + "github.com/harbourrocks/harbour/pkg/redisconfig" +) + +type Options struct { + Redis redisconfig.RedisOptions + OIDCConfig auth.OIDCConfig +} + +func NewDefaultOptions() *Options { + s := Options{ + Redis: redisconfig.NewDefaultRedisOptions(), + OIDCConfig: auth.DefaultConfig(), + } + + return &s +} + +func ParseViperConfig() *Options { + s := NewDefaultOptions() + + s.OIDCConfig = auth.ParseViperConfig() + s.Redis = redisconfig.ParseViperConfig() + return s +} diff --git a/pkg/harbourbuild/handler/build.go b/pkg/harbourbuild/handler/build.go new file mode 100644 index 0000000..1a87d9e --- /dev/null +++ b/pkg/harbourbuild/handler/build.go @@ -0,0 +1,41 @@ +package handler + +import ( + "encoding/json" + "github.com/harbourrocks/harbour/pkg/harbourbuild/models" + "github.com/harbourrocks/harbour/pkg/httphandler/traits" + "github.com/harbourrocks/harbour/pkg/redisconfig" + l "github.com/sirupsen/logrus" + "net/http" +) + +type BuilderModel struct { + traits.HttpModel + traits.IdTokenModel + redisconfig.RedisModel + buildChan chan models.BuildJob +} + +func NewBuilderModel(buildChan chan models.BuildJob) BuilderModel { + return BuilderModel{buildChan: buildChan} +} + +func (b BuilderModel) Handle() { + w := b.GetResponse() + req := b.GetRequest() + //redisConfig := b.GetRedisConfig() + var buildRequest models.BuildRequest + decoder := json.NewDecoder(req.Body) + err := decoder.Decode(&buildRequest) + if err != nil { + l.WithError(err).Error("Failed to parse build request") + w.WriteHeader(http.StatusInternalServerError) + return + } + + b.buildChan <- models.BuildJob{Request: buildRequest} + + l.Trace("Build job enqueued") + + w.WriteHeader(http.StatusAccepted) +} diff --git a/pkg/harbourbuild/models/buildjob.go b/pkg/harbourbuild/models/buildjob.go new file mode 100644 index 0000000..450d36f --- /dev/null +++ b/pkg/harbourbuild/models/buildjob.go @@ -0,0 +1,7 @@ +package models + +// BuildJob represents a job send to the Builder with a channel. +// Contains all information required for build a image. +type BuildJob struct { + Request BuildRequest +} diff --git a/pkg/harbourbuild/models/buildrequest.go b/pkg/harbourbuild/models/buildrequest.go new file mode 100644 index 0000000..d001f58 --- /dev/null +++ b/pkg/harbourbuild/models/buildrequest.go @@ -0,0 +1,7 @@ +package models + +type BuildRequest struct { + Dockerfile string `json:"dockerfile"` + Tags []string `json:"tags"` + Project string `json:"project"` +} diff --git a/pkg/harbourbuild/redis/builder.go b/pkg/harbourbuild/redis/builder.go new file mode 100644 index 0000000..bcb7881 --- /dev/null +++ b/pkg/harbourbuild/redis/builder.go @@ -0,0 +1,7 @@ +package redis + +import "fmt" + +func BuilderAppKey(buildId int) string { + return fmt.Sprintf("BUILD_%d", buildId) +} diff --git a/pkg/harbourbuild/server.go b/pkg/harbourbuild/server.go new file mode 100644 index 0000000..c841d84 --- /dev/null +++ b/pkg/harbourbuild/server.go @@ -0,0 +1,46 @@ +package harbourbuild + +import ( + "fmt" + "github.com/harbourrocks/harbour/pkg/harbourbuild/configuration" + "github.com/harbourrocks/harbour/pkg/harbourbuild/handler" + "github.com/harbourrocks/harbour/pkg/harbourbuild/models" + "github.com/harbourrocks/harbour/pkg/httphandler" + "github.com/harbourrocks/harbour/pkg/httphandler/traits" + "github.com/harbourrocks/harbour/pkg/redisconfig" + "github.com/sirupsen/logrus" + "net/http" +) + +func RunBuildServer(o *configuration.Options) error { + logrus.Info("Started Harbour build server") + + buildChan := make(chan models.BuildJob) + builder, err := NewBuilder(buildChan) + if err != nil { + logrus.Fatal(err) + return err + } + builder.Start() + logrus.Info("Started Harbour builder ") + + http.HandleFunc("/build/test", func(w http.ResponseWriter, r *http.Request) { + logrus.Trace(r) + model := handler.NewBuilderModel(buildChan) + traits.AddHttp(&model, r, w, o.OIDCConfig) + traits.AddIdToken(&model) + redisconfig.AddRedis(&model, o.Redis) + + if err := httphandler.ForceAuthenticated(&model); err == nil { + model.Handle() + } + }) + + bindAddress := "127.0.0.1:5200" + logrus.Info(fmt.Sprintf("Listening on httphandler://%s/", bindAddress)) + + err = http.ListenAndServe(bindAddress, nil) + logrus.Fatal(err) + + return err +} diff --git a/pkg/httphandler/traits/http.go b/pkg/httphandler/traits/http.go index d916da5..475935e 100644 --- a/pkg/httphandler/traits/http.go +++ b/pkg/httphandler/traits/http.go @@ -67,7 +67,7 @@ func (m *HttpModel) WriteResponse(v interface{}) (err error) { return } -// ReadRequest Parses the request as JSON into the model parameter +// ReadRequest Parses the request as JSON into the models parameter // Errors are logged and should be handled by returning 500 func (m *HttpModel) ReadRequest(model interface{}) (err error) { r := m.GetRequest() diff --git a/pkg/registry/models/repositories.go b/pkg/registry/models/repositories.go index 3fe7b1c..6d5edc2 100644 --- a/pkg/registry/models/repositories.go +++ b/pkg/registry/models/repositories.go @@ -1,6 +1,6 @@ package models -// Repositories is the response model of /v2/_catalog +// Repositories is the response models of /v2/_catalog type Repositories struct { Repositories []string `json:"repositories"` } diff --git a/pkg/registry/models/tags.go b/pkg/registry/models/tags.go index 99d14c4..e7e50ba 100644 --- a/pkg/registry/models/tags.go +++ b/pkg/registry/models/tags.go @@ -1,6 +1,6 @@ package models -// Tags is the response model of /v2//tags/list +// Tags is the response models of /v2//tags/list type Tags struct { Name string `json:"name"` Tags []string `json:"tags"`