// Deploy allows the creation of deploy.Deployments remotely func (s *SpreadCli) Deploy() *cli.Command { return &cli.Command{ Name: "deploy", Usage: "spread deploy [-s] PATH | COMMIT [kubectl context]", Description: "Deploys objects to a remote Kubernetes cluster.", ArgsUsage: "-s will deploy only if no other deployment found (otherwise fails)", Action: func(c *cli.Context) { ref := c.Args().First() var dep *deploy.Deployment proj, err := s.project() if err == nil { var docs map[string]*pb.Document if len(ref) == 0 { s.printf("Deploying from index...") docs, err = proj.Index() if err != nil { s.fatalf("Error getting index: %v", err) } if err = s.promptForArgs(docs, false); err == nil { dep, err = deploy.DeploymentFromDocMap(docs) } } else { if docs, err = proj.ResolveCommit(ref); err == nil { if err = s.promptForArgs(docs, false); err == nil { dep, err = deploy.DeploymentFromDocMap(docs) } } else { dep, err = s.globalDeploy(ref) } } } else { dep, err = s.globalDeploy(ref) } if err != nil { s.fatalf("Failed to assemble deployment: %v", err) } context := c.Args().Get(1) cluster, err := deploy.NewKubeClusterFromContext(context) if err != nil { s.fatalf("Failed to deploy: %v", err) } s.printf("Deploying %d objects using the %s.", dep.Len(), displayContext(context)) update := !c.Bool("s") err = cluster.Deploy(dep, update, false) if err != nil { //TODO: make better error messages (one to indicate a deployment already existed; another one if a deployment did not exist but some other error was thrown s.fatalf("Did not deploy.: %v", err) } s.printf("Deployment successful!") }, } }
// Status returns information about the current state of the project. func (s SpreadCli) Status() *cli.Command { return &cli.Command{ Name: "status", Usage: "spread status", Description: "Information about what's commited, changed, and staged.", Action: func(c *cli.Context) { proj := s.projectOrDie() indexDocs, err := proj.Index() if err != nil { s.fatalf("Could not load Index: %v", err) } index, err := deploy.DeploymentFromDocMap(indexDocs) if err != nil { s.fatalf("Failed to create KubeObject from index doc: %v", err) } var head *deploy.Deployment headDocs, err := proj.Head() if err == nil { head, err = deploy.DeploymentFromDocMap(headDocs) if err != nil { s.fatalf("Failed to create KubeObject from HEAD doc: %v", err) } } else { head = new(deploy.Deployment) } client, err := deploy.NewKubeClusterFromContext("") if err != nil { s.fatalf("Failed to connect to Kubernetes cluster: %v", err) } cluster, err := client.Deployment() if err != nil { s.fatalf("Could not load deployment from cluster: %v", err) } stat := deploy.Stat(index, head, cluster) s.printStatus(stat) }, } }
func (s *SpreadCli) globalDeploy(ref string) (*deploy.Deployment, error) { // check if reference is local file dep, err := s.fileDeploy(ref) if err != nil { ref, err = packages.ExpandPackageName(ref) if err == nil { var info packages.PackageInfo info, err = packages.DiscoverPackage(ref, true, false) if err != nil { s.fatalf("failed to retrieve package info: %v", err) } proj, err := s.globalProject() if err != nil { s.fatalf("error setting up global project: %v", err) } remote, err := proj.Remotes().Lookup(ref) // if does not exist or has different URL, create new remote if err != nil { remote, err = proj.Remotes().Create(ref, info.RepoURL) if err != nil { return nil, fmt.Errorf("could not create remote: %v", err) } } else if remote.Url() != info.RepoURL { s.printf("changing remote URL for %s, current: '%s' new: '%s'", ref, remote.Url(), info.RepoURL) err = proj.Remotes().SetUrl(ref, info.RepoURL) if err != nil { return nil, fmt.Errorf("failed to change URL for %s: %v", ref, err) } } s.printf("pulling repo from %s", info.RepoURL) branch := fmt.Sprintf("%s/master", ref) err = proj.Fetch(remote.Name(), "master") if err != nil { return nil, fmt.Errorf("failed to fetch '%s': %v", ref, err) } docs, err := proj.Branch(branch) if err != nil { return nil, err } if err = s.promptForArgs(docs, false); err != nil { return nil, err } return deploy.DeploymentFromDocMap(docs) } } return dep, err }
// Diff shows the difference bettwen the cluster and the index. func (s SpreadCli) Diff() *cli.Command { return &cli.Command{ Name: "diff", Usage: "spread diff", Description: "Diffs index against state of cluster", Flags: []cli.Flag{ cli.StringFlag{ Name: "context", Value: "", Usage: "kubectl context to use for requests", }, }, Action: func(c *cli.Context) { proj := s.projectOrDie() docs, err := proj.Index() if err != nil { s.fatalf("Could not load Index: %v", err) } index, err := deploy.DeploymentFromDocMap(docs) if err != nil { s.fatalf("Failed to create Deployment from Documents: %v", err) } context := c.String("context") client, err := deploy.NewKubeClusterFromContext(context) if err != nil { s.fatalf("Failed to connect to Kubernetes cluster: %v", err) } cluster, err := client.Deployment() if err != nil { s.fatalf("Could not load deployment from cluster: %v", err) } s.printf(index.Diff(cluster)) }, } }