diff --git a/cmd/analyze.go b/cmd/analyze.go index 5fc166e..28e5665 100644 --- a/cmd/analyze.go +++ b/cmd/analyze.go @@ -28,6 +28,8 @@ import ( ) var ( + // TODO (pgaikwad): this assumes that the $USER in container is always root, it may not be the case in future + M2Dir = path.Join("/", "root", ".m2") // application source path inside the container SourceMountPath = path.Join(InputPath, "source") // analyzer config files @@ -55,6 +57,7 @@ type analyzeCommand struct { output string mode string rules []string + jaegerEndpoint string // tempDirs list of temporary dirs created, used for cleanup tempDirs []string @@ -151,6 +154,7 @@ func NewAnalyzeCmd(log logr.Logger) *cobra.Command { analyzeCommand.Flags().StringVar(&analyzeCmd.mavenSettingsFile, "maven-settings", "", "path to a custom maven settings file to use") analyzeCommand.Flags().StringVarP(&analyzeCmd.mode, "mode", "m", string(provider.FullAnalysisMode), "analysis mode. Must be one of 'full' or 'source-only'") analyzeCommand.Flags().BoolVar(&analyzeCmd.jsonOutput, "json-output", false, "create analysis and dependency output as json") + analyzeCommand.Flags().StringVar(&analyzeCmd.jaegerEndpoint, "jaeger-endpoint", "", "jaeger endpoint to collect traces") return analyzeCommand } @@ -334,6 +338,8 @@ func listOptionsFromLabels(sl []string, label string) { fmt.Println("available target technologies:") } for _, tech := range newSl { + tech = strings.TrimSuffix(tech, "+") + tech = strings.TrimSuffix(tech, "-") fmt.Println(tech) } } @@ -378,6 +384,9 @@ func (a *analyzeCommand) getConfigVolumes() (map[string]string, error) { } javaConfig.InitConfig[0].ProviderSpecificConfig["mavenSettingsFile"] = fmt.Sprintf("%s/%s", ConfigMountPath, "settings.xml") } + if Settings.JvmMaxMem != "" { + javaConfig.InitConfig[0].ProviderSpecificConfig["jvmMaxMem"] = Settings.JvmMaxMem + } provConfig := []provider.Config{ { @@ -413,12 +422,26 @@ func (a *analyzeCommand) getConfigVolumes() (map[string]string, error) { } err = os.WriteFile(filepath.Join(tempDir, "settings.json"), jsonData, os.ModePerm) if err != nil { - a.log.V(1).Error(err, "failed to write provider config", "dir", tempDir, "file", "settings.json") + a.log.V(1).Error(err, + "failed to write provider config", "dir", tempDir, "file", "settings.json") return nil, err } - return map[string]string{ + + vols := map[string]string{ tempDir: ConfigMountPath, - }, nil + } + // attempt to create a .m2 directory we can use to speed things a bit + // this will be shared between analyze and dep command containers + m2Dir, err := os.MkdirTemp("", "m2-repo-") + if err != nil { + a.log.V(1).Error(err, "failed to create m2 repo", "dir", m2Dir) + } else { + vols[m2Dir] = M2Dir + a.log.V(1).Info("created directory for maven repo", "dir", m2Dir) + a.tempDirs = append(a.tempDirs, m2Dir) + } + + return vols, nil } func (a *analyzeCommand) getRulesVolumes() (map[string]string, error) { @@ -541,6 +564,11 @@ func (a *analyzeCommand) RunAnalysis(ctx context.Context, xmlOutputDir string) e fmt.Sprintf("--output-file=%s", AnalysisOutputMountPath), fmt.Sprintf("--context-lines=%d", 100), } + if a.jaegerEndpoint != "" { + args = append(args, "--enable-jaeger") + args = append(args, "--jaeger-endpoint") + args = append(args, a.jaegerEndpoint) + } if !a.analyzeKnownLibraries { args = append(args, fmt.Sprintf("--dep-label-selector=(!%s=open-source)", provider.DepSourceLabel)) diff --git a/cmd/root.go b/cmd/root.go index 9f47349..dfedd58 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -24,7 +24,6 @@ var noCleanup bool // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ - // TODO: better descriptions Short: "A cli tool for analysis and transformation of applications", Long: ``, SilenceUsage: true, diff --git a/cmd/settings.go b/cmd/settings.go index 379cde0..34c9c70 100644 --- a/cmd/settings.go +++ b/cmd/settings.go @@ -22,6 +22,7 @@ type Config struct { RootCommandName string `env:"CMD_NAME" default:"kantra"` PodmanBinary string `env:"PODMAN_BIN" default:"/usr/bin/podman"` RunnerImage string `env:"RUNNER_IMG" default:"quay.io/konveyor/kantra"` + JvmMaxMem string `env:"JVM_MAX_MEM" default:""` } func (c *Config) Load() error { diff --git a/go.mod b/go.mod index 7168d1d..1a683da 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,7 @@ require ( github.com/bombsimon/logrusr/v3 v3.1.0 github.com/codingconcepts/env v0.0.0-20200821220118-a8fbf8d84482 github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/konveyor/analyzer-lsp v0.3.0-alpha.1 + github.com/konveyor/analyzer-lsp v0.3.0-beta.1.2 github.com/shopspring/decimal v1.3.1 // indirect github.com/sirupsen/logrus v1.9.3 github.com/spf13/pflag v1.0.5 // indirect diff --git a/go.sum b/go.sum index a0143ff..6e77c7c 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc= github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= -github.com/konveyor/analyzer-lsp v0.3.0-alpha.1 h1:RilOnB9E6+zDSDQs4vBVPMITuSD3o+6P0dkXWW2H3YQ= -github.com/konveyor/analyzer-lsp v0.3.0-alpha.1/go.mod h1:Rv2WcWfVMEGEWqn0Fl4U4NcmJYPrmWdPtaFE9KDVVF8= +github.com/konveyor/analyzer-lsp v0.3.0-beta.1.2 h1:yZh5rTZYq1XYzDei3/zwZOqE8XktftaETNycV3Q7ACE= +github.com/konveyor/analyzer-lsp v0.3.0-beta.1.2/go.mod h1:zJCmIq08X0kPvtU8ZSmz+mZmQfBt4hdy9enoEy1AQw4= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= diff --git a/hack/README.md b/hack/README.md index 8bb7657..513bed8 100644 --- a/hack/README.md +++ b/hack/README.md @@ -8,4 +8,37 @@ ## General run -* `sample_jakartaee_duke_analyze.sh`: Clone and analyze a jakartaee sample \ No newline at end of file +* `sample_jakartaee_duke_analyze.sh`: Clone and analyze a jakartaee sample + +## Gather analysis traces + +Full traces of the analysis process can be collected via Jaeger. + +First, run the Jaeger container that will collect traces from analysis: + +```sh +podman run -d --net=host --name jaeger -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 jaegertracing/all-in-one:1.23 +``` + +> Note that we are running Jaeger in `host` network so that analyzer container can communicate with it later. There are several services running in the container, it could happen that the ports they use are pre-occupied on your host. In that case, you will need to free them up manually. + +The Jaeger collector listens on `14268` while the UI listens on `16686` in the container. + +Now, we will run analysis by enabling the tracer that will send traces to our Jaeger collector. + +To do that, pass `--enable-jaeger` and `--jaeger-endpoint` flags to CLI: + +```sh +kantra analyze --enable-jaeger --jaeger-enpoint 'http://172.17.0.1:14268/api/traces' +``` + +> Note that `172.17.0.1` is the IP address using which a Podman container can communicate with the host on Linux. It might be different for your system. Alternatively, you can create a network, set it as default and create your Jaeger instance in it to access it via a name instead of IP. + +When analysis finishes, download the traces from Jaeger: + +```sh +curl -o traces.json http://localhost:16686/api/traces?service=analyzer-lsp +``` + +To view the results locally, open [http://localhost:16686/](http://localhost:16686/) in your browser +