diff --git a/_proto/hapi/release/log.proto b/_proto/hapi/release/log.proto new file mode 100644 index 000000000..5825d67d8 --- /dev/null +++ b/_proto/hapi/release/log.proto @@ -0,0 +1,59 @@ + +// Copyright 2016 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. + +syntax = "proto3"; + +package hapi.release; + +import "google/protobuf/timestamp.proto"; + +option go_package = "release"; + + +message LogSubscription { + string release = 1; + Log.Level level = 2; + repeated Log.Source sources = 3; +} + +message Log { + // Allows filtering by log event source + enum Source { + UNKNOWN = 0; + HOOK = 1; + TEST = 2; + POD = 3; + SYSTEM = 4; + } + + // Syslog log levels + enum Level { + UNIVERSAL = 0; + EMERG = 1; + ALERT = 2; + CRIT = 3; + ERR = 4; + WARNING = 5; + NOTICE = 6; + INFO = 7; + DEBUG = 8; + } + + string release = 1; + Level level = 2; + Source source = 3; + string log = 4; + google.protobuf.Timestamp timestamp = 5; +} diff --git a/_proto/hapi/services/tiller.proto b/_proto/hapi/services/tiller.proto index 5897676ab..a3a530c67 100644 --- a/_proto/hapi/services/tiller.proto +++ b/_proto/hapi/services/tiller.proto @@ -19,6 +19,7 @@ package hapi.services.tiller; import "hapi/chart/chart.proto"; import "hapi/chart/config.proto"; import "hapi/release/release.proto"; +import "hapi/release/log.proto"; import "hapi/release/info.proto"; import "hapi/release/test_run.proto"; import "hapi/release/status.proto"; @@ -56,7 +57,11 @@ service ReleaseService { rpc GetReleaseContent(GetReleaseContentRequest) returns (GetReleaseContentResponse) { } - // UpdateRelease updates release content. + // GetReleaseLogs returns a stream of logging information from the release + rpc GetReleaseLogs(stream GetReleaseLogsRequest) returns (stream GetReleaseLogsResponse) { + } + + // UpdateRelease updates release content. rpc UpdateRelease(UpdateReleaseRequest) returns (UpdateReleaseResponse) { } @@ -183,6 +188,14 @@ message GetReleaseContentResponse { hapi.release.Release release = 1; } +message GetReleaseLogsRequest { + hapi.release.LogSubscription subscription = 1; +} + +message GetReleaseLogsResponse { + hapi.release.Log log = 1; +} + // UpdateReleaseRequest updates a release. message UpdateReleaseRequest { // The name of the release diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go index 4a0d10fe6..49b711ee6 100644 --- a/cmd/helm/helm.go +++ b/cmd/helm/helm.go @@ -116,6 +116,7 @@ func newRootCmd(args []string) *cobra.Command { addFlagsTLS(newHistoryCmd(nil, out)), addFlagsTLS(newInstallCmd(nil, out)), addFlagsTLS(newListCmd(nil, out)), + addFlagsTLS(newLogsCmd(nil, out)), addFlagsTLS(newRollbackCmd(nil, out)), addFlagsTLS(newStatusCmd(nil, out)), addFlagsTLS(newUpgradeCmd(nil, out)), diff --git a/cmd/helm/install.go b/cmd/helm/install.go index 55ddd8141..0842811b5 100644 --- a/cmd/helm/install.go +++ b/cmd/helm/install.go @@ -200,6 +200,23 @@ func newInstallCmd(c helm.Interface, out io.Writer) *cobra.Command { return cmd } +//func streamLogs(client helm.Interface, rlsName string, done <-chan struct{}) error { +// logs, err := client.ReleaseLogs(rlsName, done) +// if err != nil { +// return err +// } +// +// go func() { +// select { +// case log := <-logs: +// fmt.Println(log.Log) +// case <-done: +// return +// } +// }() +// return nil +//} + func (i *installCmd) run() error { debug("CHART PATH: %s\n", i.chartPath) @@ -254,6 +271,8 @@ func (i *installCmd) run() error { return fmt.Errorf("cannot load requirements: %v", err) } + //done := make(chan struct{}) + //streamLogs(i.client, i.name, done) res, err := i.client.InstallReleaseFromChart( chartRequested, i.namespace, diff --git a/cmd/helm/logs.go b/cmd/helm/logs.go new file mode 100644 index 000000000..4bba63bb3 --- /dev/null +++ b/cmd/helm/logs.go @@ -0,0 +1,87 @@ +/* +Copyright 2016 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 ( + "io" + "github.com/spf13/cobra" + + "k8s.io/helm/pkg/helm" + "fmt" + "k8s.io/helm/pkg/proto/hapi/release" +) + +var logsHelp = ` +This command gets logs for a named release +` + +type logsCmd struct { + release string + out io.Writer + client helm.Interface + version int32 +} + +func newLogsCmd(client helm.Interface, out io.Writer) *cobra.Command { + logs := &logsCmd{ + out: out, + client: client, + } + + cmd := &cobra.Command{ + Use: "logs [flags] RELEASE_NAME", + Short: "Streams logs for the given release", + Long: logsHelp, + PersistentPreRunE: setupConnection, + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) == 0 { + return errReleaseRequired + } + logs.release = args[0] + if logs.client == nil { + logs.client = helm.NewClient(helm.Host(settings.TillerHost)) + } + return logs.run() + }, + } + + return cmd +} + +func (l *logsCmd) run() error { + done := make(chan struct{}) + stream, err := l.client.ReleaseLogs(l.release, release.Log_DEBUG, done, release.Log_SYSTEM, release.Log_POD) + if err != nil { + done <- struct{}{} + return prettyError(err) + } + + fmt.Println("Listening for logs") + for { + select { + case l, ok := <-stream: + if !ok { + return nil + } + fmt.Println(l.Log.Log) + done<- struct{}{} + } + } + + return nil +} + diff --git a/glide.lock b/glide.lock index e14766948..b05b77cb2 100644 --- a/glide.lock +++ b/glide.lock @@ -238,7 +238,7 @@ imports: - name: github.com/Masterminds/vcs version: 3084677c2c188840777bff30054f2b553729d329 - name: github.com/mattn/go-runewidth - version: d6bea18f789704b5f83375793155289da36a3c7f + version: 14207d285c6c197daabb5c9793d63e7af9ab2d50 - name: github.com/matttproud/golang_protobuf_extensions version: fc2b8d3a73c4867e51861bbdd5ae3c1f0869dd6a subpackages: diff --git a/pkg/helm/client.go b/pkg/helm/client.go index c7ef4d89e..334033542 100644 --- a/pkg/helm/client.go +++ b/pkg/helm/client.go @@ -28,6 +28,8 @@ import ( "k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/proto/hapi/chart" rls "k8s.io/helm/pkg/proto/hapi/services" + "fmt" + "k8s.io/helm/pkg/proto/hapi/release" ) // maxMsgSize use 20MB as the default message size limit. @@ -228,6 +230,15 @@ func (h *Client) RollbackRelease(rlsName string, opts ...RollbackOption) (*rls.R return h.rollback(ctx, req) } +// ReleaseLogs returns a channel streaming log data from the release +func (h *Client) ReleaseLogs(rlsName string, level release.Log_Level, done <-chan struct{}, sources ...release.Log_Source) (<-chan *rls.GetReleaseLogsResponse, error) { + ctx := NewContext() + sub := &release.LogSubscription{Release: rlsName, Level: level, Sources: sources} + req := &rls.GetReleaseLogsRequest{Subscription: sub} + + return h.logs(ctx, req, done) +} + // ReleaseStatus returns the given release's status. func (h *Client) ReleaseStatus(rlsName string, opts ...StatusOption) (*rls.GetReleaseStatusResponse, error) { reqOpts := h.opts @@ -406,6 +417,47 @@ func (h *Client) status(ctx context.Context, req *rls.GetReleaseStatusRequest) ( return rlc.GetReleaseStatus(ctx, req) } +// Executes tiller.GetReleaseLogs RPC. +func (h *Client) logs(ctx context.Context, req *rls.GetReleaseLogsRequest, done <-chan struct{}) (<-chan *rls.GetReleaseLogsResponse, error) { + c, err := h.connect(ctx) + if err != nil { + return nil, err + } + + rlc := rls.NewReleaseServiceClient(c) + s, err := rlc.GetReleaseLogs(ctx) + if err != nil { + return nil, err + } + + out := make(chan *rls.GetReleaseLogsResponse) + + go func() { + <-done + s.CloseSend() + }() + + go func() { + defer close(out) + defer c.Close() + for { + rs, err := s.Recv() + if err == io.EOF { + return + } + if err != nil { + fmt.Println("gRPC error streaming logs: ", grpc.ErrorDesc(err)) + return + } + out <- rs + } + }() + + s.Send(req) + + return out, nil +} + // Executes tiller.GetReleaseContent RPC. func (h *Client) content(ctx context.Context, req *rls.GetReleaseContentRequest) (*rls.GetReleaseContentResponse, error) { c, err := h.connect(ctx) diff --git a/pkg/helm/interface.go b/pkg/helm/interface.go index 10c04c710..1b1b590d7 100644 --- a/pkg/helm/interface.go +++ b/pkg/helm/interface.go @@ -19,6 +19,7 @@ package helm import ( "k8s.io/helm/pkg/proto/hapi/chart" rls "k8s.io/helm/pkg/proto/hapi/services" + "k8s.io/helm/pkg/proto/hapi/release" ) // Interface for helm client for mocking in tests @@ -28,6 +29,7 @@ type Interface interface { InstallReleaseFromChart(chart *chart.Chart, namespace string, opts ...InstallOption) (*rls.InstallReleaseResponse, error) DeleteRelease(rlsName string, opts ...DeleteOption) (*rls.UninstallReleaseResponse, error) ReleaseStatus(rlsName string, opts ...StatusOption) (*rls.GetReleaseStatusResponse, error) + ReleaseLogs(rlsName string, level release.Log_Level, done <-chan struct{}, sources ...release.Log_Source) (<-chan *rls.GetReleaseLogsResponse, error) UpdateRelease(rlsName, chStr string, opts ...UpdateOption) (*rls.UpdateReleaseResponse, error) UpdateReleaseFromChart(rlsName string, chart *chart.Chart, opts ...UpdateOption) (*rls.UpdateReleaseResponse, error) RollbackRelease(rlsName string, opts ...RollbackOption) (*rls.RollbackReleaseResponse, error) diff --git a/pkg/kube/pod_logs.go b/pkg/kube/pod_logs.go new file mode 100644 index 000000000..a584ef767 --- /dev/null +++ b/pkg/kube/pod_logs.go @@ -0,0 +1,192 @@ +package kube + +import ( + "time" + "k8s.io/kubernetes/pkg/kubectl/cmd" + "io" + "math" + "errors" + "k8s.io/kubernetes/pkg/api" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" + "k8s.io/kubernetes/pkg/kubectl/resource" + "k8s.io/kubernetes/pkg/api/validation" + "k8s.io/apimachinery/pkg/runtime" +) + +// Mimics kubectl logs functionality + +var ( + selectorTail int64 = 10 +) + +// All options that can be passed to kubectl logs +type LogOptions struct { + // Specify if the logs should be streamed. + Follow bool + // Include timestamps on each line in the log output + Timestamps bool + // Maximum bytes of logs to return. Defaults to no limit. + LimitBytes int64 + // If true, print the logs for the previous instance of the container in a pod if it exists. + Previous bool + // Lines of recent log file to display. Defaults to -1 with no selector, showing all log lines otherwise 10, if a selector is provided. + Tail int64 + // Only return logs after a specific date (RFC3339). Defaults to all logs. Only one of since-time / since may be used. + SinceTime *time.Time + // Only return logs newer than a relative duration like 5s, 2m, or 3h. Defaults to all logs. Only one of since-time / since may be used. + Since *time.Duration + // Print the logs of this container + Container string + // Selector (label query) to filter on. + Selector string + // Namespace to query for logs + Namespace string + // Resource to query for logs + Resource string +} + +func NewLogOptions() *LogOptions { + return &LogOptions{ + Follow: false, + Timestamps: false, + LimitBytes: 0, + Previous: false, + Tail: -1, + SinceTime: nil, + Since: nil, + Container: "", + Selector: "", + Namespace: "", + Resource: "", + } +} + +func (o *LogOptions) ExecuteLogRequest(out io.Writer) error { + f := cmdutil.NewFactory(nil) + logsOptions, err := Complete(o, f, out) + if err != nil { + return err + } + Validate(logsOptions) + RunLogs(logsOptions) + return nil +} + +func Complete(opts *LogOptions, f cmdutil.Factory, out io.Writer) (*cmd.LogsOptions, error) { + o := &cmd.LogsOptions{} + containerName := opts.Container + selector := opts.Selector + if len(opts.Resource) != 0 && len(opts.Selector) != 0 { + return nil, errors.New("Specify either a selector or a resource, not both") + } + o.Namespace = opts.Namespace + if o.Namespace == "" { + return nil, errors.New("Namespace is required") + } + + logOptions := &api.PodLogOptions{ + Container: containerName, + Follow: opts.Follow, + Previous: opts.Previous, + Timestamps: opts.Timestamps, + } + if opts.SinceTime != nil { + t := metav1.NewTime(*opts.SinceTime) + logOptions.SinceTime = &t + } + if opts.LimitBytes != 0 { + logOptions.LimitBytes = &opts.LimitBytes + } + if opts.Tail != -1 { + logOptions.TailLines = &opts.Tail + } + if opts.Since != nil { + // round up to the nearest second + sec := int64(math.Ceil(opts.Since.Seconds())) + logOptions.SinceSeconds = &sec + } + o.Options = logOptions + o.LogsForObject = f.LogsForObject + o.ClientMapper = resource.ClientMapperFunc(f.ClientForMapping) + o.Out = out + + if len(selector) != 0 { + if logOptions.Follow { + return nil, errors.New("only one of follow (-f) or selector (-l) is allowed") + } + if len(logOptions.Container) != 0 { + return nil, errors.New( "a container cannot be specified when using a selector (-l)") + } + if logOptions.TailLines == nil { + logOptions.TailLines = &selectorTail + } + } + + mapper, typer := f.Object() + decoder := f.Decoder(true) + if o.Object == nil { + builder := resource.NewBuilder(mapper, typer, o.ClientMapper, decoder). + NamespaceParam(o.Namespace).DefaultNamespace(). + SingleResourceType() + if o.ResourceArg != "" { + builder.ResourceNames("pods", o.ResourceArg) + } + if selector != "" { + builder.ResourceTypes("pods").SelectorParam(selector) + } + infos, err := builder.Do().Infos() + if err != nil { + return nil, err + } + if selector == "" && len(infos) != 1 { + return nil, errors.New("expected a resource") + } + o.Object = infos[0].Object + } + + return o, nil +} + +func Validate(o *cmd.LogsOptions) error { + logsOptions, ok := o.Options.(*api.PodLogOptions) + if !ok { + return errors.New("unexpected logs options object") + } + if errs := validation.ValidatePodLogOptions(logsOptions); len(errs) > 0 { + return errs.ToAggregate() + } + + return nil +} + +// RunLogs retrieves a pod log +func RunLogs(o *cmd.LogsOptions) error { + switch t := o.Object.(type) { + case *api.PodList: + for _, p := range t.Items { + if err := getLogs(o, &p); err != nil { + return err + } + } + return nil + default: + return getLogs(o, o.Object) + } +} + +func getLogs(o *cmd.LogsOptions, obj runtime.Object) error { + req, err := o.LogsForObject(obj, o.Options) + if err != nil { + return err + } + + readCloser, err := req.Stream() + if err != nil { + return err + } + defer readCloser.Close() + + _, err = io.Copy(o.Out, readCloser) + return err +} \ No newline at end of file diff --git a/pkg/proto/hapi/chart/chart.pb.go b/pkg/proto/hapi/chart/chart.pb.go index a884ed552..dbb188e91 100644 --- a/pkg/proto/hapi/chart/chart.pb.go +++ b/pkg/proto/hapi/chart/chart.pb.go @@ -1,5 +1,6 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. +// Code generated by protoc-gen-go. // source: hapi/chart/chart.proto +// DO NOT EDIT! /* Package chart is a generated protocol buffer package. diff --git a/pkg/proto/hapi/chart/config.pb.go b/pkg/proto/hapi/chart/config.pb.go index 30c652700..4a8b36d89 100644 --- a/pkg/proto/hapi/chart/config.pb.go +++ b/pkg/proto/hapi/chart/config.pb.go @@ -1,5 +1,6 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. +// Code generated by protoc-gen-go. // source: hapi/chart/config.proto +// DO NOT EDIT! package chart diff --git a/pkg/proto/hapi/chart/metadata.pb.go b/pkg/proto/hapi/chart/metadata.pb.go index 49a4aa0ac..acc7ad2a1 100644 --- a/pkg/proto/hapi/chart/metadata.pb.go +++ b/pkg/proto/hapi/chart/metadata.pb.go @@ -1,5 +1,6 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. +// Code generated by protoc-gen-go. // source: hapi/chart/metadata.proto +// DO NOT EDIT! package chart diff --git a/pkg/proto/hapi/chart/template.pb.go b/pkg/proto/hapi/chart/template.pb.go index 439aec5a8..416269d18 100644 --- a/pkg/proto/hapi/chart/template.pb.go +++ b/pkg/proto/hapi/chart/template.pb.go @@ -1,5 +1,6 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. +// Code generated by protoc-gen-go. // source: hapi/chart/template.proto +// DO NOT EDIT! package chart diff --git a/pkg/proto/hapi/release/hook.pb.go b/pkg/proto/hapi/release/hook.pb.go index bd9391c50..8c98c02f3 100644 --- a/pkg/proto/hapi/release/hook.pb.go +++ b/pkg/proto/hapi/release/hook.pb.go @@ -1,14 +1,28 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. +// Code generated by protoc-gen-go. // source: hapi/release/hook.proto +// DO NOT EDIT! /* Package release is a generated protocol buffer package. It is generated from these files: hapi/release/hook.proto + hapi/release/info.proto + hapi/release/log.proto + hapi/release/release.proto + hapi/release/status.proto + hapi/release/test_run.proto + hapi/release/test_suite.proto It has these top-level messages: Hook + Info + LogSubscription + Log + Release + Status + TestRun + TestSuite */ package release diff --git a/pkg/proto/hapi/release/info.pb.go b/pkg/proto/hapi/release/info.pb.go index 7a7ccdd74..9485ad058 100644 --- a/pkg/proto/hapi/release/info.pb.go +++ b/pkg/proto/hapi/release/info.pb.go @@ -1,5 +1,6 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. +// Code generated by protoc-gen-go. // source: hapi/release/info.proto +// DO NOT EDIT! package release diff --git a/pkg/proto/hapi/release/log.pb.go b/pkg/proto/hapi/release/log.pb.go new file mode 100644 index 000000000..5bf48f03e --- /dev/null +++ b/pkg/proto/hapi/release/log.pb.go @@ -0,0 +1,206 @@ +// Code generated by protoc-gen-go. +// source: hapi/release/log.proto +// DO NOT EDIT! + +package release + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import google_protobuf "github.com/golang/protobuf/ptypes/timestamp" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// Allows filtering by log event source +type Log_Source int32 + +const ( + Log_UNKNOWN Log_Source = 0 + Log_HOOK Log_Source = 1 + Log_TEST Log_Source = 2 + Log_POD Log_Source = 3 + Log_SYSTEM Log_Source = 4 +) + +var Log_Source_name = map[int32]string{ + 0: "UNKNOWN", + 1: "HOOK", + 2: "TEST", + 3: "POD", + 4: "SYSTEM", +} +var Log_Source_value = map[string]int32{ + "UNKNOWN": 0, + "HOOK": 1, + "TEST": 2, + "POD": 3, + "SYSTEM": 4, +} + +func (x Log_Source) String() string { + return proto.EnumName(Log_Source_name, int32(x)) +} +func (Log_Source) EnumDescriptor() ([]byte, []int) { return fileDescriptor2, []int{1, 0} } + +// Syslog log levels +type Log_Level int32 + +const ( + Log_UNIVERSAL Log_Level = 0 + Log_EMERG Log_Level = 1 + Log_ALERT Log_Level = 2 + Log_CRIT Log_Level = 3 + Log_ERR Log_Level = 4 + Log_WARNING Log_Level = 5 + Log_NOTICE Log_Level = 6 + Log_INFO Log_Level = 7 + Log_DEBUG Log_Level = 8 +) + +var Log_Level_name = map[int32]string{ + 0: "UNIVERSAL", + 1: "EMERG", + 2: "ALERT", + 3: "CRIT", + 4: "ERR", + 5: "WARNING", + 6: "NOTICE", + 7: "INFO", + 8: "DEBUG", +} +var Log_Level_value = map[string]int32{ + "UNIVERSAL": 0, + "EMERG": 1, + "ALERT": 2, + "CRIT": 3, + "ERR": 4, + "WARNING": 5, + "NOTICE": 6, + "INFO": 7, + "DEBUG": 8, +} + +func (x Log_Level) String() string { + return proto.EnumName(Log_Level_name, int32(x)) +} +func (Log_Level) EnumDescriptor() ([]byte, []int) { return fileDescriptor2, []int{1, 1} } + +type LogSubscription struct { + Release string `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"` + Level Log_Level `protobuf:"varint,2,opt,name=level,enum=hapi.release.Log_Level" json:"level,omitempty"` + Sources []Log_Source `protobuf:"varint,3,rep,packed,name=sources,enum=hapi.release.Log_Source" json:"sources,omitempty"` +} + +func (m *LogSubscription) Reset() { *m = LogSubscription{} } +func (m *LogSubscription) String() string { return proto.CompactTextString(m) } +func (*LogSubscription) ProtoMessage() {} +func (*LogSubscription) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{0} } + +func (m *LogSubscription) GetRelease() string { + if m != nil { + return m.Release + } + return "" +} + +func (m *LogSubscription) GetLevel() Log_Level { + if m != nil { + return m.Level + } + return Log_UNIVERSAL +} + +func (m *LogSubscription) GetSources() []Log_Source { + if m != nil { + return m.Sources + } + return nil +} + +type Log struct { + Release string `protobuf:"bytes,1,opt,name=release" json:"release,omitempty"` + Level Log_Level `protobuf:"varint,2,opt,name=level,enum=hapi.release.Log_Level" json:"level,omitempty"` + Source Log_Source `protobuf:"varint,3,opt,name=source,enum=hapi.release.Log_Source" json:"source,omitempty"` + Log string `protobuf:"bytes,4,opt,name=log" json:"log,omitempty"` + Timestamp *google_protobuf.Timestamp `protobuf:"bytes,5,opt,name=timestamp" json:"timestamp,omitempty"` +} + +func (m *Log) Reset() { *m = Log{} } +func (m *Log) String() string { return proto.CompactTextString(m) } +func (*Log) ProtoMessage() {} +func (*Log) Descriptor() ([]byte, []int) { return fileDescriptor2, []int{1} } + +func (m *Log) GetRelease() string { + if m != nil { + return m.Release + } + return "" +} + +func (m *Log) GetLevel() Log_Level { + if m != nil { + return m.Level + } + return Log_UNIVERSAL +} + +func (m *Log) GetSource() Log_Source { + if m != nil { + return m.Source + } + return Log_UNKNOWN +} + +func (m *Log) GetLog() string { + if m != nil { + return m.Log + } + return "" +} + +func (m *Log) GetTimestamp() *google_protobuf.Timestamp { + if m != nil { + return m.Timestamp + } + return nil +} + +func init() { + proto.RegisterType((*LogSubscription)(nil), "hapi.release.LogSubscription") + proto.RegisterType((*Log)(nil), "hapi.release.Log") + proto.RegisterEnum("hapi.release.Log_Source", Log_Source_name, Log_Source_value) + proto.RegisterEnum("hapi.release.Log_Level", Log_Level_name, Log_Level_value) +} + +func init() { proto.RegisterFile("hapi/release/log.proto", fileDescriptor2) } + +var fileDescriptor2 = []byte{ + // 379 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x90, 0x4f, 0x8f, 0xd3, 0x30, + 0x10, 0xc5, 0x37, 0x75, 0xfe, 0x34, 0xb3, 0xb0, 0x58, 0x3e, 0x80, 0xb5, 0x17, 0xa2, 0x9c, 0x72, + 0xc1, 0x41, 0xe1, 0xc2, 0x09, 0xa9, 0xbb, 0x6b, 0x4a, 0xb4, 0x59, 0x07, 0x39, 0x29, 0x15, 0xdc, + 0xda, 0xca, 0x84, 0x48, 0x29, 0x8e, 0x92, 0x94, 0x8f, 0xc1, 0x17, 0xe6, 0x82, 0x9c, 0x34, 0x80, + 0x84, 0xb8, 0x71, 0x1b, 0x7b, 0x7e, 0xf3, 0xde, 0xcc, 0x83, 0xa7, 0x5f, 0x76, 0x6d, 0x1d, 0x77, + 0xaa, 0x51, 0xbb, 0x5e, 0xc5, 0x8d, 0xae, 0x58, 0xdb, 0xe9, 0x41, 0x93, 0x47, 0xe6, 0x9f, 0x9d, + 0xff, 0xaf, 0x9f, 0x57, 0x5a, 0x57, 0x8d, 0x8a, 0xc7, 0xde, 0xfe, 0xf4, 0x39, 0x1e, 0xea, 0xa3, + 0xea, 0x87, 0xdd, 0xb1, 0x9d, 0xf0, 0xf0, 0xbb, 0x05, 0x4f, 0x32, 0x5d, 0x15, 0xa7, 0x7d, 0x7f, + 0xe8, 0xea, 0x76, 0xa8, 0xf5, 0x57, 0x42, 0xc1, 0x3b, 0xcf, 0x53, 0x2b, 0xb0, 0x22, 0x5f, 0xce, + 0x4f, 0xf2, 0x02, 0x9c, 0x46, 0x7d, 0x53, 0x0d, 0x5d, 0x04, 0x56, 0x74, 0x95, 0x3c, 0x63, 0x7f, + 0x9a, 0xb1, 0x4c, 0x57, 0x2c, 0x33, 0x6d, 0x39, 0x51, 0x24, 0x01, 0xaf, 0xd7, 0xa7, 0xee, 0xa0, + 0x7a, 0x8a, 0x02, 0x14, 0x5d, 0x25, 0xf4, 0xef, 0x81, 0x62, 0x04, 0xe4, 0x0c, 0x86, 0x3f, 0x16, + 0x80, 0x32, 0x5d, 0xfd, 0xbf, 0x25, 0x5e, 0x82, 0x3b, 0x69, 0x53, 0x34, 0xf2, 0xff, 0xde, 0xe1, + 0xcc, 0x11, 0x0c, 0xa8, 0xd1, 0x15, 0xb5, 0x47, 0x5b, 0x53, 0x92, 0xd7, 0xe0, 0xff, 0x0a, 0x8e, + 0x3a, 0x81, 0x15, 0x5d, 0x26, 0xd7, 0x6c, 0x8a, 0x96, 0xcd, 0xd1, 0xb2, 0x72, 0x26, 0xe4, 0x6f, + 0x38, 0x7c, 0x03, 0xee, 0xa4, 0x4e, 0x2e, 0xc1, 0xdb, 0x88, 0x7b, 0x91, 0x6f, 0x05, 0xbe, 0x20, + 0x4b, 0xb0, 0xdf, 0xe5, 0xf9, 0x3d, 0xb6, 0x4c, 0x55, 0xf2, 0xa2, 0xc4, 0x0b, 0xe2, 0x01, 0x7a, + 0x9f, 0xdf, 0x61, 0x44, 0x00, 0xdc, 0xe2, 0x63, 0x51, 0xf2, 0x07, 0x6c, 0x87, 0x47, 0x70, 0xc6, + 0x6b, 0xc8, 0x63, 0xf0, 0x37, 0x22, 0xfd, 0xc0, 0x65, 0xb1, 0xca, 0xf0, 0x05, 0xf1, 0xc1, 0xe1, + 0x0f, 0x5c, 0xae, 0xb1, 0x65, 0xca, 0x55, 0xc6, 0xa5, 0x91, 0x58, 0x82, 0x7d, 0x2b, 0xd3, 0x12, + 0x23, 0x23, 0xc6, 0xa5, 0xc4, 0xb6, 0xb1, 0xdd, 0xae, 0xa4, 0x48, 0xc5, 0x1a, 0x3b, 0x46, 0x59, + 0xe4, 0x65, 0x7a, 0xcb, 0xb1, 0x6b, 0xd8, 0x54, 0xbc, 0xcd, 0xb1, 0x67, 0x04, 0xee, 0xf8, 0xcd, + 0x66, 0x8d, 0x97, 0x37, 0xfe, 0xa7, 0x39, 0xe6, 0xbd, 0x3b, 0x1e, 0xf6, 0xea, 0x67, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xd5, 0xde, 0x02, 0xe9, 0x69, 0x02, 0x00, 0x00, +} diff --git a/pkg/proto/hapi/release/release.pb.go b/pkg/proto/hapi/release/release.pb.go index 511b543d7..f58ce1502 100644 --- a/pkg/proto/hapi/release/release.pb.go +++ b/pkg/proto/hapi/release/release.pb.go @@ -1,5 +1,6 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. +// Code generated by protoc-gen-go. // source: hapi/release/release.proto +// DO NOT EDIT! package release @@ -39,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) GetName() string { if m != nil { @@ -101,9 +102,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, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x90, 0xbf, 0x4e, 0xc3, 0x40, 0x0c, 0xc6, 0x95, 0x36, 0x7f, 0x1a, 0xc3, 0x82, 0x07, 0xb0, 0x22, 0x86, 0x88, 0x01, 0x22, 0x86, diff --git a/pkg/proto/hapi/release/status.pb.go b/pkg/proto/hapi/release/status.pb.go index 284892642..5d081790a 100644 --- a/pkg/proto/hapi/release/status.pb.go +++ b/pkg/proto/hapi/release/status.pb.go @@ -1,5 +1,6 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. +// Code generated by protoc-gen-go. // source: hapi/release/status.proto +// DO NOT EDIT! package release @@ -62,7 +63,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 { @@ -78,7 +79,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) GetCode() Status_Code { if m != nil { @@ -113,9 +114,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{ // 333 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x90, 0xd1, 0x6e, 0xa2, 0x40, 0x14, 0x86, 0x17, 0x45, 0xd4, 0xa3, 0x71, 0x27, 0xa3, 0xc9, 0xa2, 0xd9, 0x4d, 0x8c, 0x57, 0xde, diff --git a/pkg/proto/hapi/release/test_run.pb.go b/pkg/proto/hapi/release/test_run.pb.go index 4d39d17c2..b70a9e7b4 100644 --- a/pkg/proto/hapi/release/test_run.pb.go +++ b/pkg/proto/hapi/release/test_run.pb.go @@ -1,5 +1,6 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. +// Code generated by protoc-gen-go. // source: hapi/release/test_run.proto +// DO NOT EDIT! package release @@ -38,7 +39,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"` @@ -51,7 +52,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) GetName() string { if m != nil { @@ -93,9 +94,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{ // 274 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x8f, 0xc1, 0x4b, 0xfb, 0x30, 0x1c, 0xc5, 0x7f, 0xe9, 0xf6, 0x6b, 0x69, 0x3a, 0xa4, 0xe4, 0x54, 0xa6, 0x60, 0xd9, 0xa9, 0xa7, diff --git a/pkg/proto/hapi/release/test_suite.pb.go b/pkg/proto/hapi/release/test_suite.pb.go index b7fa26147..304cded78 100644 --- a/pkg/proto/hapi/release/test_suite.pb.go +++ b/pkg/proto/hapi/release/test_suite.pb.go @@ -1,5 +1,6 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. +// Code generated by protoc-gen-go. // source: hapi/release/test_suite.proto +// DO NOT EDIT! package release @@ -26,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 { @@ -53,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, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x8f, 0xc1, 0x4a, 0x86, 0x40, 0x14, 0x85, 0x31, 0x21, 0x71, 0x74, 0x35, 0x10, 0x88, 0x11, 0x49, 0x2b, 0x57, 0x33, 0x60, 0xab, diff --git a/pkg/proto/hapi/rudder/rudder.pb.go b/pkg/proto/hapi/rudder/rudder.pb.go index 6e26d71eb..3f64ba713 100644 --- a/pkg/proto/hapi/rudder/rudder.pb.go +++ b/pkg/proto/hapi/rudder/rudder.pb.go @@ -1,5 +1,6 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. +// Code generated by protoc-gen-go. // source: hapi/rudder/rudder.proto +// DO NOT EDIT! /* Package rudder is a generated protocol buffer package. diff --git a/pkg/proto/hapi/services/tiller.pb.go b/pkg/proto/hapi/services/tiller.pb.go index 2112ea67f..0bcc65762 100644 --- a/pkg/proto/hapi/services/tiller.pb.go +++ b/pkg/proto/hapi/services/tiller.pb.go @@ -1,5 +1,6 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. +// Code generated by protoc-gen-go. // source: hapi/services/tiller.proto +// DO NOT EDIT! /* Package services is a generated protocol buffer package. @@ -15,6 +16,8 @@ It has these top-level messages: GetReleaseStatusResponse GetReleaseContentRequest GetReleaseContentResponse + GetReleaseLogsRequest + GetReleaseLogsResponse UpdateReleaseRequest UpdateReleaseResponse RollbackReleaseRequest @@ -38,6 +41,7 @@ import math "math" import hapi_chart3 "k8s.io/helm/pkg/proto/hapi/chart" import hapi_chart "k8s.io/helm/pkg/proto/hapi/chart" import hapi_release5 "k8s.io/helm/pkg/proto/hapi/release" +import hapi_release6 "k8s.io/helm/pkg/proto/hapi/release" import hapi_release4 "k8s.io/helm/pkg/proto/hapi/release" import hapi_release1 "k8s.io/helm/pkg/proto/hapi/release" import hapi_release3 "k8s.io/helm/pkg/proto/hapi/release" @@ -350,6 +354,38 @@ func (m *GetReleaseContentResponse) GetRelease() *hapi_release5.Release { return nil } +type GetReleaseLogsRequest struct { + Subscription *hapi_release6.LogSubscription `protobuf:"bytes,1,opt,name=subscription" json:"subscription,omitempty"` +} + +func (m *GetReleaseLogsRequest) Reset() { *m = GetReleaseLogsRequest{} } +func (m *GetReleaseLogsRequest) String() string { return proto.CompactTextString(m) } +func (*GetReleaseLogsRequest) ProtoMessage() {} +func (*GetReleaseLogsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } + +func (m *GetReleaseLogsRequest) GetSubscription() *hapi_release6.LogSubscription { + if m != nil { + return m.Subscription + } + return nil +} + +type GetReleaseLogsResponse struct { + Log *hapi_release6.Log `protobuf:"bytes,1,opt,name=log" json:"log,omitempty"` +} + +func (m *GetReleaseLogsResponse) Reset() { *m = GetReleaseLogsResponse{} } +func (m *GetReleaseLogsResponse) String() string { return proto.CompactTextString(m) } +func (*GetReleaseLogsResponse) ProtoMessage() {} +func (*GetReleaseLogsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } + +func (m *GetReleaseLogsResponse) GetLog() *hapi_release6.Log { + if m != nil { + return m.Log + } + return nil +} + // UpdateReleaseRequest updates a release. type UpdateReleaseRequest struct { // The name of the release @@ -381,7 +417,7 @@ type UpdateReleaseRequest struct { func (m *UpdateReleaseRequest) Reset() { *m = UpdateReleaseRequest{} } func (m *UpdateReleaseRequest) String() string { return proto.CompactTextString(m) } func (*UpdateReleaseRequest) ProtoMessage() {} -func (*UpdateReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } +func (*UpdateReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } func (m *UpdateReleaseRequest) GetName() string { if m != nil { @@ -468,7 +504,7 @@ type UpdateReleaseResponse struct { func (m *UpdateReleaseResponse) Reset() { *m = UpdateReleaseResponse{} } func (m *UpdateReleaseResponse) String() string { return proto.CompactTextString(m) } func (*UpdateReleaseResponse) ProtoMessage() {} -func (*UpdateReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } +func (*UpdateReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } func (m *UpdateReleaseResponse) GetRelease() *hapi_release5.Release { if m != nil { @@ -500,7 +536,7 @@ type RollbackReleaseRequest struct { func (m *RollbackReleaseRequest) Reset() { *m = RollbackReleaseRequest{} } func (m *RollbackReleaseRequest) String() string { return proto.CompactTextString(m) } func (*RollbackReleaseRequest) ProtoMessage() {} -func (*RollbackReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } +func (*RollbackReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } func (m *RollbackReleaseRequest) GetName() string { if m != nil { @@ -566,7 +602,7 @@ type RollbackReleaseResponse struct { func (m *RollbackReleaseResponse) Reset() { *m = RollbackReleaseResponse{} } func (m *RollbackReleaseResponse) String() string { return proto.CompactTextString(m) } func (*RollbackReleaseResponse) ProtoMessage() {} -func (*RollbackReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } +func (*RollbackReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } func (m *RollbackReleaseResponse) GetRelease() *hapi_release5.Release { if m != nil { @@ -605,7 +641,7 @@ type InstallReleaseRequest struct { func (m *InstallReleaseRequest) Reset() { *m = InstallReleaseRequest{} } func (m *InstallReleaseRequest) String() string { return proto.CompactTextString(m) } func (*InstallReleaseRequest) ProtoMessage() {} -func (*InstallReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } +func (*InstallReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } func (m *InstallReleaseRequest) GetChart() *hapi_chart3.Chart { if m != nil { @@ -678,7 +714,7 @@ type InstallReleaseResponse struct { func (m *InstallReleaseResponse) Reset() { *m = InstallReleaseResponse{} } func (m *InstallReleaseResponse) String() string { return proto.CompactTextString(m) } func (*InstallReleaseResponse) ProtoMessage() {} -func (*InstallReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } +func (*InstallReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } func (m *InstallReleaseResponse) GetRelease() *hapi_release5.Release { if m != nil { @@ -702,7 +738,7 @@ type UninstallReleaseRequest struct { func (m *UninstallReleaseRequest) Reset() { *m = UninstallReleaseRequest{} } func (m *UninstallReleaseRequest) String() string { return proto.CompactTextString(m) } func (*UninstallReleaseRequest) ProtoMessage() {} -func (*UninstallReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } +func (*UninstallReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } func (m *UninstallReleaseRequest) GetName() string { if m != nil { @@ -743,7 +779,7 @@ type UninstallReleaseResponse struct { func (m *UninstallReleaseResponse) Reset() { *m = UninstallReleaseResponse{} } func (m *UninstallReleaseResponse) String() string { return proto.CompactTextString(m) } func (*UninstallReleaseResponse) ProtoMessage() {} -func (*UninstallReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } +func (*UninstallReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } func (m *UninstallReleaseResponse) GetRelease() *hapi_release5.Release { if m != nil { @@ -766,7 +802,7 @@ type GetVersionRequest struct { func (m *GetVersionRequest) Reset() { *m = GetVersionRequest{} } func (m *GetVersionRequest) String() string { return proto.CompactTextString(m) } func (*GetVersionRequest) ProtoMessage() {} -func (*GetVersionRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } +func (*GetVersionRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } type GetVersionResponse struct { Version *hapi_version.Version `protobuf:"bytes,1,opt,name=Version" json:"Version,omitempty"` @@ -775,7 +811,7 @@ type GetVersionResponse struct { func (m *GetVersionResponse) Reset() { *m = GetVersionResponse{} } func (m *GetVersionResponse) String() string { return proto.CompactTextString(m) } func (*GetVersionResponse) ProtoMessage() {} -func (*GetVersionResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } +func (*GetVersionResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } func (m *GetVersionResponse) GetVersion() *hapi_version.Version { if m != nil { @@ -795,7 +831,7 @@ type GetHistoryRequest struct { func (m *GetHistoryRequest) Reset() { *m = GetHistoryRequest{} } func (m *GetHistoryRequest) String() string { return proto.CompactTextString(m) } func (*GetHistoryRequest) ProtoMessage() {} -func (*GetHistoryRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } +func (*GetHistoryRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } func (m *GetHistoryRequest) GetName() string { if m != nil { @@ -819,7 +855,7 @@ type GetHistoryResponse struct { func (m *GetHistoryResponse) Reset() { *m = GetHistoryResponse{} } func (m *GetHistoryResponse) String() string { return proto.CompactTextString(m) } func (*GetHistoryResponse) ProtoMessage() {} -func (*GetHistoryResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } +func (*GetHistoryResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} } func (m *GetHistoryResponse) GetReleases() []*hapi_release5.Release { if m != nil { @@ -841,7 +877,7 @@ type TestReleaseRequest struct { func (m *TestReleaseRequest) Reset() { *m = TestReleaseRequest{} } func (m *TestReleaseRequest) String() string { return proto.CompactTextString(m) } func (*TestReleaseRequest) ProtoMessage() {} -func (*TestReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } +func (*TestReleaseRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} } func (m *TestReleaseRequest) GetName() string { if m != nil { @@ -873,7 +909,7 @@ type TestReleaseResponse struct { func (m *TestReleaseResponse) Reset() { *m = TestReleaseResponse{} } func (m *TestReleaseResponse) String() string { return proto.CompactTextString(m) } func (*TestReleaseResponse) ProtoMessage() {} -func (*TestReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} } +func (*TestReleaseResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} } func (m *TestReleaseResponse) GetMsg() string { if m != nil { @@ -897,6 +933,8 @@ func init() { proto.RegisterType((*GetReleaseStatusResponse)(nil), "hapi.services.tiller.GetReleaseStatusResponse") proto.RegisterType((*GetReleaseContentRequest)(nil), "hapi.services.tiller.GetReleaseContentRequest") proto.RegisterType((*GetReleaseContentResponse)(nil), "hapi.services.tiller.GetReleaseContentResponse") + proto.RegisterType((*GetReleaseLogsRequest)(nil), "hapi.services.tiller.GetReleaseLogsRequest") + proto.RegisterType((*GetReleaseLogsResponse)(nil), "hapi.services.tiller.GetReleaseLogsResponse") proto.RegisterType((*UpdateReleaseRequest)(nil), "hapi.services.tiller.UpdateReleaseRequest") proto.RegisterType((*UpdateReleaseResponse)(nil), "hapi.services.tiller.UpdateReleaseResponse") proto.RegisterType((*RollbackReleaseRequest)(nil), "hapi.services.tiller.RollbackReleaseRequest") @@ -935,6 +973,8 @@ type ReleaseServiceClient interface { GetReleaseStatus(ctx context.Context, in *GetReleaseStatusRequest, opts ...grpc.CallOption) (*GetReleaseStatusResponse, error) // GetReleaseContent retrieves the release content (chart + value) for the specified release. GetReleaseContent(ctx context.Context, in *GetReleaseContentRequest, opts ...grpc.CallOption) (*GetReleaseContentResponse, error) + // GetReleaseLogs returns a stream of logging information from the release + GetReleaseLogs(ctx context.Context, opts ...grpc.CallOption) (ReleaseService_GetReleaseLogsClient, error) // UpdateRelease updates release content. UpdateRelease(ctx context.Context, in *UpdateReleaseRequest, opts ...grpc.CallOption) (*UpdateReleaseResponse, error) // InstallRelease requests installation of a chart as a new release. @@ -1011,6 +1051,37 @@ func (c *releaseServiceClient) GetReleaseContent(ctx context.Context, in *GetRel return out, nil } +func (c *releaseServiceClient) GetReleaseLogs(ctx context.Context, opts ...grpc.CallOption) (ReleaseService_GetReleaseLogsClient, error) { + stream, err := grpc.NewClientStream(ctx, &_ReleaseService_serviceDesc.Streams[1], c.cc, "/hapi.services.tiller.ReleaseService/GetReleaseLogs", opts...) + if err != nil { + return nil, err + } + x := &releaseServiceGetReleaseLogsClient{stream} + return x, nil +} + +type ReleaseService_GetReleaseLogsClient interface { + Send(*GetReleaseLogsRequest) error + Recv() (*GetReleaseLogsResponse, error) + grpc.ClientStream +} + +type releaseServiceGetReleaseLogsClient struct { + grpc.ClientStream +} + +func (x *releaseServiceGetReleaseLogsClient) Send(m *GetReleaseLogsRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *releaseServiceGetReleaseLogsClient) Recv() (*GetReleaseLogsResponse, error) { + m := new(GetReleaseLogsResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + func (c *releaseServiceClient) UpdateRelease(ctx context.Context, in *UpdateReleaseRequest, opts ...grpc.CallOption) (*UpdateReleaseResponse, error) { out := new(UpdateReleaseResponse) err := grpc.Invoke(ctx, "/hapi.services.tiller.ReleaseService/UpdateRelease", in, out, c.cc, opts...) @@ -1066,7 +1137,7 @@ func (c *releaseServiceClient) GetHistory(ctx context.Context, in *GetHistoryReq } func (c *releaseServiceClient) RunReleaseTest(ctx context.Context, in *TestReleaseRequest, opts ...grpc.CallOption) (ReleaseService_RunReleaseTestClient, error) { - stream, err := grpc.NewClientStream(ctx, &_ReleaseService_serviceDesc.Streams[1], c.cc, "/hapi.services.tiller.ReleaseService/RunReleaseTest", opts...) + stream, err := grpc.NewClientStream(ctx, &_ReleaseService_serviceDesc.Streams[2], c.cc, "/hapi.services.tiller.ReleaseService/RunReleaseTest", opts...) if err != nil { return nil, err } @@ -1117,6 +1188,8 @@ type ReleaseServiceServer interface { GetReleaseStatus(context.Context, *GetReleaseStatusRequest) (*GetReleaseStatusResponse, error) // GetReleaseContent retrieves the release content (chart + value) for the specified release. GetReleaseContent(context.Context, *GetReleaseContentRequest) (*GetReleaseContentResponse, error) + // GetReleaseLogs returns a stream of logging information from the release + GetReleaseLogs(ReleaseService_GetReleaseLogsServer) error // UpdateRelease updates release content. UpdateRelease(context.Context, *UpdateReleaseRequest) (*UpdateReleaseResponse, error) // InstallRelease requests installation of a chart as a new release. @@ -1194,6 +1267,32 @@ func _ReleaseService_GetReleaseContent_Handler(srv interface{}, ctx context.Cont return interceptor(ctx, in, info, handler) } +func _ReleaseService_GetReleaseLogs_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(ReleaseServiceServer).GetReleaseLogs(&releaseServiceGetReleaseLogsServer{stream}) +} + +type ReleaseService_GetReleaseLogsServer interface { + Send(*GetReleaseLogsResponse) error + Recv() (*GetReleaseLogsRequest, error) + grpc.ServerStream +} + +type releaseServiceGetReleaseLogsServer struct { + grpc.ServerStream +} + +func (x *releaseServiceGetReleaseLogsServer) Send(m *GetReleaseLogsResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *releaseServiceGetReleaseLogsServer) Recv() (*GetReleaseLogsRequest, error) { + m := new(GetReleaseLogsRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + func _ReleaseService_UpdateRelease_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(UpdateReleaseRequest) if err := dec(in); err != nil { @@ -1374,6 +1473,12 @@ var _ReleaseService_serviceDesc = grpc.ServiceDesc{ Handler: _ReleaseService_ListReleases_Handler, ServerStreams: true, }, + { + StreamName: "GetReleaseLogs", + Handler: _ReleaseService_GetReleaseLogs_Handler, + ServerStreams: true, + ClientStreams: true, + }, { StreamName: "RunReleaseTest", Handler: _ReleaseService_RunReleaseTest_Handler, @@ -1386,82 +1491,87 @@ var _ReleaseService_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("hapi/services/tiller.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 1217 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xdd, 0x6e, 0xe3, 0xc4, - 0x17, 0xaf, 0xf3, 0x9d, 0x93, 0x36, 0xff, 0x74, 0x9a, 0xb6, 0xae, 0xff, 0x0b, 0x2a, 0x46, 0xb0, - 0xd9, 0x85, 0x4d, 0x21, 0x70, 0x83, 0x84, 0x90, 0xba, 0xdd, 0xa8, 0x2d, 0x94, 0xae, 0xe4, 0x6c, - 0x17, 0x09, 0x01, 0x91, 0x9b, 0x4c, 0x5a, 0xb3, 0x8e, 0x27, 0x78, 0xc6, 0x65, 0x7b, 0xcb, 0x1d, - 0x8f, 0xc2, 0x5b, 0xf0, 0x1e, 0x5c, 0xc2, 0x83, 0x20, 0xcf, 0x87, 0xeb, 0x49, 0xed, 0xd6, 0xf4, - 0x26, 0x9e, 0x99, 0xf3, 0xfd, 0x3b, 0x67, 0xce, 0x9c, 0x80, 0x75, 0xe9, 0x2e, 0xbc, 0x3d, 0x8a, - 0xc3, 0x2b, 0x6f, 0x82, 0xe9, 0x1e, 0xf3, 0x7c, 0x1f, 0x87, 0xfd, 0x45, 0x48, 0x18, 0x41, 0xdd, - 0x98, 0xd6, 0x57, 0xb4, 0xbe, 0xa0, 0x59, 0x5b, 0x5c, 0x62, 0x72, 0xe9, 0x86, 0x4c, 0xfc, 0x0a, - 0x6e, 0x6b, 0x3b, 0x7d, 0x4e, 0x82, 0x99, 0x77, 0x21, 0x09, 0xc2, 0x44, 0x88, 0x7d, 0xec, 0x52, - 0xac, 0xbe, 0x9a, 0x90, 0xa2, 0x79, 0xc1, 0x8c, 0x48, 0xc2, 0xff, 0x35, 0x02, 0xc3, 0x94, 0x8d, - 0xc3, 0x28, 0x90, 0xc4, 0x1d, 0x8d, 0x48, 0x99, 0xcb, 0x22, 0xaa, 0x19, 0xbb, 0xc2, 0x21, 0xf5, - 0x48, 0xa0, 0xbe, 0x82, 0x66, 0xff, 0x59, 0x82, 0x8d, 0x13, 0x8f, 0x32, 0x47, 0x08, 0x52, 0x07, - 0xff, 0x12, 0x61, 0xca, 0x50, 0x17, 0xaa, 0xbe, 0x37, 0xf7, 0x98, 0x69, 0xec, 0x1a, 0xbd, 0xb2, - 0x23, 0x36, 0x68, 0x0b, 0x6a, 0x64, 0x36, 0xa3, 0x98, 0x99, 0xa5, 0x5d, 0xa3, 0xd7, 0x74, 0xe4, - 0x0e, 0x7d, 0x05, 0x75, 0x4a, 0x42, 0x36, 0x3e, 0xbf, 0x36, 0xcb, 0xbb, 0x46, 0xaf, 0x3d, 0xf8, - 0xa0, 0x9f, 0x85, 0x53, 0x3f, 0xb6, 0x34, 0x22, 0x21, 0xeb, 0xc7, 0x3f, 0xcf, 0xaf, 0x9d, 0x1a, - 0xe5, 0xdf, 0x58, 0xef, 0xcc, 0xf3, 0x19, 0x0e, 0xcd, 0x8a, 0xd0, 0x2b, 0x76, 0xe8, 0x10, 0x80, - 0xeb, 0x25, 0xe1, 0x14, 0x87, 0x66, 0x95, 0xab, 0xee, 0x15, 0x50, 0xfd, 0x32, 0xe6, 0x77, 0x9a, - 0x54, 0x2d, 0xd1, 0x97, 0xb0, 0x2a, 0x20, 0x19, 0x4f, 0xc8, 0x14, 0x53, 0xb3, 0xb6, 0x5b, 0xee, - 0xb5, 0x07, 0x3b, 0x42, 0x95, 0x82, 0x7f, 0x24, 0x40, 0x3b, 0x20, 0x53, 0xec, 0xb4, 0x04, 0x7b, - 0xbc, 0xa6, 0xe8, 0x11, 0x34, 0x03, 0x77, 0x8e, 0xe9, 0xc2, 0x9d, 0x60, 0xb3, 0xce, 0x3d, 0xbc, - 0x39, 0xb0, 0x7f, 0x82, 0x86, 0x32, 0x6e, 0x0f, 0xa0, 0x26, 0x42, 0x43, 0x2d, 0xa8, 0x9f, 0x9d, - 0x7e, 0x73, 0xfa, 0xf2, 0xbb, 0xd3, 0xce, 0x0a, 0x6a, 0x40, 0xe5, 0x74, 0xff, 0xdb, 0x61, 0xc7, - 0x40, 0xeb, 0xb0, 0x76, 0xb2, 0x3f, 0x7a, 0x35, 0x76, 0x86, 0x27, 0xc3, 0xfd, 0xd1, 0xf0, 0x45, - 0xa7, 0x64, 0xbf, 0x0b, 0xcd, 0xc4, 0x67, 0x54, 0x87, 0xf2, 0xfe, 0xe8, 0x40, 0x88, 0xbc, 0x18, - 0x8e, 0x0e, 0x3a, 0x86, 0xfd, 0xbb, 0x01, 0x5d, 0x3d, 0x45, 0x74, 0x41, 0x02, 0x8a, 0xe3, 0x1c, - 0x4d, 0x48, 0x14, 0x24, 0x39, 0xe2, 0x1b, 0x84, 0xa0, 0x12, 0xe0, 0xb7, 0x2a, 0x43, 0x7c, 0x1d, - 0x73, 0x32, 0xc2, 0x5c, 0x9f, 0x67, 0xa7, 0xec, 0x88, 0x0d, 0xfa, 0x14, 0x1a, 0x32, 0x74, 0x6a, - 0x56, 0x76, 0xcb, 0xbd, 0xd6, 0x60, 0x53, 0x07, 0x44, 0x5a, 0x74, 0x12, 0x36, 0xfb, 0x10, 0xb6, - 0x0f, 0xb1, 0xf2, 0x44, 0xe0, 0xa5, 0x2a, 0x26, 0xb6, 0xeb, 0xce, 0x31, 0x77, 0x26, 0xb6, 0xeb, - 0xce, 0x31, 0x32, 0xa1, 0x2e, 0xcb, 0x8d, 0xbb, 0x53, 0x75, 0xd4, 0xd6, 0x66, 0x60, 0xde, 0x56, - 0x24, 0xe3, 0xca, 0xd2, 0xf4, 0x21, 0x54, 0xe2, 0x9b, 0xc0, 0xd5, 0xb4, 0x06, 0x48, 0xf7, 0xf3, - 0x38, 0x98, 0x11, 0x87, 0xd3, 0xf5, 0x54, 0x95, 0x97, 0x53, 0x75, 0x94, 0xb6, 0x7a, 0x40, 0x02, - 0x86, 0x03, 0xf6, 0x30, 0xff, 0x4f, 0x60, 0x27, 0x43, 0x93, 0x0c, 0x60, 0x0f, 0xea, 0xd2, 0x35, - 0xae, 0x2d, 0x17, 0x57, 0xc5, 0x65, 0xff, 0x5d, 0x82, 0xee, 0xd9, 0x62, 0xea, 0x32, 0xac, 0x48, - 0x77, 0x38, 0xf5, 0x18, 0xaa, 0xbc, 0xa3, 0x48, 0x2c, 0xd6, 0x85, 0x6e, 0xd1, 0x76, 0x0e, 0xe2, - 0x5f, 0x47, 0xd0, 0xd1, 0x53, 0xa8, 0x5d, 0xb9, 0x7e, 0x84, 0x29, 0x07, 0x22, 0x41, 0x4d, 0x72, - 0xf2, 0x76, 0xe4, 0x48, 0x0e, 0xb4, 0x0d, 0xf5, 0x69, 0x78, 0x1d, 0xf7, 0x13, 0x7e, 0x05, 0x1b, - 0x4e, 0x6d, 0x1a, 0x5e, 0x3b, 0x51, 0x80, 0xde, 0x87, 0xb5, 0xa9, 0x47, 0xdd, 0x73, 0x1f, 0x8f, - 0x2f, 0x09, 0x79, 0x43, 0xf9, 0x2d, 0x6c, 0x38, 0xab, 0xf2, 0xf0, 0x28, 0x3e, 0x43, 0x56, 0x5c, - 0x49, 0x93, 0x10, 0xbb, 0x0c, 0x9b, 0x35, 0x4e, 0x4f, 0xf6, 0x31, 0x86, 0xcc, 0x9b, 0x63, 0x12, - 0x31, 0x7e, 0x75, 0xca, 0x8e, 0xda, 0xa2, 0xf7, 0x60, 0x35, 0xc4, 0x14, 0xb3, 0xb1, 0xf4, 0xb2, - 0xc1, 0x25, 0x5b, 0xfc, 0xec, 0xb5, 0x70, 0x0b, 0x41, 0xe5, 0x57, 0xd7, 0x63, 0x66, 0x93, 0x93, - 0xf8, 0x5a, 0x88, 0x45, 0x14, 0x2b, 0x31, 0x50, 0x62, 0x11, 0xc5, 0x52, 0xac, 0x0b, 0xd5, 0x19, - 0x09, 0x27, 0xd8, 0x6c, 0x71, 0x9a, 0xd8, 0xd8, 0x47, 0xb0, 0xb9, 0x04, 0xf2, 0x43, 0xf3, 0xf5, - 0x8f, 0x01, 0x5b, 0x0e, 0xf1, 0xfd, 0x73, 0x77, 0xf2, 0xa6, 0x40, 0xc6, 0x52, 0xe0, 0x96, 0xee, - 0x06, 0xb7, 0x9c, 0x01, 0x6e, 0xaa, 0x08, 0x2b, 0x5a, 0x11, 0x6a, 0xb0, 0x57, 0xf3, 0x61, 0xaf, - 0xe9, 0xb0, 0x2b, 0x4c, 0xeb, 0x29, 0x4c, 0x13, 0xc0, 0x1a, 0x69, 0xc0, 0xbe, 0x86, 0xed, 0x5b, - 0x51, 0x3e, 0x14, 0xb2, 0x3f, 0x4a, 0xb0, 0x79, 0x1c, 0x50, 0xe6, 0xfa, 0xfe, 0x12, 0x62, 0x49, - 0x3d, 0x1b, 0x85, 0xeb, 0xb9, 0xf4, 0x5f, 0xea, 0xb9, 0xac, 0x41, 0xae, 0xf2, 0x53, 0x49, 0xe5, - 0xa7, 0x50, 0x8d, 0x6b, 0x9d, 0xa5, 0xb6, 0xd4, 0x59, 0xd0, 0x3b, 0x00, 0xa2, 0x28, 0xb9, 0x72, - 0x01, 0x6d, 0x93, 0x9f, 0x9c, 0xca, 0x46, 0xa2, 0xb2, 0xd1, 0xc8, 0xce, 0x46, 0xaa, 0xc2, 0xed, - 0x63, 0xd8, 0x5a, 0x86, 0xea, 0xa1, 0xb0, 0xff, 0x66, 0xc0, 0xf6, 0x59, 0xe0, 0x65, 0x02, 0x9f, - 0x55, 0xaa, 0xb7, 0xa0, 0x28, 0x65, 0x40, 0xd1, 0x85, 0xea, 0x22, 0x0a, 0x2f, 0xb0, 0x84, 0x56, - 0x6c, 0xd2, 0x31, 0x56, 0xb4, 0x18, 0xed, 0x31, 0x98, 0xb7, 0x7d, 0x78, 0x60, 0x44, 0xb1, 0xd7, - 0xc9, 0x4b, 0xd0, 0x14, 0x5d, 0xdf, 0xde, 0x80, 0xf5, 0x43, 0xcc, 0x5e, 0x8b, 0x6b, 0x21, 0xc3, - 0xb3, 0x87, 0x80, 0xd2, 0x87, 0x37, 0xf6, 0xe4, 0x91, 0x6e, 0x4f, 0x8d, 0x45, 0x8a, 0x5f, 0x71, - 0xd9, 0x5f, 0x70, 0xdd, 0x47, 0x1e, 0x65, 0x24, 0xbc, 0xbe, 0x0b, 0xba, 0x0e, 0x94, 0xe7, 0xee, - 0x5b, 0xf9, 0x50, 0xc4, 0x4b, 0xfb, 0x90, 0x7b, 0x90, 0x88, 0x4a, 0x0f, 0xd2, 0xcf, 0xae, 0x51, - 0xec, 0xd9, 0xfd, 0x01, 0xd0, 0x2b, 0x9c, 0x4c, 0x00, 0xf7, 0xbc, 0x58, 0x2a, 0x09, 0x25, 0xbd, - 0xd0, 0x4c, 0xa8, 0x4f, 0x7c, 0xec, 0x06, 0xd1, 0x42, 0xa6, 0x4d, 0x6d, 0xed, 0x1f, 0x61, 0x43, - 0xd3, 0x2e, 0xfd, 0x8c, 0xe3, 0xa1, 0x17, 0x52, 0x7b, 0xbc, 0x44, 0x9f, 0x43, 0x4d, 0x8c, 0x45, - 0x5c, 0x77, 0x7b, 0xf0, 0x48, 0xf7, 0x9b, 0x2b, 0x89, 0x02, 0x39, 0x47, 0x39, 0x92, 0x77, 0xf0, - 0x57, 0x03, 0xda, 0xea, 0xa1, 0x17, 0x43, 0x1b, 0xf2, 0x60, 0x35, 0x3d, 0xd1, 0xa0, 0x27, 0xf9, - 0x33, 0xdd, 0xd2, 0x60, 0x6a, 0x3d, 0x2d, 0xc2, 0x2a, 0x22, 0xb0, 0x57, 0x3e, 0x31, 0x10, 0x85, - 0xce, 0xf2, 0xa0, 0x81, 0x9e, 0x65, 0xeb, 0xc8, 0x99, 0x6c, 0xac, 0x7e, 0x51, 0x76, 0x65, 0x16, - 0x5d, 0xf1, 0x9a, 0xd1, 0xa7, 0x03, 0x74, 0xaf, 0x1a, 0x7d, 0x20, 0xb1, 0xf6, 0x0a, 0xf3, 0x27, - 0x76, 0x7f, 0x86, 0x35, 0xed, 0x85, 0x43, 0x39, 0x68, 0x65, 0xcd, 0x1a, 0xd6, 0x47, 0x85, 0x78, - 0x13, 0x5b, 0x73, 0x68, 0xeb, 0x4d, 0x0a, 0xe5, 0x28, 0xc8, 0xec, 0xfa, 0xd6, 0xc7, 0xc5, 0x98, - 0x13, 0x73, 0x14, 0x3a, 0xcb, 0x3d, 0x24, 0x2f, 0x8f, 0x39, 0xfd, 0x2e, 0x2f, 0x8f, 0x79, 0xad, - 0xc9, 0x5e, 0x41, 0x2e, 0xc0, 0x4d, 0x0b, 0x41, 0x8f, 0x73, 0x13, 0xa2, 0x77, 0x1e, 0xab, 0x77, - 0x3f, 0x63, 0x62, 0x62, 0x01, 0xff, 0x5b, 0x7a, 0x63, 0x51, 0x0e, 0x34, 0xd9, 0x03, 0x87, 0xf5, - 0xac, 0x20, 0xf7, 0x52, 0x50, 0xb2, 0x2b, 0xdd, 0x11, 0x94, 0xde, 0xf2, 0xee, 0x08, 0x6a, 0xa9, - 0xc1, 0xd9, 0x2b, 0xc8, 0x83, 0xb6, 0x13, 0x05, 0xd2, 0x74, 0xdc, 0x16, 0x50, 0x8e, 0xf4, 0xed, - 0xae, 0x66, 0x3d, 0x29, 0xc0, 0x79, 0x73, 0xbf, 0x9f, 0xc3, 0xf7, 0x0d, 0xc5, 0x7a, 0x5e, 0xe3, - 0xff, 0x69, 0x3f, 0xfb, 0x37, 0x00, 0x00, 0xff, 0xff, 0xf3, 0x7c, 0x9c, 0x49, 0xc1, 0x0f, 0x00, - 0x00, + // 1303 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xef, 0x72, 0xdb, 0x44, + 0x10, 0x8f, 0xfc, 0xdf, 0x9b, 0xd4, 0xa4, 0xd7, 0xfc, 0x51, 0x4d, 0xcb, 0x04, 0x75, 0xa0, 0x6e, + 0x4b, 0x9d, 0x62, 0xf8, 0xc2, 0x0c, 0x30, 0x93, 0xa6, 0x99, 0xa4, 0x10, 0xd2, 0x19, 0xb9, 0x2d, + 0x33, 0x1d, 0xc0, 0xa3, 0xd8, 0x67, 0x47, 0x54, 0xd6, 0xb9, 0xba, 0x53, 0x68, 0xbe, 0xf2, 0x8d, + 0x47, 0xe1, 0x2d, 0x78, 0x02, 0x5e, 0x02, 0x1e, 0x84, 0xb9, 0x7f, 0x8a, 0x4e, 0x91, 0x12, 0x91, + 0x2f, 0x96, 0xee, 0x76, 0xef, 0xb7, 0xbb, 0xbf, 0x5d, 0xed, 0xad, 0xa1, 0x7b, 0xe2, 0x2d, 0xfc, + 0x6d, 0x8a, 0xa3, 0x53, 0x7f, 0x8c, 0xe9, 0x36, 0xf3, 0x83, 0x00, 0x47, 0xfd, 0x45, 0x44, 0x18, + 0x41, 0x6b, 0x5c, 0xd6, 0xd7, 0xb2, 0xbe, 0x94, 0x75, 0x37, 0xc4, 0x89, 0xf1, 0x89, 0x17, 0x31, + 0xf9, 0x2b, 0xb5, 0xbb, 0x9b, 0xe9, 0x7d, 0x12, 0x4e, 0xfd, 0x99, 0x12, 0x48, 0x13, 0x11, 0x0e, + 0xb0, 0x47, 0xb1, 0x7e, 0x2a, 0xd9, 0x86, 0x21, 0x0b, 0xc8, 0xcc, 0x00, 0xd3, 0xfb, 0x7e, 0x38, + 0x25, 0x4a, 0xf0, 0xa1, 0x21, 0x60, 0x98, 0xb2, 0x51, 0x14, 0x87, 0x4a, 0x78, 0xdb, 0x10, 0x52, + 0xe6, 0xb1, 0x98, 0x1a, 0x4e, 0x9c, 0xe2, 0x88, 0xfa, 0x24, 0xd4, 0x4f, 0x29, 0x73, 0xfe, 0xaa, + 0xc0, 0xad, 0x43, 0x9f, 0x32, 0x57, 0x1e, 0xa4, 0x2e, 0x7e, 0x17, 0x63, 0xca, 0xd0, 0x1a, 0xd4, + 0x03, 0x7f, 0xee, 0x33, 0xdb, 0xda, 0xb2, 0x7a, 0x55, 0x57, 0x2e, 0xd0, 0x06, 0x34, 0xc8, 0x74, + 0x4a, 0x31, 0xb3, 0x2b, 0x5b, 0x56, 0xaf, 0xed, 0xaa, 0x15, 0xfa, 0x16, 0x9a, 0x94, 0x44, 0x6c, + 0x74, 0x7c, 0x66, 0x57, 0xb7, 0xac, 0x5e, 0x67, 0xf0, 0x49, 0x3f, 0x8f, 0xbf, 0x3e, 0xb7, 0x34, + 0x24, 0x11, 0xeb, 0xf3, 0x9f, 0xa7, 0x67, 0x6e, 0x83, 0x8a, 0x27, 0xc7, 0x9d, 0xfa, 0x01, 0xc3, + 0x91, 0x5d, 0x93, 0xb8, 0x72, 0x85, 0xf6, 0x01, 0x04, 0x2e, 0x89, 0x26, 0x38, 0xb2, 0xeb, 0x02, + 0xba, 0x57, 0x02, 0xfa, 0x05, 0xd7, 0x77, 0xdb, 0x54, 0xbf, 0xa2, 0xaf, 0x61, 0x45, 0x52, 0x32, + 0x1a, 0x93, 0x09, 0xa6, 0x76, 0x63, 0xab, 0xda, 0xeb, 0x0c, 0x6e, 0x4b, 0x28, 0x9d, 0x96, 0xa1, + 0x24, 0x6d, 0x97, 0x4c, 0xb0, 0xbb, 0x2c, 0xd5, 0xf9, 0x3b, 0x45, 0x77, 0xa0, 0x1d, 0x7a, 0x73, + 0x4c, 0x17, 0xde, 0x18, 0xdb, 0x4d, 0xe1, 0xe1, 0xf9, 0x86, 0xf3, 0x0b, 0xb4, 0xb4, 0x71, 0x67, + 0x00, 0x0d, 0x19, 0x1a, 0x5a, 0x86, 0xe6, 0xab, 0xa3, 0xef, 0x8f, 0x5e, 0xfc, 0x78, 0xb4, 0xba, + 0x84, 0x5a, 0x50, 0x3b, 0xda, 0xf9, 0x61, 0x6f, 0xd5, 0x42, 0x37, 0xe1, 0xc6, 0xe1, 0xce, 0xf0, + 0xe5, 0xc8, 0xdd, 0x3b, 0xdc, 0xdb, 0x19, 0xee, 0x3d, 0x5b, 0xad, 0x38, 0x1f, 0x41, 0x3b, 0xf1, + 0x19, 0x35, 0xa1, 0xba, 0x33, 0xdc, 0x95, 0x47, 0x9e, 0xed, 0x0d, 0x77, 0x57, 0x2d, 0xe7, 0x0f, + 0x0b, 0xd6, 0xcc, 0x14, 0xd1, 0x05, 0x09, 0x29, 0xe6, 0x39, 0x1a, 0x93, 0x38, 0x4c, 0x72, 0x24, + 0x16, 0x08, 0x41, 0x2d, 0xc4, 0xef, 0x75, 0x86, 0xc4, 0x3b, 0xd7, 0x64, 0x84, 0x79, 0x81, 0xc8, + 0x4e, 0xd5, 0x95, 0x0b, 0xf4, 0x39, 0xb4, 0x54, 0xe8, 0xd4, 0xae, 0x6d, 0x55, 0x7b, 0xcb, 0x83, + 0x75, 0x93, 0x10, 0x65, 0xd1, 0x4d, 0xd4, 0x9c, 0x7d, 0xd8, 0xdc, 0xc7, 0xda, 0x13, 0xc9, 0x97, + 0xae, 0x18, 0x6e, 0xd7, 0x9b, 0x63, 0xe1, 0x0c, 0xb7, 0xeb, 0xcd, 0x31, 0xb2, 0xa1, 0xa9, 0xca, + 0x4d, 0xb8, 0x53, 0x77, 0xf5, 0xd2, 0x61, 0x60, 0x5f, 0x04, 0x52, 0x71, 0xe5, 0x21, 0x7d, 0x0a, + 0x35, 0xfe, 0x25, 0x08, 0x98, 0xe5, 0x01, 0x32, 0xfd, 0x7c, 0x1e, 0x4e, 0x89, 0x2b, 0xe4, 0x66, + 0xaa, 0xaa, 0xd9, 0x54, 0x1d, 0xa4, 0xad, 0xee, 0x92, 0x90, 0xe1, 0x90, 0x5d, 0xcf, 0xff, 0x43, + 0xb8, 0x9d, 0x83, 0xa4, 0x02, 0xd8, 0x86, 0xa6, 0x72, 0x4d, 0xa0, 0x15, 0xf2, 0xaa, 0xb5, 0x9c, + 0x37, 0xb0, 0x7e, 0x8e, 0x76, 0x48, 0x66, 0x09, 0xa9, 0x3b, 0xb0, 0x42, 0xe3, 0x63, 0x3a, 0x8e, + 0xfc, 0x05, 0xe3, 0x5e, 0x48, 0xb8, 0xbb, 0x26, 0xdc, 0x21, 0x99, 0x0d, 0x53, 0x4a, 0xae, 0x71, + 0xc4, 0xf9, 0x06, 0x36, 0xb2, 0xd8, 0xca, 0xcd, 0x7b, 0x50, 0x0d, 0xc8, 0x4c, 0x61, 0xde, 0xbc, + 0x80, 0xe9, 0x72, 0xa9, 0xf3, 0x4f, 0x05, 0xd6, 0x5e, 0x2d, 0x26, 0x1e, 0xc3, 0xda, 0xeb, 0x4b, + 0xf8, 0xba, 0x0f, 0x75, 0xd1, 0x04, 0x55, 0x9a, 0x14, 0xa6, 0xec, 0x94, 0xbb, 0xfc, 0xd7, 0x95, + 0x72, 0xf4, 0x10, 0x1a, 0xa7, 0x5e, 0x10, 0x63, 0x2a, 0x72, 0x94, 0x24, 0x54, 0x69, 0x8a, 0x0e, + 0xea, 0x2a, 0x0d, 0xb4, 0x09, 0xcd, 0x49, 0x74, 0xc6, 0x5b, 0x9d, 0xe8, 0x0e, 0x2d, 0xb7, 0x31, + 0x89, 0xce, 0xdc, 0x38, 0x44, 0xf7, 0xe0, 0xc6, 0xc4, 0xa7, 0xde, 0x71, 0x80, 0x47, 0x27, 0x84, + 0xbc, 0xa5, 0xa2, 0x41, 0xb4, 0xdc, 0x15, 0xb5, 0x79, 0xc0, 0xf7, 0x50, 0x97, 0x17, 0xf9, 0x38, + 0xc2, 0x1e, 0xc3, 0x76, 0x43, 0xc8, 0x93, 0x35, 0x4f, 0x2f, 0xf3, 0xe7, 0x98, 0xc4, 0x4c, 0x7c, + 0xd5, 0x55, 0x57, 0x2f, 0xd1, 0xc7, 0xb0, 0x12, 0x61, 0x8a, 0xd9, 0x48, 0x79, 0xd9, 0x12, 0x27, + 0x97, 0xc5, 0xde, 0x6b, 0xe9, 0x16, 0x82, 0xda, 0x6f, 0x9e, 0xcf, 0xec, 0xb6, 0x10, 0x89, 0x77, + 0x79, 0x2c, 0xa6, 0x58, 0x1f, 0x03, 0x7d, 0x2c, 0xa6, 0x58, 0x1d, 0x5b, 0x83, 0xfa, 0x94, 0x44, + 0x63, 0x6c, 0x2f, 0x0b, 0x99, 0x5c, 0x38, 0x07, 0xb0, 0x9e, 0x21, 0xf9, 0xba, 0xa5, 0xf4, 0xaf, + 0x05, 0x1b, 0x2e, 0x09, 0x82, 0x63, 0x6f, 0xfc, 0xb6, 0x44, 0xc6, 0x52, 0xe4, 0x56, 0x2e, 0x27, + 0xb7, 0x9a, 0x43, 0x6e, 0xea, 0xfb, 0xa8, 0x19, 0xdf, 0x87, 0x41, 0x7b, 0xbd, 0x98, 0xf6, 0x86, + 0x49, 0xbb, 0xe6, 0xb4, 0x99, 0xe2, 0x34, 0x21, 0xac, 0x95, 0x26, 0xec, 0x3b, 0xd8, 0xbc, 0x10, + 0xe5, 0x75, 0x29, 0xfb, 0xb3, 0x02, 0xeb, 0xcf, 0x43, 0xca, 0xbc, 0x20, 0xc8, 0x30, 0x96, 0xd4, + 0xb3, 0x55, 0xba, 0x9e, 0x2b, 0xff, 0xa7, 0x9e, 0xab, 0x06, 0xe5, 0x3a, 0x3f, 0xb5, 0x54, 0x7e, + 0x4a, 0xd5, 0xb8, 0xd1, 0xf4, 0x1a, 0x99, 0xa6, 0x87, 0xee, 0x02, 0xc8, 0xa2, 0x14, 0xe0, 0x92, + 0xda, 0xb6, 0xd8, 0x39, 0x52, 0x3d, 0x4e, 0x67, 0xa3, 0x95, 0x9f, 0x8d, 0x54, 0x85, 0x3b, 0xcf, + 0x61, 0x23, 0x4b, 0xd5, 0x75, 0x69, 0xff, 0xdd, 0x82, 0xcd, 0x57, 0xa1, 0x9f, 0x4b, 0x7c, 0x5e, + 0xa9, 0x5e, 0xa0, 0xa2, 0x92, 0x43, 0xc5, 0x1a, 0xd4, 0x17, 0x71, 0x34, 0xc3, 0x8a, 0x5a, 0xb9, + 0x48, 0xc7, 0x58, 0x33, 0x62, 0x74, 0x46, 0x60, 0x5f, 0xf4, 0xe1, 0x9a, 0x11, 0x71, 0xaf, 0x93, + 0x4b, 0xaa, 0x2d, 0x2f, 0x24, 0xe7, 0x16, 0xdc, 0xdc, 0xc7, 0xec, 0xb5, 0xfc, 0x2c, 0x54, 0x78, + 0xce, 0x1e, 0xa0, 0xf4, 0xe6, 0xb9, 0x3d, 0xb5, 0x65, 0xda, 0xd3, 0x13, 0x9b, 0xd6, 0xd7, 0x5a, + 0xce, 0x57, 0x02, 0xfb, 0xc0, 0xa7, 0x8c, 0x44, 0x67, 0x97, 0x51, 0xb7, 0x0a, 0xd5, 0xb9, 0xf7, + 0x5e, 0xdd, 0x61, 0xfc, 0xd5, 0xd9, 0x17, 0x1e, 0x24, 0x47, 0x95, 0x07, 0xe9, 0x89, 0xc0, 0x2a, + 0x37, 0x11, 0xfc, 0x04, 0xe8, 0x25, 0x4e, 0x86, 0x93, 0x2b, 0x2e, 0x53, 0x9d, 0x84, 0x8a, 0x59, + 0x68, 0x36, 0x34, 0xc7, 0x01, 0xf6, 0xc2, 0x78, 0xa1, 0xd2, 0xa6, 0x97, 0xce, 0xcf, 0x70, 0xcb, + 0x40, 0x57, 0x7e, 0xf2, 0x78, 0xe8, 0x4c, 0xa1, 0xf3, 0x57, 0xf4, 0x25, 0x34, 0xe4, 0xc4, 0x26, + 0xb0, 0x3b, 0x83, 0x3b, 0xa6, 0xdf, 0x02, 0x24, 0x0e, 0xd5, 0x88, 0xe7, 0x2a, 0xdd, 0xc1, 0xdf, + 0x6d, 0xe8, 0xe8, 0x19, 0x44, 0xce, 0x93, 0xc8, 0x87, 0x95, 0xf4, 0xb0, 0x85, 0x1e, 0x14, 0x8f, + 0x9b, 0x99, 0x99, 0xb9, 0xfb, 0xb0, 0x8c, 0xaa, 0x8c, 0xc0, 0x59, 0x7a, 0x62, 0x21, 0x0a, 0xab, + 0xd9, 0x19, 0x08, 0x3d, 0xce, 0xc7, 0x28, 0x18, 0xba, 0xba, 0xfd, 0xb2, 0xea, 0xda, 0x2c, 0x3a, + 0x15, 0x35, 0x63, 0x0e, 0x2e, 0xe8, 0x4a, 0x18, 0x73, 0x56, 0xea, 0x6e, 0x97, 0xd6, 0x4f, 0xec, + 0xbe, 0x83, 0x8e, 0x39, 0x86, 0xa0, 0x47, 0x57, 0x81, 0xa4, 0x06, 0xa1, 0xee, 0x67, 0xe5, 0x94, + 0xb5, 0xb9, 0x9e, 0xf5, 0xc4, 0x42, 0xbf, 0xc2, 0x0d, 0xe3, 0x52, 0x45, 0x05, 0x09, 0xca, 0x1b, + 0x6f, 0xba, 0x8f, 0x4a, 0xe9, 0x26, 0xe1, 0xcd, 0xa1, 0x63, 0xf6, 0xc5, 0xa2, 0xf0, 0x72, 0x2f, + 0x9a, 0xa2, 0xf0, 0xf2, 0x5b, 0xad, 0xb3, 0xc4, 0x4b, 0x27, 0xdb, 0xb6, 0x8a, 0x4a, 0xa7, 0xa0, + 0xc5, 0x16, 0x95, 0x4e, 0x51, 0x37, 0x74, 0x96, 0x90, 0x07, 0x70, 0xde, 0xb5, 0xd0, 0xfd, 0xc2, + 0x8c, 0x98, 0xcd, 0xae, 0xdb, 0xbb, 0x5a, 0x31, 0x31, 0xb1, 0x80, 0x0f, 0x32, 0xd7, 0x3a, 0x2a, + 0xa0, 0x26, 0x7f, 0xc6, 0xe9, 0x3e, 0x2e, 0xa9, 0x9d, 0x09, 0x4a, 0x35, 0xc2, 0x4b, 0x82, 0x32, + 0xbb, 0xec, 0x25, 0x41, 0x65, 0x7a, 0xaa, 0xb3, 0x84, 0x7c, 0xe8, 0xb8, 0x71, 0xa8, 0x4c, 0xf3, + 0x4e, 0x84, 0x0a, 0x4e, 0x5f, 0x6c, 0xa4, 0xdd, 0x07, 0x25, 0x34, 0xcf, 0x5b, 0xca, 0x53, 0x78, + 0xd3, 0xd2, 0xaa, 0xc7, 0x0d, 0xf1, 0x0f, 0xff, 0x8b, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x21, + 0xdc, 0x0b, 0xff, 0xe7, 0x10, 0x00, 0x00, } diff --git a/pkg/proto/hapi/version/version.pb.go b/pkg/proto/hapi/version/version.pb.go index 13c8568f0..e3d8a7096 100644 --- a/pkg/proto/hapi/version/version.pb.go +++ b/pkg/proto/hapi/version/version.pb.go @@ -1,5 +1,6 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. +// Code generated by protoc-gen-go. // source: hapi/version/version.proto +// DO NOT EDIT! /* Package version is a generated protocol buffer package. diff --git a/pkg/tiller/logs/log_streamer.go b/pkg/tiller/logs/log_streamer.go new file mode 100644 index 000000000..0c2329e39 --- /dev/null +++ b/pkg/tiller/logs/log_streamer.go @@ -0,0 +1,106 @@ +package logs + +import ( + rspb "k8s.io/helm/pkg/proto/hapi/release" + "strings" +) + +type Logsub struct { + C chan *rspb.Log + release string + sources []rspb.Log_Source + level rspb.Log_Level +} + +type LogWriter struct { + rls string + source rspb.Log_Source + level rspb.Log_Level + ps *Pubsub +} + +type release struct { + name string + sourceMappings map[rspb.Log_Source]map[*Logsub]bool +} + +type Pubsub struct { + releases map[string]*release +} + +func New() *Pubsub { + rls := make(map[string]*release) + return &Pubsub{releases: rls} +} + +func newRelease(name string) *release { + rs := &release{name: name} + rs.sourceMappings = make(map[rspb.Log_Source]map[*Logsub]bool, len(rspb.Log_Source_name)) + return rs +} + +func (rs *release) subscribe(sub *Logsub) { + for _, source := range sub.sources { + Log_Source := rspb.Log_Source(source) + if _, ok := rs.sourceMappings[Log_Source]; !ok { + subs := make(map[*Logsub]bool, 1) + rs.sourceMappings[Log_Source] = subs + } + rs.sourceMappings[Log_Source][sub] = true + } +} + +func (ps *Pubsub) subscribe(sub *Logsub) { + if _, ok := ps.releases[sub.release]; !ok { + rs := newRelease(sub.release) + rs.subscribe(sub) + ps.releases[sub.release] = rs + } + ps.releases[sub.release].subscribe(sub) +} + +func (ps *Pubsub) Subscribe(release string, level rspb.Log_Level, sources ...rspb.Log_Source) *Logsub { + ch := make(chan *rspb.Log) + ls := &Logsub{C: ch, release: release, level: level, sources: sources} + ps.subscribe(ls) + return ls +} + +func (ps *Pubsub) Unsubscribe(sub *Logsub) { + if rs, ok := ps.releases[sub.release]; ok { + for source, subMap := range rs.sourceMappings { + delete(subMap, sub) + if len(subMap) == 0 { + delete(rs.sourceMappings, source) + } + } + if len(rs.sourceMappings) == 0 { + delete(ps.releases, sub.release) + } + } +} + +func (ps *Pubsub) PubLog(rls string, source rspb.Log_Source, level rspb.Log_Level, message string) { + log := &rspb.Log{Release: rls, Source: source, Level: level, Log: message} + if rls, ok := ps.releases[log.Release]; ok { + if subs, ok := rls.sourceMappings[log.Source]; ok { + for sub := range subs { + if sub.level >= log.Level { + sub.C <- log + } + } + } + } +} + +func (ps *Pubsub) GetWriter(rls string, source rspb.Log_Source, level rspb.Log_Level) *LogWriter { + return &LogWriter{rls: rls, source: source, level: level, ps: ps} +} + +func (lw *LogWriter) Write(p []byte) (n int, err error) { + logs := strings.Split(string(p), "\n") + for _, l := range logs { + lw.ps.PubLog(lw.rls, lw.source, lw.level, l) + } + return len(p), nil +} diff --git a/pkg/tiller/logs/log_streamer_test.go b/pkg/tiller/logs/log_streamer_test.go new file mode 100644 index 000000000..2fa8e50b3 --- /dev/null +++ b/pkg/tiller/logs/log_streamer_test.go @@ -0,0 +1,89 @@ +package logs + +import ( + "testing" + "fmt" + rspb "k8s.io/helm/pkg/proto/hapi/release" +) + +func TestPubsub_Subscribe(t *testing.T) { + ps := New() + rlsName := "testrls" + + ps.Subscribe(rlsName, rspb.Log_WARNING, rspb.Log_HOOK) + if len(ps.releases[rlsName].sourceMappings) != 1 { + t.Error("testrls should have one log source entry") + } + ps.Subscribe(rlsName, rspb.Log_WARNING, rspb.Log_POD) + if len(ps.releases[rlsName].sourceMappings) != 2 { + t.Error("testrls should have two log source entries") + } + + if len(ps.releases[rlsName].sourceMappings[rspb.Log_HOOK]) != 1 { + t.Error("testrls should have one subscription to the Log_HOOK event stream") + } + if len(ps.releases[rlsName].sourceMappings[rspb.Log_POD]) != 1 { + t.Error("testrls should have one subscription to the Log_POD event stream") + } + if len(ps.releases[rlsName].sourceMappings[rspb.Log_SYSTEM]) != 0 { + t.Error("testrls should have no subscriptions to the Log_SYSTEM event stream") + } +} + +func TestPubsub_Unsubscribe(t *testing.T) { + ps := New() + rlsName := "testrls" + + sub := ps.Subscribe(rlsName, rspb.Log_WARNING, rspb.Log_HOOK) + if len(ps.releases[rlsName].sourceMappings) != 1 { + t.Error("testrls should have one log source entry") + } + + ps.Unsubscribe(sub) + if _, ok := ps.releases[rlsName]; ok { + t.Error("pubsub should have no entry for testrls") + } + + sub2 := ps.Subscribe(rlsName, rspb.Log_WARNING, rspb.Log_HOOK) + sub3 := ps.Subscribe(rlsName, rspb.Log_WARNING, rspb.Log_POD) + + if len(ps.releases[rlsName].sourceMappings) != 2 { + t.Error("testrls should have two log source entries") + } + + ps.Unsubscribe(sub3) + + if len(ps.releases[rlsName].sourceMappings) != 1 { + t.Error("testrls should have one log source entry") + } + + ps.Unsubscribe(sub2) + if _, ok := ps.releases[rlsName]; ok { + t.Error("pubsub should have no entry for testrls") + } + +} + +func TestPubsub_PubLog(t *testing.T) { + +} + +func Example() { + ps := New() + sub := ps.Subscribe("testrls", rspb.Log_WARNING, rspb.Log_HOOK, rspb.Log_POD) + + go func() { + for { + select { + case l := <-sub.C: + fmt.Println(l.Log) + } + } + }() + + // No output as log level is too low for the configured subscription + ps.PubLog("testrls", rspb.Log_POD, rspb.Log_DEBUG, "Test log!") + // Picked up by the subscription + ps.PubLog("testrls", rspb.Log_POD, rspb.Log_ERR, "Test log!") + // Output: Test log! +}