pull/2151/merge
Maciej Kwiek 9 years ago committed by GitHub
commit 2af0551d9f

1
.gitignore vendored

@ -6,6 +6,7 @@ _dist/
_proto/*.pb.go
bin/
rootfs/tiller
rootfs/rudder
vendor/
*.exe
.idea/

@ -1,9 +1,10 @@
DOCKER_REGISTRY ?= gcr.io
IMAGE_PREFIX ?= kubernetes-helm
SHORT_NAME ?= tiller
TARGETS = darwin/amd64 linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64le windows/amd64
DIST_DIRS = find * -type d -exec
APP = helm
DOCKER_REGISTRY ?= gcr.io
IMAGE_PREFIX ?= kubernetes-helm
SHORT_NAME ?= tiller
SHORT_NAME_RUDDER ?= rudder
TARGETS = darwin/amd64 linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64le windows/amd64
DIST_DIRS = find * -type d -exec
APP = helm
# go option
GO ?= go
@ -60,12 +61,20 @@ docker-binary: BINDIR = ./rootfs
docker-binary: GOFLAGS += -a -installsuffix cgo
docker-binary:
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 $(GO) build -o $(BINDIR)/tiller $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)' k8s.io/helm/cmd/tiller
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 $(GO) build -o $(BINDIR)/rudder $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)' k8s.io/helm/cmd/rudder
.PHONY: docker-build
docker-build: check-docker docker-binary
docker build --rm -t ${IMAGE} rootfs
docker tag ${IMAGE} ${MUTABLE_IMAGE}
.PHONY: docker-build-experimental
docker-build-experimental: check-docker docker-binary
docker build --rm -t ${IMAGE} rootfs -f rootfs/Dockerfile.experimental
docker tag ${IMAGE} ${MUTABLE_IMAGE}
docker build --rm -t ${IMAGE_RUDDER} rootfs -f rootfs/Dockerfile.rudder
docker tag ${IMAGE_RUDDER} ${MUTABLE_IMAGE_RUDDER}
.PHONY: test
test: build
test: TESTFLAGS += -race -v

@ -0,0 +1,91 @@
syntax = "proto3";
package hapi.release;
import "hapi/release/release.proto";
option go_package = "release";
service ReleaseModuleService {
rpc Version(VersionReleaseRequest) returns (VersionReleaseResponse) {
}
// InstallRelease requests installation of a chart as a new release.
rpc InstallRelease(InstallReleaseRequest) returns (InstallReleaseResponse) {
}
// DeleteRelease requests deletion of a named release.
rpc DeleteRelease(DeleteReleaseRequest) returns (DeleteReleaseResponse) {
}
// RollbackRelease rolls back a release to a previous version.
rpc RollbackRelease(RollbackReleaseRequest) returns (RollbackReleaseResponse) {
}
// UpgradeRelease updates release content.
rpc UpgradeRelease(UpgradeReleaseRequest) returns (UpgradeReleaseResponse) {
}
}
message Result {
enum Status {
// No status set
UNKNOWN = 0;
// Operation was successful
SUCCESS = 1;
// Operation had no results (e.g. upgrade identical, rollback to same, delete non-existent)
UNCHANGED = 2;
// Operation failed
ERROR = 3;
}
string info = 1;
repeated string log = 2;
}
message VersionReleaseRequest {
}
message VersionReleaseResponse {
string name = 1; // The canonical name of the release module
string version = 2; // The version of the release module
}
message InstallReleaseRequest {
hapi.release.Release release = 1;
}
message InstallReleaseResponse {
hapi.release.Release release = 1;
Result result = 2;
}
message DeleteReleaseRequest {
hapi.release.Release release = 1;
}
message DeleteReleaseResponse {
hapi.release.Release release = 1;
Result result = 2;
}
message UpgradeReleaseRequest{
hapi.release.Release current = 1;
hapi.release.Release target = 2;
int64 Timeout = 3;
bool Wait = 4;
bool Recreate = 5;
}
message UpgradeReleaseResponse{
hapi.release.Release release = 1;
Result result = 2;
}
message RollbackReleaseRequest{
hapi.release.Release current = 1;
hapi.release.Release target = 2;
int64 Timeout = 3;
bool Wait = 4;
bool Recreate = 5;
}
message RollbackReleaseResponse{
hapi.release.Release release = 1;
Result result = 2;
}

@ -0,0 +1,132 @@
/*
Copyright 2017 The Kubernetes Authors All rights reserved.
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 main // import "k8s.io/helm/cmd/rudder"
import (
"bytes"
"fmt"
"strings"
"github.com/Mirantis/k8s-appcontroller/cmd/format"
"github.com/technosophos/moniker"
"google.golang.org/grpc/grpclog"
"k8s.io/helm/pkg/proto/hapi/chart"
"k8s.io/helm/pkg/proto/hapi/release"
"k8s.io/helm/pkg/releaseutil"
)
type Dependency struct {
Name string
Child string
Parent string
}
func (d Dependency) String() string {
return fmt.Sprintf(`apiVersion: appcontroller.k8s/v1alpha1
kind: Dependency
metadata:
name: %s
parent: %s
child: %s`, d.Name, d.Parent, d.Child)
}
func wrapManifest(r *release.Release) (*bytes.Buffer, error) {
b := bytes.NewBuffer(nil)
var err error
sep := "\n---\n"
manifests, err := releaseutil.SplitManifestsWithHeads(r.Manifest)
if err != nil {
grpclog.Printf("Could not split manifest")
return nil, err
}
for _, m := range manifests {
grpclog.Printf("Trying to wrap %s", m.Metadata.Name)
wrapped, err := format.Yaml{}.Wrap(getInput(m.Content, 2))
if err != nil {
grpclog.Printf("didn't wrap %s: %s", m.Metadata.Name, err)
//TODO: should we return b here?
return nil, err
}
grpclog.Printf("wrapped %s", m.Metadata.Name)
b.WriteString(wrapped)
b.WriteString(sep)
}
deps := getDependencies(r.Chart, manifests)
for _, d := range deps {
b.WriteString(d.String())
b.WriteString(sep)
}
return b, err
}
func getInput(in string, indent int) string {
spaces := strings.Repeat(" ", indent)
result := spaces + strings.Replace(in, "\n", "\n"+spaces, -1)
return result
}
func getDependencies(ch *chart.Chart, manifests []releaseutil.Manifest) []Dependency {
dependencies := []Dependency{}
for _, dep := range ch.Dependencies {
dependencies = append(dependencies, getDependencies(dep, manifests)...)
dependencies = append(dependencies, getInterChartDependencies(ch, dep, manifests)...)
}
return dependencies
}
func getInterChartDependencies(child, parent *chart.Chart, manifests []releaseutil.Manifest) []Dependency {
parentNames := []string{}
childNames := []string{}
for _, m := range manifests {
kind := m.Kind
name := m.Metadata.Name
grpclog.Printf("comparing %s and %s with %s/%s", child.Metadata.Name, parent.Metadata.Name, kind, name)
//so hacky I'm gonna cry. need to find a better way
//I had to remove first segment of helm release name for this to work (chart names were truncated from release name)
if strings.Contains(name, parent.Metadata.Name) {
grpclog.Printf("adding %s to parents", strings.ToLower(kind)+"/"+name)
parentNames = append(parentNames, strings.ToLower(kind)+"/"+name)
}
if strings.Contains(name, child.Metadata.Name) {
grpclog.Printf("adding %s to children", strings.ToLower(kind)+"/"+name)
childNames = append(childNames, strings.ToLower(kind)+"/"+name)
}
}
deps := make([]Dependency, 0, len(parentNames)*len(childNames))
for _, parent := range parentNames {
for _, child := range childNames {
namer := moniker.New()
deps = append(deps, Dependency{
Name: namer.NameSep("-"),
Child: child,
Parent: parent,
})
}
}
return deps
}

@ -0,0 +1,99 @@
/*
Copyright 2017 The Kubernetes Authors All rights reserved.
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 main // import "k8s.io/helm/cmd/rudder"
import (
"bytes"
"fmt"
"net"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/grpclog"
"k8s.io/helm/pkg/kube"
"k8s.io/helm/pkg/proto/hapi/release"
"k8s.io/helm/pkg/rudder"
"k8s.io/helm/pkg/version"
)
var kubeClient = kube.New(nil)
func main() {
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", rudder.GrpcPort))
if err != nil {
grpclog.Fatalf("failed to listen: %v", err)
}
grpcServer := grpc.NewServer()
release.RegisterReleaseModuleServiceServer(grpcServer, &ReleaseModuleServiceServer{})
grpclog.Print("Server starting")
grpcServer.Serve(lis)
grpclog.Print("Server started")
}
// ReleaseModuleServiceServer provides implementation for release.ReleaseModuleServiceServer
type ReleaseModuleServiceServer struct{}
// Version is not yet implemented
func (r *ReleaseModuleServiceServer) Version(ctx context.Context, in *release.VersionReleaseRequest) (*release.VersionReleaseResponse, error) {
grpclog.Print("version")
return &release.VersionReleaseResponse{
Name: "helm-rudder-native",
Version: version.Version,
}, nil
}
// InstallRelease creates a release using kubeClient.Create
func (r *ReleaseModuleServiceServer) InstallRelease(ctx context.Context, in *release.InstallReleaseRequest) (*release.InstallReleaseResponse, error) {
grpclog.Print("install")
b, err := wrapManifest(in.Release)
if err != nil {
grpclog.Printf("error wrapping release: %s", err)
}
err = kubeClient.Create(in.Release.Namespace, b, 500, false)
if err != nil {
grpclog.Printf("error when creating release: %s", err)
}
return &release.InstallReleaseResponse{}, err
}
// DeleteRelease is not implemented
func (r *ReleaseModuleServiceServer) DeleteRelease(ctx context.Context, in *release.DeleteReleaseRequest) (*release.DeleteReleaseResponse, error) {
grpclog.Print("delete")
return nil, nil
}
// RollbackRelease is not implemented
func (r *ReleaseModuleServiceServer) RollbackRelease(ctx context.Context, in *release.RollbackReleaseRequest) (*release.RollbackReleaseResponse, error) {
grpclog.Print("rollback")
c := bytes.NewBufferString(in.Current.Manifest)
t := bytes.NewBufferString(in.Target.Manifest)
err := kubeClient.Update(in.Target.Namespace, c, t, in.Recreate, in.Timeout, in.Wait)
return &release.RollbackReleaseResponse{}, err
}
// UpgradeRelease upgrades manifests using kubernetes client
func (r *ReleaseModuleServiceServer) UpgradeRelease(ctx context.Context, in *release.UpgradeReleaseRequest) (*release.UpgradeReleaseResponse, error) {
grpclog.Print("upgrade")
c := bytes.NewBufferString(in.Current.Manifest)
t := bytes.NewBufferString(in.Target.Manifest)
err := kubeClient.Update(in.Target.Namespace, c, t, in.Recreate, in.Timeout, in.Wait)
// upgrade response object should be changed to include status
return &release.UpgradeReleaseResponse{}, err
}

@ -52,11 +52,12 @@ var rootServer = tiller.NewServer()
var env = environment.New()
var (
grpcAddr = ":44134"
probeAddr = ":44135"
traceAddr = ":44136"
enableTracing = false
store = storageConfigMap
grpcAddr = ":44134"
probeAddr = ":44135"
traceAddr = ":44136"
enableTracing = false
store = storageConfigMap
remoteReleaseModules = false
)
const globalUsage = `The Kubernetes Helm server.
@ -82,6 +83,7 @@ func main() {
p.StringVarP(&grpcAddr, "listen", "l", ":44134", "address:port to listen on")
p.StringVar(&store, "storage", storageConfigMap, "storage driver to use. One of 'configmap' or 'memory'")
p.BoolVar(&enableTracing, "trace", false, "enable rpc tracing")
p.BoolVar(&remoteReleaseModules, "experimental-release", false, "enable experimental release modules")
if err := rootCommand.Execute(); err != nil {
fmt.Fprint(os.Stderr, err)
@ -121,7 +123,7 @@ func start(c *cobra.Command, args []string) {
srvErrCh := make(chan error)
probeErrCh := make(chan error)
go func() {
svc := tiller.NewReleaseServer(env, clientset)
svc := tiller.NewReleaseServer(env, clientset, remoteReleaseModules)
services.RegisterReleaseServiceServer(rootServer, svc)
if err := rootServer.Serve(lstn); err != nil {
srvErrCh <- err

4
glide.lock generated

@ -501,6 +501,10 @@ imports:
- third_party/forked/golang/netutil
- third_party/forked/golang/reflect
- third_party/forked/golang/template
- name: github.com/Mirantis/k8s-appcontroller
version: cfc62d2de68d9e7f52c9c84f976dc93502bf59ab
subpackages:
- cmd/format
testImports:
- name: github.com/pmezard/go-difflib
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d

@ -69,3 +69,5 @@ import:
version: ~0.1.0
- package: github.com/naoina/go-stringutil
version: ~0.1.0
- package: github.com/Mirantis/k8s-appcontroller
version: ~0.5.0

@ -8,6 +8,7 @@ Package release is a generated protocol buffer package.
It is generated from these files:
hapi/release/hook.proto
hapi/release/info.proto
hapi/release/modules.proto
hapi/release/release.proto
hapi/release/status.proto
hapi/release/test_run.proto
@ -16,6 +17,17 @@ It is generated from these files:
It has these top-level messages:
Hook
Info
Result
VersionReleaseRequest
VersionReleaseResponse
InstallReleaseRequest
InstallReleaseResponse
DeleteReleaseRequest
DeleteReleaseResponse
UpgradeReleaseRequest
UpgradeReleaseResponse
RollbackReleaseRequest
RollbackReleaseResponse
Release
Status
TestRun

@ -0,0 +1,526 @@
// Code generated by protoc-gen-go.
// source: hapi/release/modules.proto
// DO NOT EDIT!
package release
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
type Result_Status int32
const (
// No status set
Result_UNKNOWN Result_Status = 0
// Operation was successful
Result_SUCCESS Result_Status = 1
// Operation had no results (e.g. upgrade identical, rollback to same, delete non-existent)
Result_UNCHANGED Result_Status = 2
// Operation failed
Result_ERROR Result_Status = 3
)
var Result_Status_name = map[int32]string{
0: "UNKNOWN",
1: "SUCCESS",
2: "UNCHANGED",
3: "ERROR",
}
var Result_Status_value = map[string]int32{
"UNKNOWN": 0,
"SUCCESS": 1,
"UNCHANGED": 2,
"ERROR": 3,
}
func (x Result_Status) String() string {
return proto.EnumName(Result_Status_name, int32(x))
}
func (Result_Status) EnumDescriptor() ([]byte, []int) { return fileDescriptor2, []int{0, 0} }
type Result struct {
Info string `protobuf:"bytes,1,opt,name=info" json:"info,omitempty"`
Log []string `protobuf:"bytes,2,rep,name=log" json:"log,omitempty"`
}
func (m *Result) Reset() { *m = Result{} }
func (m *Result) String() string { return proto.CompactTextString(m) }
func (*Result) ProtoMessage() {}
func (*Result) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0} }
type VersionReleaseRequest struct {
}
func (m *VersionReleaseRequest) Reset() { *m = VersionReleaseRequest{} }
func (m *VersionReleaseRequest) String() string { return proto.CompactTextString(m) }
func (*VersionReleaseRequest) ProtoMessage() {}
func (*VersionReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{1} }
type VersionReleaseResponse struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Version string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"`
}
func (m *VersionReleaseResponse) Reset() { *m = VersionReleaseResponse{} }
func (m *VersionReleaseResponse) String() string { return proto.CompactTextString(m) }
func (*VersionReleaseResponse) ProtoMessage() {}
func (*VersionReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{2} }
type InstallReleaseRequest struct {
Release *Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
}
func (m *InstallReleaseRequest) Reset() { *m = InstallReleaseRequest{} }
func (m *InstallReleaseRequest) String() string { return proto.CompactTextString(m) }
func (*InstallReleaseRequest) ProtoMessage() {}
func (*InstallReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{3} }
func (m *InstallReleaseRequest) GetRelease() *Release {
if m != nil {
return m.Release
}
return nil
}
type InstallReleaseResponse struct {
Release *Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
Result *Result `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"`
}
func (m *InstallReleaseResponse) Reset() { *m = InstallReleaseResponse{} }
func (m *InstallReleaseResponse) String() string { return proto.CompactTextString(m) }
func (*InstallReleaseResponse) ProtoMessage() {}
func (*InstallReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{4} }
func (m *InstallReleaseResponse) GetRelease() *Release {
if m != nil {
return m.Release
}
return nil
}
func (m *InstallReleaseResponse) GetResult() *Result {
if m != nil {
return m.Result
}
return nil
}
type DeleteReleaseRequest struct {
Release *Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
}
func (m *DeleteReleaseRequest) Reset() { *m = DeleteReleaseRequest{} }
func (m *DeleteReleaseRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteReleaseRequest) ProtoMessage() {}
func (*DeleteReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{5} }
func (m *DeleteReleaseRequest) GetRelease() *Release {
if m != nil {
return m.Release
}
return nil
}
type DeleteReleaseResponse struct {
Release *Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
Result *Result `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"`
}
func (m *DeleteReleaseResponse) Reset() { *m = DeleteReleaseResponse{} }
func (m *DeleteReleaseResponse) String() string { return proto.CompactTextString(m) }
func (*DeleteReleaseResponse) ProtoMessage() {}
func (*DeleteReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{6} }
func (m *DeleteReleaseResponse) GetRelease() *Release {
if m != nil {
return m.Release
}
return nil
}
func (m *DeleteReleaseResponse) GetResult() *Result {
if m != nil {
return m.Result
}
return nil
}
type UpgradeReleaseRequest struct {
Current *Release `protobuf:"bytes,1,opt,name=current" json:"current,omitempty"`
Target *Release `protobuf:"bytes,2,opt,name=target" json:"target,omitempty"`
Timeout int64 `protobuf:"varint,3,opt,name=Timeout" json:"Timeout,omitempty"`
Wait bool `protobuf:"varint,4,opt,name=Wait" json:"Wait,omitempty"`
Recreate bool `protobuf:"varint,5,opt,name=Recreate" json:"Recreate,omitempty"`
}
func (m *UpgradeReleaseRequest) Reset() { *m = UpgradeReleaseRequest{} }
func (m *UpgradeReleaseRequest) String() string { return proto.CompactTextString(m) }
func (*UpgradeReleaseRequest) ProtoMessage() {}
func (*UpgradeReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{7} }
func (m *UpgradeReleaseRequest) GetCurrent() *Release {
if m != nil {
return m.Current
}
return nil
}
func (m *UpgradeReleaseRequest) GetTarget() *Release {
if m != nil {
return m.Target
}
return nil
}
type UpgradeReleaseResponse struct {
Release *Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
Result *Result `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"`
}
func (m *UpgradeReleaseResponse) Reset() { *m = UpgradeReleaseResponse{} }
func (m *UpgradeReleaseResponse) String() string { return proto.CompactTextString(m) }
func (*UpgradeReleaseResponse) ProtoMessage() {}
func (*UpgradeReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{8} }
func (m *UpgradeReleaseResponse) GetRelease() *Release {
if m != nil {
return m.Release
}
return nil
}
func (m *UpgradeReleaseResponse) GetResult() *Result {
if m != nil {
return m.Result
}
return nil
}
type RollbackReleaseRequest struct {
Current *Release `protobuf:"bytes,1,opt,name=current" json:"current,omitempty"`
Target *Release `protobuf:"bytes,2,opt,name=target" json:"target,omitempty"`
Timeout int64 `protobuf:"varint,3,opt,name=Timeout" json:"Timeout,omitempty"`
Wait bool `protobuf:"varint,4,opt,name=Wait" json:"Wait,omitempty"`
Recreate bool `protobuf:"varint,5,opt,name=Recreate" json:"Recreate,omitempty"`
}
func (m *RollbackReleaseRequest) Reset() { *m = RollbackReleaseRequest{} }
func (m *RollbackReleaseRequest) String() string { return proto.CompactTextString(m) }
func (*RollbackReleaseRequest) ProtoMessage() {}
func (*RollbackReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{9} }
func (m *RollbackReleaseRequest) GetCurrent() *Release {
if m != nil {
return m.Current
}
return nil
}
func (m *RollbackReleaseRequest) GetTarget() *Release {
if m != nil {
return m.Target
}
return nil
}
type RollbackReleaseResponse struct {
Release *Release `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"`
Result *Result `protobuf:"bytes,2,opt,name=result" json:"result,omitempty"`
}
func (m *RollbackReleaseResponse) Reset() { *m = RollbackReleaseResponse{} }
func (m *RollbackReleaseResponse) String() string { return proto.CompactTextString(m) }
func (*RollbackReleaseResponse) ProtoMessage() {}
func (*RollbackReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{10} }
func (m *RollbackReleaseResponse) GetRelease() *Release {
if m != nil {
return m.Release
}
return nil
}
func (m *RollbackReleaseResponse) GetResult() *Result {
if m != nil {
return m.Result
}
return nil
}
func init() {
proto.RegisterType((*Result)(nil), "hapi.release.Result")
proto.RegisterType((*VersionReleaseRequest)(nil), "hapi.release.VersionReleaseRequest")
proto.RegisterType((*VersionReleaseResponse)(nil), "hapi.release.VersionReleaseResponse")
proto.RegisterType((*InstallReleaseRequest)(nil), "hapi.release.InstallReleaseRequest")
proto.RegisterType((*InstallReleaseResponse)(nil), "hapi.release.InstallReleaseResponse")
proto.RegisterType((*DeleteReleaseRequest)(nil), "hapi.release.DeleteReleaseRequest")
proto.RegisterType((*DeleteReleaseResponse)(nil), "hapi.release.DeleteReleaseResponse")
proto.RegisterType((*UpgradeReleaseRequest)(nil), "hapi.release.UpgradeReleaseRequest")
proto.RegisterType((*UpgradeReleaseResponse)(nil), "hapi.release.UpgradeReleaseResponse")
proto.RegisterType((*RollbackReleaseRequest)(nil), "hapi.release.RollbackReleaseRequest")
proto.RegisterType((*RollbackReleaseResponse)(nil), "hapi.release.RollbackReleaseResponse")
proto.RegisterEnum("hapi.release.Result_Status", Result_Status_name, Result_Status_value)
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion3
// Client API for ReleaseModuleService service
type ReleaseModuleServiceClient interface {
Version(ctx context.Context, in *VersionReleaseRequest, opts ...grpc.CallOption) (*VersionReleaseResponse, error)
// InstallRelease requests installation of a chart as a new release.
InstallRelease(ctx context.Context, in *InstallReleaseRequest, opts ...grpc.CallOption) (*InstallReleaseResponse, error)
// DeleteRelease requests deletion of a named release.
DeleteRelease(ctx context.Context, in *DeleteReleaseRequest, opts ...grpc.CallOption) (*DeleteReleaseResponse, error)
// RollbackRelease rolls back a release to a previous version.
RollbackRelease(ctx context.Context, in *RollbackReleaseRequest, opts ...grpc.CallOption) (*RollbackReleaseResponse, error)
// UpgradeRelease updates release content.
UpgradeRelease(ctx context.Context, in *UpgradeReleaseRequest, opts ...grpc.CallOption) (*UpgradeReleaseResponse, error)
}
type releaseModuleServiceClient struct {
cc *grpc.ClientConn
}
func NewReleaseModuleServiceClient(cc *grpc.ClientConn) ReleaseModuleServiceClient {
return &releaseModuleServiceClient{cc}
}
func (c *releaseModuleServiceClient) Version(ctx context.Context, in *VersionReleaseRequest, opts ...grpc.CallOption) (*VersionReleaseResponse, error) {
out := new(VersionReleaseResponse)
err := grpc.Invoke(ctx, "/hapi.release.ReleaseModuleService/Version", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *releaseModuleServiceClient) InstallRelease(ctx context.Context, in *InstallReleaseRequest, opts ...grpc.CallOption) (*InstallReleaseResponse, error) {
out := new(InstallReleaseResponse)
err := grpc.Invoke(ctx, "/hapi.release.ReleaseModuleService/InstallRelease", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *releaseModuleServiceClient) DeleteRelease(ctx context.Context, in *DeleteReleaseRequest, opts ...grpc.CallOption) (*DeleteReleaseResponse, error) {
out := new(DeleteReleaseResponse)
err := grpc.Invoke(ctx, "/hapi.release.ReleaseModuleService/DeleteRelease", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *releaseModuleServiceClient) RollbackRelease(ctx context.Context, in *RollbackReleaseRequest, opts ...grpc.CallOption) (*RollbackReleaseResponse, error) {
out := new(RollbackReleaseResponse)
err := grpc.Invoke(ctx, "/hapi.release.ReleaseModuleService/RollbackRelease", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *releaseModuleServiceClient) UpgradeRelease(ctx context.Context, in *UpgradeReleaseRequest, opts ...grpc.CallOption) (*UpgradeReleaseResponse, error) {
out := new(UpgradeReleaseResponse)
err := grpc.Invoke(ctx, "/hapi.release.ReleaseModuleService/UpgradeRelease", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for ReleaseModuleService service
type ReleaseModuleServiceServer interface {
Version(context.Context, *VersionReleaseRequest) (*VersionReleaseResponse, error)
// InstallRelease requests installation of a chart as a new release.
InstallRelease(context.Context, *InstallReleaseRequest) (*InstallReleaseResponse, error)
// DeleteRelease requests deletion of a named release.
DeleteRelease(context.Context, *DeleteReleaseRequest) (*DeleteReleaseResponse, error)
// RollbackRelease rolls back a release to a previous version.
RollbackRelease(context.Context, *RollbackReleaseRequest) (*RollbackReleaseResponse, error)
// UpgradeRelease updates release content.
UpgradeRelease(context.Context, *UpgradeReleaseRequest) (*UpgradeReleaseResponse, error)
}
func RegisterReleaseModuleServiceServer(s *grpc.Server, srv ReleaseModuleServiceServer) {
s.RegisterService(&_ReleaseModuleService_serviceDesc, srv)
}
func _ReleaseModuleService_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(VersionReleaseRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ReleaseModuleServiceServer).Version(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hapi.release.ReleaseModuleService/Version",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ReleaseModuleServiceServer).Version(ctx, req.(*VersionReleaseRequest))
}
return interceptor(ctx, in, info, handler)
}
func _ReleaseModuleService_InstallRelease_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(InstallReleaseRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ReleaseModuleServiceServer).InstallRelease(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hapi.release.ReleaseModuleService/InstallRelease",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ReleaseModuleServiceServer).InstallRelease(ctx, req.(*InstallReleaseRequest))
}
return interceptor(ctx, in, info, handler)
}
func _ReleaseModuleService_DeleteRelease_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DeleteReleaseRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ReleaseModuleServiceServer).DeleteRelease(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hapi.release.ReleaseModuleService/DeleteRelease",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ReleaseModuleServiceServer).DeleteRelease(ctx, req.(*DeleteReleaseRequest))
}
return interceptor(ctx, in, info, handler)
}
func _ReleaseModuleService_RollbackRelease_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(RollbackReleaseRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ReleaseModuleServiceServer).RollbackRelease(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hapi.release.ReleaseModuleService/RollbackRelease",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ReleaseModuleServiceServer).RollbackRelease(ctx, req.(*RollbackReleaseRequest))
}
return interceptor(ctx, in, info, handler)
}
func _ReleaseModuleService_UpgradeRelease_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(UpgradeReleaseRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ReleaseModuleServiceServer).UpgradeRelease(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/hapi.release.ReleaseModuleService/UpgradeRelease",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ReleaseModuleServiceServer).UpgradeRelease(ctx, req.(*UpgradeReleaseRequest))
}
return interceptor(ctx, in, info, handler)
}
var _ReleaseModuleService_serviceDesc = grpc.ServiceDesc{
ServiceName: "hapi.release.ReleaseModuleService",
HandlerType: (*ReleaseModuleServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Version",
Handler: _ReleaseModuleService_Version_Handler,
},
{
MethodName: "InstallRelease",
Handler: _ReleaseModuleService_InstallRelease_Handler,
},
{
MethodName: "DeleteRelease",
Handler: _ReleaseModuleService_DeleteRelease_Handler,
},
{
MethodName: "RollbackRelease",
Handler: _ReleaseModuleService_RollbackRelease_Handler,
},
{
MethodName: "UpgradeRelease",
Handler: _ReleaseModuleService_UpgradeRelease_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: fileDescriptor2,
}
func init() { proto.RegisterFile("hapi/release/modules.proto", fileDescriptor2) }
var fileDescriptor2 = []byte{
// 523 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xd4, 0x55, 0xc1, 0x6e, 0xd3, 0x40,
0x10, 0x8d, 0xe3, 0x36, 0xa9, 0x27, 0x14, 0xac, 0x55, 0x9c, 0x5a, 0x3e, 0x45, 0x5b, 0x90, 0x72,
0x80, 0x44, 0x0a, 0x57, 0x2e, 0x90, 0x86, 0x16, 0x21, 0x5c, 0x69, 0x4d, 0x5a, 0xa9, 0x12, 0x12,
0xdb, 0x74, 0x08, 0x16, 0x1b, 0x3b, 0xac, 0xd7, 0x81, 0xdf, 0x83, 0xcf, 0xe1, 0x2b, 0x90, 0x1d,
0xbb, 0xaa, 0x17, 0xd3, 0x0a, 0x21, 0x45, 0xea, 0x29, 0x33, 0x9e, 0x97, 0xb7, 0x33, 0xcf, 0xb3,
0xcf, 0xe0, 0x7d, 0xe6, 0xab, 0x70, 0x24, 0x51, 0x20, 0x4f, 0x70, 0xb4, 0x8c, 0xaf, 0x52, 0x81,
0xc9, 0x70, 0x25, 0x63, 0x15, 0x93, 0x07, 0x59, 0x6d, 0x58, 0xd4, 0xbc, 0x2a, 0xb2, 0xf8, 0xdd,
0x20, 0xa9, 0x80, 0x16, 0xc3, 0x24, 0x15, 0x8a, 0x10, 0xd8, 0x09, 0xa3, 0x4f, 0xb1, 0x6b, 0xf4,
0x8d, 0x81, 0xc5, 0xf2, 0x98, 0xd8, 0x60, 0x8a, 0x78, 0xe1, 0x36, 0xfb, 0xe6, 0xc0, 0x62, 0x59,
0x48, 0x5f, 0x40, 0x2b, 0x50, 0x5c, 0xa5, 0x09, 0xe9, 0x40, 0x7b, 0xe6, 0xbf, 0xf5, 0x4f, 0xcf,
0x7d, 0xbb, 0x91, 0x25, 0xc1, 0x6c, 0x32, 0x99, 0x06, 0x81, 0x6d, 0x90, 0x7d, 0xb0, 0x66, 0xfe,
0xe4, 0xe4, 0xa5, 0x7f, 0x3c, 0x3d, 0xb2, 0x9b, 0xc4, 0x82, 0xdd, 0x29, 0x63, 0xa7, 0xcc, 0x36,
0xe9, 0x01, 0x38, 0x67, 0x28, 0x93, 0x30, 0x8e, 0xd8, 0xa6, 0x0b, 0x86, 0x5f, 0x53, 0x4c, 0x14,
0x7d, 0x0d, 0x3d, 0xbd, 0x90, 0xac, 0xe2, 0x28, 0xc1, 0xac, 0xad, 0x88, 0x2f, 0xb1, 0x6c, 0x2b,
0x8b, 0x89, 0x0b, 0xed, 0xf5, 0x06, 0xed, 0x36, 0xf3, 0xc7, 0x65, 0x4a, 0x4f, 0xc0, 0x79, 0x13,
0x25, 0x8a, 0x0b, 0x51, 0x3d, 0x80, 0x8c, 0xa0, 0x5d, 0x0c, 0x9e, 0x33, 0x75, 0xc6, 0xce, 0xf0,
0xa6, 0x46, 0xc3, 0x12, 0x5e, 0xa2, 0xe8, 0x37, 0xe8, 0xe9, 0x4c, 0x45, 0x47, 0xff, 0x4a, 0x45,
0x9e, 0x42, 0x4b, 0xe6, 0x1a, 0xe7, 0xdd, 0x76, 0xc6, 0x5d, 0x1d, 0x9f, 0xd5, 0x58, 0x81, 0xa1,
0xc7, 0xd0, 0x3d, 0x42, 0x81, 0x0a, 0xff, 0x77, 0x82, 0x35, 0x38, 0x1a, 0xd1, 0x76, 0x06, 0xf8,
0x61, 0x80, 0x33, 0x5b, 0x2d, 0x24, 0xbf, 0xaa, 0x19, 0x61, 0x9e, 0x4a, 0x89, 0x91, 0xba, 0xe3,
0xe0, 0x02, 0x45, 0x9e, 0x41, 0x4b, 0x71, 0xb9, 0xc0, 0xf2, 0xe0, 0xbf, 0xe0, 0x0b, 0x50, 0xb6,
0x17, 0xef, 0xc3, 0x25, 0xc6, 0xa9, 0x72, 0xcd, 0xbe, 0x31, 0x30, 0x59, 0x99, 0x66, 0x5b, 0x74,
0xce, 0x43, 0xe5, 0xee, 0xf4, 0x8d, 0xc1, 0x1e, 0xcb, 0x63, 0xe2, 0xc1, 0x1e, 0xc3, 0xb9, 0x44,
0xae, 0xd0, 0xdd, 0xcd, 0x9f, 0x5f, 0xe7, 0xd9, 0xdb, 0xd7, 0x47, 0xd8, 0x8e, 0x78, 0x3f, 0x0d,
0xe8, 0xb1, 0x58, 0x88, 0x4b, 0x3e, 0xff, 0x72, 0x6f, 0xd5, 0xfb, 0x0e, 0x07, 0x7f, 0xcc, 0xb0,
0x15, 0xf9, 0xc6, 0xbf, 0x4c, 0xe8, 0x16, 0x14, 0xef, 0x72, 0x47, 0x0c, 0x50, 0xae, 0xc3, 0x39,
0x92, 0x33, 0x68, 0x17, 0x06, 0x43, 0x0e, 0xab, 0x0c, 0xb5, 0x86, 0xe4, 0x3d, 0xbe, 0x1d, 0xb4,
0x99, 0x86, 0x36, 0xc8, 0x07, 0x78, 0x58, 0xb5, 0x09, 0x9d, 0xbe, 0xd6, 0x8e, 0x74, 0xfa, 0x7a,
0xa7, 0xa1, 0x0d, 0x72, 0x01, 0xfb, 0x95, 0x3b, 0x4c, 0x68, 0xf5, 0x8f, 0x75, 0x4e, 0xe1, 0x1d,
0xde, 0x8a, 0xb9, 0xe6, 0xfe, 0x08, 0x8f, 0xb4, 0xb7, 0x44, 0xb4, 0xb6, 0xea, 0x17, 0xd1, 0x7b,
0x72, 0x07, 0xea, 0xa6, 0x38, 0xd5, 0x5b, 0xa4, 0x8b, 0x53, 0x6b, 0x13, 0xba, 0x38, 0xf5, 0x17,
0x91, 0x36, 0x5e, 0x59, 0x17, 0xe5, 0x96, 0x5c, 0xb6, 0xf2, 0xaf, 0xd9, 0xf3, 0xdf, 0x01, 0x00,
0x00, 0xff, 0xff, 0x6c, 0xb6, 0x1e, 0x06, 0x15, 0x07, 0x00, 0x00,
}

@ -40,7 +40,7 @@ type Release struct {
func (m *Release) Reset() { *m = Release{} }
func (m *Release) String() string { return proto.CompactTextString(m) }
func (*Release) ProtoMessage() {}
func (*Release) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0} }
func (*Release) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{0} }
func (m *Release) GetInfo() *Info {
if m != nil {
@ -74,9 +74,9 @@ func init() {
proto.RegisterType((*Release)(nil), "hapi.release.Release")
}
func init() { proto.RegisterFile("hapi/release/release.proto", fileDescriptor2) }
func init() { proto.RegisterFile("hapi/release/release.proto", fileDescriptor3) }
var fileDescriptor2 = []byte{
var fileDescriptor3 = []byte{
// 256 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x64, 0x90, 0xbf, 0x4e, 0xc3, 0x40,
0x0c, 0xc6, 0x95, 0x36, 0x7f, 0x1a, 0xc3, 0x82, 0x07, 0xb0, 0x22, 0x86, 0x88, 0x01, 0x22, 0x86,

@ -51,7 +51,7 @@ var Status_Code_value = map[string]int32{
func (x Status_Code) String() string {
return proto.EnumName(Status_Code_name, int32(x))
}
func (Status_Code) EnumDescriptor() ([]byte, []int) { return fileDescriptor3, []int{0, 0} }
func (Status_Code) EnumDescriptor() ([]byte, []int) { return fileDescriptor4, []int{0, 0} }
// Status defines the status of a release.
type Status struct {
@ -67,7 +67,7 @@ type Status struct {
func (m *Status) Reset() { *m = Status{} }
func (m *Status) String() string { return proto.CompactTextString(m) }
func (*Status) ProtoMessage() {}
func (*Status) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{0} }
func (*Status) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{0} }
func (m *Status) GetLastTestSuiteRun() *TestSuite {
if m != nil {
@ -81,9 +81,9 @@ func init() {
proto.RegisterEnum("hapi.release.Status_Code", Status_Code_name, Status_Code_value)
}
func init() { proto.RegisterFile("hapi/release/status.proto", fileDescriptor3) }
func init() { proto.RegisterFile("hapi/release/status.proto", fileDescriptor4) }
var fileDescriptor3 = []byte{
var fileDescriptor4 = []byte{
// 291 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x54, 0x90, 0xdf, 0x6a, 0xc2, 0x30,
0x14, 0xc6, 0x57, 0xad, 0x3a, 0x8f, 0x22, 0x21, 0x1b, 0xac, 0xca, 0x06, 0xc5, 0xab, 0xde, 0xac,

@ -36,7 +36,7 @@ var TestRun_Status_value = map[string]int32{
func (x TestRun_Status) String() string {
return proto.EnumName(TestRun_Status_name, int32(x))
}
func (TestRun_Status) EnumDescriptor() ([]byte, []int) { return fileDescriptor4, []int{0, 0} }
func (TestRun_Status) EnumDescriptor() ([]byte, []int) { return fileDescriptor5, []int{0, 0} }
type TestRun struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
@ -49,7 +49,7 @@ type TestRun struct {
func (m *TestRun) Reset() { *m = TestRun{} }
func (m *TestRun) String() string { return proto.CompactTextString(m) }
func (*TestRun) ProtoMessage() {}
func (*TestRun) Descriptor() ([]byte, []int) { return fileDescriptor4, []int{0} }
func (*TestRun) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{0} }
func (m *TestRun) GetStartedAt() *google_protobuf.Timestamp {
if m != nil {
@ -70,9 +70,9 @@ func init() {
proto.RegisterEnum("hapi.release.TestRun_Status", TestRun_Status_name, TestRun_Status_value)
}
func init() { proto.RegisterFile("hapi/release/test_run.proto", fileDescriptor4) }
func init() { proto.RegisterFile("hapi/release/test_run.proto", fileDescriptor5) }
var fileDescriptor4 = []byte{
var fileDescriptor5 = []byte{
// 265 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x84, 0x8f, 0x41, 0x4b, 0xfb, 0x40,
0x14, 0xc4, 0xff, 0xc9, 0xbf, 0x26, 0x64, 0x53, 0x24, 0xec, 0x29, 0x54, 0xc1, 0xd0, 0x53, 0x4e,

@ -27,7 +27,7 @@ type TestSuite struct {
func (m *TestSuite) Reset() { *m = TestSuite{} }
func (m *TestSuite) String() string { return proto.CompactTextString(m) }
func (*TestSuite) ProtoMessage() {}
func (*TestSuite) Descriptor() ([]byte, []int) { return fileDescriptor5, []int{0} }
func (*TestSuite) Descriptor() ([]byte, []int) { return fileDescriptor6, []int{0} }
func (m *TestSuite) GetStartedAt() *google_protobuf.Timestamp {
if m != nil {
@ -54,9 +54,9 @@ func init() {
proto.RegisterType((*TestSuite)(nil), "hapi.release.TestSuite")
}
func init() { proto.RegisterFile("hapi/release/test_suite.proto", fileDescriptor5) }
func init() { proto.RegisterFile("hapi/release/test_suite.proto", fileDescriptor6) }
var fileDescriptor5 = []byte{
var fileDescriptor6 = []byte{
// 207 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x84, 0x8f, 0xc1, 0x4a, 0x86, 0x40,
0x14, 0x85, 0x31, 0x21, 0x71, 0x74, 0x35, 0x10, 0x88, 0x11, 0x49, 0x2b, 0x57, 0x33, 0x60, 0xab,

@ -19,6 +19,8 @@ package releaseutil
import (
"fmt"
"strings"
"github.com/ghodss/yaml"
)
// SimpleHead defines what the structure of the head of a manifest file
@ -38,11 +40,39 @@ func SplitManifests(bigfile string) map[string]string {
// array of YAML docs. In the current implementation, the file name is just
// a place holder, and doesn't have any further meaning.
sep := "\n---\n"
cutset := " \n\t"
tpl := "manifest-%d"
res := map[string]string{}
tmp := strings.Split(bigfile, sep)
for i, d := range tmp {
res[fmt.Sprintf(tpl, i)] = d
if len(strings.Trim(d, cutset)) > 0 {
res[fmt.Sprintf(tpl, i)] = d
}
}
return res
}
// Manifest reperestens a single manifest content with SimpleHead added for additional metadata
type Manifest struct {
SimpleHead
Content string
}
// SplitManifestsWithHeads
func SplitManifestsWithHeads(bigfile string) ([]Manifest, error) {
raws := SplitManifests(bigfile)
result := make([]Manifest, 0, len(raws))
var err error
for _, raw := range raws {
var head SimpleHead
err = yaml.Unmarshal([]byte(raw), &head)
result = append(result, Manifest{
Content: raw,
SimpleHead: head,
})
}
return result, err
}

@ -0,0 +1,63 @@
/*
Copyright 2017 The Kubernetes Authors All rights reserved.
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 releaseutil
import (
"testing"
)
func TestSplitManifestsWithHeads(t *testing.T) {
rawManifest := `kind: TestKind
apiVersion: v1
metadata:
name: TestName
annotations:
key1: value1
key2: value2`
rawManifests := rawManifest + "\n---\n" + rawManifest
manifests, err := SplitManifestsWithHeads(rawManifests)
if err != nil {
t.Errorf("Expected error to be nil, got %s", err)
}
if len(manifests) != 2 {
t.Errorf("Expected manifests length to be 2, got %d", len(manifests))
}
for _, m := range manifests {
if m.SimpleHead.Kind != "TestKind" {
t.Errorf("Expected Kind to be TestKind, got %s", m.SimpleHead.Kind)
}
if m.SimpleHead.Version != "v1" {
t.Errorf("Expected Version to be v1, got %s", m.SimpleHead.Version)
}
if m.SimpleHead.Metadata.Name != "TestName" {
t.Errorf("Expected Name to be TestName, got %s", m.SimpleHead.Metadata.Name)
}
if val1, ok := m.SimpleHead.Metadata.Annotations["key1"]; !ok || val1 != "value1" {
t.Errorf("Expected annotation key1 to be value1, got %s", val1)
}
if val2, ok := m.SimpleHead.Metadata.Annotations["key2"]; !ok || val2 != "value2" {
t.Errorf("Expected annotation key2 to be value2, got %s", val2)
}
if m.Content != rawManifest {
t.Errorf("Expected Content to be equal to original, got %s", m.Content)
}
}
}

@ -0,0 +1,68 @@
/*
Copyright 2017 The Kubernetes Authors All rights reserved.
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 rudder // import "k8s.io/helm/pkg/rudder"
import (
"fmt"
"golang.org/x/net/context"
"google.golang.org/grpc"
"k8s.io/helm/pkg/proto/hapi/release"
)
// GrpcPort specifies port on which rudder will spawn a server
const (
GrpcPort = 10001
)
var grpcAddr = fmt.Sprintf("127.0.0.1:%d", GrpcPort)
// InstallRelease calls Rudder InstallRelease method which should create provided release
func InstallRelease(rel *release.InstallReleaseRequest) (*release.InstallReleaseResponse, error) {
//TODO(mkwiek): parametrize this
conn, err := grpc.Dial(grpcAddr, grpc.WithInsecure())
if err != nil {
return nil, err
}
defer conn.Close()
client := release.NewReleaseModuleServiceClient(conn)
return client.InstallRelease(context.Background(), rel)
}
// UpgradeRelease calls Rudder UpgradeRelease method which should perform update
func UpgradeRelease(req *release.UpgradeReleaseRequest) (*release.UpgradeReleaseResponse, error) {
conn, err := grpc.Dial(grpcAddr, grpc.WithInsecure())
if err != nil {
return nil, err
}
defer conn.Close()
client := release.NewReleaseModuleServiceClient(conn)
return client.UpgradeRelease(context.Background(), req)
}
// RollbackRelease calls Rudder RollbackRelease method which should perform update
func RollbackRelease(req *release.RollbackReleaseRequest) (*release.RollbackReleaseResponse, error) {
conn, err := grpc.Dial(grpcAddr, grpc.WithInsecure())
if err != nil {
return nil, err
}
defer conn.Close()
client := release.NewReleaseModuleServiceClient(conn)
return client.RollbackRelease(context.Background(), req)
}

@ -0,0 +1,90 @@
/*
Copyright 2017 The Kubernetes Authors All rights reserved.
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 tiller
import (
"bytes"
"k8s.io/helm/pkg/proto/hapi/release"
"k8s.io/helm/pkg/proto/hapi/services"
"k8s.io/helm/pkg/rudder"
"k8s.io/helm/pkg/tiller/environment"
)
// ReleaseModule is an interface that allows ReleaseServer to run operations on release via either local implementation or Rudder service
type ReleaseModule interface {
Create(r *release.Release, req *services.InstallReleaseRequest, env *environment.Environment) error
Update(current, target *release.Release, req *services.UpdateReleaseRequest, env *environment.Environment) error
Rollback(current, target *release.Release, req *services.RollbackReleaseRequest, env *environment.Environment) error
}
// LocalReleaseModule is a local implementation of ReleaseModule
type LocalReleaseModule struct{}
// Create creates a release via kubeclient from provided environment
func (m *LocalReleaseModule) Create(r *release.Release, req *services.InstallReleaseRequest, env *environment.Environment) error {
b := bytes.NewBufferString(r.Manifest)
return env.KubeClient.Create(r.Namespace, b, req.Timeout, req.Wait)
}
func (m *LocalReleaseModule) Update(current, target *release.Release, req *services.UpdateReleaseRequest, env *environment.Environment) error {
c := bytes.NewBufferString(current.Manifest)
t := bytes.NewBufferString(target.Manifest)
return env.KubeClient.Update(target.Namespace, c, t, req.Recreate, req.Timeout, req.Wait)
}
func (m *LocalReleaseModule) Rollback(current, target *release.Release, req *services.RollbackReleaseRequest, env *environment.Environment) error {
c := bytes.NewBufferString(current.Manifest)
t := bytes.NewBufferString(target.Manifest)
return env.KubeClient.Update(target.Namespace, c, t, req.Recreate, req.Timeout, req.Wait)
}
// RemoteReleaseModule is a ReleaseModule which calls Rudder service to operate on a release
type RemoteReleaseModule struct{}
// Create calls rudder.InstallRelease
func (m *RemoteReleaseModule) Create(r *release.Release, req *services.InstallReleaseRequest, env *environment.Environment) error {
request := &release.InstallReleaseRequest{Release: r}
_, err := rudder.InstallRelease(request)
return err
}
// Update calls rudder.UpgradeRelease
func (m *RemoteReleaseModule) Update(current, target *release.Release, req *services.UpdateReleaseRequest, env *environment.Environment) error {
upgrade := &release.UpgradeReleaseRequest{
Current: current,
Target: target,
Recreate: req.Recreate,
Timeout: req.Timeout,
Wait: req.Wait,
}
_, err := rudder.UpgradeRelease(upgrade)
return err
}
// Rollback calls rudder.Rollback
func (m *RemoteReleaseModule) Rollback(current, target *release.Release, req *services.RollbackReleaseRequest, env *environment.Environment) error {
rollback := &release.RollbackReleaseRequest{
Current: current,
Target: target,
Recreate: req.Recreate,
Timeout: req.Timeout,
Wait: req.Wait,
}
_, err := rudder.RollbackRelease(rollback)
return err
}

@ -83,15 +83,24 @@ var ValidName = regexp.MustCompile("^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])+
// ReleaseServer implements the server-side gRPC endpoint for the HAPI services.
type ReleaseServer struct {
ReleaseModule
env *environment.Environment
clientset internalclientset.Interface
}
// NewReleaseServer creates a new release server.
func NewReleaseServer(env *environment.Environment, clientset internalclientset.Interface) *ReleaseServer {
func NewReleaseServer(env *environment.Environment, clientset internalclientset.Interface, useRemote bool) *ReleaseServer {
var releaseModule ReleaseModule
if useRemote {
releaseModule = &RemoteReleaseModule{}
} else {
releaseModule = &LocalReleaseModule{}
}
return &ReleaseServer{
env: env,
clientset: clientset,
env: env,
clientset: clientset,
ReleaseModule: releaseModule,
}
}
@ -318,8 +327,7 @@ func (s *ReleaseServer) performUpdate(originalRelease, updatedRelease *release.R
return res, err
}
}
if err := s.performKubeUpdate(originalRelease, updatedRelease, req.Recreate, req.Timeout, req.Wait); err != nil {
if err := s.ReleaseModule.Update(originalRelease, updatedRelease, req, s.env); err != nil {
msg := fmt.Sprintf("Upgrade %q failed: %s", updatedRelease.Name, err)
log.Printf("warning: %s", msg)
originalRelease.Info.Status.Code = release.Status_SUPERSEDED
@ -477,7 +485,7 @@ func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.R
}
}
if err := s.performKubeUpdate(currentRelease, targetRelease, req.Recreate, req.Timeout, req.Wait); err != nil {
if err := s.ReleaseModule.Rollback(currentRelease, targetRelease, req, s.env); err != nil {
msg := fmt.Sprintf("Rollback %q failed: %s", targetRelease.Name, err)
log.Printf("warning: %s", msg)
currentRelease.Info.Status.Code = release.Status_SUPERSEDED
@ -503,13 +511,6 @@ func (s *ReleaseServer) performRollback(currentRelease, targetRelease *release.R
return res, nil
}
func (s *ReleaseServer) performKubeUpdate(currentRelease, targetRelease *release.Release, recreate bool, timeout int64, shouldWait bool) error {
kubeCli := s.env.KubeClient
current := bytes.NewBufferString(currentRelease.Manifest)
target := bytes.NewBufferString(targetRelease.Manifest)
return kubeCli.Update(targetRelease.Namespace, current, target, recreate, timeout, shouldWait)
}
// prepareRollback finds the previous release and prepares a new release object with
// the previous release's configuration
func (s *ReleaseServer) prepareRollback(req *services.RollbackReleaseRequest) (*release.Release, *release.Release, error) {
@ -851,8 +852,12 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install
// update new release with next revision number
// so as to append to the old release's history
r.Version = old.Version + 1
if err := s.performKubeUpdate(old, r, false, req.Timeout, req.Wait); err != nil {
updateReq := &services.UpdateReleaseRequest{
Wait: req.Wait,
Recreate: false,
Timeout: req.Timeout,
}
if err := s.ReleaseModule.Update(old, r, updateReq, s.env); err != nil {
msg := fmt.Sprintf("Release replace %q failed: %s", r.Name, err)
log.Printf("warning: %s", msg)
old.Info.Status.Code = release.Status_SUPERSEDED
@ -866,8 +871,7 @@ func (s *ReleaseServer) performRelease(r *release.Release, req *services.Install
default:
// nothing to replace, create as normal
// regular manifests
b := bytes.NewBufferString(r.Manifest)
if err := s.env.KubeClient.Create(r.Namespace, b, req.Timeout, req.Wait); err != nil {
if err := s.ReleaseModule.Create(r, req, s.env); err != nil {
msg := fmt.Sprintf("Release %q failed: %s", r.Name, err)
log.Printf("warning: %s", msg)
r.Info.Status.Code = release.Status_FAILED

@ -98,8 +98,9 @@ data:
func rsFixture() *ReleaseServer {
return &ReleaseServer{
env: MockEnvironment(),
clientset: fake.NewSimpleClientset(),
ReleaseModule: &LocalReleaseModule{},
env: MockEnvironment(),
clientset: fake.NewSimpleClientset(),
}
}

@ -0,0 +1,24 @@
# Copyright 2017 The Kubernetes Authors.
#
# 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 alpine:3.3
ENV HOME /tmp
COPY . /
EXPOSE 44134
CMD ["/tiller", "--experimental-release"]

@ -0,0 +1,23 @@
# Copyright 2017 The Kubernetes Authors.
#
# 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 alpine:3.3
ENV HOME /tmp
COPY . /
EXPOSE 10001
CMD ["/rudder"]

@ -14,7 +14,9 @@ DOCKER_VERSION ?= git-${GIT_SHA}
BINARY_VERSION ?= ${GIT_TAG}-${GIT_SHA}
IMAGE := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME}:${DOCKER_VERSION}
IMAGE_RUDDER := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME_RUDDER}:${DOCKER_VERSION}
MUTABLE_IMAGE := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME}:${MUTABLE_VERSION}
MUTABLE_IMAGE_RUDDER:= ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${SHORT_NAME_RUDDER}:${DOCKER_VERSION}
LDFLAGS += -X k8s.io/helm/pkg/version.Version=${GIT_TAG}
LDFLAGS += -X k8s.io/helm/pkg/version.GitCommit=${GIT_COMMIT}

Loading…
Cancel
Save