File: dirty.go

package info (click to toggle)
docker.io 26.1.5%2Bdfsg1-9
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 68,576 kB
  • sloc: sh: 5,748; makefile: 912; ansic: 664; asm: 228; python: 162
file content (58 lines) | stat: -rw-r--r-- 1,815 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package manager

import (
	"fmt"
	"reflect"

	"github.com/moby/swarmkit/v2/api"
	"github.com/moby/swarmkit/v2/manager/state/store"
)

// IsStateDirty returns true if any objects have been added to raft which make
// the state "dirty". Currently, the existence of any object other than the
// default cluster or the local node implies a dirty state.
func (m *Manager) IsStateDirty() (bool, error) {
	var (
		storeSnapshot *api.StoreSnapshot
		err           error
	)
	m.raftNode.MemoryStore().View(func(readTx store.ReadTx) {
		storeSnapshot, err = m.raftNode.MemoryStore().Save(readTx)
	})

	if err != nil {
		return false, err
	}

	// Check Nodes and Clusters fields.
	nodeID := m.config.SecurityConfig.ClientTLSCreds.NodeID()
	if len(storeSnapshot.Nodes) > 1 || (len(storeSnapshot.Nodes) == 1 && storeSnapshot.Nodes[0].ID != nodeID) {
		return true, nil
	}

	clusterID := m.config.SecurityConfig.ClientTLSCreds.Organization()
	if len(storeSnapshot.Clusters) > 1 || (len(storeSnapshot.Clusters) == 1 && storeSnapshot.Clusters[0].ID != clusterID) {
		return true, nil
	}

	// Use reflection to check that other fields don't have values. This
	// lets us implement a whitelist-type approach, where we don't need to
	// remember to add individual types here.

	val := reflect.ValueOf(*storeSnapshot)
	numFields := val.NumField()

	for i := 0; i != numFields; i++ {
		field := val.Field(i)
		structField := val.Type().Field(i)
		if structField.Type.Kind() != reflect.Slice {
			panic(fmt.Sprintf("unexpected field type in StoreSnapshot: %s (type %v)", structField.Name, structField.Type.Kind()))
		}
		if structField.Name != "Nodes" && structField.Name != "Clusters" && structField.Name != "Networks" && field.Len() != 0 {
			// One of the other data types has an entry
			return true, nil
		}
	}

	return false, nil
}