Skip to content
Snippets Groups Projects
Commit ca62da0e authored by Sheng Yang's avatar Sheng Yang
Browse files

Provisioner works with DynamicProvisioningScheduling on Kubernetes v1.11

parent 17988e96
No related branches found
No related tags found
No related merge requests found
main.go 0 → 100644
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"github.com/Sirupsen/logrus"
"github.com/pkg/errors"
"github.com/urfave/cli"
pvController "github.com/kubernetes-incubator/external-storage/lib/controller"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)
var (
VERSION = "0.0.1"
DefaultProvisionerName = "rancher.io/local-path"
FlagProvisionerName = "provisioner-name"
EnvProvisionerName = "PROVISIONER_NAME"
)
func cmdNotFound(c *cli.Context, command string) {
panic(fmt.Errorf("Unrecognized command: %s", command))
}
func onUsageError(c *cli.Context, err error, isSubcommand bool) error {
panic(fmt.Errorf("Usage error, please check your command"))
}
func RegisterShutdownChannel(done chan struct{}) {
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
sig := <-sigs
logrus.Infof("Receive %v to exit", sig)
close(done)
}()
}
func StartCmd() cli.Command {
return cli.Command{
Name: "start",
Flags: []cli.Flag{
cli.StringFlag{
Name: FlagProvisionerName,
Usage: "Specify provisioner name",
EnvVar: EnvProvisionerName,
Value: DefaultProvisionerName,
},
},
Action: func(c *cli.Context) {
if err := startDaemon(c); err != nil {
logrus.Fatalf("Error starting daemon: %v", err)
}
},
}
}
func startDaemon(c *cli.Context) error {
stopCh := make(chan struct{})
RegisterShutdownChannel(stopCh)
config, err := rest.InClusterConfig()
if err != nil {
return errors.Wrap(err, "unable to get client config")
}
kubeClient, err := clientset.NewForConfig(config)
if err != nil {
return errors.Wrap(err, "unable to get k8s client")
}
serverVersion, err := kubeClient.Discovery().ServerVersion()
if err != nil {
return errors.Wrap(err, "Cannot start Provisioner: failed to get Kubernetes server version")
}
provisionerName := c.String(FlagProvisionerName)
if provisionerName == "" {
return fmt.Errorf("invalid empty provisioner name")
}
provisioner := NewProvisioner()
pc := pvController.NewProvisionController(
kubeClient,
provisionerName,
provisioner,
serverVersion.GitVersion,
)
logrus.Debug("Provisioner started")
pc.Run(stopCh)
logrus.Debug("Provisioner stopped")
return nil
}
func main() {
logrus.SetFormatter(&logrus.TextFormatter{FullTimestamp: true})
a := cli.NewApp()
a.Version = VERSION
a.Usage = "Local Path Provisioner"
a.Before = func(c *cli.Context) error {
if c.GlobalBool("debug") {
logrus.SetLevel(logrus.DebugLevel)
}
return nil
}
a.Flags = []cli.Flag{
cli.BoolFlag{
Name: "debug, d",
Usage: "enable debug logging level",
EnvVar: "RANCHER_DEBUG",
},
}
a.Commands = []cli.Command{
StartCmd(),
}
a.CommandNotFound = cmdNotFound
a.OnUsageError = onUsageError
if err := a.Run(os.Args); err != nil {
logrus.Fatalf("Critical error: %v", err)
}
}
package main
import (
"fmt"
"path/filepath"
"github.com/Sirupsen/logrus"
pvController "github.com/kubernetes-incubator/external-storage/lib/controller"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
var (
DefaultPath = "/opt"
)
type LocalPathProvisioner struct {
}
func NewProvisioner() *LocalPathProvisioner {
return &LocalPathProvisioner{}
}
func (p *LocalPathProvisioner) Provision(opts pvController.VolumeOptions) (*v1.PersistentVolume, error) {
pvc := opts.PVC
if pvc.Spec.Selector != nil {
return nil, fmt.Errorf("claim.Spec.Selector is not supported")
}
for _, accessMode := range pvc.Spec.AccessModes {
if accessMode != v1.ReadWriteOnce {
return nil, fmt.Errorf("Only support ReadWriteOnce access mode")
}
}
node := opts.SelectedNode
if opts.SelectedNode == nil {
return nil, fmt.Errorf("configuration error, no node was specified")
}
name := opts.PVName
path := filepath.Join(DefaultPath, name)
logrus.Infof("Created volume %v", name)
fs := v1.PersistentVolumeFilesystem
hostPathType := v1.HostPathDirectoryOrCreate
return &v1.PersistentVolume{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: v1.PersistentVolumeSpec{
PersistentVolumeReclaimPolicy: opts.PersistentVolumeReclaimPolicy,
AccessModes: pvc.Spec.AccessModes,
VolumeMode: &fs,
Capacity: v1.ResourceList{
v1.ResourceName(v1.ResourceStorage): pvc.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)],
},
PersistentVolumeSource: v1.PersistentVolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: path,
Type: &hostPathType,
},
},
NodeAffinity: &v1.VolumeNodeAffinity{
Required: &v1.NodeSelector{
NodeSelectorTerms: []v1.NodeSelectorTerm{
{
MatchExpressions: []v1.NodeSelectorRequirement{
{
Key: "kubernetes.io/hostname",
Operator: v1.NodeSelectorOpIn,
Values: []string{
node.Name,
},
},
},
},
},
},
},
},
}, nil
}
func (p *LocalPathProvisioner) Delete(pv *v1.PersistentVolume) error {
return nil
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment