-
Notifications
You must be signed in to change notification settings - Fork 4
/
node.go
166 lines (139 loc) 路 4.06 KB
/
node.go
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
package ipfs
import (
"encoding/json"
"fmt"
"strconv"
"github.com/docker/docker/api/types"
)
const (
keyNetworkID = "network_id"
keyJobID = "job_id"
keyBootstrapPeers = "bootstrap_peers"
keyDataDir = "data_dir"
keyPortSwarm = "ports.swarm"
keyPortAPI = "ports.api"
keyPortGateway = "ports.gateway"
keyResourcesDisk = "resources.disk"
keyResourcesMemory = "resources.memory"
keyResourcesCPUs = "resources.cpus"
)
// NodeInfo defines metadata about an IPFS node
type NodeInfo struct {
NetworkID string `json:"network_id"`
JobID string `json:"job_id"`
Ports NodePorts `json:"ports"`
Resources NodeResources `json:"resources"`
// Metadata set by node client:
// DockerID is the ID of the node's Docker container
DockerID string `json:"docker_id"`
// ContainerName is the name of the node's Docker container
ContainerName string `json:"container_id"`
// DataDir is the path to the directory holding all data relevant to this
// IPFS node
DataDir string `json:"data_dir"`
// BootstrapPeers lists the peers this node was bootstrapped onto upon init
BootstrapPeers []string `json:"bootstrap_peers"`
}
// NodePorts declares the exposed ports of an IPFS node
type NodePorts struct {
Swarm string `json:"swarm"` // default: 4001
API string `json:"api"` // default: 5001
Gateway string `json:"gateway"` // default: 8080
}
// NodeResources declares resource quotas for this node
type NodeResources struct {
DiskGB int `json:"disk"`
MemoryGB int `json:"memory"`
CPUs int `json:"cpus"`
}
func newNode(id, name string, attributes map[string]string) (NodeInfo, error) {
// check if container is a node
if !isNodeContainer(name) {
return NodeInfo{DockerID: id, ContainerName: name}, fmt.Errorf("unknown name format %s", name)
}
// parse bootstrap state
var peers []string
json.Unmarshal([]byte(attributes[keyBootstrapPeers]), &peers)
// parse resource data
var (
disk, _ = strconv.Atoi(attributes[keyResourcesDisk])
mem, _ = strconv.Atoi(attributes[keyResourcesMemory])
cpus, _ = strconv.Atoi(attributes[keyResourcesCPUs])
)
// create node metadata to return
return NodeInfo{
NetworkID: attributes[keyNetworkID],
JobID: attributes[keyJobID],
Ports: NodePorts{
Swarm: attributes[keyPortSwarm],
API: attributes[keyPortAPI],
Gateway: attributes[keyPortGateway],
},
Resources: NodeResources{
DiskGB: disk,
MemoryGB: mem,
CPUs: cpus,
},
DockerID: id,
ContainerName: name,
DataDir: attributes[keyDataDir],
BootstrapPeers: peers,
}, nil
}
func (n *NodeInfo) withDefaults() {
if n.Resources.CPUs == 0 {
n.Resources.CPUs = 4
}
if n.Resources.DiskGB == 0 {
n.Resources.DiskGB = 100
}
if n.Resources.MemoryGB == 0 {
n.Resources.MemoryGB = 4
}
// set container name from network name
if n.ContainerName == "" {
n.ContainerName = toNodeContainerName(n.NetworkID)
}
// set name for node operations - container name can be used interchangably
// with container name
if n.DockerID == "" {
n.DockerID = n.ContainerName
}
}
func (n *NodeInfo) labels(peers []string, dataDir string) map[string]string {
var peerBytes, _ = json.Marshal(peers)
return map[string]string{
keyNetworkID: n.NetworkID,
keyJobID: n.JobID,
keyPortSwarm: n.Ports.Swarm,
keyPortAPI: n.Ports.API,
keyPortGateway: n.Ports.Gateway,
keyBootstrapPeers: string(peerBytes),
keyDataDir: dataDir,
keyResourcesCPUs: strconv.Itoa(n.Resources.CPUs),
keyResourcesDisk: strconv.Itoa(n.Resources.DiskGB),
keyResourcesMemory: strconv.Itoa(n.Resources.MemoryGB),
}
}
func (n *NodeInfo) updateFromContainerDetails(c *types.Container) {
if c == nil {
return
}
// check container ID
n.DockerID = c.ID
// check ports
if len(c.Ports) > 0 {
for _, p := range c.Ports {
var public = strconv.Itoa(int(p.PublicPort))
var private = strconv.Itoa(int(p.PrivatePort))
switch private {
case containerSwarmPort:
n.Ports.Swarm = public
case containerAPIPort:
n.Ports.API = public
case containerGatewayPort:
n.Ports.Gateway = public
}
}
}
}