Skip to content

Commit

Permalink
Use kpt Renderer in Porch (kptdev#2735)
Browse files Browse the repository at this point in the history
* Use kpt Renderer in Porch
* Accept gRPC function runner endpoint
  • Loading branch information
martinmaly committed Feb 18, 2022
1 parent 156bc76 commit 86c62b7
Show file tree
Hide file tree
Showing 18 changed files with 353 additions and 63 deletions.
6 changes: 5 additions & 1 deletion porch/apiserver/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ require (
go.opentelemetry.io/otel/exporters/stdout v0.20.0
go.opentelemetry.io/otel/sdk v0.20.0
go.opentelemetry.io/otel/sdk/metric v0.20.0
google.golang.org/grpc v1.43.0
google.golang.org/grpc v1.44.0
k8s.io/api v0.23.1
k8s.io/apimachinery v0.23.1
k8s.io/apiserver v0.23.0
Expand All @@ -33,13 +33,15 @@ replace (
github.com/GoogleContainerTools/kpt/porch/apiserver => ./
github.com/GoogleContainerTools/kpt/porch/controllers => ../controllers
github.com/GoogleContainerTools/kpt/porch/engine => ../engine
github.com/GoogleContainerTools/kpt/porch/func => ../func
github.com/GoogleContainerTools/kpt/porch/repository => ../repository
)

require (
cloud.google.com/go v0.99.0 // indirect
github.com/GoogleContainerTools/kpt v0.0.0-00010101000000-000000000000 // indirect
github.com/GoogleContainerTools/kpt-functions-catalog/functions/go/apply-setters v0.2.0 // indirect
github.com/GoogleContainerTools/kpt/porch/func v0.0.0-00010101000000-000000000000 // indirect
github.com/Microsoft/go-winio v0.5.1 // indirect
github.com/NYTimes/gziphandler v1.1.1 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20220113124808-70ae35bab23f // indirect
Expand Down Expand Up @@ -76,6 +78,7 @@ require (
github.com/google/go-cmp v0.5.7 // indirect
github.com/google/go-containerregistry v0.8.0 // indirect
github.com/google/gofuzz v1.1.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/gnostic v0.5.5 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
Expand Down Expand Up @@ -122,6 +125,7 @@ require (
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.19.1 // indirect
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
golang.org/x/mod v0.5.1 // indirect
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f // indirect
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
Expand Down
3 changes: 2 additions & 1 deletion porch/apiserver/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1558,8 +1558,9 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM=
google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg=
google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
Expand Down
5 changes: 4 additions & 1 deletion porch/apiserver/pkg/apiserver/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ func init() {
type ExtraConfig struct {
CoreAPIKubeconfigPath string
CacheDirectory string
FunctionRunnerAddress string
}

// Config defines the config for the apiserver
Expand Down Expand Up @@ -159,7 +160,9 @@ func (c completedConfig) New() (*PorchServer, error) {
return nil, fmt.Errorf("failed to build client for core apiserver: %w", err)
}

porchGroup, err := porch.NewRESTStorage(Scheme, Codecs, c.GenericConfig.RESTOptionsGetter, coreClient, c.ExtraConfig.CacheDirectory)
porchGroup, err := porch.NewRESTStorage(
Scheme, Codecs, c.GenericConfig.RESTOptionsGetter, coreClient,
c.ExtraConfig.CacheDirectory, c.ExtraConfig.FunctionRunnerAddress)
if err != nil {
return nil, err
}
Expand Down
3 changes: 3 additions & 0 deletions porch/apiserver/pkg/cmd/server/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type PorchServerOptions struct {
LocalStandaloneDebugging bool // Enables local standalone running/debugging of the apiserver.
CacheDirectory string
CoreAPIKubeconfigPath string
FunctionRunnerAddress string

SharedInformerFactory informers.SharedInformerFactory
StdOut io.Writer
Expand Down Expand Up @@ -179,6 +180,7 @@ func (o *PorchServerOptions) Config() (*apiserver.Config, error) {
ExtraConfig: apiserver.ExtraConfig{
CoreAPIKubeconfigPath: o.CoreAPIKubeconfigPath,
CacheDirectory: o.CacheDirectory,
FunctionRunnerAddress: o.FunctionRunnerAddress,
},
}
return config, nil
Expand Down Expand Up @@ -221,5 +223,6 @@ func (o *PorchServerOptions) AddFlags(fs *pflag.FlagSet) {
"authorizing the requests, this flag is only intended for debugging in your workstation.")
}

fs.StringVar(&o.FunctionRunnerAddress, "function-runner", "", "Address of the function runner gRPC service.")
fs.StringVar(&o.CacheDirectory, "cache-directory", "", "Directory where Porch server stores repository and package caches.")
}
4 changes: 2 additions & 2 deletions porch/apiserver/pkg/registry/porch/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ import (
)

func NewRESTStorage(scheme *runtime.Scheme, codecs serializer.CodecFactory, restOptionsGetter genericregistry.RESTOptionsGetter,
coreClient client.WithWatch, cacheDirectory string) (genericapiserver.APIGroupInfo, error) {
coreClient client.WithWatch, cacheDirectory string, functionRunnerAddress string) (genericapiserver.APIGroupInfo, error) {

c := cache.NewCache(cacheDirectory)
cad, err := engine.NewCaDEngine(c)
cad, err := engine.NewCaDEngine(c, functionRunnerAddress)

if err != nil {
return genericapiserver.APIGroupInfo{}, err
Expand Down
4 changes: 4 additions & 0 deletions porch/engine/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ require (
github.com/GoogleContainerTools/kpt-functions-catalog/functions/go/apply-setters v0.2.0
github.com/GoogleContainerTools/kpt/porch/api v0.0.0-00010101000000-000000000000
github.com/GoogleContainerTools/kpt/porch/controllers v0.0.0-00010101000000-000000000000
github.com/GoogleContainerTools/kpt/porch/func v0.0.0-00010101000000-000000000000
github.com/GoogleContainerTools/kpt/porch/repository v0.0.0-00010101000000-000000000000
github.com/google/go-cmp v0.5.7
google.golang.org/grpc v1.44.0
k8s.io/klog/v2 v2.40.1
sigs.k8s.io/kustomize/kyaml v0.13.3
)
Expand All @@ -17,6 +19,7 @@ replace (
github.com/GoogleContainerTools/kpt => ../../
github.com/GoogleContainerTools/kpt/porch/api => ../api
github.com/GoogleContainerTools/kpt/porch/controllers => ../controllers
github.com/GoogleContainerTools/kpt/porch/func => ../func
github.com/GoogleContainerTools/kpt/porch/kpt => ../kpt
github.com/GoogleContainerTools/kpt/porch/repository => ../repository
)
Expand Down Expand Up @@ -84,6 +87,7 @@ require (
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
Expand Down
3 changes: 3 additions & 0 deletions porch/engine/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1447,6 +1447,7 @@ google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ6
google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa h1:I0YcKz0I7OAhddo7ya8kMnvprhcWM045PmkBdMO9zN0=
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
Expand Down Expand Up @@ -1480,6 +1481,8 @@ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg=
google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
Expand Down
34 changes: 31 additions & 3 deletions porch/engine/pkg/engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,12 @@ import (
api "github.com/GoogleContainerTools/kpt/porch/api/porch/v1alpha1"
configapi "github.com/GoogleContainerTools/kpt/porch/controllers/pkg/apis/porch/v1alpha1"
"github.com/GoogleContainerTools/kpt/porch/engine/pkg/kpt"
"github.com/GoogleContainerTools/kpt/porch/func/evaluator"
"github.com/GoogleContainerTools/kpt/porch/repository/pkg/cache"
"github.com/GoogleContainerTools/kpt/porch/repository/pkg/repository"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"k8s.io/klog/v2"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
Expand All @@ -45,14 +49,38 @@ type CaDEngine interface {
ListFunctions(ctx context.Context, repositoryObj *configapi.Repository, auth repository.AuthOptions) ([]repository.Function, error)
}

func NewCaDEngine(cache *cache.Cache) (CaDEngine, error) {
func NewCaDEngine(cache *cache.Cache, functionRunnerAddress string) (CaDEngine, error) {
runtime, err := createFunctionRuntime(functionRunnerAddress)
if err != nil {
return nil, fmt.Errorf("failed to create function runtime: %w", err)
}

return &cadEngine{
cache: cache,
renderer: kpt.NewPlaceholderRenderer(),
runtime: kpt.NewPlaceholderFunctionRuntime(),
renderer: kpt.NewRenderer(),
runtime: runtime,
}, nil
}

func createFunctionRuntime(address string) (kpt.FunctionRuntime, error) {
if address == "" {
klog.Warningf("Using simple kpt function runner (in-process)")
return kpt.NewSimpleFunctionRuntime(), nil
}

klog.Infof("Dialing grpc function runner %q", address)

cc, err := grpc.Dial(address, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
return nil, fmt.Errorf("failed to dial grpc function evaluator: %w", err)
}

return &grpcRuntime{
cc: cc,
client: evaluator.NewFunctionEvaluatorClient(cc),
}, err
}

type cadEngine struct {
cache *cache.Cache
renderer fn.Renderer
Expand Down
82 changes: 82 additions & 0 deletions porch/engine/pkg/engine/grpcruntime.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package engine

import (
"context"
"fmt"
"io"
"io/ioutil"

v1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1"
"github.com/GoogleContainerTools/kpt/pkg/fn"
"github.com/GoogleContainerTools/kpt/porch/engine/pkg/kpt"
"github.com/GoogleContainerTools/kpt/porch/func/evaluator"
"google.golang.org/grpc"
"k8s.io/klog/v2"
)

type grpcRuntime struct {
cc *grpc.ClientConn
client evaluator.FunctionEvaluatorClient
}

var _ kpt.FunctionRuntime = &grpcRuntime{}

func (gr *grpcRuntime) GetRunner(ctx context.Context, fn *v1.Function) (fn.FunctionRunner, error) {
return &grpcRunner{
ctx: ctx,
client: gr.client,
image: fn.Image,
}, nil
}

func (gr *grpcRuntime) Close() error {
var err error
if gr.cc != nil {
if err = gr.cc.Close(); err != nil {
klog.Warningf("Failed to close grpc client connection: %v", err)
}
gr.cc = nil
}
return err
}

type grpcRunner struct {
ctx context.Context
client evaluator.FunctionEvaluatorClient
image string
}

var _ fn.FunctionRunner = &grpcRunner{}

func (gr *grpcRunner) Run(r io.Reader, w io.Writer) error {
in, err := ioutil.ReadAll(r)
if err != nil {
return fmt.Errorf("failed to read function runner input: %w", err)
}

res, err := gr.client.EvaluateFunction(gr.ctx, &evaluator.EvaluateFunctionRequest{
ResourceList: in,
Image: gr.image,
})
if err != nil {
return fmt.Errorf("func eval failed: %w (%s)", err, string(res.Log))
}
if _, err := w.Write(res.ResourceList); err != nil {
return fmt.Errorf("failed to write function runner output: %w", err)
}
return nil
}
30 changes: 23 additions & 7 deletions porch/engine/pkg/engine/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ var _ mutation = &renderPackageMutation{}
func (m *renderPackageMutation) Apply(ctx context.Context, resources repository.PackageResources) (repository.PackageResources, *api.Task, error) {
fs := filesys.MakeFsInMemory()

if err := writeResources(fs, resources); err != nil {
pkgPath, err := writeResources(fs, resources)
if err != nil {
return repository.PackageResources{}, nil, err
}

if err := m.renderer.Render(ctx, fs, fn.RenderOptions{
PkgPath: pkgPath,
Runtime: m.runtime,
}); err != nil {
return repository.PackageResources{}, nil, err
Expand All @@ -62,16 +64,30 @@ func (m *renderPackageMutation) Apply(ctx context.Context, resources repository.
}

// TODO: Implement filesystem abstraction directly rather than on top of PackageResources
func writeResources(fs filesys.FileSystem, resources repository.PackageResources) error {
func writeResources(fs filesys.FileSystem, resources repository.PackageResources) (string, error) {
var packageDir string // path to the topmost directory containing Kptfile
for k, v := range resources.Contents {
if err := fs.MkdirAll(path.Dir(k)); err != nil {
return err
dir := path.Dir(k)
if dir == "." {
dir = "/"
}
if err := fs.MkdirAll(dir); err != nil {
return "", err
}
if err := fs.WriteFile(k, []byte(v)); err != nil {
return err
base := path.Base(k)
if err := fs.WriteFile(path.Join(dir, base), []byte(v)); err != nil {
return "", err
}
if base == "Kptfile" {
// Found Kptfile. Check if the current directory is ancestor of the current
// topmost package directory. If so, use it instead.
if packageDir == "" || strings.HasPrefix(packageDir, dir+"/") {
packageDir = dir
}
}
}
return nil
// Return topmost directory containing Kptfile
return packageDir, nil
}

func readResources(fs filesys.FileSystem) (repository.PackageResources, error) {
Expand Down
Loading

0 comments on commit 86c62b7

Please sign in to comment.