Skip to content

Commit

Permalink
Combined Porch Commit
Browse files Browse the repository at this point in the history
Create function-runner Deployment (kptdev#2733)

Use kpt Renderer in Porch (kptdev#2735)

* Use kpt Renderer in Porch
* Accept gRPC function runner endpoint

RemoteRootSyncSet: use specified OCI image (kptdev#2722)

Stop hard-coding and use the image the user specifies!

RemoteRootSyncSet: apply changes with force (kptdev#2723)

This lets us switch from client-side-applied to server-side-applied.

RemoteRootSyncSet: Remove hack where we set namespace (kptdev#2724)

It's now causing problems; we shouldn't need it and we should fix it
later in the logic anyway (with a default namespace).

Create push-images target to push all our images (kptdev#2721)

Also a few tweaks to make the porch image build faster.

Create dockerfile / makefile / manifest for pushing controllers to cluster (kptdev#2694)

This lets us start to run these on the server, instead of just locally.

Introduce mapTaskToMutation function (kptdev#2744)

This is a small refactor so that we can reuse this logic in future.
  • Loading branch information
martinmaly committed Feb 18, 2022
1 parent 699a72e commit aa5d467
Show file tree
Hide file tree
Showing 32 changed files with 686 additions and 117 deletions.
8 changes: 8 additions & 0 deletions porch/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ BUILDDIR=$(CURDIR)/.build
CACHEDIR=$(CURDIR)/.cache
MODULES = $(shell find . -path ./.build -prune -o -path ./.cache -prune -o -name 'go.mod' -print)

# GCP project to use for development
GCP_PROJECT_ID ?= $(shell gcloud config get-value project)

.PHONY: all
all: stop network start-etcd start-kube-apiserver start-function-runner run-local

Expand Down Expand Up @@ -125,3 +128,8 @@ fix-headers:

.PHONY: fix-all
fix-all: fix-headers fmt tidy

.PHONY: push-images
push-images:
hack/build-image.sh --project $(GCP_PROJECT_ID) --push
make -C controllers/ push-image
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
54 changes: 54 additions & 0 deletions porch/controllers/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# 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.

FROM golang:1.17-bullseye as builder

WORKDIR /workspace
COPY go.mod go.sum ./
COPY porch/api/go.mod porch/api/go.sum porch/api/
COPY porch/controllers/go.mod porch/controllers/go.sum porch/controllers/
COPY porch/controllers/remoterootsync/go.mod porch/controllers/remoterootsync/go.sum porch/controllers/remoterootsync/
COPY porch/repository/go.mod porch/repository/go.sum porch/repository/

WORKDIR /workspace/porch/controllers/remoterootsync/
RUN go mod download
# Prebuild some libraries to warm the cache
RUN CGO_ENABLED=0 go build -v \
k8s.io/klog/v2 \
k8s.io/klog/v2/klogr \
k8s.io/client-go/plugin/pkg/client/auth \
sigs.k8s.io/controller-runtime \
sigs.k8s.io/controller-runtime/pkg/client \
sigs.k8s.io/controller-runtime/pkg/controller/controllerutil \
k8s.io/client-go/kubernetes \
go.opentelemetry.io/otel \
cloud.google.com/go/container/apiv1 \
github.com/google/go-containerregistry/pkg/gcrane \
github.com/google/go-containerregistry/pkg/v1 \
github.com/google/go-containerregistry/pkg/v1/cache \
k8s.io/client-go/discovery/cached

WORKDIR /workspace
COPY porch/api/ porch/api/
COPY porch/controllers/ porch/controllers/
COPY porch/repository/ porch/repository/

WORKDIR /workspace/porch/controllers/remoterootsync/
RUN CGO_ENABLED=0 go build -o /porch-controllers -v .

FROM gcr.io/distroless/static
WORKDIR /data
COPY --from=builder /porch-controllers /porch-controllers

ENTRYPOINT ["/porch-controllers"]
20 changes: 20 additions & 0 deletions porch/controllers/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# 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.

# GCP project to use for development
GCP_PROJECT_ID ?= $(shell gcloud config get-value project)

.PHONY: push-image
push-image:
cd ../..; docker buildx build --push --tag gcr.io/${GCP_PROJECT_ID}/porch-controllers:latest -f porch/controllers/Dockerfile .
83 changes: 83 additions & 0 deletions porch/controllers/config/deploy/manifest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# 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.

apiVersion: v1
kind: Namespace
metadata:
name: porch-system

---

kind: ServiceAccount
apiVersion: v1
metadata:
name: porch-controllers
namespace: porch-system

---

apiVersion: apps/v1
kind: Deployment
metadata:
name: porch-controllers
namespace: porch-system
labels:
k8s-app: "porch-controllers"
spec:
replicas: 1
selector:
matchLabels:
k8s-app: "porch-controllers"
template:
metadata:
labels:
k8s-app: "porch-controllers"
spec:
serviceAccountName: porch-controllers
containers:
- name: porch-controllers
# Update to the image of your porch-controllers build.
image: gcr.io/example-google-project-id/porch-controllers:latest

---

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: porch-controllers
rules:
- apiGroups: ["config.porch.kpt.dev"]
resources: ["repositories"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: ["config.cloud.google.com"]
resources: ["remoterootsyncsets"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: ["config.cloud.google.com"]
resources: ["remoterootsyncsets/status"]
verbs: ["get", "list", "watch", "create", "update", "patch"]

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: porch-system:porch-controllers
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: porch-controllers
subjects:
- kind: ServiceAccount
name: porch-controllers
namespace: porch-system
2 changes: 1 addition & 1 deletion porch/controllers/remoterootsync/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ GCP_PROJECT_ID ?= $(shell gcloud config get-value project)

.PHONY: run-local
run-local:
GCP_PROJECT_ID=${GCP_PROJECT_ID} HACK_ENABLE_LOOPBACK=1 go run .
GCP_PROJECT_ID=${GCP_PROJECT_ID} HACK_ENABLE_LOOPBACK=1 go run .
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,26 @@ type RemoteRootSyncSet struct {
Status RemoteRootSyncSetStatus `json:"status,omitempty"`
}

func (o *RemoteRootSyncSet) GetSpec() *RemoteRootSyncSetSpec {
if o == nil {
return nil
}
return &o.Spec
}

// RemoteRootSyncSetSpec defines the desired state of RemoteRootSync
type RemoteRootSyncSetSpec struct {
ClusterRefs []*ClusterRef `json:"clusterRefs,omitempty"`
Template *RootSyncTemplate `json:"template,omitempty"`
}

func (o *RemoteRootSyncSetSpec) GetTemplate() *RootSyncTemplate {
if o == nil {
return nil
}
return o.Template
}

type ClusterRef struct {
ApiVersion string `json:"apiVersion,omitempty"`
Kind string `json:"kind,omitempty"`
Expand All @@ -61,10 +75,24 @@ type RootSyncTemplate struct {
OCI *OCISpec `json:"oci,omitempty"`
}

func (o *RootSyncTemplate) GetOCI() *OCISpec {
if o == nil {
return nil
}
return o.OCI
}

type OCISpec struct {
Repository string `json:"repository,omitempty"`
}

func (o *OCISpec) GetRepository() string {
if o == nil {
return ""
}
return o.Repository
}

// RootSyncSetStatus defines the observed state of RootSyncSet
type RemoteRootSyncSetStatus struct {
Targets []TargetStatus `json:"targets,omitempty"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,15 @@ func (r *RemoteRootSyncSetReconciler) applyToClusterRef(ctx context.Context, sub
}

// TODO: Cache applyset
patchOptions := metav1.PatchOptions{FieldManager: "remoterootsync-" + subject.GetNamespace() + "-" + subject.GetName()}
patchOptions := metav1.PatchOptions{
FieldManager: "remoterootsync-" + subject.GetNamespace() + "-" + subject.GetName(),
}

// We force to overcome errors like: Apply failed with 1 conflict: conflict with "kubectl-client-side-apply" using apps/v1: .spec.template.spec.containers[name="porch-server"].image
// TODO: How to handle this better
force := true
patchOptions.Force = &force

applyset, err := applyset.New(applyset.Options{
RESTMapper: restMapper,
Client: client,
Expand All @@ -233,14 +241,17 @@ func (r *RemoteRootSyncSetReconciler) applyToClusterRef(ctx context.Context, sub

// BuildObjectsToApply config root sync
func (r *RemoteRootSyncSetReconciler) BuildObjectsToApply(ctx context.Context, subject *api.RemoteRootSyncSet) ([]*unstructured.Unstructured, error) {
// TODO: stop hard-coding the image source; get from a deployment instead
gcpProjectID := os.Getenv("GCP_PROJECT_ID")
imageName := oci.ImageTagName{
Image: "us-west1-docker.pkg.dev/" + gcpProjectID + "/deployment/myfirstnginx",
Tag: "v1",
repository := subject.GetSpec().GetTemplate().GetOCI().GetRepository()
if repository == "" {
return nil, fmt.Errorf("spec.template.oci.repository is not set")
}
imageName, err := oci.ParseImageTagName(repository)
if err != nil {
return nil, fmt.Errorf("unable to parse image %q: %w", repository, err)
}
klog.Infof("image name %s -> %#v", repository, *imageName)

digest, err := r.ociStorage.LookupImageTag(ctx, imageName)
digest, err := r.ociStorage.LookupImageTag(ctx, *imageName)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -279,12 +290,6 @@ func (r *RemoteRootSyncSetReconciler) BuildObjectsToApply(ctx context.Context, s
return nil, fmt.Errorf("error parsing yaml from %s: %w", item.Path, err)
}

// Hack: default namespace until we populate the namespace in our packages
if o.GetNamespace() == "" {
klog.Warningf("HACK: setting namespace to default")
o.SetNamespace("default")
}

// TODO: sync with kpt logic; skip objects marked with the local-only annotation
objects = append(objects, o)
}
Expand Down
Loading

0 comments on commit aa5d467

Please sign in to comment.