Skip to content

Commit

Permalink
Merge pull request #55 from iovisor/chore/cli
Browse files Browse the repository at this point in the history
Images and headers flags for run command
  • Loading branch information
fntlnz committed Feb 7, 2019
2 parents 350fc53 + 4689c62 commit 45fba8a
Show file tree
Hide file tree
Showing 12 changed files with 96 additions and 61 deletions.
10 changes: 8 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,22 @@ GIT_BRANCH_CLEAN := $(shell echo $(GIT_BRANCH) | sed -e "s/[^[:alnum:]]/-/g")
IMAGE_NAME ?= quay.io/fntlnz/kubectl-trace-bpftrace
IMAGE_NAME_BASE ?= quay.io/fntlnz/kubectl-trace-bpftrace-base

IMAGE_NAME_INIT ?= quay.io/fntlnz/kubectl-trace-init

IMAGE_TRACERUNNER_BRANCH := $(IMAGE_NAME):$(GIT_BRANCH_CLEAN)
IMAGE_TRACERUNNER_COMMIT := $(IMAGE_NAME):$(GIT_COMMIT)
IMAGE_TRACERUNNER_LATEST := $(IMAGE_NAME):latest

IMAGE_INITCONTAINER_BRANCH := $(IMAGE_NAME_INIT):$(GIT_BRANCH_CLEAN)
IMAGE_INITCONTAINER_COMMIT := $(IMAGE_NAME_INIT):$(GIT_COMMIT)
IMAGE_INITCONTAINER_LATEST := $(IMAGE_NAME_INIT):latest

BPFTRACESHA ?= 2ae2a53f62622631a304def6c193680e603994e3
IMAGE_BPFTRACE_BASE := $(IMAGE_NAME_BASE):$(BPFTRACESHA)

IMAGE_BUILD_FLAGS ?= "--no-cache"

LDFLAGS := -ldflags '-X github.com/iovisor/kubectl-trace/pkg/version.buildTime=$(shell date +%s) -X github.com/iovisor/kubectl-trace/pkg/version.gitCommit=${GIT_COMMIT} -X github.com/iovisor/kubectl-trace/pkg/version.imageName=${IMAGE_NAME}'
LDFLAGS := -ldflags '-X github.com/iovisor/kubectl-trace/pkg/version.buildTime=$(shell date +%s) -X github.com/iovisor/kubectl-trace/pkg/version.gitCommit=${GIT_COMMIT} -X github.com/iovisor/kubectl-trace/pkg/cmd.ImageNameTag=${IMAGE_TRACERUNNER_COMMIT} -X github.com/iovisor/kubectl-trace/pkg/cmd.InitImageNameTag=${IMAGE_INITCONTAINER_COMMIT}'
TESTPACKAGES := $(shell go list ./... | grep -v github.com/iovisor/kubectl-trace/integration)

kubectl_trace ?= _output/bin/kubectl-trace
Expand Down Expand Up @@ -65,7 +71,7 @@ test:

.PHONY: integration
integration:
TEST_KUBECTLTRACE_BINARY=$(shell pwd)/$(kubectl_trace) $(GO) test ${LDFLAGS} -v ./integration/...
TEST_KUBECTLTRACE_BINARY=$(shell pwd)/$(kubectl_trace) $(GO) test ${LDFLAGS} -v ./integration/...

.PHONY: bpftraceimage/build
bpftraceimage/build:
Expand Down
4 changes: 2 additions & 2 deletions integration/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"time"

"github.com/go-check/check"
"github.com/iovisor/kubectl-trace/pkg/version"
"github.com/iovisor/kubectl-trace/pkg/cmd"
"gotest.tools/icmd"
"sigs.k8s.io/kind/pkg/cluster"
"sigs.k8s.io/kind/pkg/cluster/config/encoding"
Expand Down Expand Up @@ -59,7 +59,7 @@ func (k *KubectlTraceSuite) SetUpSuite(c *check.C) {

// copy the bpftrace image to the nodes
for _, n := range nodes {
loadcomm := fmt.Sprintf("docker save %s | docker exec -i %s docker load", version.ImageNameTag(), n.String())
loadcomm := fmt.Sprintf("docker save %s | docker exec -i %s docker load", cmd.ImageNameTag, n.String())
res := icmd.RunCommand("bash", "-c", loadcomm)
c.Assert(res.Error, check.IsNil)
}
Expand Down
1 change: 1 addition & 0 deletions pkg/cmd/attach.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ func (o *AttachOptions) Validate(cmd *cobra.Command, args []string) error {
return nil
}

// Complete completes the setup of the command.
func (o *AttachOptions) Complete(factory factory.Factory, cmd *cobra.Command, args []string) error {
// Prepare namespace
var err error
Expand Down
1 change: 1 addition & 0 deletions pkg/cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ func (o *DeleteOptions) Validate(cmd *cobra.Command, args []string) error {
return nil
}

// Complete completes the setup of the command.
func (o *DeleteOptions) Complete(factory factory.Factory, cmd *cobra.Command, args []string) error {
// Prepare namespace
var err error
Expand Down
3 changes: 2 additions & 1 deletion pkg/cmd/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ func (o *GetOptions) Validate(cmd *cobra.Command, args []string) error {
return nil
}

// Complete completes the setup of the command.
func (o *GetOptions) Complete(factory factory.Factory, cmd *cobra.Command, args []string) error {
// Prepare namespace
var err error
Expand All @@ -125,7 +126,7 @@ func (o *GetOptions) Complete(factory factory.Factory, cmd *cobra.Command, args
o.namespace = ""
}

//// Prepare client
// Prepare client
o.clientConfig, err = factory.ToRESTConfig()
if err != nil {
return err
Expand Down
2 changes: 2 additions & 0 deletions pkg/cmd/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func NewLogCommand(factory factory.Factory, streams genericclioptions.IOStreams)
return cmd
}

// Validate validates the arguments and flags populating LogOptions accordingly.
func (o *LogOptions) Validate(cmd *cobra.Command, args []string) error {
if meta.IsObjectName(args[0]) {
o.traceName = &args[0]
Expand All @@ -96,6 +97,7 @@ func (o *LogOptions) Validate(cmd *cobra.Command, args []string) error {
return nil
}

// Complete completes the setup of the command.
func (o *LogOptions) Complete(factory factory.Factory, cmd *cobra.Command, args []string) error {
// Prepare namespace
var err error
Expand Down
50 changes: 38 additions & 12 deletions pkg/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,34 @@ import (
"k8s.io/client-go/rest"
)

var (
// ImageNameTag represents the default tracerunner image
ImageNameTag = "quay.io/fntlnz/kubectl-trace-bpftrace:latest"
// InitImageNameTag represents the default init container image
InitImageNameTag = "quay.io/fntlnz/kubectl-trace-init:latest"
)

var (
runShort = `Execute a bpftrace program on resources` // Wrap with i18n.T()

runLong = runShort

runExamples = `
# Count system calls using tracepoints on a specific node
%[1]s trace run node/kubernetes-node-emt8.c.myproject.internal -e 'kprobe:do_sys_open { printf("%s: %s\n", comm, str(arg1)) }'
%[1]s trace run node/kubernetes-node-emt8.c.myproject.internal -e 'kprobe:do_sys_open { printf("%%s: %%s\n", comm, str(arg1)) }'
# Execute a bpftrace program from file on a specific node
%[1]s trace run node/kubernetes-node-emt8.c.myproject.internal -f read.bt
# Run an bpftrace inline program on a pod container
%[1]s trace run pod/nginx -c nginx -e "tracepoint:syscalls:sys_enter_* { @[probe] = count(); }"
%[1]s trace run pod/nginx nginx -e "tracepoint:syscalls:sys_enter_* { @[probe] = count(); }"
%[1]s trace run pod/nginx nginx -e "tracepoint:syscalls:sys_enter_* { @[probe] = count(); }"`
# Run a bpftrace inline program on a pod container with a custom image for the init container responsible to fetch linux headers
%[1]s trace run pod/nginx nginx -e "tracepoint:syscalls:sys_enter_* { @[probe] = count(); } --init-imagename=quay.io/custom-init-image-name --fetch-headers"
# Run a bpftrace inline program on a pod container with a custom image for the bpftrace container that will run your program in the cluster
%[1]s trace run pod/nginx nginx -e "tracepoint:syscalls:sys_enter_* { @[probe] = count(); } --imagename=quay.io/custom-bpftrace-image-name"`

runCommand = "run"
usageString = "(POD | TYPE/NAME)"
Expand All @@ -53,17 +65,20 @@ type RunOptions struct {
namespace string
explicitNamespace bool

// Local to this command
// Flags local to this command
container string
eval string
program string
resourceArg string
attach bool
isPod bool
podUID string
serviceAccount string
imageName string
initImageName string
fetchHeaders bool

nodeName string
resourceArg string
attach bool
isPod bool
podUID string
nodeName string

clientConfig *rest.Config
}
Expand All @@ -72,6 +87,10 @@ type RunOptions struct {
func NewRunOptions(streams genericclioptions.IOStreams) *RunOptions {
return &RunOptions{
IOStreams: streams,

serviceAccount: "default",
imageName: ImageNameTag,
initImageName: InitImageNameTag,
}
}

Expand Down Expand Up @@ -101,10 +120,13 @@ func NewRunCommand(factory factory.Factory, streams genericclioptions.IOStreams)
}

cmd.Flags().StringVarP(&o.container, "container", "c", o.container, "Specify the container")
cmd.Flags().BoolVarP(&o.attach, "attach", "a", o.attach, "Wheter or not to attach to the trace program once it is created")
cmd.Flags().StringVarP(&o.eval, "eval", "e", "", "Literal string to be evaluated as a bpftrace program")
cmd.Flags().StringVarP(&o.program, "filename", "f", "", "File containing a bpftrace program")
cmd.Flags().StringVar(&o.serviceAccount, "serviceaccount", "default", "Service account to use to set in the pod spec of the kubectl-trace job")
cmd.Flags().BoolVarP(&o.attach, "attach", "a", o.attach, "Whether or not to attach to the trace program once it is created")
cmd.Flags().StringVarP(&o.eval, "eval", "e", o.eval, "Literal string to be evaluated as a bpftrace program")
cmd.Flags().StringVarP(&o.program, "filename", "f", o.program, "File containing a bpftrace program")
cmd.Flags().StringVar(&o.serviceAccount, "serviceaccount", o.serviceAccount, "Service account to use to set in the pod spec of the kubectl-trace job")
cmd.Flags().StringVar(&o.imageName, "imagename", o.imageName, "Custom image for the tracerunner")
cmd.Flags().StringVar(&o.initImageName, "init-imagename", o.initImageName, "Custom image for the init container responsible to fetch and prepare linux headers")
cmd.Flags().BoolVar(&o.fetchHeaders, "fetch-headers", o.fetchHeaders, "Whether to fetch linux headers or not")

return cmd
}
Expand Down Expand Up @@ -276,6 +298,10 @@ func (o *RunOptions) Run() error {
PodUID: o.podUID,
ContainerName: o.container,
IsPod: o.isPod,
// todo(dalehamel) > following fields to be used for #48
ImageNameTag: o.imageName,
InitImageNameTag: o.initImageName,
FetchHeaders: o.fetchHeaders,
}

job, err := tc.CreateJob(tj)
Expand Down
13 changes: 13 additions & 0 deletions pkg/cmd/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,18 @@ func NewTraceCommand(streams genericclioptions.IOStreams) *cobra.Command {
cmd.AddCommand(NewVersionCommand(streams))
cmd.AddCommand(NewLogCommand(f, streams))

// Override help on all the commands tree
walk(cmd, func(c *cobra.Command) {
c.Flags().BoolP("help", "h", false, fmt.Sprintf("Help for the %s command", c.Name()))
})

return cmd
}

// walk calls f for c and all of its children.
func walk(c *cobra.Command, f func(*cobra.Command)) {
f(c)
for _, c := range c.Commands() {
walk(c, f)
}
}
3 changes: 2 additions & 1 deletion pkg/cmd/tracerunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func NewTraceRunnerCommand() *cobra.Command {
cmd.Flags().StringVarP(&o.podUID, "poduid", "p", o.podUID, "Specify the pod UID")
cmd.Flags().StringVarP(&o.programPath, "program", "f", "program.bt", "Specify the bpftrace program path")
cmd.Flags().StringVarP(&o.bpftraceBinaryPath, "bpftracebinary", "b", "/bin/bpftrace", "Specify the bpftrace binary path")
cmd.Flags().BoolVar(&o.inPod, "inpod", false, "Wether or not run this bpftrace in a pod's container process namespace")
cmd.Flags().BoolVar(&o.inPod, "inpod", false, "Whether or not run this bpftrace in a pod's container process namespace")
return cmd
}

Expand All @@ -62,6 +62,7 @@ func (o *TraceRunnerOptions) Validate(cmd *cobra.Command, args []string) error {
return nil
}

// Complete completes the setup of the command.
func (o *TraceRunnerOptions) Complete(cmd *cobra.Command, args []string) error {
return nil
}
Expand Down
1 change: 1 addition & 0 deletions pkg/cmd/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"k8s.io/cli-runtime/pkg/genericclioptions"
)

// NewVersionCommand provides the version command.
func NewVersionCommand(streams genericclioptions.IOStreams) *cobra.Command {
cmd := &cobra.Command{
Use: "version",
Expand Down
45 changes: 23 additions & 22 deletions pkg/tracejob/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@ package tracejob

import (
"fmt"

"github.com/iovisor/kubectl-trace/pkg/version"

"io"
"io/ioutil"

"github.com/iovisor/kubectl-trace/pkg/meta"
batchv1 "k8s.io/api/batch/v1"
apiv1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/api/resource"
batchv1typed "k8s.io/client-go/kubernetes/typed/batch/v1"
corev1typed "k8s.io/client-go/kubernetes/typed/core/v1"
)
Expand All @@ -24,16 +21,20 @@ type TraceJobClient struct {
outStream io.Writer
}

// TraceJob is a container of info needed to create the job responsible for tracing.
type TraceJob struct {
Name string
ID types.UID
Namespace string
ServiceAccount string
Hostname string
Program string
PodUID string
ContainerName string
IsPod bool
Name string
ID types.UID
Namespace string
ServiceAccount string
Hostname string
Program string
PodUID string
ContainerName string
IsPod bool
ImageNameTag string
InitImageNameTag string
FetchHeaders bool
}

// WithOutStream setup a file stream to output trace job operation information
Expand Down Expand Up @@ -252,19 +253,19 @@ func (t *TraceJobClient) CreateJob(nj TraceJob) (*batchv1.Job, error) {
Containers: []apiv1.Container{
apiv1.Container{
Name: nj.Name,
Image: version.ImageNameTag(),
Image: nj.ImageNameTag,
Command: bpfTraceCmd,
TTY: true,
Stdin: true,
Resources: apiv1.ResourceRequirements{
Requests: apiv1.ResourceList{
apiv1.ResourceCPU: resource.MustParse("100m"),
apiv1.ResourceMemory: resource.MustParse("100Mi"),
},
Limits: apiv1.ResourceList{
apiv1.ResourceCPU: resource.MustParse("1"),
apiv1.ResourceMemory: resource.MustParse("1G"),
},
Requests: apiv1.ResourceList{
apiv1.ResourceCPU: resource.MustParse("100m"),
apiv1.ResourceMemory: resource.MustParse("100Mi"),
},
Limits: apiv1.ResourceList{
apiv1.ResourceCPU: resource.MustParse("1"),
apiv1.ResourceMemory: resource.MustParse("1G"),
},
},
VolumeMounts: []apiv1.VolumeMount{
apiv1.VolumeMount{
Expand Down
24 changes: 3 additions & 21 deletions pkg/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,15 @@ import (

// Populated by makefile
var gitCommit string
var imageName string
var buildTime string
var versionFormat = "git commit: %s\nbuild date: %s"
var imageNameTagFormat = "%s:%s"
var defaultImageName = "quay.io/fntlnz/kubectl-trace-bpftrace"
var defaultImageTag = "latest"

// ImageName returns the container image name defined in Makefile
func ImageName() string {
return imageName
}

// GitCommit returns the git commit
func GitCommit() string {
return gitCommit
}

func ImageNameTag() string {
imageName := ImageName()
tag := GitCommit()
if len(tag) == 0 {
tag = defaultImageTag
}
if len(imageName) == 0 {
imageName = defaultImageName
}
return fmt.Sprintf(imageNameTagFormat, imageName, tag)
}

// Time returns the build time
func Time() *time.Time {
if len(buildTime) == 0 {
return nil
Expand All @@ -48,6 +29,7 @@ func Time() *time.Time {
return &t
}

// String returns version info as a string
func String() string {
ts := Time()
if ts == nil {
Expand Down

0 comments on commit 45fba8a

Please sign in to comment.