Skip to content

Commit

Permalink
nri-plugin: file prefetching
Browse files Browse the repository at this point in the history
1. add licence claim in prefetch.go
2. replace global variables in prefetch.go with structures
3. locked when accessong prefetchMap
4. add logic to handle type assertion
5. move NRI plugin config file to misc/nri-prefetch
6. and so on
  • Loading branch information
billie60 committed Aug 25, 2023
1 parent a6f4457 commit a4792cf
Show file tree
Hide file tree
Showing 11 changed files with 903 additions and 22 deletions.
211 changes: 211 additions & 0 deletions cmd/prefetchfiles-nri-plugin/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/*
* Copyright (c) 2023. Nydus Developers. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/

package main

import (
"context"
"fmt"
"io"
"log/syslog"
"net"
"net/http"
"os"
"path/filepath"
"strings"

"github.com/containerd/nri/pkg/api"
"github.com/containerd/nri/pkg/stub"
"github.com/pelletier/go-toml"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"

"github.com/containerd/nydus-snapshotter/pkg/errdefs"
"github.com/containerd/nydus-snapshotter/version"
)

const (
endpointPrefetch = "/api/v1/prefetch"
defaultEvents = "RunPodSandbox"
defaultSystemControllerAddress = "/run/containerd-nydus/system.sock"
nydusPrefetchAnnotation = "containerd.io/nydus-prefetch"
)

type PluginArgs struct {
PluginName string
PluginIdx string
SocketAddress string
}

type Flags struct {
Args *PluginArgs
Flag []cli.Flag
}

func buildFlags(args *PluginArgs) []cli.Flag {
return []cli.Flag{
&cli.StringFlag{
Name: "name",
Usage: "plugin name to register to NRI",
Destination: &args.PluginName,
},
&cli.StringFlag{
Name: "idx",
Usage: "plugin index to register to NRI",
Destination: &args.PluginIdx,
},
&cli.StringFlag{
Name: "socket-addr",
Value: defaultSystemControllerAddress,
Usage: "unix domain socket address. If defined in the configuration file, there is no need to add ",
Destination: &args.SocketAddress,
},
}
}

func NewPluginFlags() *Flags {
var args PluginArgs
return &Flags{
Args: &args,
Flag: buildFlags(&args),
}
}

type plugin struct {
stub stub.Stub
mask stub.EventMask
}

var (
globalSocket string
log *logrus.Logger
logWriter *syslog.Writer
)

// sendDataOverHTTP sends the prefetch data to the specified endpoint over HTTP using a Unix socket.
func sendDataOverHTTP(data string, endpoint, sock string) error {
url := fmt.Sprintf("http://unix%s", endpoint)

req, err := http.NewRequest(http.MethodPut, url, strings.NewReader(data))
if err != nil {
return err
}

client := &http.Client{
Transport: &http.Transport{
DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
return net.Dial("unix", sock)
},
},
}
resp, err := client.Do(req)
if err != nil {
return err
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to send data, status code: %d", resp.StatusCode)
}
resp.Body.Close()

return nil
}

func (p *plugin) RunPodSandbox(pod *api.PodSandbox) error {
prefetchList, ok := pod.Annotations[nydusPrefetchAnnotation]
if !ok {
return nil
}

err := sendDataOverHTTP(prefetchList, endpointPrefetch, globalSocket)
if err != nil {
log.Errorf("failed to send data: %v", err)
return err
}

return nil
}

func main() {

flags := NewPluginFlags()

app := &cli.App{
Name: "prefetch-nri-plugin",
Usage: "NRI plugin for obtaining and transmitting prefetch files path",
Version: version.Version,
Flags: flags.Flag,
HideVersion: true,
Action: func(c *cli.Context) error {
var (
opts []stub.Option
err error
)

log = logrus.StandardLogger()

configFileName := "prefetchConfig.toml"
configDir := "../../misc/nri-prefetch"
configFilePath := filepath.Join(configDir, configFileName)

config, err := toml.LoadFile(configFilePath)
if err != nil {
log.Warnf("failed to read config file: %v", err)
}

configSocketAddrRaw := config.Get("file_prefetch.socket_address")
if configSocketAddrRaw != nil {
if configSocketAddr, ok := configSocketAddrRaw.(string); ok {
globalSocket = configSocketAddr
} else {
log.Warnf("failed to read config: 'file_prefetch.socket_address' is not a string")
}
} else {
globalSocket = flags.Args.SocketAddress
}

log.SetFormatter(&logrus.TextFormatter{
PadLevelText: true,
})
logWriter, err = syslog.New(syslog.LOG_INFO, "prefetch-nri-plugin")

if err == nil {
log.SetOutput(io.MultiWriter(os.Stdout, logWriter))
}

if flags.Args.PluginName != "" {
opts = append(opts, stub.WithPluginName(flags.Args.PluginName))
}
if flags.Args.PluginIdx != "" {
opts = append(opts, stub.WithPluginIdx(flags.Args.PluginIdx))
}

p := &plugin{}

if p.mask, err = api.ParseEventMask(defaultEvents); err != nil {
log.Fatalf("failed to parse events: %v", err)
}

if p.stub, err = stub.New(p, opts...); err != nil {
log.Fatalf("failed to create plugin stub: %v", err)
}

err = p.stub.Run(context.Background())
if err != nil {
return errors.Wrap(err, "plugin exited")
}
return nil
},
}
if err := app.Run(os.Args); err != nil {

if errdefs.IsConnectionClosed(err) {
log.Info("prefetch NRI plugin exited")
} else {
log.WithError(err).Fatal("failed to start prefetch NRI plugin")
}
}
}
3 changes: 2 additions & 1 deletion config/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import (
"time"

"github.com/containerd/containerd/log"
"github.com/pkg/errors"

"github.com/containerd/nydus-snapshotter/internal/logging"
"github.com/containerd/nydus-snapshotter/pkg/utils/mount"
"github.com/pkg/errors"
)

var (
Expand Down
71 changes: 57 additions & 14 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
github.com/containerd/nri v0.3.0
github.com/containerd/stargz-snapshotter v0.14.3
github.com/containerd/stargz-snapshotter/estargz v0.14.3
github.com/containers/ocicrypt v1.1.7
github.com/docker/cli v23.0.1+incompatible
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
github.com/google/go-containerregistry v0.13.0
Expand All @@ -32,21 +33,63 @@ require (
github.com/prometheus/client_model v0.3.0
github.com/rs/xid v1.4.0
github.com/sirupsen/logrus v1.9.0
github.com/stretchr/testify v1.8.2
github.com/stretchr/testify v1.8.3
github.com/urfave/cli/v2 v2.25.0
go.etcd.io/bbolt v1.3.7
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
golang.org/x/net v0.8.0
golang.org/x/net v0.10.0
golang.org/x/sync v0.1.0
golang.org/x/sys v0.6.0
google.golang.org/grpc v1.53.0
golang.org/x/sys v0.10.0
google.golang.org/grpc v1.55.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gotest.tools v2.2.0+incompatible
k8s.io/api v0.26.2
k8s.io/apimachinery v0.26.2
k8s.io/client-go v0.26.2
k8s.io/cri-api v0.27.0-alpha.3
github.com/containers/ocicrypt v1.1.7
)

require (
cloud.google.com/go v0.110.0 // indirect
cloud.google.com/go/compute v1.19.0 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/firestore v1.9.0 // indirect
cloud.google.com/go/longrunning v0.4.1 // indirect
github.com/armon/go-metrics v0.4.0 // indirect
github.com/cilium/ebpf v0.9.1 // indirect
github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/google/s2a-go v0.1.3 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/googleapis/gax-go/v2 v2.8.0 // indirect
github.com/hashicorp/consul/api v1.20.0 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/serf v0.10.1 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/sagikazarmark/crypt v0.10.0 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/viper v1.16.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
go.etcd.io/etcd/api/v3 v3.5.9 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.9 // indirect
go.etcd.io/etcd/client/v2 v2.305.7 // indirect
go.etcd.io/etcd/client/v3 v3.5.9 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.21.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.122.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)

require (
Expand Down Expand Up @@ -112,6 +155,7 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/miekg/pkcs11 v1.1.1 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/moby/locker v1.0.1
github.com/moby/sys/mountinfo v0.6.2 // indirect
Expand All @@ -128,21 +172,25 @@ require (
github.com/prometheus/procfs v0.9.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 // indirect
github.com/vbatts/tar-split v0.11.2 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel v1.14.0 // indirect
go.opentelemetry.io/otel/trace v1.14.0 // indirect
golang.org/x/crypto v0.9.0 // indirect
golang.org/x/mod v0.9.0
golang.org/x/oauth2 v0.6.0 // indirect
golang.org/x/term v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/oauth2 v0.7.0 // indirect
golang.org/x/term v0.10.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.7.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.90.1 // indirect
Expand All @@ -151,11 +199,6 @@ require (
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
github.com/miekg/pkcs11 v1.1.1 // indirect
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 // indirect
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 // indirect
golang.org/x/crypto v0.1.0 // indirect
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
)

retract (
Expand Down
Loading

0 comments on commit a4792cf

Please sign in to comment.