Skip to content

Commit 31fe3bc

Browse files
authored
cluster_id is vulnerable to race condition when called concurrently (#94)
* fix(cluster_id): Get() is "insert if not exist", needs read-write lock protection * fix(jobs): remove static clusterID getter in sendVersionsImpl 1) add generic data.ClusterID type in sendVersions type struct 2) enable common clusterID reference to be included in multiple, concurrent jobs, so that appropriate locking can be enforced
1 parent 2582640 commit 31fe3bc

File tree

3 files changed

+9
-2
lines changed

3 files changed

+9
-2
lines changed

boot.go

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ func main() {
4747

4848
svPeriodic := jobs.NewSendVersionsPeriodic(
4949
apiClient,
50+
clusterID,
5051
deisK8sResources,
5152
availableVersion,
5253
pollDur,

data/cluster_id.go

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ func NewClusterIDFromPersistentStorage(sgc k8s.KubeSecretGetterCreator) ClusterI
5151

5252
// Get is the ClusterID interface implementation
5353
func (c clusterIDFromPersistentStorage) Get() (string, error) {
54+
c.rwm.Lock()
55+
defer c.rwm.Unlock()
5456
secret, err := c.secretGetterCreator.Get(wfmSecretName)
5557
//If we don't have the secret we shouldn't be returning error and instead a create a new one
5658
if err != nil && !apierrors.IsNotFound(err) {

jobs/jobs.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type Periodic interface {
2222
// SendVersions fulfills the Periodic interface
2323
type sendVersions struct {
2424
k8sResources *k8s.ResourceInterfaceNamespaced
25+
clusterID data.ClusterID
2526
apiClient *apiclient.WorkflowManager
2627
availableVersions data.AvailableVersions
2728
frequency time.Duration
@@ -30,12 +31,14 @@ type sendVersions struct {
3031
// NewSendVersionsPeriodic creates a new SendVersions using sgc and rcl as the the secret getter / creator and replication controller lister implementations (respectively)
3132
func NewSendVersionsPeriodic(
3233
apiClient *apiclient.WorkflowManager,
34+
clusterID data.ClusterID,
3335
ri *k8s.ResourceInterfaceNamespaced,
3436
availableVersions data.AvailableVersions,
3537
frequency time.Duration,
3638
) Periodic {
3739
return &sendVersions{
3840
k8sResources: ri,
41+
clusterID: clusterID,
3942
apiClient: apiClient,
4043
availableVersions: availableVersions,
4144
frequency: frequency,
@@ -45,7 +48,7 @@ func NewSendVersionsPeriodic(
4548
// Do is the Periodic interface implementation
4649
func (s sendVersions) Do() error {
4750
if config.Spec.CheckVersions {
48-
err := sendVersionsImpl(s.apiClient, s.k8sResources, s.availableVersions)
51+
err := sendVersionsImpl(s.apiClient, s.clusterID, s.k8sResources, s.availableVersions)
4952
if err != nil {
5053
return err
5154
}
@@ -135,12 +138,13 @@ func DoPeriodic(pSlice []Periodic) chan<- struct{} {
135138
// sendVersions sends cluster version data
136139
func sendVersionsImpl(
137140
apiClient *apiclient.WorkflowManager,
141+
clusterID data.ClusterID,
138142
k8sResources *k8s.ResourceInterfaceNamespaced,
139143
availableVersions data.AvailableVersions,
140144
) error {
141145
cluster, err := data.GetCluster(
142146
data.NewInstalledDeisData(k8sResources),
143-
data.NewClusterIDFromPersistentStorage(k8sResources.Secrets()),
147+
clusterID,
144148
data.NewLatestReleasedComponent(k8sResources, availableVersions),
145149
)
146150
if err != nil {

0 commit comments

Comments
 (0)