mirror of https://github.com/helm/helm
Merge pull request #53 from fibonacci1729/feat/tiller-client
feat(tiller): add initial tiller client for basic helm installs.pull/613/head
commit
104126d2d2
@ -0,0 +1,65 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/deis/tiller/pkg/chart"
|
||||||
|
"github.com/deis/tiller/pkg/helm"
|
||||||
|
)
|
||||||
|
|
||||||
|
const installDesc = `
|
||||||
|
This command installs a chart archive.
|
||||||
|
`
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RootCommand.Flags()
|
||||||
|
RootCommand.AddCommand(installCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
var installCmd = &cobra.Command{
|
||||||
|
Use: "install [CHART]",
|
||||||
|
Short: "install a chart archive.",
|
||||||
|
Long: installDesc,
|
||||||
|
RunE: runInstall,
|
||||||
|
}
|
||||||
|
|
||||||
|
func runInstall(cmd *cobra.Command, args []string) error {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return fmt.Errorf("This command needs at least one argument, the name of the chart.")
|
||||||
|
}
|
||||||
|
|
||||||
|
ch, err := loadChart(args[0])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := helm.InstallRelease(ch)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("release.name: %s\n", res.Release.Name)
|
||||||
|
fmt.Printf("release.chart: %s\n", res.Release.Chart.Metadata.Name)
|
||||||
|
fmt.Printf("release.status: %s\n", res.Release.Info.Status.Code)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadChart(path string) (*chart.Chart, error) {
|
||||||
|
path, err := filepath.Abs(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if fi, err := os.Stat(path); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if fi.IsDir() {
|
||||||
|
return chart.LoadDir(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
return chart.Load(path)
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package helm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
|
"github.com/deis/tiller/pkg/proto/hapi/services"
|
||||||
|
)
|
||||||
|
|
||||||
|
type client struct {
|
||||||
|
cfg *config
|
||||||
|
conn *grpc.ClientConn
|
||||||
|
impl services.ReleaseServiceClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) dial() (err error) {
|
||||||
|
c.conn, err = grpc.Dial(c.cfg.ServAddr, c.cfg.DialOpts()...)
|
||||||
|
c.impl = services.NewReleaseServiceClient(c.conn)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) install(req *services.InstallReleaseRequest) (res *services.InstallReleaseResponse, err error) {
|
||||||
|
if err = c.dial(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
|
return c.impl.InstallRelease(context.TODO(), req, c.cfg.CallOpts()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *client) Close() error {
|
||||||
|
return c.conn.Close()
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package helm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type config struct {
|
||||||
|
ServAddr string
|
||||||
|
Insecure bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *config) DialOpts() (opts []grpc.DialOption) {
|
||||||
|
if cfg.Insecure {
|
||||||
|
opts = append(opts, grpc.WithInsecure())
|
||||||
|
} else {
|
||||||
|
// TODO: handle transport credentials
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *config) CallOpts() (opts []grpc.CallOption) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *config) client() *client {
|
||||||
|
return &client{cfg: cfg}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package helm
|
||||||
|
|
||||||
|
const (
|
||||||
|
errNotImplemented = Error("helm api not implemented")
|
||||||
|
errMissingSrvAddr = Error("missing tiller address")
|
||||||
|
errMissingTpls = Error("missing chart templates")
|
||||||
|
errMissingChart = Error("missing chart metadata")
|
||||||
|
errMissingValues = Error("missing chart values")
|
||||||
|
)
|
||||||
|
|
||||||
|
type Error string
|
||||||
|
|
||||||
|
func (e Error) Error() string {
|
||||||
|
return string(e)
|
||||||
|
}
|
@ -0,0 +1,120 @@
|
|||||||
|
package helm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/deis/tiller/pkg/chart"
|
||||||
|
chartpb "github.com/deis/tiller/pkg/proto/hapi/chart"
|
||||||
|
"github.com/deis/tiller/pkg/proto/hapi/services"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Config = &config{
|
||||||
|
ServAddr: ":44134",
|
||||||
|
Insecure: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListReleases(limit, offset int) (<-chan *services.ListReleasesResponse, error) {
|
||||||
|
return nil, errNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetReleaseStatus(name string) (*services.GetReleaseStatusResponse, error) {
|
||||||
|
return nil, errNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetReleaseContent(name string) (*services.GetReleaseContentResponse, error) {
|
||||||
|
return nil, errNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateRelease(name string) (*services.UpdateReleaseResponse, error) {
|
||||||
|
return nil, errNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
func UninstallRelease(name string) (*services.UninstallReleaseResponse, error) {
|
||||||
|
return nil, errNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
|
func InstallRelease(ch *chart.Chart) (res *services.InstallReleaseResponse, err error) {
|
||||||
|
chpb := new(chartpb.Chart)
|
||||||
|
|
||||||
|
chpb.Metadata, err = mkProtoMetadata(ch.Chartfile())
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chpb.Templates, err = mkProtoTemplates(ch)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chpb.Dependencies, err = mkProtoChartDeps(ch)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var vals *chartpb.Config
|
||||||
|
|
||||||
|
vals, err = mkProtoConfigValues(ch)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err = Config.client().install(&services.InstallReleaseRequest{
|
||||||
|
Chart: chpb,
|
||||||
|
Values: vals,
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// pkg/chart to proto/hapi/chart helpers. temporary.
|
||||||
|
func mkProtoMetadata(ch *chart.Chartfile) (*chartpb.Metadata, error) {
|
||||||
|
if ch == nil {
|
||||||
|
return nil, errMissingChart
|
||||||
|
}
|
||||||
|
|
||||||
|
md := &chartpb.Metadata{
|
||||||
|
Name: ch.Name,
|
||||||
|
Home: ch.Home,
|
||||||
|
Version: ch.Version,
|
||||||
|
Description: ch.Description,
|
||||||
|
}
|
||||||
|
|
||||||
|
md.Sources = make([]string, len(ch.Source))
|
||||||
|
copy(md.Sources, ch.Source)
|
||||||
|
|
||||||
|
md.Keywords = make([]string, len(ch.Keywords))
|
||||||
|
copy(md.Keywords, ch.Keywords)
|
||||||
|
|
||||||
|
for _, maintainer := range ch.Maintainers {
|
||||||
|
md.Maintainers = append(md.Maintainers, &chartpb.Maintainer{
|
||||||
|
Name: maintainer.Name,
|
||||||
|
Email: maintainer.Email,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return md, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func mkProtoTemplates(ch *chart.Chart) ([]*chartpb.Template, error) {
|
||||||
|
tpls, err := ch.LoadTemplates()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = tpls
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func mkProtoChartDeps(ch *chart.Chart) ([]*chartpb.Chart, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func mkProtoConfigValues(ch *chart.Chart) (*chartpb.Config, error) {
|
||||||
|
vals, err := ch.LoadValues()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errMissingValues
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = vals
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
Loading…
Reference in new issue