Skip to content

Commit 45fba8a

Browse files
authored
Merge pull request #55 from iovisor/chore/cli
Images and headers flags for run command
2 parents 350fc53 + 4689c62 commit 45fba8a

File tree

12 files changed

+96
-61
lines changed

12 files changed

+96
-61
lines changed

Makefile

+8-2
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,22 @@ GIT_BRANCH_CLEAN := $(shell echo $(GIT_BRANCH) | sed -e "s/[^[:alnum:]]/-/g")
1111
IMAGE_NAME ?= quay.io/fntlnz/kubectl-trace-bpftrace
1212
IMAGE_NAME_BASE ?= quay.io/fntlnz/kubectl-trace-bpftrace-base
1313

14+
IMAGE_NAME_INIT ?= quay.io/fntlnz/kubectl-trace-init
15+
1416
IMAGE_TRACERUNNER_BRANCH := $(IMAGE_NAME):$(GIT_BRANCH_CLEAN)
1517
IMAGE_TRACERUNNER_COMMIT := $(IMAGE_NAME):$(GIT_COMMIT)
1618
IMAGE_TRACERUNNER_LATEST := $(IMAGE_NAME):latest
1719

20+
IMAGE_INITCONTAINER_BRANCH := $(IMAGE_NAME_INIT):$(GIT_BRANCH_CLEAN)
21+
IMAGE_INITCONTAINER_COMMIT := $(IMAGE_NAME_INIT):$(GIT_COMMIT)
22+
IMAGE_INITCONTAINER_LATEST := $(IMAGE_NAME_INIT):latest
23+
1824
BPFTRACESHA ?= 2ae2a53f62622631a304def6c193680e603994e3
1925
IMAGE_BPFTRACE_BASE := $(IMAGE_NAME_BASE):$(BPFTRACESHA)
2026

2127
IMAGE_BUILD_FLAGS ?= "--no-cache"
2228

23-
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}'
29+
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}'
2430
TESTPACKAGES := $(shell go list ./... | grep -v github.com/iovisor/kubectl-trace/integration)
2531

2632
kubectl_trace ?= _output/bin/kubectl-trace
@@ -65,7 +71,7 @@ test:
6571

6672
.PHONY: integration
6773
integration:
68-
TEST_KUBECTLTRACE_BINARY=$(shell pwd)/$(kubectl_trace) $(GO) test ${LDFLAGS} -v ./integration/...
74+
TEST_KUBECTLTRACE_BINARY=$(shell pwd)/$(kubectl_trace) $(GO) test ${LDFLAGS} -v ./integration/...
6975

7076
.PHONY: bpftraceimage/build
7177
bpftraceimage/build:

integration/suite_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"time"
1010

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

6060
// copy the bpftrace image to the nodes
6161
for _, n := range nodes {
62-
loadcomm := fmt.Sprintf("docker save %s | docker exec -i %s docker load", version.ImageNameTag(), n.String())
62+
loadcomm := fmt.Sprintf("docker save %s | docker exec -i %s docker load", cmd.ImageNameTag, n.String())
6363
res := icmd.RunCommand("bash", "-c", loadcomm)
6464
c.Assert(res.Error, check.IsNil)
6565
}

pkg/cmd/attach.go

+1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ func (o *AttachOptions) Validate(cmd *cobra.Command, args []string) error {
9292
return nil
9393
}
9494

95+
// Complete completes the setup of the command.
9596
func (o *AttachOptions) Complete(factory factory.Factory, cmd *cobra.Command, args []string) error {
9697
// Prepare namespace
9798
var err error

pkg/cmd/delete.go

+1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ func (o *DeleteOptions) Validate(cmd *cobra.Command, args []string) error {
102102
return nil
103103
}
104104

105+
// Complete completes the setup of the command.
105106
func (o *DeleteOptions) Complete(factory factory.Factory, cmd *cobra.Command, args []string) error {
106107
// Prepare namespace
107108
var err error

pkg/cmd/get.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ func (o *GetOptions) Validate(cmd *cobra.Command, args []string) error {
111111
return nil
112112
}
113113

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

128-
//// Prepare client
129+
// Prepare client
129130
o.clientConfig, err = factory.ToRESTConfig()
130131
if err != nil {
131132
return err

pkg/cmd/log.go

+2
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ func NewLogCommand(factory factory.Factory, streams genericclioptions.IOStreams)
8585
return cmd
8686
}
8787

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

100+
// Complete completes the setup of the command.
99101
func (o *LogOptions) Complete(factory factory.Factory, cmd *cobra.Command, args []string) error {
100102
// Prepare namespace
101103
var err error

pkg/cmd/run.go

+38-12
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,34 @@ import (
2020
"k8s.io/client-go/rest"
2121
)
2222

23+
var (
24+
// ImageNameTag represents the default tracerunner image
25+
ImageNameTag = "quay.io/fntlnz/kubectl-trace-bpftrace:latest"
26+
// InitImageNameTag represents the default init container image
27+
InitImageNameTag = "quay.io/fntlnz/kubectl-trace-init:latest"
28+
)
29+
2330
var (
2431
runShort = `Execute a bpftrace program on resources` // Wrap with i18n.T()
2532

2633
runLong = runShort
2734

2835
runExamples = `
2936
# Count system calls using tracepoints on a specific node
30-
%[1]s trace run node/kubernetes-node-emt8.c.myproject.internal -e 'kprobe:do_sys_open { printf("%s: %s\n", comm, str(arg1)) }'
37+
%[1]s trace run node/kubernetes-node-emt8.c.myproject.internal -e 'kprobe:do_sys_open { printf("%%s: %%s\n", comm, str(arg1)) }'
3138
3239
# Execute a bpftrace program from file on a specific node
3340
%[1]s trace run node/kubernetes-node-emt8.c.myproject.internal -f read.bt
3441
3542
# Run an bpftrace inline program on a pod container
3643
%[1]s trace run pod/nginx -c nginx -e "tracepoint:syscalls:sys_enter_* { @[probe] = count(); }"
3744
%[1]s trace run pod/nginx nginx -e "tracepoint:syscalls:sys_enter_* { @[probe] = count(); }"
38-
%[1]s trace run pod/nginx nginx -e "tracepoint:syscalls:sys_enter_* { @[probe] = count(); }"`
45+
46+
# Run a bpftrace inline program on a pod container with a custom image for the init container responsible to fetch linux headers
47+
%[1]s trace run pod/nginx nginx -e "tracepoint:syscalls:sys_enter_* { @[probe] = count(); } --init-imagename=quay.io/custom-init-image-name --fetch-headers"
48+
49+
# 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
50+
%[1]s trace run pod/nginx nginx -e "tracepoint:syscalls:sys_enter_* { @[probe] = count(); } --imagename=quay.io/custom-bpftrace-image-name"`
3951

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

56-
// Local to this command
68+
// Flags local to this command
5769
container string
5870
eval string
5971
program string
60-
resourceArg string
61-
attach bool
62-
isPod bool
63-
podUID string
6472
serviceAccount string
73+
imageName string
74+
initImageName string
75+
fetchHeaders bool
6576

66-
nodeName string
77+
resourceArg string
78+
attach bool
79+
isPod bool
80+
podUID string
81+
nodeName string
6782

6883
clientConfig *rest.Config
6984
}
@@ -72,6 +87,10 @@ type RunOptions struct {
7287
func NewRunOptions(streams genericclioptions.IOStreams) *RunOptions {
7388
return &RunOptions{
7489
IOStreams: streams,
90+
91+
serviceAccount: "default",
92+
imageName: ImageNameTag,
93+
initImageName: InitImageNameTag,
7594
}
7695
}
7796

@@ -101,10 +120,13 @@ func NewRunCommand(factory factory.Factory, streams genericclioptions.IOStreams)
101120
}
102121

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

109131
return cmd
110132
}
@@ -276,6 +298,10 @@ func (o *RunOptions) Run() error {
276298
PodUID: o.podUID,
277299
ContainerName: o.container,
278300
IsPod: o.isPod,
301+
// todo(dalehamel) > following fields to be used for #48
302+
ImageNameTag: o.imageName,
303+
InitImageNameTag: o.initImageName,
304+
FetchHeaders: o.fetchHeaders,
279305
}
280306

281307
job, err := tc.CreateJob(tj)

pkg/cmd/trace.go

+13
Original file line numberDiff line numberDiff line change
@@ -76,5 +76,18 @@ func NewTraceCommand(streams genericclioptions.IOStreams) *cobra.Command {
7676
cmd.AddCommand(NewVersionCommand(streams))
7777
cmd.AddCommand(NewLogCommand(f, streams))
7878

79+
// Override help on all the commands tree
80+
walk(cmd, func(c *cobra.Command) {
81+
c.Flags().BoolP("help", "h", false, fmt.Sprintf("Help for the %s command", c.Name()))
82+
})
83+
7984
return cmd
8085
}
86+
87+
// walk calls f for c and all of its children.
88+
func walk(c *cobra.Command, f func(*cobra.Command)) {
89+
f(c)
90+
for _, c := range c.Commands() {
91+
walk(c, f)
92+
}
93+
}

pkg/cmd/tracerunner.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func NewTraceRunnerCommand() *cobra.Command {
5050
cmd.Flags().StringVarP(&o.podUID, "poduid", "p", o.podUID, "Specify the pod UID")
5151
cmd.Flags().StringVarP(&o.programPath, "program", "f", "program.bt", "Specify the bpftrace program path")
5252
cmd.Flags().StringVarP(&o.bpftraceBinaryPath, "bpftracebinary", "b", "/bin/bpftrace", "Specify the bpftrace binary path")
53-
cmd.Flags().BoolVar(&o.inPod, "inpod", false, "Wether or not run this bpftrace in a pod's container process namespace")
53+
cmd.Flags().BoolVar(&o.inPod, "inpod", false, "Whether or not run this bpftrace in a pod's container process namespace")
5454
return cmd
5555
}
5656

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

65+
// Complete completes the setup of the command.
6566
func (o *TraceRunnerOptions) Complete(cmd *cobra.Command, args []string) error {
6667
return nil
6768
}

pkg/cmd/version.go

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"k8s.io/cli-runtime/pkg/genericclioptions"
99
)
1010

11+
// NewVersionCommand provides the version command.
1112
func NewVersionCommand(streams genericclioptions.IOStreams) *cobra.Command {
1213
cmd := &cobra.Command{
1314
Use: "version",

pkg/tracejob/job.go

+23-22
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,15 @@ package tracejob
22

33
import (
44
"fmt"
5-
6-
"github.com/iovisor/kubectl-trace/pkg/version"
7-
85
"io"
96
"io/ioutil"
107

118
"github.com/iovisor/kubectl-trace/pkg/meta"
129
batchv1 "k8s.io/api/batch/v1"
1310
apiv1 "k8s.io/api/core/v1"
11+
"k8s.io/apimachinery/pkg/api/resource"
1412
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1513
"k8s.io/apimachinery/pkg/types"
16-
"k8s.io/apimachinery/pkg/api/resource"
1714
batchv1typed "k8s.io/client-go/kubernetes/typed/batch/v1"
1815
corev1typed "k8s.io/client-go/kubernetes/typed/core/v1"
1916
)
@@ -24,16 +21,20 @@ type TraceJobClient struct {
2421
outStream io.Writer
2522
}
2623

24+
// TraceJob is a container of info needed to create the job responsible for tracing.
2725
type TraceJob struct {
28-
Name string
29-
ID types.UID
30-
Namespace string
31-
ServiceAccount string
32-
Hostname string
33-
Program string
34-
PodUID string
35-
ContainerName string
36-
IsPod bool
26+
Name string
27+
ID types.UID
28+
Namespace string
29+
ServiceAccount string
30+
Hostname string
31+
Program string
32+
PodUID string
33+
ContainerName string
34+
IsPod bool
35+
ImageNameTag string
36+
InitImageNameTag string
37+
FetchHeaders bool
3738
}
3839

3940
// WithOutStream setup a file stream to output trace job operation information
@@ -252,19 +253,19 @@ func (t *TraceJobClient) CreateJob(nj TraceJob) (*batchv1.Job, error) {
252253
Containers: []apiv1.Container{
253254
apiv1.Container{
254255
Name: nj.Name,
255-
Image: version.ImageNameTag(),
256+
Image: nj.ImageNameTag,
256257
Command: bpfTraceCmd,
257258
TTY: true,
258259
Stdin: true,
259260
Resources: apiv1.ResourceRequirements{
260-
Requests: apiv1.ResourceList{
261-
apiv1.ResourceCPU: resource.MustParse("100m"),
262-
apiv1.ResourceMemory: resource.MustParse("100Mi"),
263-
},
264-
Limits: apiv1.ResourceList{
265-
apiv1.ResourceCPU: resource.MustParse("1"),
266-
apiv1.ResourceMemory: resource.MustParse("1G"),
267-
},
261+
Requests: apiv1.ResourceList{
262+
apiv1.ResourceCPU: resource.MustParse("100m"),
263+
apiv1.ResourceMemory: resource.MustParse("100Mi"),
264+
},
265+
Limits: apiv1.ResourceList{
266+
apiv1.ResourceCPU: resource.MustParse("1"),
267+
apiv1.ResourceMemory: resource.MustParse("1G"),
268+
},
268269
},
269270
VolumeMounts: []apiv1.VolumeMount{
270271
apiv1.VolumeMount{

pkg/version/version.go

+3-21
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,15 @@ import (
88

99
// Populated by makefile
1010
var gitCommit string
11-
var imageName string
1211
var buildTime string
1312
var versionFormat = "git commit: %s\nbuild date: %s"
14-
var imageNameTagFormat = "%s:%s"
15-
var defaultImageName = "quay.io/fntlnz/kubectl-trace-bpftrace"
16-
var defaultImageTag = "latest"
17-
18-
// ImageName returns the container image name defined in Makefile
19-
func ImageName() string {
20-
return imageName
21-
}
2213

14+
// GitCommit returns the git commit
2315
func GitCommit() string {
2416
return gitCommit
2517
}
2618

27-
func ImageNameTag() string {
28-
imageName := ImageName()
29-
tag := GitCommit()
30-
if len(tag) == 0 {
31-
tag = defaultImageTag
32-
}
33-
if len(imageName) == 0 {
34-
imageName = defaultImageName
35-
}
36-
return fmt.Sprintf(imageNameTagFormat, imageName, tag)
37-
}
38-
19+
// Time returns the build time
3920
func Time() *time.Time {
4021
if len(buildTime) == 0 {
4122
return nil
@@ -48,6 +29,7 @@ func Time() *time.Time {
4829
return &t
4930
}
5031

32+
// String returns version info as a string
5133
func String() string {
5234
ts := Time()
5335
if ts == nil {

0 commit comments

Comments
 (0)