-
Notifications
You must be signed in to change notification settings - Fork 80
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add architecture and os checks when fetching tags
This updates the controller to check the architecture of the cluster nodes and select only tags for the current architecture. Signed-off-by: oluwole.fadeyi <[email protected]>
- Loading branch information
oluwole.fadeyi
committed
Nov 16, 2020
1 parent
9bfbe1d
commit 79273fa
Showing
13 changed files
with
443 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package architecture | ||
|
||
import ( | ||
"fmt" | ||
"sync" | ||
|
||
corev1 "k8s.io/api/core/v1" | ||
) | ||
|
||
var _ NodeArchitectureMap = &defaultNodeMap{} | ||
|
||
const ( | ||
invalidFuncInput = "invalid function input" | ||
) | ||
|
||
// NodeMetadata metadata about a particular node | ||
type NodeMetadata struct { | ||
OS string | ||
Architecture string | ||
} | ||
|
||
type NodeArchitectureMap interface { | ||
GetNodeArchitecture(node string) (*NodeMetadata, error) | ||
AddNode(node *corev1.Node) error | ||
DeleteNode(node string) error | ||
Length() int | ||
} | ||
|
||
type defaultNodeMap struct { | ||
mu sync.RWMutex | ||
nodes map[string]*NodeMetadata | ||
} | ||
|
||
func New() *defaultNodeMap { | ||
// might need to pass an initial map | ||
return &defaultNodeMap{ | ||
nodes: make(map[string]*NodeMetadata), | ||
} | ||
} | ||
|
||
func (m *defaultNodeMap) GetNodeArchitecture(node string) (*NodeMetadata, error) { | ||
m.mu.Lock() | ||
defer m.mu.Unlock() | ||
|
||
if _, ok := m.nodes[node]; !ok { | ||
// no data about the node was found, return error | ||
return nil, fmt.Errorf("error fetching node's architecture data") | ||
} | ||
return m.nodes[node], nil | ||
} | ||
|
||
func (m *defaultNodeMap) AddNode(node *corev1.Node) error { | ||
m.mu.Lock() | ||
defer m.mu.Unlock() | ||
if node == nil { | ||
return fmt.Errorf("add node %s", invalidFuncInput) | ||
} | ||
|
||
arch, ok := node.Labels["kubernetes.io/arch"] | ||
if !ok { | ||
return fmt.Errorf("\"kubernetes.io/arch\" label not found on node: %s", node.Name) | ||
} | ||
|
||
os, ok := node.Labels["kubernetes.io/os"] | ||
if !ok { | ||
return fmt.Errorf("\"kubernetes.io/os\" label not found on node: %s", node.Name) | ||
} | ||
|
||
// change name to uid or selflink | ||
m.nodes[node.Name] = &NodeMetadata{ | ||
OS: os, | ||
Architecture: arch, | ||
} | ||
return nil | ||
} | ||
|
||
func (m *defaultNodeMap) DeleteNode(node string) error { | ||
m.mu.Lock() | ||
defer m.mu.Unlock() | ||
if node == "" { | ||
return fmt.Errorf("delete node %s", invalidFuncInput) | ||
} | ||
// change name to uid or selflink | ||
delete(m.nodes, node) | ||
return nil | ||
} | ||
|
||
func (m *defaultNodeMap) Length() int { | ||
m.mu.Lock() | ||
defer m.mu.Unlock() | ||
return len(m.nodes) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
package architecture | ||
|
||
import ( | ||
"fmt" | ||
"sync" | ||
"testing" | ||
|
||
"github.com/google/uuid" | ||
corev1 "k8s.io/api/core/v1" | ||
) | ||
|
||
func TestAdd(t *testing.T) { | ||
var wg sync.WaitGroup // using wait group to know if task was completed | ||
var commonMap = New() | ||
var expectedNumberOfNodes = 100 | ||
|
||
// Adding random nodes to the concurrent map | ||
for i := 0; i < expectedNumberOfNodes; i++ { | ||
wg.Add(1) | ||
go func() { | ||
defer wg.Done() | ||
node, err := generateNode("node", "amd64", "linux") | ||
if err != nil { | ||
t.Errorf("unxepected error when generating the node info: %s", err) | ||
} | ||
err = commonMap.AddNode(node) | ||
if err != nil { | ||
t.Errorf("unxepected error when appending the node info: %s", err) | ||
} | ||
}() | ||
} | ||
wg.Wait() | ||
|
||
// checking if all operations occurred without any issues on the locks | ||
if commonMap.Length() != expectedNumberOfNodes { | ||
t.Errorf("unxepected number of node information was found: exp=%d act=%d", expectedNumberOfNodes, commonMap.Length()) | ||
} | ||
|
||
} | ||
|
||
func TestRead(t *testing.T) { | ||
var wg sync.WaitGroup // using wait group to know if task was completed | ||
var commonMap = New() | ||
var expectedNumberOfNodes = 1000 | ||
var nodes []*corev1.Node | ||
|
||
for i := 0; i < expectedNumberOfNodes; i++ { | ||
node, err := generateNode("node", "amd64", "linux") | ||
if err != nil { | ||
t.Errorf("unxepected error when generating the node info: %s", err) | ||
} | ||
err = commonMap.AddNode(node) | ||
if err != nil { | ||
t.Errorf("unxepected error when appending the node info: %s", err) | ||
} | ||
nodes = append(nodes, node) | ||
} | ||
|
||
for _, node := range nodes { | ||
wg.Add(1) | ||
go func() { | ||
arch, err := commonMap.GetNodeArchitecture(node.Name) | ||
if err != nil { | ||
t.Errorf("unxepected error when reading node information: %s", err) | ||
} | ||
if expectedArch, ok := node.Labels["kubernetes.io/arch"]; ok { | ||
if arch.Architecture != expectedArch { | ||
t.Errorf("unxepected node architecture was found: exp=%q act=%q", expectedArch, arch.Architecture) | ||
} | ||
} | ||
if expectedOS, ok := node.Labels["kubernetes.io/os"]; ok { | ||
if arch.OS != expectedOS { | ||
t.Errorf("unxepected node architecture was found: exp=%q act=%q", expectedOS, arch.OS) | ||
} | ||
} | ||
wg.Done() | ||
}() | ||
} | ||
wg.Wait() | ||
|
||
if commonMap.Length() != expectedNumberOfNodes { | ||
t.Errorf("unxepected number of node information was found: exp=%d act=%d", expectedNumberOfNodes, commonMap.Length()) | ||
} | ||
|
||
} | ||
|
||
func TestDelete(t *testing.T) { | ||
var wg sync.WaitGroup // using wait group to know if task was completed | ||
var commonMap = New() | ||
var expectedNumberOfNodes = 1000 | ||
var nodes []*corev1.Node | ||
|
||
for i := 0; i < expectedNumberOfNodes; i++ { | ||
node, err := generateNode("node", "amd64", "linux") | ||
if err != nil { | ||
t.Errorf("unxepected error when generating the node info: %s", err) | ||
} | ||
err = commonMap.AddNode(node) | ||
if err != nil { | ||
t.Errorf("unxepected error when appending the node info: %s", err) | ||
} | ||
nodes = append(nodes, node) | ||
} | ||
|
||
for _, node := range nodes { | ||
wg.Add(1) | ||
go func() { | ||
defer wg.Done() | ||
err := commonMap.DeleteNode(node.Name) | ||
if err != nil { | ||
t.Errorf("unxepected error when deleting the node info: %s", err) | ||
} | ||
}() | ||
wg.Wait() | ||
} | ||
|
||
// checking if all operations occurred without any issues on the locks | ||
if commonMap.Length() != 0 { | ||
t.Errorf("unxepected number of node information was found: exp=%d act=%d", 0, commonMap.Length()) | ||
} | ||
|
||
} | ||
|
||
func generateNode(name, arch, os string) (*corev1.Node, error) { | ||
suffix, err := uuid.NewRandom() | ||
node := &corev1.Node{} | ||
node.Name = fmt.Sprintf("%s%d", name, suffix.ID()) | ||
node.Labels = map[string]string{ | ||
"kubernetes.io/arch": arch, | ||
"kubernetes.io/os": os, | ||
} | ||
return node, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.