Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
H
helm3
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
helm3
Commits
ae4ff5cd
Commit
ae4ff5cd
authored
Aug 09, 2016
by
Michelle Noorali
Committed by
GitHub
Aug 09, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1030 from michelleN/feat/690-helm-upgrade
feat(*): implement helm upgrade + upgrade hooks
parents
37e33e7d
f9922877
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
289 additions
and
104 deletions
+289
-104
tiller.proto
_proto/hapi/services/tiller.proto
+3
-0
upgrade.go
cmd/helm/upgrade.go
+5
-2
upgrade_test.go
cmd/helm/upgrade_test.go
+6
-2
release_server.go
cmd/tiller/release_server.go
+98
-48
release_server_test.go
cmd/tiller/release_server_test.go
+110
-0
option.go
pkg/helm/option.go
+15
-2
tiller.pb.go
pkg/proto/hapi/services/tiller.pb.go
+52
-50
No files found.
_proto/hapi/services/tiller.proto
View file @
ae4ff5cd
...
...
@@ -162,6 +162,9 @@ message UpdateReleaseRequest {
hapi.chart.Config
values
=
3
;
// dry_run, if true, will run through the release logic, but neither create
bool
dry_run
=
4
;
// DisableHooks causes the server to skip running any hooks for the upgrade.
bool
disable_hooks
=
5
;
}
// UpdateReleaseResponse is the response to an update request.
...
...
cmd/helm/upgrade.go
View file @
ae4ff5cd
...
...
@@ -39,6 +39,7 @@ type upgradeCmd struct {
out
io
.
Writer
client
helm
.
Interface
dryRun
bool
disableHooks
bool
valuesFile
string
}
...
...
@@ -70,6 +71,7 @@ func newUpgradeCmd(client helm.Interface, out io.Writer) *cobra.Command {
f
:=
cmd
.
Flags
()
f
.
StringVarP
(
&
upgrade
.
valuesFile
,
"values"
,
"f"
,
""
,
"path to a values YAML file"
)
f
.
BoolVar
(
&
upgrade
.
dryRun
,
"dry-run"
,
false
,
"simulate an upgrade"
)
f
.
BoolVar
(
&
upgrade
.
disableHooks
,
"disable-hooks"
,
false
,
"disable pre/post upgrade hooks"
)
return
cmd
}
...
...
@@ -88,12 +90,13 @@ func (u *upgradeCmd) run() error {
}
}
_
,
err
=
u
.
client
.
UpdateRelease
(
u
.
release
,
chartPath
,
helm
.
UpdateValueOverrides
(
rawVals
),
helm
.
UpgradeDryRun
(
u
.
dryRun
))
_
,
err
=
u
.
client
.
UpdateRelease
(
u
.
release
,
chartPath
,
helm
.
UpdateValueOverrides
(
rawVals
),
helm
.
UpgradeDryRun
(
u
.
dryRun
)
,
helm
.
UpgradeDisableHooks
(
u
.
disableHooks
)
)
if
err
!=
nil
{
return
prettyError
(
err
)
}
fmt
.
Fprintf
(
u
.
out
,
"It's not you. It's me
\n
Your upgrade looks valid but this command is still under active development.
\n
Hang tight.
\n
"
)
success
:=
u
.
release
+
" has been upgraded. Happy Helming!
\n
"
fmt
.
Fprintf
(
u
.
out
,
success
)
return
nil
...
...
cmd/helm/upgrade_test.go
View file @
ae4ff5cd
...
...
@@ -52,18 +52,22 @@ func TestUpgradeCmd(t *testing.T) {
Description
:
"A Helm chart for Kubernetes"
,
Version
:
"0.1.2"
,
}
chartPath
,
err
=
chartutil
.
Create
(
cfile
,
tmpChart
)
if
err
!=
nil
{
t
.
Errorf
(
"Error creating chart: %v"
,
err
)
}
ch
,
_
=
chartutil
.
Load
(
chartPath
)
ch
,
err
=
chartutil
.
Load
(
chartPath
)
if
err
!=
nil
{
t
.
Errorf
(
"Error loading updated chart: %v"
,
err
)
}
tests
:=
[]
releaseCase
{
{
name
:
"upgrade a release"
,
args
:
[]
string
{
"funny-bunny"
,
chartPath
},
resp
:
releaseMock
(
&
releaseOptions
{
name
:
"funny-bunny"
,
version
:
2
,
chart
:
ch
}),
expected
:
"
It's not you. It's me
\n
Your upgrade looks valid but this command is still under active development.
\n
Hang tight.
\n
"
,
expected
:
"
funny-bunny has been upgraded. Happy Helming!
\n
"
,
},
}
...
...
cmd/tiller/release_server.go
View file @
ae4ff5cd
...
...
@@ -24,7 +24,6 @@ import (
"regexp"
"sort"
"github.com/Masterminds/semver"
"github.com/ghodss/yaml"
"github.com/technosophos/moniker"
ctx
"golang.org/x/net/context"
...
...
@@ -171,65 +170,107 @@ func (s *releaseServer) GetReleaseContent(c ctx.Context, req *services.GetReleas
}
func
(
s
*
releaseServer
)
UpdateRelease
(
c
ctx
.
Context
,
req
*
services
.
UpdateReleaseRequest
)
(
*
services
.
UpdateReleaseResponse
,
error
)
{
rel
,
err
:=
s
.
prepareUpdate
(
req
)
currentRelease
,
updatedRelease
,
err
:=
s
.
prepareUpdate
(
req
)
if
err
!=
nil
{
return
nil
,
err
}
// TODO: perform update
res
,
err
:=
s
.
performUpdate
(
currentRelease
,
updatedRelease
,
req
)
if
err
!=
nil
{
return
nil
,
err
}
if
err
:=
s
.
env
.
Releases
.
Update
(
updatedRelease
);
err
!=
nil
{
return
nil
,
err
}
return
res
,
nil
}
func
(
s
*
releaseServer
)
performUpdate
(
originalRelease
,
updatedRelease
*
release
.
Release
,
req
*
services
.
UpdateReleaseRequest
)
(
*
services
.
UpdateReleaseResponse
,
error
)
{
res
:=
&
services
.
UpdateReleaseResponse
{
Release
:
updatedRelease
}
if
req
.
DryRun
{
log
.
Printf
(
"Dry run for %s"
,
updatedRelease
.
Name
)
return
res
,
nil
}
// pre-ugrade hooks
if
!
req
.
DisableHooks
{
if
err
:=
s
.
execHook
(
updatedRelease
.
Hooks
,
updatedRelease
.
Name
,
updatedRelease
.
Namespace
,
preUpgrade
);
err
!=
nil
{
return
res
,
err
}
}
kubeCli
:=
s
.
env
.
KubeClient
original
:=
bytes
.
NewBufferString
(
originalRelease
.
Manifest
)
modified
:=
bytes
.
NewBufferString
(
updatedRelease
.
Manifest
)
if
err
:=
kubeCli
.
Update
(
updatedRelease
.
Namespace
,
original
,
modified
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"Update of %s failed: %s"
,
updatedRelease
.
Name
,
err
)
}
// post-upgrade hooks
if
!
req
.
DisableHooks
{
if
err
:=
s
.
execHook
(
updatedRelease
.
Hooks
,
updatedRelease
.
Name
,
updatedRelease
.
Namespace
,
postUpgrade
);
err
!=
nil
{
return
res
,
err
}
}
return
&
services
.
UpdateReleaseResponse
{
Release
:
rel
},
nil
updatedRelease
.
Info
.
Status
.
Code
=
release
.
Status_DEPLOYED
return
res
,
nil
}
// prepareUpdate builds a release for an update operation.
func
(
s
*
releaseServer
)
prepareUpdate
(
req
*
services
.
UpdateReleaseRequest
)
(
*
release
.
Release
,
error
)
{
// prepareUpdate builds a
n updated
release for an update operation.
func
(
s
*
releaseServer
)
prepareUpdate
(
req
*
services
.
UpdateReleaseRequest
)
(
*
release
.
Release
,
*
release
.
Release
,
error
)
{
if
req
.
Name
==
""
{
return
nil
,
errMissingRelease
return
nil
,
nil
,
errMissingRelease
}
if
req
.
Chart
==
nil
{
return
nil
,
errMissingChart
return
nil
,
nil
,
errMissingChart
}
// finds the non-deleted release with the given name
rel
,
err
:=
s
.
env
.
Releases
.
Read
(
req
.
Name
)
currentRelease
,
err
:=
s
.
env
.
Releases
.
Read
(
req
.
Name
)
if
err
!=
nil
{
return
nil
,
err
return
nil
,
nil
,
err
}
//validate chart name is same as previous release
givenChart
:=
req
.
Chart
.
Metadata
.
Name
releasedChart
:=
rel
.
Chart
.
Metadata
.
Name
if
givenChart
!=
releasedChart
{
return
nil
,
fmt
.
Errorf
(
"Given chart, %s, does not match chart originally released, %s"
,
givenChart
,
releasedChart
)
ts
:=
timeconv
.
Now
()
options
:=
chartutil
.
ReleaseOptions
{
Name
:
req
.
Name
,
Time
:
ts
,
Namespace
:
currentRelease
.
Namespace
,
}
// validate new chart version is higher than old
givenChartVersion
:=
req
.
Chart
.
Metadata
.
Version
releasedChartVersion
:=
rel
.
Chart
.
Metadata
.
Version
c
,
err
:=
semver
.
NewConstraint
(
"> "
+
releasedChartVersion
)
valuesToRender
,
err
:=
chartutil
.
ToRenderValues
(
req
.
Chart
,
req
.
Values
,
options
)
if
err
!=
nil
{
return
nil
,
err
return
nil
,
nil
,
err
}
v
,
err
:=
semver
.
NewVersion
(
givenChartVersion
)
hooks
,
manifestDoc
,
err
:=
s
.
renderResources
(
req
.
Chart
,
valuesToRender
)
if
err
!=
nil
{
return
nil
,
err
}
if
a
:=
c
.
Check
(
v
);
!
a
{
return
nil
,
fmt
.
Errorf
(
"Given chart (%s-%v) must be a higher version than released chart (%s-%v)"
,
givenChart
,
givenChartVersion
,
releasedChart
,
releasedChartVersion
)
return
nil
,
nil
,
err
}
// Store an updated release.
updatedRelease
:=
&
release
.
Release
{
Name
:
req
.
Name
,
Namespace
:
currentRelease
.
Namespace
,
Chart
:
req
.
Chart
,
Config
:
req
.
Values
,
Version
:
rel
.
Version
+
1
,
Info
:
&
release
.
Info
{
FirstDeployed
:
currentRelease
.
Info
.
FirstDeployed
,
LastDeployed
:
ts
,
Status
:
&
release
.
Status
{
Code
:
release
.
Status_UNKNOWN
},
},
Version
:
currentRelease
.
Version
+
1
,
Manifest
:
manifestDoc
.
String
(),
Hooks
:
hooks
,
}
return
updatedRelease
,
nil
return
currentRelease
,
updatedRelease
,
nil
}
func
(
s
*
releaseServer
)
uniqName
(
start
string
,
reuse
bool
)
(
string
,
error
)
{
...
...
@@ -308,12 +349,36 @@ func (s *releaseServer) prepareRelease(req *services.InstallReleaseRequest) (*re
return
nil
,
err
}
renderer
:=
s
.
engine
(
req
.
Chart
)
files
,
err
:=
renderer
.
Render
(
req
.
Chart
,
valuesToRender
)
hooks
,
manifestDoc
,
err
:=
s
.
renderResources
(
req
.
Chart
,
valuesToRender
)
if
err
!=
nil
{
return
nil
,
err
}
// Store a release.
rel
:=
&
release
.
Release
{
Name
:
name
,
Namespace
:
req
.
Namespace
,
Chart
:
req
.
Chart
,
Config
:
req
.
Values
,
Info
:
&
release
.
Info
{
FirstDeployed
:
ts
,
LastDeployed
:
ts
,
Status
:
&
release
.
Status
{
Code
:
release
.
Status_UNKNOWN
},
},
Manifest
:
manifestDoc
.
String
(),
Hooks
:
hooks
,
Version
:
1
,
}
return
rel
,
nil
}
func
(
s
*
releaseServer
)
renderResources
(
ch
*
chart
.
Chart
,
values
chartutil
.
Values
)
([]
*
release
.
Hook
,
*
bytes
.
Buffer
,
error
)
{
renderer
:=
s
.
engine
(
ch
)
files
,
err
:=
renderer
.
Render
(
ch
,
values
)
if
err
!=
nil
{
return
nil
,
nil
,
err
}
// Sort hooks, manifests, and partials. Only hooks and manifests are returned,
// as partials are not used after renderer.Render. Empty manifests are also
// removed here.
...
...
@@ -321,7 +386,7 @@ func (s *releaseServer) prepareRelease(req *services.InstallReleaseRequest) (*re
if
err
!=
nil
{
// By catching parse errors here, we can prevent bogus releases from going
// to Kubernetes.
return
nil
,
err
return
nil
,
nil
,
err
}
// Aggregate all valid manifests into one big doc.
...
...
@@ -331,22 +396,7 @@ func (s *releaseServer) prepareRelease(req *services.InstallReleaseRequest) (*re
b
.
WriteString
(
file
)
}
// Store a release.
rel
:=
&
release
.
Release
{
Name
:
name
,
Namespace
:
req
.
Namespace
,
Chart
:
req
.
Chart
,
Config
:
req
.
Values
,
Info
:
&
release
.
Info
{
FirstDeployed
:
ts
,
LastDeployed
:
ts
,
Status
:
&
release
.
Status
{
Code
:
release
.
Status_UNKNOWN
},
},
Manifest
:
b
.
String
(),
Hooks
:
hooks
,
Version
:
1
,
}
return
rel
,
nil
return
hooks
,
b
,
nil
}
// validateYAML checks to see if YAML is well-formed.
...
...
cmd/tiller/release_server_test.go
View file @
ae4ff5cd
...
...
@@ -44,6 +44,16 @@ data:
name: value
`
var
manifestWithUpgradeHooks
=
`apiVersion: v1
kind: ConfigMap
metadata:
name: test-cm
annotations:
"helm.sh/hook": post-upgrade,pre-upgrade
data:
name: value
`
func
rsFixture
()
*
releaseServer
{
return
&
releaseServer
{
env
:
mockEnvironment
(),
...
...
@@ -81,6 +91,7 @@ func releaseStub() *release.Release {
},
Chart
:
chartStub
(),
Config
:
&
chart
.
Config
{
Raw
:
`name = "value"`
},
Version
:
1
,
Hooks
:
[]
*
release
.
Hook
{
{
Name
:
"test-cm"
,
...
...
@@ -289,6 +300,105 @@ func TestInstallReleaseReuseName(t *testing.T) {
}
}
func
TestUpdateRelease
(
t
*
testing
.
T
)
{
c
:=
context
.
Background
()
rs
:=
rsFixture
()
rel
:=
releaseStub
()
rs
.
env
.
Releases
.
Create
(
rel
)
req
:=
&
services
.
UpdateReleaseRequest
{
Name
:
rel
.
Name
,
Chart
:
&
chart
.
Chart
{
Metadata
:
&
chart
.
Metadata
{
Name
:
"hello"
},
Templates
:
[]
*
chart
.
Template
{
{
Name
:
"hello"
,
Data
:
[]
byte
(
"hello: world"
)},
{
Name
:
"hooks"
,
Data
:
[]
byte
(
manifestWithUpgradeHooks
)},
},
},
}
res
,
err
:=
rs
.
UpdateRelease
(
c
,
req
)
if
err
!=
nil
{
t
.
Errorf
(
"Failed updated: %s"
,
err
)
}
if
res
.
Release
.
Name
==
""
{
t
.
Errorf
(
"Expected release name."
)
}
if
res
.
Release
.
Name
!=
rel
.
Name
{
t
.
Errorf
(
"Updated release name does not match previous release name. Expected %s, got %s"
,
rel
.
Name
,
res
.
Release
.
Name
)
}
if
res
.
Release
.
Namespace
!=
rel
.
Namespace
{
t
.
Errorf
(
"Expected release namespace '%s', got '%s'."
,
rel
.
Namespace
,
res
.
Release
.
Namespace
)
}
updated
,
err
:=
rs
.
env
.
Releases
.
Read
(
res
.
Release
.
Name
)
if
err
!=
nil
{
t
.
Errorf
(
"Expected release for %s (%v)."
,
res
.
Release
.
Name
,
rs
.
env
.
Releases
)
}
if
len
(
updated
.
Hooks
)
!=
1
{
t
.
Fatalf
(
"Expected 1 hook, got %d"
,
len
(
updated
.
Hooks
))
}
if
updated
.
Hooks
[
0
]
.
Manifest
!=
manifestWithUpgradeHooks
{
t
.
Errorf
(
"Unexpected manifest: %v"
,
updated
.
Hooks
[
0
]
.
Manifest
)
}
if
updated
.
Hooks
[
0
]
.
Events
[
0
]
!=
release
.
Hook_POST_UPGRADE
{
t
.
Errorf
(
"Expected event 0 to be post upgrade"
)
}
if
updated
.
Hooks
[
0
]
.
Events
[
1
]
!=
release
.
Hook_PRE_UPGRADE
{
t
.
Errorf
(
"Expected event 0 to be pre upgrade"
)
}
if
len
(
res
.
Release
.
Manifest
)
==
0
{
t
.
Errorf
(
"No manifest returned: %v"
,
res
.
Release
)
}
if
len
(
updated
.
Manifest
)
==
0
{
t
.
Errorf
(
"Expected manifest in %v"
,
res
)
}
if
!
strings
.
Contains
(
updated
.
Manifest
,
"---
\n
# Source: hello/hello
\n
hello: world"
)
{
t
.
Errorf
(
"unexpected output: %s"
,
rel
.
Manifest
)
}
if
res
.
Release
.
Version
!=
2
{
t
.
Errorf
(
"Expected release version to be %v, got %v"
,
2
,
res
.
Release
.
Version
)
}
}
func
TestUpdateReleaseNoHooks
(
t
*
testing
.
T
)
{
c
:=
context
.
Background
()
rs
:=
rsFixture
()
rel
:=
releaseStub
()
rs
.
env
.
Releases
.
Create
(
rel
)
req
:=
&
services
.
UpdateReleaseRequest
{
Name
:
rel
.
Name
,
DisableHooks
:
true
,
Chart
:
&
chart
.
Chart
{
Metadata
:
&
chart
.
Metadata
{
Name
:
"hello"
},
Templates
:
[]
*
chart
.
Template
{
{
Name
:
"hello"
,
Data
:
[]
byte
(
"hello: world"
)},
{
Name
:
"hooks"
,
Data
:
[]
byte
(
manifestWithUpgradeHooks
)},
},
},
}
res
,
err
:=
rs
.
UpdateRelease
(
c
,
req
)
if
err
!=
nil
{
t
.
Errorf
(
"Failed updated: %s"
,
err
)
}
if
hl
:=
res
.
Release
.
Hooks
[
0
]
.
LastRun
;
hl
!=
nil
{
t
.
Errorf
(
"Expected that no hooks were run. Got %d"
,
hl
)
}
}
func
TestUninstallRelease
(
t
*
testing
.
T
)
{
c
:=
context
.
Background
()
rs
:=
rsFixture
()
...
...
pkg/helm/option.go
View file @
ae4ff5cd
...
...
@@ -143,6 +143,13 @@ func DeleteDryRun(dry bool) DeleteOption {
}
}
// UpgradeDisableHooks will disable hooks for an upgrade operation.
func
UpgradeDisableHooks
(
disable
bool
)
UpdateOption
{
return
func
(
opts
*
options
)
{
opts
.
disableHooks
=
disable
}
}
// UpgradeDryRun will (if true) execute an upgrade as a dry run.
func
UpgradeDryRun
(
dry
bool
)
UpdateOption
{
return
func
(
opts
*
options
)
{
...
...
@@ -237,9 +244,15 @@ func (o *options) rpcDeleteRelease(rlsName string, rlc rls.ReleaseServiceClient,
// Executes tiller.UpdateRelease RPC.
func
(
o
*
options
)
rpcUpdateRelease
(
rlsName
string
,
chr
*
cpb
.
Chart
,
rlc
rls
.
ReleaseServiceClient
,
opts
...
UpdateOption
)
(
*
rls
.
UpdateReleaseResponse
,
error
)
{
//TODO: handle dryRun
for
_
,
opt
:=
range
opts
{
opt
(
o
)
}
o
.
updateReq
.
Chart
=
chr
o
.
updateReq
.
DryRun
=
o
.
dryRun
o
.
updateReq
.
Name
=
rlsName
return
rlc
.
UpdateRelease
(
context
.
TODO
(),
&
rls
.
UpdateReleaseRequest
{
Name
:
rlsName
,
Chart
:
chr
}
)
return
rlc
.
UpdateRelease
(
context
.
TODO
(),
&
o
.
updateReq
)
}
// Executes tiller.GetReleaseStatus RPC.
...
...
pkg/proto/hapi/services/tiller.pb.go
View file @
ae4ff5cd
...
...
@@ -226,6 +226,8 @@ type UpdateReleaseRequest struct {
Values
*
hapi_chart
.
Config
`protobuf:"bytes,3,opt,name=values" json:"values,omitempty"`
// dry_run, if true, will run through the release logic, but neither create
DryRun
bool
`protobuf:"varint,4,opt,name=dry_run,json=dryRun" json:"dry_run,omitempty"`
// DisableHooks causes the server to skip running any hooks for the upgrade.
DisableHooks
bool
`protobuf:"varint,5,opt,name=disable_hooks,json=disableHooks" json:"disable_hooks,omitempty"`
}
func
(
m
*
UpdateReleaseRequest
)
Reset
()
{
*
m
=
UpdateReleaseRequest
{}
}
...
...
@@ -624,54 +626,54 @@ var _ReleaseService_serviceDesc = grpc.ServiceDesc{
}
var
fileDescriptor0
=
[]
byte
{
// 7
69
bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x09
,
0x6e
,
0x88
,
0x02
,
0xff
,
0x9c
,
0x56
,
0xdb
,
0x6e
,
0xd3
,
0x4
a
,
0x1
4
,
0xad
,
0x93
,
0xd4
,
0x49
,
0x76
,
0x2f
,
0x4a
,
0xe7
,
0xb4
,
0x8d
,
0x8f
,
0x75
,
0x0e
,
0x42
,
0x46
,
0x
40
,
0x29
,
0xd4
,
0x81
,
0xf0
,
0x8e
,
0x94
,
0xb6
,
0x51
,
0x5b
,
0x35
,
0xa4
,
0xd2
,
0x84
,
0x82
,
0xc4
,
0x0
3
,
0x91
,
0x9b
,
0x4c
,
0xa8
,
0xc1
,
0xb5
,
0x83
,
0x67
,
0x52
,
0xd1
,
0x4f
,
0xe0
,
0x0f
,
0xf8
,
0x14
,
0x
3e
,
0x88
,
0xbf
,
0xe0
,
0x85
,
0xb9
,
0xd8
,
0x26
,
0x17
,
0x1b
,
0x4c
,
0x5f
,
0x9c
,
0x99
,
0xd9
,
0x6
b
,
0x
af
,
0x7d
,
0xdf
,
0x0a
,
0x98
,
0x97
,
0xce
,
0xd8
,
0x6d
,
0x50
,
0x12
,
0x5e
,
0xbb
,
0x03
,
0x42
,
0x1b
,
0x
cc
,
0xf5
,
0x3c
,
0x12
,
0xda
,
0xe3
,
0x30
,
0x60
,
0x01
,
0xda
,
0x14
,
0x32
,
0x3b
,
0x96
,
0xd9
,
0x4a
,
0x
66
,
0x6e
,
0x4b
,
0x8d
,
0xc1
,
0xa5
,
0x13
,
0x32
,
0xf5
,
0x55
,
0x68
,
0xb3
,
0x3e
,
0xfd
,
0x1e
,
0xf8
,
0x
23
,
0xf7
,
0x7d
,
0x24
,
0x50
,
0x26
,
0x42
,
0xe2
,
0x11
,
0x87
,
0x92
,
0xf8
,
0x77
,
0x46
,
0x29
,
0x96
,
0x
b9
,
0xfe
,
0x28
,
0x50
,
0x02
,
0xeb
,
0xbb
,
0x06
,
0xff
,
0x74
,
0x5c
,
0xca
,
0xb0
,
0x12
,
0x51
,
0x4c
,
0x
3e
,
0x4d
,
0x08
,
0x65
,
0x68
,
0x13
,
0x96
,
0x3d
,
0xf7
,
0xca
,
0x65
,
0x86
,
0x76
,
0x57
,
0xdb
,
0x29
,
0x
62
,
0x75
,
0x41
,
0xdb
,
0xa0
,
0x07
,
0xa3
,
0x11
,
0x25
,
0xcc
,
0x28
,
0xf0
,
0xe7
,
0x2a
,
0x8e
,
0x6e
,
0x
e8
,
0x05
,
0x94
,
0x69
,
0x10
,
0xb2
,
0xfe
,
0xc5
,
0x8d
,
0x51
,
0xe4
,
0x82
,
0xf5
,
0xe6
,
0x7d
,
0x3
b
,
0x
2d
,
0x26
,
0x5b
,
0x58
,
0xea
,
0x71
,
0xa0
,
0x2d
,
0x3e
,
0xfb
,
0x37
,
0x58
,
0xa7
,
0xf2
,
0x57
,
0xf0
,
0x
8e
,
0x5c
,
0x8f
,
0x91
,
0xd0
,
0x28
,
0x29
,
0x5e
,
0x75
,
0x43
,
0x47
,
0x00
,
0x92
,
0x37
,
0x08
,
0x87
,
0x
5c
,
0xb6
,
0x2c
,
0xa9
,
0x77
,
0x72
,
0x50
,
0x9f
,
0x09
,
0x3c
,
0xae
,
0xd2
,
0xf8
,
0x68
,
0xbd
,
0x83
,
0x
4a
,
0x0c
,
0xb0
,
0x9a
,
0xa0
,
0x2b
,
0xf3
,
0x68
,
0x05
,
0xca
,
0xe7
,
0xdd
,
0xd3
,
0xee
,
0xd9
,
0x9b
,
0x
6e
,
0x6d
,
0x09
,
0x55
,
0xa0
,
0xd4
,
0x6d
,
0xbd
,
0x6c
,
0xd7
,
0x34
,
0xb4
,
0x01
,
0x6b
,
0x9d
,
0x56
,
0xe
f
,
0x55
,
0x1f
,
0xb7
,
0x3b
,
0xed
,
0x56
,
0xaf
,
0x7d
,
0x58
,
0x2b
,
0x58
,
0x77
,
0xa0
,
0x9a
,
0xf0
,
0x
a2
,
0x32
,
0x14
,
0x5b
,
0xbd
,
0x03
,
0xa5
,
0x72
,
0xd8
,
0xe6
,
0x27
,
0xcd
,
0xfa
,
0xa2
,
0xc1
,
0xe6
,
0x
6c
,
0x1a
,
0xe9
,
0x38
,
0xf0
,
0x29
,
0x11
,
0x79
,
0x1c
,
0x04
,
0x13
,
0x3f
,
0xc9
,
0xa3
,
0xbc
,
0x20
,
0x
04
,
0x25
,
0x9f
,
0x7c
,
0x8e
,
0xb3
,
0x28
,
0xcf
,
0x02
,
0xc9
,
0x02
,
0xe6
,
0x78
,
0x32
,
0x83
,
0x1c
,
0x2
9
,
0x2f
,
0xe8
,
0x19
,
0x54
,
0xa2
,
0xaa
,
0x51
,
0x9e
,
0x9b
,
0xe2
,
0xce
,
0x4a
,
0x73
,
0x4b
,
0xc5
,
0x
1f
,
0xd7
,
0x37
,
0xb2
,
0x88
,
0x13
,
0x98
,
0xb5
,
0x07
,
0xf5
,
0x23
,
0x12
,
0x7b
,
0xd2
,
0x63
,
0x0
e
,
0x
9b
,
0x24
,
0x55
,
0x15
,
0x76
,
0x9d
,
0x2b
,
0x22
,
0x9d
,
0x11
,
0x76
,
0xf9
,
0xd9
,
0x7a
,
0x0d
,
0xc6
,
0x
22
,
0x3c
,
0xf2
,
0x3e
,
0x05
,
0x8f
,
0x1e
,
0x40
,
0x49
,
0xf4
,
0x8f
,
0xf4
,
0x7d
,
0xa5
,
0x89
,
0x66
,
0x
bd
,
0x39
,
0xe1
,
0x12
,
0x2c
,
0xe5
,
0x96
,
0x3d
,
0xcd
,
0x7b
,
0x10
,
0xf8
,
0x8c
,
0xf8
,
0xec
,
0x77
,
0x7e
,
0x
74
,
0xe0
,
0xdf
,
0x14
,
0x7c
,
0xe4
,
0x48
,
0x03
,
0xca
,
0x91
,
0x09
,
0xa9
,
0x93
,
0x99
,
0x85
,
0x
18
,
0x65
,
0x7d
,
0xe5
,
0x05
,
0x39
,
0x1f
,
0x0f
,
0x1d
,
0x46
,
0x62
,
0x51
,
0xb6
,
0x69
,
0xf4
,
0x90
,
0x
17
,
0x49
,
0xcc
,
0x53
,
0x14
,
0xd3
,
0x86
,
0xe2
,
0x56
,
0x43
,
0x77
,
0x20
,
0xbe
,
0x58
,
0xc9
,
0xd1
,
0x
2e
,
0xe8
,
0xd7
,
0x8e
,
0xc7
,
0x79
,
0x64
,
0x91
,
0x92
,
0xe8
,
0x23
,
0xa4
,
0x1c
,
0x46
,
0x1c
,
0x2
1
,
0x
50
,
0x1d
,
0xca
,
0xc3
,
0xf0
,
0xa6
,
0x1f
,
0x4e
,
0x7c
,
0xd9
,
0xd4
,
0x15
,
0xac
,
0xf3
,
0x2b
,
0x9e
,
0x
f8
,
0xd6
,
0x31
,
0x6c
,
0xcd
,
0x79
,
0x76
,
0xdb
,
0x20
,
0x7f
,
0x68
,
0xb0
,
0x75
,
0xe2
,
0x53
,
0xde
,
0x
27
,
0xde
,
0x5c
,
0x94
,
0x49
,
0x44
,
0x5a
,
0xee
,
0x88
,
0x0a
,
0x7f
,
0x13
,
0x51
,
0x71
,
0x3a
,
0xa2
,
0x
24
,
0xa7
,
0xa5
,
0xa9
,
0x9c
,
0xde
,
0x83
,
0xb5
,
0xa1
,
0x4b
,
0x9d
,
0x0b
,
0x8f
,
0xf4
,
0x2f
,
0x83
,
0x
e0
,
0x23
,
0x95
,
0xd3
,
0x5b
,
0xc1
,
0xab
,
0xd1
,
0xe3
,
0xb1
,
0x78
,
0x43
,
0xff
,
0x41
,
0x55
,
0x80
,
0x
e9
,
0xd8
,
0x19
,
0x10
,
0x43
,
0x97
,
0xda
,
0xbf
,
0x1e
,
0xd0
,
0xff
,
0x00
,
0x21
,
0x99
,
0x50
,
0xd2
,
0x
97
,
0xe4
,
0x65
,
0xa9
,
0x5f
,
0x95
,
0x2f
,
0x5d
,
0xd1
,
0x30
,
0x27
,
0xb0
,
0x3d
,
0x1f
,
0xfc
,
0x6d
,
0x
13
,
0x89
,
0xa1
,
0x7e
,
0xee
,
0xbb
,
0xa9
,
0x99
,
0x4c
,
0xeb
,
0x97
,
0x85
,
0xd8
,
0x0a
,
0x8b
,
0xb1
,
0x
59
,
0xa7
,
0x60
,
0x2c
,
0x72
,
0xde
,
0xd2
,
0xc1
,
0xe6
,
0xb7
,
0x65
,
0x58
,
0x8f
,
0x47
,
0x54
,
0x2d
,
0x
3e
,
0xe4
,
0xc2
,
0xea
,
0xf4
,
0xc6
,
0x41
,
0x8f
,
0xb2
,
0xf7
,
0xe2
,
0xdc
,
0x72
,
0x37
,
0x77
,
0xf
3
,
0x
40
,
0x95
,
0xab
,
0xd6
,
0xd2
,
0x53
,
0x0d
,
0x51
,
0xa8
,
0xcd
,
0xaf
,
0x08
,
0xb4
,
0x97
,
0xce
,
0x91
,
0x
b1
,
0x79
,
0x4c
,
0x3b
,
0x2f
,
0x3c
,
0x36
,
0x8b
,
0xae
,
0x61
,
0x63
,
0x61
,
0x1f
,
0xa0
,
0x3f
,
0xd2
,
0x
cc
,
0x2e
,
0x1a
,
0xb3
,
0x91
,
0x1b
,
0x9f
,
0xd8
,
0xfd
,
0x00
,
0x6b
,
0x33
,
0xe3
,
0x89
,
0x32
,
0xb2
,
0x
95
,
0xb6
,
0x5d
,
0xcc
,
0xc7
,
0xb9
,
0xb0
,
0x89
,
0xad
,
0x2b
,
0x58
,
0x9f
,
0x6d
,
0x61
,
0x94
,
0x41
,
0x
90
,
0x3a
,
0xe5
,
0xe6
,
0x93
,
0x7c
,
0xe0
,
0xc4
,
0x1c
,
0xaf
,
0xe3
,
0x7c
,
0x4b
,
0x66
,
0xd5
,
0x31
,
0x
63
,
0x1c
,
0xb2
,
0xea
,
0x98
,
0xd5
,
0xe9
,
0xd6
,
0xd2
,
0x3e
,
0xbc
,
0xad
,
0xc4
,
0xe8
,
0x0b
,
0x5d
,
0x
fe
,
0xe9
,
0x78
,
0xfe
,
0x33
,
0x00
,
0x00
,
0xff
,
0xff
,
0xa6
,
0x56
,
0x6f
,
0xa5
,
0x0e
,
0x09
,
0x00
,
0x00
,
// 7
74
bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x09
,
0x6e
,
0x88
,
0x02
,
0xff
,
0x9c
,
0x56
,
0xdb
,
0x6e
,
0xd3
,
0x4
c
,
0x1
0
,
0xae
,
0x93
,
0x34
,
0x87
,
0xe9
,
0x41
,
0xe9
,
0xfe
,
0x6d
,
0x93
,
0xdf
,
0xfa
,
0x7f
,
0x84
,
0x8c
,
0x
80
,
0x52
,
0xa8
,
0x03
,
0xe1
,
0x1e
,
0x29
,
0x6d
,
0xa3
,
0xb6
,
0x6a
,
0x48
,
0xa5
,
0x0d
,
0x05
,
0x89
,
0x0
b
,
0x22
,
0x37
,
0xd9
,
0x50
,
0x83
,
0x6b
,
0x07
,
0xef
,
0xa6
,
0xa2
,
0x8f
,
0xc0
,
0x1b
,
0x71
,
0xc3
,
0x
db
,
0xf0
,
0x16
,
0xdc
,
0xb0
,
0x07
,
0xaf
,
0xc9
,
0xc1
,
0x06
,
0xd3
,
0x1b
,
0x67
,
0x77
,
0xe7
,
0xd
b
,
0x
6f
,
0x66
,
0xbe
,
0x99
,
0x9d
,
0x16
,
0xcc
,
0x4b
,
0x67
,
0xec
,
0x36
,
0x28
,
0x09
,
0xaf
,
0xdd
,
0x01
,
0x
a1
,
0x0d
,
0xe6
,
0x7a
,
0x1e
,
0x09
,
0xed
,
0x71
,
0x18
,
0xb0
,
0x00
,
0x6d
,
0x0a
,
0x9b
,
0xad
,
0x6d
,
0x
b6
,
0xb2
,
0x99
,
0xdb
,
0xf2
,
0xc6
,
0xe0
,
0xd2
,
0x09
,
0x99
,
0xfa
,
0x2a
,
0xb4
,
0x59
,
0x9b
,
0x3e
,
0x
0f
,
0xfc
,
0x91
,
0xfb
,
0x3e
,
0x32
,
0x28
,
0x17
,
0x21
,
0xf1
,
0x88
,
0x43
,
0x89
,
0xfe
,
0x9d
,
0xb9
,
0x
a4
,
0x6d
,
0xae
,
0x3f
,
0x0a
,
0x94
,
0xc1
,
0xfa
,
0x6e
,
0xc0
,
0x3f
,
0x1d
,
0x97
,
0x32
,
0xac
,
0x4c
,
0x
14
,
0x93
,
0x4f
,
0x13
,
0x42
,
0x19
,
0xda
,
0x84
,
0x65
,
0xcf
,
0xbd
,
0x72
,
0x59
,
0xdd
,
0xb8
,
0x6b
,
0x
ec
,
0xe4
,
0xb1
,
0xda
,
0xa0
,
0x6d
,
0x28
,
0x06
,
0xa3
,
0x11
,
0x25
,
0xac
,
0x9e
,
0xe3
,
0xc7
,
0x15
,
0x
1c
,
0xed
,
0xd0
,
0x0b
,
0x28
,
0xd1
,
0x20
,
0x64
,
0xfd
,
0x8b
,
0x9b
,
0x7a
,
0x9e
,
0x1b
,
0xd6
,
0x9
b
,
0x
f7
,
0xed
,
0xa4
,
0x9c
,
0x6c
,
0xe1
,
0xa9
,
0xc7
,
0x81
,
0xb6
,
0xf8
,
0xec
,
0xdf
,
0xe0
,
0x22
,
0x95
,
0x
bf
,
0x82
,
0x77
,
0xe4
,
0x7a
,
0x8c
,
0x84
,
0xf5
,
0x82
,
0xe2
,
0x55
,
0x3b
,
0x74
,
0x04
,
0x20
,
0x79
,
0x
83
,
0x70
,
0xc8
,
0x6d
,
0xcb
,
0x92
,
0x7a
,
0x27
,
0x03
,
0xf5
,
0x99
,
0xc0
,
0xe3
,
0x0a
,
0xd5
,
0x4b
,
0x
eb
,
0x1d
,
0x94
,
0x35
,
0xc0
,
0x6a
,
0x42
,
0x51
,
0xb9
,
0x47
,
0x2b
,
0x50
,
0x3a
,
0xef
,
0x9e
,
0x76
,
0x
cf
,
0xde
,
0x74
,
0xab
,
0x4b
,
0xa8
,
0x0c
,
0x85
,
0x6e
,
0xeb
,
0x65
,
0xbb
,
0x6a
,
0xa0
,
0x0d
,
0x58
,
0xe
b
,
0xb4
,
0x7a
,
0xaf
,
0xfa
,
0xb8
,
0xdd
,
0x69
,
0xb7
,
0x7a
,
0xed
,
0xc3
,
0x6a
,
0xce
,
0xba
,
0x03
,
0x
95
,
0x98
,
0x17
,
0x95
,
0x20
,
0xdf
,
0xea
,
0x1d
,
0xa8
,
0x2b
,
0x87
,
0x6d
,
0xbe
,
0x32
,
0xac
,
0x2f
,
0x
06
,
0x6c
,
0xce
,
0xca
,
0x48
,
0xc7
,
0x81
,
0x4f
,
0x89
,
0xd0
,
0x71
,
0x10
,
0x4c
,
0xfc
,
0x58
,
0x47
,
0x
b9
,
0x41
,
0x08
,
0x0a
,
0x3e
,
0xf9
,
0xac
,
0x55
,
0x94
,
0x6b
,
0x81
,
0x64
,
0x01
,
0x73
,
0x3c
,
0xa9
,
0x2
0
,
0x47
,
0xca
,
0x0d
,
0x7a
,
0x06
,
0xe5
,
0xa8
,
0x6a
,
0x94
,
0x6b
,
0x93
,
0xdf
,
0x59
,
0x69
,
0x6e
,
0x
a9
,
0xfc
,
0x75
,
0x7d
,
0x23
,
0x8f
,
0x38
,
0x86
,
0x59
,
0x7b
,
0x50
,
0x3b
,
0x22
,
0x3a
,
0x92
,
0x1
e
,
0x
73
,
0xd8
,
0x24
,
0xae
,
0xaa
,
0xf0
,
0xeb
,
0x5c
,
0x11
,
0x19
,
0x8c
,
0xf0
,
0xcb
,
0xd7
,
0xd6
,
0x6b
,
0x
a8
,
0x2f
,
0xc2
,
0xa3
,
0xe8
,
0x13
,
0xf0
,
0xe8
,
0x01
,
0x14
,
0x44
,
0xff
,
0xc8
,
0xd8
,
0x57
,
0x9a
,
0x
68
,
0x36
,
0x9a
,
0x13
,
0x6e
,
0xc1
,
0xd2
,
0x6e
,
0xd9
,
0xd3
,
0xbc
,
0x07
,
0x81
,
0xcf
,
0x88
,
0xcf
,
0x7e
,
0x
17
,
0x47
,
0x07
,
0xfe
,
0x4d
,
0xc0
,
0x47
,
0x81
,
0x34
,
0xa0
,
0x14
,
0xb9
,
0x90
,
0x77
,
0x52
,
0x
55
,
0xd0
,
0x28
,
0xeb
,
0x1b
,
0x2f
,
0xc8
,
0xf9
,
0x78
,
0xe8
,
0x30
,
0xa2
,
0x4d
,
0xe9
,
0xae
,
0xd1
,
0x
43
,
0x5e
,
0x24
,
0xf1
,
0x9e
,
0xa2
,
0x9c
,
0x36
,
0x14
,
0xb7
,
0x7a
,
0x74
,
0x07
,
0xe2
,
0x8b
,
0x95
,
0x
1d
,
0xed
,
0x42
,
0xf1
,
0xda
,
0xf1
,
0x38
,
0x8f
,
0x2c
,
0x52
,
0x9c
,
0x7d
,
0x84
,
0x94
,
0x8f
,
0x1
1
,
0x
47
,
0x08
,
0x54
,
0x83
,
0xd2
,
0x30
,
0xbc
,
0xe9
,
0x87
,
0x13
,
0x5f
,
0x36
,
0x75
,
0x19
,
0x17
,
0xf9
,
0x
16
,
0x4f
,
0x7c
,
0x74
,
0x0f
,
0xd6
,
0x86
,
0x2e
,
0x75
,
0x2e
,
0x3c
,
0xd2
,
0xbf
,
0x0c
,
0x82
,
0x8f
,
0x
54
,
0xf6
,
0x75
,
0x19
,
0xaf
,
0x46
,
0x87
,
0xc7
,
0xe2
,
0xcc
,
0x3a
,
0x86
,
0xad
,
0xb9
,
0xf0
,
0x6f
,
0x
ab
,
0xc4
,
0x0f
,
0x03
,
0xb6
,
0x4e
,
0x7c
,
0xca
,
0x9b
,
0xc9
,
0x9b
,
0x93
,
0x22
,
0x4e
,
0xdb
,
0xc8
,
0x
9c
,
0x76
,
0xee
,
0x6f
,
0xd2
,
0xce
,
0xcf
,
0xa4
,
0xad
,
0x85
,
0x2f
,
0x4c
,
0x09
,
0x9f
,
0x45
,
0x0a
,
0x
f4
,
0x1f
,
0x54
,
0x04
,
0x98
,
0x8e
,
0x9d
,
0x01
,
0xa9
,
0x17
,
0xe5
,
0xed
,
0x5f
,
0x07
,
0xe8
,
0x7f
,
0x
80
,
0x90
,
0x4c
,
0x28
,
0xe9
,
0x4b
,
0xf2
,
0x92
,
0xbc
,
0x5f
,
0x91
,
0x27
,
0x5d
,
0xd1
,
0x55
,
0x27
,
0x
b0
,
0x3d
,
0x9f
,
0xfc
,
0x6d
,
0x85
,
0xc4
,
0x50
,
0x3b
,
0xf7
,
0xdd
,
0x44
,
0x25
,
0x93
,
0x9a
,
0x6a
,
0x
21
,
0xb7
,
0x5c
,
0x42
,
0x99
,
0x4f
,
0xa1
,
0xbe
,
0xc8
,
0x79
,
0xcb
,
0x00
,
0x9b
,
0x5f
,
0x97
,
0x61
,
0x
5d
,
0xbf
,
0x63
,
0x35
,
0x1d
,
0x91
,
0x0b
,
0xab
,
0xd3
,
0x63
,
0x09
,
0x3d
,
0x4a
,
0x1f
,
0x9e
,
0x7
3
,
0x
7f
,
0x01
,
0xcc
,
0xdd
,
0x2c
,
0x50
,
0x15
,
0xaa
,
0xb5
,
0xf4
,
0xd4
,
0x40
,
0x14
,
0xaa
,
0xf3
,
0x73
,
0x
04
,
0xed
,
0x25
,
0x73
,
0xa4
,
0x8c
,
0x27
,
0xd3
,
0xce
,
0x0a
,
0xd7
,
0x6e
,
0xd1
,
0x35
,
0x6c
,
0x2c
,
0x
0c
,
0x0d
,
0xf4
,
0x47
,
0x9a
,
0xd9
,
0x69
,
0x64
,
0x36
,
0x32
,
0xe3
,
0x63
,
0xbf
,
0x1f
,
0x60
,
0x6d
,
0x
e6
,
0x79
,
0xa2
,
0x14
,
0xb5
,
0x92
,
0x46
,
0x90
,
0xf9
,
0x38
,
0x13
,
0x36
,
0xf6
,
0x75
,
0x05
,
0xeb
,
0x
b3
,
0x2d
,
0x8c
,
0x52
,
0x08
,
0x12
,
0x5f
,
0xb9
,
0xf9
,
0x24
,
0x1b
,
0x38
,
0x76
,
0xc7
,
0xeb
,
0x38
,
0x
df
,
0x92
,
0x69
,
0x75
,
0x4c
,
0x79
,
0x0e
,
0x69
,
0x75
,
0x4c
,
0xeb
,
0x74
,
0x6b
,
0x69
,
0x1f
,
0xde
,
0x
96
,
0x35
,
0xfa
,
0xa2
,
0x28
,
0xff
,
0x33
,
0x79
,
0xfe
,
0x33
,
0x00
,
0x00
,
0xff
,
0xff
,
0x97
,
0xd7
,
0x
36
,
0xd6
,
0x33
,
0x09
,
0x00
,
0x
00
,
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment