Skip to content

Commit

Permalink
Merge pull request #4 from arangodb/creating-pods
Browse files Browse the repository at this point in the history
Creating pods
  • Loading branch information
ewoutp authored Feb 16, 2018
2 parents 01bc088 + 17f357d commit 6ec749c
Show file tree
Hide file tree
Showing 11 changed files with 600 additions and 101 deletions.
14 changes: 14 additions & 0 deletions examples/nodeport-cluster.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
kind: Service
apiVersion: v1
metadata:
name: arangodb-exposed-cluster
spec:
selector:
app: arangodb
role: coordinator
type: NodePort
ports:
- protocol: TCP
port: 8529
targetPort: 8529
nodePort: 31529
14 changes: 14 additions & 0 deletions examples/nodeport-single-server.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
kind: Service
apiVersion: v1
metadata:
name: arangodb-exposed
spec:
selector:
app: arangodb
role: single
type: NodePort
ports:
- protocol: TCP
port: 8529
targetPort: 8529
nodePort: 30529
89 changes: 65 additions & 24 deletions pkg/apis/arangodb/v1alpha/deployment_spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,30 +197,41 @@ func (s *SSLSpec) SetDefaults() {

// SyncSpec holds dc2dc replication specific configuration settings
type SyncSpec struct {
Enabled bool `json:"enabled,omitempty"`
Enabled bool `json:"enabled,omitempty"`
Image string `json:"image,omitempty"`
ImagePullPolicy v1.PullPolicy `json:"imagePullPolicy,omitempty"`
}

// Validate the given spec
func (s SyncSpec) Validate(mode DeploymentMode) error {
if s.Enabled && !mode.SupportsSync() {
return maskAny(errors.Wrapf(ValidationError, "Cannot enable sync with mode: '%s'", mode))
}
if s.Image == "" {
return maskAny(errors.Wrapf(ValidationError, "image must be set"))
}
return nil
}

// SetDefaults fills in missing defaults
func (s *SyncSpec) SetDefaults() {
func (s *SyncSpec) SetDefaults(defaultImage string, defaulPullPolicy v1.PullPolicy) {
if s.Image == "" {
s.Image = defaultImage
}
if s.ImagePullPolicy == "" {
s.ImagePullPolicy = defaulPullPolicy
}
}

type ServerGroup int

const (
ServerGroupSingle = 1
ServerGroupAgents = 2
ServerGroupDBServers = 3
ServerGroupCoordinators = 4
ServerGroupSyncMasters = 5
ServerGroupSyncWorkers = 6
ServerGroupSingle ServerGroup = 1
ServerGroupAgents ServerGroup = 2
ServerGroupDBServers ServerGroup = 3
ServerGroupCoordinators ServerGroup = 4
ServerGroupSyncMasters ServerGroup = 5
ServerGroupSyncWorkers ServerGroup = 6
)

// AsRole returns the "role" value for the given group.
Expand All @@ -243,6 +254,26 @@ func (g ServerGroup) AsRole() string {
}
}

// IsArangod returns true when the groups runs servers of type `arangod`.
func (g ServerGroup) IsArangod() bool {
switch g {
case ServerGroupSingle, ServerGroupAgents, ServerGroupDBServers, ServerGroupCoordinators:
return true
default:
return false
}
}

// IsArangosync returns true when the groups runs servers of type `arangosync`.
func (g ServerGroup) IsArangosync() bool {
switch g {
case ServerGroupSyncMasters, ServerGroupSyncWorkers:
return true
default:
return false
}
}

// ServerGroupSpec contains the specification for all servers in a specific group (e.g. all agents)
type ServerGroupSpec struct {
// Count holds the requested number of servers
Expand All @@ -256,23 +287,30 @@ type ServerGroupSpec struct {
}

// Validate the given group spec
func (s ServerGroupSpec) Validate(group ServerGroup, used bool) error {
func (s ServerGroupSpec) Validate(group ServerGroup, used bool, mode DeploymentMode) error {
if used {
if s.Count < 1 {
return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d. Expected >= 1", s.Count))
}
if s.Count > 1 && group == ServerGroupSingle && mode == DeploymentModeSingle {
return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d. Expected 1", s.Count))
}
} else if s.Count != 0 {
return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d for un-used group. Expected 0", s.Count))
}
return nil
}

// SetDefaults fills in missing defaults
func (s *ServerGroupSpec) SetDefaults(group ServerGroup, used bool) {
func (s *ServerGroupSpec) SetDefaults(group ServerGroup, used bool, mode DeploymentMode) {
if s.Count == 0 && used {
switch group {
case ServerGroupSingle:
s.Count = 1
if mode == DeploymentModeSingle {
s.Count = 1 // Single server
} else {
s.Count = 2 // Resilient single
}
default:
s.Count = 3
}
Expand Down Expand Up @@ -323,16 +361,19 @@ func (s *DeploymentSpec) SetDefaults() {
if s.Image == "" && s.IsDevelopment() {
s.Image = defaultImage
}
if s.ImagePullPolicy == "" {
s.ImagePullPolicy = v1.PullIfNotPresent
}
s.RocksDB.SetDefaults()
s.Authentication.SetDefaults()
s.SSL.SetDefaults()
s.Sync.SetDefaults()
s.Single.SetDefaults(ServerGroupSingle, s.Mode.HasSingleServers())
s.Agents.SetDefaults(ServerGroupAgents, s.Mode.HasAgents())
s.DBServers.SetDefaults(ServerGroupDBServers, s.Mode.HasDBServers())
s.Coordinators.SetDefaults(ServerGroupCoordinators, s.Mode.HasCoordinators())
s.SyncMasters.SetDefaults(ServerGroupSyncMasters, s.Sync.Enabled)
s.SyncWorkers.SetDefaults(ServerGroupSyncWorkers, s.Sync.Enabled)
s.Sync.SetDefaults(s.Image, s.ImagePullPolicy)
s.Single.SetDefaults(ServerGroupSingle, s.Mode.HasSingleServers(), s.Mode)
s.Agents.SetDefaults(ServerGroupAgents, s.Mode.HasAgents(), s.Mode)
s.DBServers.SetDefaults(ServerGroupDBServers, s.Mode.HasDBServers(), s.Mode)
s.Coordinators.SetDefaults(ServerGroupCoordinators, s.Mode.HasCoordinators(), s.Mode)
s.SyncMasters.SetDefaults(ServerGroupSyncMasters, s.Sync.Enabled, s.Mode)
s.SyncWorkers.SetDefaults(ServerGroupSyncWorkers, s.Sync.Enabled, s.Mode)
}

// Validate the specification.
Expand Down Expand Up @@ -365,22 +406,22 @@ func (s *DeploymentSpec) Validate() error {
if err := s.Sync.Validate(s.Mode); err != nil {
return maskAny(err)
}
if err := s.Single.Validate(ServerGroupSingle, s.Mode.HasSingleServers()); err != nil {
if err := s.Single.Validate(ServerGroupSingle, s.Mode.HasSingleServers(), s.Mode); err != nil {
return maskAny(err)
}
if err := s.Agents.Validate(ServerGroupAgents, s.Mode.HasAgents()); err != nil {
if err := s.Agents.Validate(ServerGroupAgents, s.Mode.HasAgents(), s.Mode); err != nil {
return maskAny(err)
}
if err := s.DBServers.Validate(ServerGroupDBServers, s.Mode.HasDBServers()); err != nil {
if err := s.DBServers.Validate(ServerGroupDBServers, s.Mode.HasDBServers(), s.Mode); err != nil {
return maskAny(err)
}
if err := s.Coordinators.Validate(ServerGroupCoordinators, s.Mode.HasCoordinators()); err != nil {
if err := s.Coordinators.Validate(ServerGroupCoordinators, s.Mode.HasCoordinators(), s.Mode); err != nil {
return maskAny(err)
}
if err := s.SyncMasters.Validate(ServerGroupSyncMasters, s.Sync.Enabled); err != nil {
if err := s.SyncMasters.Validate(ServerGroupSyncMasters, s.Sync.Enabled, s.Mode); err != nil {
return maskAny(err)
}
if err := s.SyncWorkers.Validate(ServerGroupSyncWorkers, s.Sync.Enabled); err != nil {
if err := s.SyncWorkers.Validate(ServerGroupSyncWorkers, s.Sync.Enabled, s.Mode); err != nil {
return maskAny(err)
}
return nil
Expand Down
42 changes: 6 additions & 36 deletions pkg/deployment/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ func (d *Deployment) run() {
return
}

// Create pods
if err := d.ensurePods(d.apiObject); err != nil {
d.failOnError(err, "Failed to create pods")
return
}

d.status.State = api.DeploymentStateRunning
if err := d.updateCRStatus(); err != nil {
log.Warn().Err(err).Msg("update initial CR status failed")
Expand Down Expand Up @@ -185,42 +191,6 @@ func (d *Deployment) handleUpdateEvent(event *deploymentEvent) error {
return nil
}

// createServices creates all services needed to service the given deployment
func (d *Deployment) createServices(apiObject *api.ArangoDeployment) error {
log := d.deps.Log
kubecli := d.deps.KubeCli
owner := apiObject.AsOwner()

log.Debug().Msg("creating services...")

if _, err := k8sutil.CreateHeadlessService(kubecli, apiObject, owner); err != nil {
log.Debug().Err(err).Msg("Failed to create headless service")
return maskAny(err)
}
single := apiObject.Spec.Mode.HasSingleServers()
if svcName, err := k8sutil.CreateDatabaseClientService(kubecli, apiObject, single, owner); err != nil {
log.Debug().Err(err).Msg("Failed to create database client service")
return maskAny(err)
} else {
d.status.ServiceName = svcName
if err := d.updateCRStatus(); err != nil {
return maskAny(err)
}
}
if apiObject.Spec.Sync.Enabled {
if svcName, err := k8sutil.CreateSyncMasterClientService(kubecli, apiObject, owner); err != nil {
log.Debug().Err(err).Msg("Failed to create syncmaster client service")
return maskAny(err)
} else {
d.status.ServiceName = svcName
if err := d.updateCRStatus(); err != nil {
return maskAny(err)
}
}
}
return nil
}

// Update the status of the API object from the internal status
func (d *Deployment) updateCRStatus() error {
if reflect.DeepEqual(d.apiObject.Status, d.status) {
Expand Down
24 changes: 0 additions & 24 deletions pkg/deployment/members.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,27 +142,3 @@ func (d *Deployment) createMember(group api.ServerGroup, apiObject *api.ArangoDe

return nil
}

// ensurePVCs creates a PVC's listed in member status
func (d *Deployment) ensurePVCs(apiObject *api.ArangoDeployment) error {
kubecli := d.deps.KubeCli
deploymentName := apiObject.GetName()
ns := apiObject.GetNamespace()
owner := apiObject.AsOwner()
if err := apiObject.ForeachServerGroup(func(group api.ServerGroup, spec api.ServerGroupSpec, status *api.MemberStatusList) error {
for _, m := range *status {
if m.PersistentVolumeClaimName != "" {
storageClassName := spec.StorageClassName
role := group.AsRole()
resources := spec.Resources
if err := k8sutil.CreatePersistentVolumeClaim(kubecli, m.PersistentVolumeClaimName, deploymentName, ns, storageClassName, role, resources, owner); err != nil {
return maskAny(err)
}
}
}
return nil
}, &d.status); err != nil {
return maskAny(err)
}
return nil
}
Loading

0 comments on commit 6ec749c

Please sign in to comment.