Skip to content

Commit

Permalink
Pull from latest and resolve conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuabezaleel committed Feb 8, 2022
2 parents 9bbe7e3 + 79ee7c3 commit bdcd919
Show file tree
Hide file tree
Showing 149 changed files with 3,035 additions and 584 deletions.
37 changes: 37 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* [Makefile explained](#makefile-explained)
* [Install mixins](#install-mixins)
* [Preview documentation](#preview-documentation)
* [View a trace of a Porter command](#view-a-trace-of-a-porter-command)
* [Write a blog post](#write-a-blog-post)
* [Code structure and practices](#code-structure-and-practices)
* [What is the general code layout?](#what-is-the-general-code-layout)
Expand Down Expand Up @@ -436,6 +437,42 @@ a new blog post and then preview it:
Our pull request preview and the live site will not show posts with a date in
the future. If you don't see your post, change the date to today's date.

## View a trace of a Porter command

Porter has an experimental feature, structured-logs, that sends trace data about the commands run to an OpenTelemetry backend.
It can be very helpful when figuring out why a command failed because you can see the values of variables and stack traces.

In development, you can use the [otel-jaeger bundle] to set up a development instance of Jaeger, which gives you a nice website to see each command run.

```
porter install --reference carolynvs/otel-jaeger:v0.1.0 --allow-docker-host-access
```

Then to turn on tracing in Porter, set the following environment variables.
This tells Porter to turn on tracing, and connect to OpenTelemetry server that you just installed.

**Posix**
```bash
export PORTER_EXPERIMENTAL="structured-logs"
export PORTER_TELEMETRY_ENABLED="true"
export OTEL_EXPORTER_OTLP_PROTOCOL="grpc"
export OTEL_EXPORTER_OTLP_INSECURE="true"
```

**Powershell**
```powershell
$env:PORTER_EXPERIMENTAL="structured-logs"
$env:PORTER_TELEMETRY_ENABLED="true"
$env:OTEL_EXPORTER_OTLP_PROTOCOL="grpc"
$env:OTEL_EXPORTER_OTLP_INSECURE="true"
```

Next run a Porter command to generate some trace data, such as `porter list`.
Then go to the Jaeger website to see your data: http://localhost:16686.
On the Jaeger dashboard, select "porter" from the service drop down, and click "Find Traces".

[otel-jaeger bundle]: https://github.com/getporter/example-bundles/tree/main/otel-jaeger

## Command Documentation

Our commands are documented at <https://porter.sh/cli> and that documentation is
Expand Down
4 changes: 3 additions & 1 deletion CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,6 @@ and we will add you. **All** contributors belong here. 💯
* [Jérémy Audiger](https://github.com/jaudiger)
* [Om More](https://github.com/thisisommore)
* [Joshua Bezaleel Abednego](https://github.com/joshuabezaleel)
* [Avinash Upadhyaya](https://github.com/avinashupadhya99)
* [Avinash Upadhyaya](https://github.com/avinashupadhya99)
* [Mahendra Bishnoi](https://github.com/mahendrabishnoi2)
* [Yingrong Zhao](https://github.com/VinozzZ)
44 changes: 32 additions & 12 deletions cmd/porter/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ func buildBundleBuildCommand(p *porter.Porter) *cobra.Command {
cmd := &cobra.Command{
Use: "build",
Short: "Build a bundle",
Long: "Builds the bundle in the current directory by generating a Dockerfile and a CNAB bundle.json, and then building the invocation image.",
Long: `Builds the bundle in the current directory by generating a Dockerfile and a CNAB bundle.json, and then building the invocation image.
Porter uses the docker driver as the default build driver, an alternate driver may be supplied via --driver or the PORTER_BUILD_DRIVER environment variable.
`,
Example: ` porter build
porter build --name newbuns
porter build --version 0.1.0
Expand All @@ -64,7 +67,7 @@ func buildBundleBuildCommand(p *porter.Porter) *cobra.Command {
return opts.Validate(p)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.Build(opts)
return p.Build(cmd.Context(), opts)
},
}

Expand Down Expand Up @@ -132,7 +135,7 @@ The first argument is the name of the installation to create. This defaults to t
Once a bundle has been successfully installed, the install action cannot be repeated. This is a precaution to avoid accidentally overwriting an existing installation. If you need to re-run install, which is common when authoring a bundle, you can use the --force flag to by-pass this check.
Porter uses the Docker driver as the default runtime for executing a bundle's invocation image, but an alternate driver may be supplied via '--driver/-d'.
Porter uses the Docker driver as the default runtime for executing a bundle's invocation image, but an alternate driver may be supplied via '--driver/-d' or the PORTER_RUNTIME_DRIVER environment variable.
For example, the 'debug' driver may be specified, which simply logs the info given to it and then exits.`,
Example: ` porter bundle install
porter bundle install MyAppFromReference --reference getporter/kubernetes:v0.1.0 --namespace dev
Expand All @@ -147,7 +150,7 @@ For example, the 'debug' driver may be specified, which simply logs the info giv
return opts.Validate(args, p)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.InstallBundle(opts)
return p.InstallBundle(cmd.Context(), opts)
},
}

Expand All @@ -173,6 +176,11 @@ For example, the 'debug' driver may be specified, which simply logs the info giv
f.BoolVar(&opts.NoLogs, "no-logs", false,
"Do not persist the bundle execution logs")
addBundlePullFlags(f, &opts.BundlePullOptions)

// Allow configuring the --driver flag with runtime-driver, to avoid conflicts with other commands
cmd.Flag("driver").Annotations = map[string][]string{
"viper-key": {"runtime-driver"},
}
return cmd
}

Expand All @@ -185,7 +193,7 @@ func buildBundleUpgradeCommand(p *porter.Porter) *cobra.Command {
The first argument is the installation name to upgrade. This defaults to the name of the bundle.
Porter uses the Docker driver as the default runtime for executing a bundle's invocation image, but an alternate driver may be supplied via '--driver/-d'.
Porter uses the Docker driver as the default runtime for executing a bundle's invocation image, but an alternate driver may be supplied via '--driver/-d' or the PORTER_RUNTIME_DRIVER environment variable.
For example, the 'debug' driver may be specified, which simply logs the info given to it and then exits.`,
Example: ` porter bundle upgrade --version 0.2.0
porter bundle upgrade --reference getporter/kubernetes:v0.1.0
Expand All @@ -199,7 +207,7 @@ For example, the 'debug' driver may be specified, which simply logs the info giv
return opts.Validate(args, p)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.UpgradeBundle(opts)
return p.UpgradeBundle(cmd.Context(), opts)
},
}

Expand All @@ -226,6 +234,10 @@ For example, the 'debug' driver may be specified, which simply logs the info giv
"Do not persist the bundle execution logs")
addBundlePullFlags(f, &opts.BundlePullOptions)

// Allow configuring the --driver flag with runtime-driver, to avoid conflicts with other commands
cmd.Flag("driver").Annotations = map[string][]string{
"viper-key": {"runtime-driver"},
}
return cmd
}

Expand All @@ -238,7 +250,7 @@ func buildBundleInvokeCommand(p *porter.Porter) *cobra.Command {
The first argument is the installation name upon which to invoke the action. This defaults to the name of the bundle.
Porter uses the Docker driver as the default runtime for executing a bundle's invocation image, but an alternate driver may be supplied via '--driver/-d'.
Porter uses the Docker driver as the default runtime for executing a bundle's invocation image, but an alternate driver may be supplied via '--driver/-d' or the PORTER_RUNTIME_DRIVER environment variable.
For example, the 'debug' driver may be specified, which simply logs the info given to it and then exits.`,
Example: ` porter bundle invoke --action ACTION
porter bundle invoke --reference getporter/kubernetes:v0.1.0
Expand All @@ -252,7 +264,7 @@ For example, the 'debug' driver may be specified, which simply logs the info giv
return opts.Validate(args, p)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.InvokeBundle(opts)
return p.InvokeBundle(cmd.Context(), opts)
},
}

Expand All @@ -279,6 +291,10 @@ For example, the 'debug' driver may be specified, which simply logs the info giv
"Do not persist the bundle execution logs")
addBundlePullFlags(f, &opts.BundlePullOptions)

// Allow configuring the --driver flag with runtime-driver, to avoid conflicts with other commands
cmd.Flag("driver").Annotations = map[string][]string{
"viper-key": {"runtime-driver"},
}
return cmd
}

Expand All @@ -291,7 +307,7 @@ func buildBundleUninstallCommand(p *porter.Porter) *cobra.Command {
The first argument is the installation name to uninstall. This defaults to the name of the bundle.
Porter uses the Docker driver as the default runtime for executing a bundle's invocation image, but an alternate driver may be supplied via '--driver/-d'.
Porter uses the Docker driver as the default runtime for executing a bundle's invocation image, but an alternate driver may be supplied via '--driver/-d'' or the PORTER_RUNTIME_DRIVER environment variable.
For example, the 'debug' driver may be specified, which simply logs the info given to it and then exits.`,
Example: ` porter bundle uninstall
porter bundle uninstall --reference getporter/kubernetes:v0.1.0
Expand All @@ -307,7 +323,7 @@ For example, the 'debug' driver may be specified, which simply logs the info giv
return opts.Validate(args, p)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.UninstallBundle(opts)
return p.UninstallBundle(cmd.Context(), opts)
},
}

Expand Down Expand Up @@ -336,6 +352,10 @@ For example, the 'debug' driver may be specified, which simply logs the info giv
"Do not persist the bundle execution logs")
addBundlePullFlags(f, &opts.BundlePullOptions)

// Allow configuring the --driver flag with runtime-driver, to avoid conflicts with other commands
cmd.Flag("driver").Annotations = map[string][]string{
"viper-key": {"runtime-driver"},
}
return cmd
}

Expand All @@ -359,7 +379,7 @@ Note: if overrides for registry/tag/reference are provided, this command only re
return opts.Validate(p.Context)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.Publish(opts)
return p.Publish(cmd.Context(), opts)
},
}

Expand Down Expand Up @@ -391,7 +411,7 @@ func buildBundleArchiveCommand(p *porter.Porter) *cobra.Command {
return opts.Validate(args, p)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.Archive(opts)
return p.Archive(cmd.Context(), opts)
},
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/porter/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ will then provide it to the bundle in the correct location. `,
return opts.Validate(args, p)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.GenerateCredentials(opts)
return p.GenerateCredentials(cmd.Context(), opts)
},
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/porter/explain.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func buildBundleExplainCommand(p *porter.Porter) *cobra.Command {
return opts.Validate(args, p.Context)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.Explain(opts)
return p.Explain(cmd.Context(), opts)
},
}
f := cmd.Flags()
Expand Down
2 changes: 1 addition & 1 deletion cmd/porter/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ like parameters, credentials, outputs and custom actions available.
return opts.Validate(args, p.Context)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.Inspect(opts)
return p.Inspect(cmd.Context(), opts)
},
}
f := cmd.Flags()
Expand Down
4 changes: 2 additions & 2 deletions cmd/porter/installations.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Optional output formats include json and yaml.`,
return opts.Validate()
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.PrintInstallations(opts)
return p.PrintInstallations(cmd.Context(), opts)
},
}

Expand Down Expand Up @@ -118,7 +118,7 @@ You can use the show command to create the initial file:
return opts.Validate(p.Context, args)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.InstallationApply(opts)
return p.InstallationApply(cmd.Context(), opts)
},
}

Expand Down
82 changes: 76 additions & 6 deletions cmd/porter/main.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
package main

import (
"context"
_ "embed"
"fmt"
"os"
"strings"

"get.porter.sh/porter/pkg/cli"
"get.porter.sh/porter/pkg/experimental"
"get.porter.sh/porter/pkg/porter"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"go.opentelemetry.io/otel/attribute"
)

var includeDocsCommand = false
Expand All @@ -16,13 +22,67 @@ var includeDocsCommand = false
var usageText string

func main() {
p := porter.New()
defer p.Close()
run := func() int {
p := porter.New()

rootCmd := buildRootCommandFrom(p)

// Trace the command that called porter, e.g. porter installation show
calledCommand, formattedCommand := getCalledCommand(rootCmd)
ctx, log := p.StartRootSpan(context.Background(), calledCommand, attribute.String("command", formattedCommand))
defer func() {
// Capture panics and trace them
if panicErr := recover(); panicErr != nil {
log.Error(errors.New(fmt.Sprintf("%s", panicErr)), attribute.Bool("panic", true))
log.EndSpan()
p.Close()
os.Exit(1)
} else {
log.EndSpan()
p.Close()
}
}()

if err := rootCmd.ExecuteContext(ctx); err != nil {
// Ideally we log all errors in the span that generated it,
// but as a failsafe, always log the error at the root span as well
log.Error(err)
return 1
}
return 0
}

cmd := buildRootCommandFrom(p)
if err := cmd.Execute(); err != nil {
os.Exit(1)
// Wrapping the main run logic in a function because os.Exit will not
// execute defer statements
os.Exit(run())
}

// Returns the porter command called, e.g. porter installation list
// and also the fully formatted command as passed with arguments/flags.
func getCalledCommand(cmd *cobra.Command) (string, string) {
// Ask cobra what sub-command was called, and walk up the tree to get the full command called.
var cmdChain []string
cmd, _, err := cmd.Find(os.Args[1:])
if err != nil {
cmdChain = append(cmdChain, "porter")
} else {
for cmd != nil {
cmdChain = append(cmdChain, cmd.Name())
cmd = cmd.Parent()
}
}
// reverse the command from [list installations porter] to porter installation list
var calledCommand strings.Builder
for i := len(cmdChain); i > 0; i-- {
calledCommand.WriteString(cmdChain[i-1])
calledCommand.WriteString(" ")
}
calledCommandStr := calledCommand.String()[0 : calledCommand.Len()-1]

// Also figure out the full command called, with args/flags.
formattedCommand := fmt.Sprintf("porter %s", strings.Join(os.Args[1:], " "))

return calledCommandStr, formattedCommand
}

func buildRootCommand() *cobra.Command {
Expand Down Expand Up @@ -57,7 +117,17 @@ Try our QuickStart https://porter.sh/quickstart to learn how to use Porter.
return nil
default:
p.DataLoader = cli.LoadHierarchicalConfig(cmd)
return p.LoadData()
err := p.LoadData()
if err != nil {
return err
}

if p.Config.IsFeatureEnabled(experimental.FlagStructuredLogs) {
// When structured logging is enabled, the error is printed
// to the console by the logger, we don't need to re-print it again.
cmd.Root().SilenceErrors = true
}
return nil
}
},
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down
2 changes: 1 addition & 1 deletion cmd/porter/parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ will then provide it to the bundle in the correct location. `,
return opts.Validate(args, p)
},
RunE: func(cmd *cobra.Command, args []string) error {
return p.GenerateParameters(opts)
return p.GenerateParameters(cmd.Context(), opts)
},
}

Expand Down
Loading

0 comments on commit bdcd919

Please sign in to comment.