Skip to content

Commit f9e1ca6

Browse files
committed
Rewrite gemini-agent as external plugin
1 parent 32fe11a commit f9e1ca6

9 files changed

Lines changed: 1381 additions & 0 deletions

File tree

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
Copyright The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"flag"
21+
"fmt"
22+
"net/http"
23+
"os"
24+
"strconv"
25+
"time"
26+
27+
"github.com/sirupsen/logrus"
28+
29+
"sigs.k8s.io/prow/cmd/external-plugins/geminiagent/plugin"
30+
"sigs.k8s.io/prow/pkg/config/secret"
31+
"sigs.k8s.io/prow/pkg/flagutil"
32+
prowflagutil "sigs.k8s.io/prow/pkg/flagutil"
33+
pluginsflagutil "sigs.k8s.io/prow/pkg/flagutil/plugins"
34+
"sigs.k8s.io/prow/pkg/interrupts"
35+
"sigs.k8s.io/prow/pkg/logrusutil"
36+
"sigs.k8s.io/prow/pkg/pjutil"
37+
"sigs.k8s.io/prow/pkg/pluginhelp/externalplugins"
38+
)
39+
40+
type options struct {
41+
port int
42+
43+
pluginsConfig pluginsflagutil.PluginOptions
44+
dryRun bool
45+
github prowflagutil.GitHubOptions
46+
instrumentationOptions prowflagutil.InstrumentationOptions
47+
logLevel string
48+
49+
webhookSecretFile string
50+
}
51+
52+
const defaultHourlyTokens = 360
53+
54+
func (o *options) Validate() error {
55+
for idx, group := range []flagutil.OptionGroup{&o.github} {
56+
if err := group.Validate(o.dryRun); err != nil {
57+
return fmt.Errorf("%d: %w", idx, err)
58+
}
59+
}
60+
61+
return nil
62+
}
63+
64+
func gatherOptions() options {
65+
o := options{}
66+
fs := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
67+
fs.IntVar(&o.port, "port", 8888, "Port to listen on.")
68+
fs.BoolVar(&o.dryRun, "dry-run", true, "Dry run for testing. Uses API tokens but does not mutate.")
69+
fs.StringVar(&o.webhookSecretFile, "hmac-secret-file", "/etc/webhook/hmac", "Path to the file containing the GitHub HMAC secret.")
70+
fs.StringVar(&o.logLevel, "log-level", "debug", fmt.Sprintf("Log level is one of %v.", logrus.AllLevels))
71+
72+
o.github.AddCustomizedFlags(fs, prowflagutil.ThrottlerDefaults(defaultHourlyTokens, defaultHourlyTokens))
73+
74+
o.pluginsConfig.PluginConfigPathDefault = "/etc/plugins/plugins.yaml"
75+
for _, group := range []flagutil.OptionGroup{&o.instrumentationOptions, &o.pluginsConfig} {
76+
group.AddFlags(fs)
77+
}
78+
fs.Parse(os.Args[1:])
79+
return o
80+
}
81+
82+
func main() {
83+
logrusutil.ComponentInit()
84+
o := gatherOptions()
85+
if err := o.Validate(); err != nil {
86+
logrus.Fatalf("Invalid options: %v", err)
87+
}
88+
89+
logLevel, err := logrus.ParseLevel(o.logLevel)
90+
if err != nil {
91+
logrus.WithError(err).Fatal("Failed to parse loglevel")
92+
}
93+
logrus.SetLevel(logLevel)
94+
log := logrus.StandardLogger().WithField("plugin", plugin.PluginName)
95+
96+
if err := secret.Add(o.webhookSecretFile); err != nil {
97+
logrus.WithError(err).Fatal("Error starting secrets agent.")
98+
}
99+
100+
pluginAgent, err := o.pluginsConfig.PluginAgent()
101+
if err != nil {
102+
log.WithError(err).Fatal("Error loading plugin config")
103+
}
104+
105+
githubClient, err := o.github.GitHubClient(o.dryRun)
106+
if err != nil {
107+
logrus.WithError(err).Fatal("Error getting GitHub client.")
108+
}
109+
110+
server := &Server{
111+
tokenGenerator: secret.GetTokenGenerator(o.webhookSecretFile),
112+
ghc: githubClient,
113+
log: log,
114+
pluginAgent: pluginAgent,
115+
handleGenericComment: plugin.HandleGenericComment,
116+
}
117+
118+
health := pjutil.NewHealthOnPort(o.instrumentationOptions.HealthPort)
119+
health.ServeReady()
120+
121+
mux := http.NewServeMux()
122+
mux.Handle("/", server)
123+
externalplugins.ServeExternalPluginHelp(mux, log, plugin.HelpProvider)
124+
httpServer := &http.Server{Addr: ":" + strconv.Itoa(o.port), Handler: mux}
125+
defer interrupts.WaitForGracefulShutdown()
126+
interrupts.ListenAndServe(httpServer, 5*time.Second)
127+
}

0 commit comments

Comments
 (0)