Files
coder/cli/templateinit.go
Kyle Carberry fb9dc4f346 feat: Improve resource preview and first-time experience (#946)
* Improve CLI documentation

* feat: Allow workspace resources to attach multiple agents

This enables a "kubernetes_pod" to attach multiple agents that
could be for multiple services. Each agent is required to have
a unique name, so SSH syntax is:

`coder ssh <workspace>.<agent>`

A resource can have zero agents too, they aren't required.

* Add tree view

* Improve table UI

* feat: Allow workspace resources to attach multiple agents

This enables a "kubernetes_pod" to attach multiple agents that
could be for multiple services. Each agent is required to have
a unique name, so SSH syntax is:

`coder ssh <workspace>.<agent>`

A resource can have zero agents too, they aren't required.

* Rename `tunnel` to `skip-tunnel`

This command was `true` by default, which causes
a confusing user experience.

* Add disclaimer about editing templates

* Add help to template create

* Improve workspace create flow

* Add end-to-end test for config-ssh

* Improve testing of config-ssh

* Fix workspace list

* Fix config ssh tests

* Update cli/configssh.go

Co-authored-by: Cian Johnston <public@cianjohnston.ie>

* Fix requested changes

* Remove socat requirement

* Fix resources not reading in TTY

Co-authored-by: Cian Johnston <public@cianjohnston.ie>
2022-04-11 18:54:30 -05:00

77 lines
2.2 KiB
Go

package cli
import (
"fmt"
"os"
"path/filepath"
"github.com/spf13/cobra"
"github.com/coder/coder/cli/cliui"
"github.com/coder/coder/examples"
"github.com/coder/coder/provisionersdk"
)
func templateInit() *cobra.Command {
return &cobra.Command{
Use: "init [directory]",
Short: "Get started with a templated template.",
RunE: func(cmd *cobra.Command, args []string) error {
exampleList, err := examples.List()
if err != nil {
return err
}
exampleNames := []string{}
exampleByName := map[string]examples.Example{}
for _, example := range exampleList {
exampleNames = append(exampleNames, example.Name)
exampleByName[example.Name] = example
}
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Wrap.Render(
"A template defines infrastructure as code to be provisioned "+
"for individual developer workspaces. Select an example to get started:\n"))
option, err := cliui.Select(cmd, cliui.SelectOptions{
Options: exampleNames,
})
if err != nil {
return err
}
selectedTemplate := exampleByName[option]
archive, err := examples.Archive(selectedTemplate.ID)
if err != nil {
return err
}
workingDir, err := os.Getwd()
if err != nil {
return err
}
var directory string
if len(args) > 0 {
directory = args[0]
} else {
directory = filepath.Join(workingDir, selectedTemplate.ID)
}
relPath, err := filepath.Rel(workingDir, directory)
if err != nil {
relPath = directory
} else {
relPath = "./" + relPath
}
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "Extracting %s to %s...\n", cliui.Styles.Field.Render(selectedTemplate.ID), relPath)
err = os.MkdirAll(directory, 0700)
if err != nil {
return err
}
err = provisionersdk.Untar(directory, archive)
if err != nil {
return err
}
_, _ = fmt.Fprintln(cmd.OutOrStdout(), "Create your template by running:")
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Paragraph.Render(cliui.Styles.Code.Render("cd "+relPath+" && coder templates create"))+"\n")
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Wrap.Render("Examples provide a starting point and are expected to be edited! 🎨"))
return nil
},
}
}