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