Skip to content

Commit

Permalink
add transfer and rsync server implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Alay Patel <[email protected]>
  • Loading branch information
alaypatel07 committed Jan 26, 2022
1 parent 02dbbbb commit 7052d05
Show file tree
Hide file tree
Showing 6 changed files with 1,611 additions and 0 deletions.
34 changes: 34 additions & 0 deletions transfer/pvc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package transfer

import (
corev1 "k8s.io/api/core/v1"
)

// PVC knows how to return v1.PersistentVolumeClaim and an additional validated
// name which can be used by different transfers as per their own requirements
type PVC interface {
// Claim returns the v1.PersistentVolumeClaim reference this PVC is associated with
Claim() *corev1.PersistentVolumeClaim
// LabelSafeName returns a name for the PVC that can be used as a label value
// it may be validated differently by different transfers
LabelSafeName() string
}

type PVCList interface {
GetNamespaces() []string
InNamespace(ns string) PVCList
PVCs() []PVC
}

// GetNames takes PVCList and returns a map with a unique md5 hash for each namespace
// based on the members in PVCList for that namespace.
func GetNames(pvcs PVCList) map[string]string {
p := map[string]string{}
for _, pvc := range pvcs.PVCs() {
p[pvc.Claim().Namespace] += pvc.Claim().Name
}
for _, ns := range p {
p[ns] = getMD5Hash(p[ns])
}
return p
}
94 changes: 94 additions & 0 deletions transfer/pvc_list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package transfer

import (
"crypto/md5"
"encoding/hex"

corev1 "k8s.io/api/core/v1"
)

// pvc represents a PersistentVolumeClaim
type pvc struct {
p *corev1.PersistentVolumeClaim
}

// Claim returns ref to associated PersistentVolumeClaim
func (p pvc) Claim() *corev1.PersistentVolumeClaim {
return p.p
}

// LabelSafeName returns a name which is guaranteed to be a safe label value
func (p pvc) LabelSafeName() string {
return getMD5Hash(p.p.Name)
}

func getMD5Hash(s string) string {
hash := md5.Sum([]byte(s))
return hex.EncodeToString(hash[:])
}

// pvcList defines a managed list of PVCs
type pvcList []PVC

// NewPVCPairList when given a list of PVCPair, returns a managed list
func NewPVCList(pvcs ...*corev1.PersistentVolumeClaim) (PVCList, error) {
pvcList := pvcList{}
for _, p := range pvcs {
if p != nil {
pvcList = append(pvcList, pvc{p})
}
// TODO: log an error here pvc list has an invalid entry
}
return pvcList, nil
}

// GetNamespaces returns all the namespaces present in the list of pvcs
func (p pvcList) GetNamespaces() (namespaces []string) {
nsSet := map[string]bool{}
for i := range p {
pvc := p[i]
if _, exists := nsSet[pvc.Claim().Namespace]; !exists {
nsSet[pvc.Claim().Namespace] = true
namespaces = append(namespaces, pvc.Claim().Namespace)
}
}
return
}

// InNamespace given a destination namespace, returns a list of pvcs that will be migrated to it
func (p pvcList) InNamespace(ns string) PVCList {
pvcList := pvcList{}
for i := range p {
pvc := p[i]
if pvc.Claim().Namespace == ns {
pvcList = append(pvcList, pvc)
}
}
return pvcList
}

func (p pvcList) PVCs() []PVC {
pvcs := []PVC{}
for i := range p {
if p[i].Claim() != nil {
pvcs = append(pvcs, p[i])
}
}
return pvcs
}

type singletonPVC struct {
pvc *corev1.PersistentVolumeClaim
}

func (s singletonPVC) Claim() *corev1.PersistentVolumeClaim {
return s.pvc
}

func (s singletonPVC) LabelSafeName() string {
return "data"
}

func NewSingletonPVC(pvc *corev1.PersistentVolumeClaim) PVCList {
return pvcList([]PVC{singletonPVC{pvc}})
}
39 changes: 39 additions & 0 deletions transfer/rsync/rsync.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package rsync

import (
"github.com/backube/pvc-transfer/transfer"
corev1 "k8s.io/api/core/v1"
)

const (
RsyncContainer = "rsync"
)

const (
rsyncImage = "quay.io/konveyor/rsync-transfer:latest"
rsyncConfig = "backube-rsync-config"
rsyncSecretPrefix = "backube-rsync"
rsyncServiceAccount = "backube-rsync-sa"
rsyncRole = "backube-rsync-role"
rsyncRoleBinding = "backube-rsync-rolebinding"
rsyncdLogDir = "rsyncd-logs"
rsyncdLogDirPath = "/var/log/rsyncd/"
)

// applyPodOptions take a PodSpec and PodOptions, applies
// each option to the given podSpec
// Following fields will be mutated:
// - spec.NodeSelector
// - spec.SecurityContext
// - spec.NodeName
// - spec.Containers[*].SecurityContext
// - spec.Containers[*].Resources
func applyPodOptions(podSpec *corev1.PodSpec, options transfer.PodOptions) {
podSpec.NodeSelector = options.NodeSelector
podSpec.NodeName = options.NodeName
podSpec.SecurityContext = &options.PodSecurityContext
for _, c := range podSpec.Containers {
c.SecurityContext = &options.ContainerSecurityContext
c.Resources = options.Resources
}
}
Loading

0 comments on commit 7052d05

Please sign in to comment.