Skip to content

Commit da83050

Browse files
committed
[WIP] Add support for dedicated chaincode nodes
See #228 Signed-off-by: James Taylor <[email protected]>
1 parent fd880c0 commit da83050

File tree

7 files changed

+55
-2
lines changed

7 files changed

+55
-2
lines changed

cmd/run/main.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import (
99
"github.com/hyperledger-labs/fabric-builder-k8s/internal/builder"
1010
"github.com/hyperledger-labs/fabric-builder-k8s/internal/log"
1111
"github.com/hyperledger-labs/fabric-builder-k8s/internal/util"
12-
"k8s.io/apimachinery/pkg/api/validation"
12+
apivalidation "k8s.io/apimachinery/pkg/api/validation"
13+
"k8s.io/apimachinery/pkg/util/validation"
1314
)
1415

1516
const (
@@ -56,6 +57,15 @@ func main() {
5657
}
5758
}
5859

60+
kubeNodeRole := util.GetOptionalEnv(util.ChaincodeNodeRoleVariable, "")
61+
logger.Debugf("%s=%s", util.ChaincodeNodeRoleVariable, kubeNodeRole)
62+
63+
// TODO: are valid taint values the same?!
64+
if msgs := validation.IsValidLabelValue(kubeNodeRole); len(msgs) > 0 {
65+
logger.Printf("The FABRIC_K8S_BUILDER_NODE_ROLE environment variable must be a valid Kubernetes label value: %s", msgs[0])
66+
os.Exit(1)
67+
}
68+
5969
kubeServiceAccount := util.GetOptionalEnv(util.ChaincodeServiceAccountVariable, util.DefaultServiceAccountName)
6070
logger.Debugf("%s=%s", util.ChaincodeServiceAccountVariable, kubeServiceAccount)
6171

@@ -67,7 +77,7 @@ func main() {
6777
os.Exit(1)
6878
}
6979

70-
if msgs := validation.NameIsDNS1035Label(kubeNamePrefix, true); len(msgs) > 0 {
80+
if msgs := apivalidation.NameIsDNS1035Label(kubeNamePrefix, true); len(msgs) > 0 {
7181
logger.Printf("The FABRIC_K8S_BUILDER_OBJECT_NAME_PREFIX environment variable must be a valid DNS-1035 label: %s", msgs[0])
7282
os.Exit(1)
7383
}
@@ -78,6 +88,7 @@ func main() {
7888
PeerID: peerID,
7989
KubeconfigPath: kubeconfigPath,
8090
KubeNamespace: kubeNamespace,
91+
KubeNodeRole: kubeNodeRole,
8192
KubeServiceAccount: kubeServiceAccount,
8293
KubeNamePrefix: kubeNamePrefix,
8394
}

cmd/run/main_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,28 @@ var _ = Describe("Main", func() {
4545
),
4646
)
4747

48+
DescribeTable("Running the run command produces the correct error for invalid FABRIC_K8S_BUILDER_NODE_ROLE environment variable values",
49+
func(kubeNodeRoleValue, expectedErrorMessage string) {
50+
args := []string{"BUILD_OUTPUT_DIR", "RUN_METADATA_DIR"}
51+
command := exec.Command(runCmdPath, args...)
52+
command.Env = append(os.Environ(),
53+
"CORE_PEER_ID=core-peer-id-abcdefghijklmnopqrstuvwxyz-0123456789",
54+
"FABRIC_K8S_BUILDER_NODE_ROLE="+kubeNodeRoleValue,
55+
)
56+
session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
57+
Expect(err).NotTo(HaveOccurred())
58+
59+
Eventually(session).Should(gexec.Exit(1))
60+
Eventually(
61+
session.Err,
62+
).Should(gbytes.Say(expectedErrorMessage))
63+
},
64+
Entry("When the FABRIC_K8S_BUILDER_NODE_ROLE is too long", "long-node-role-is-looooooooooooooooooooooooooooooooooooooooooong", `run \[\d+\]: The FABRIC_K8S_BUILDER_NODE_ROLE environment variable must be a valid Kubernetes label value: must be no more than 63 characters`),
65+
Entry("When the FABRIC_K8S_BUILDER_NODE_ROLE contains invalid characters", "invalid*value", `run \[\d+\]: The FABRIC_K8S_BUILDER_NODE_ROLE environment variable must be a valid Kubernetes label value: a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '\.', and must start and end with an alphanumeric character`),
66+
Entry("When the FABRIC_K8S_BUILDER_NODE_ROLE does not start with an alphanumeric character", ".role", `run \[\d+\]: The FABRIC_K8S_BUILDER_NODE_ROLE environment variable must be a valid Kubernetes label value: a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '\.', and must start and end with an alphanumeric character`),
67+
Entry("When the FABRIC_K8S_BUILDER_NODE_ROLE does not end with an alphanumeric character", "role-", `run \[\d+\]: The FABRIC_K8S_BUILDER_NODE_ROLE environment variable must be a valid Kubernetes label value: a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '\.', and must start and end with an alphanumeric character`),
68+
)
69+
4870
DescribeTable("Running the run command produces the correct error for invalid FABRIC_K8S_BUILDER_OBJECT_NAME_PREFIX environment variable values",
4971
func(kubeNamePrefixValue, expectedErrorMessage string) {
5072
args := []string{"BUILD_OUTPUT_DIR", "RUN_METADATA_DIR"}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Dedicated nodes
2+
3+
TBC
4+
5+
The `FABRIC_K8S_BUILDER_NODE_ROLE` environment variable can be used to...
6+
7+
For example, if `FABRIC_K8S_BUILDER_NODE_ROLE` is set to `chaincode`, ... using the following command.
8+
9+
```shell
10+
kubectl label nodes node1 fabric-builder-k8s-role=chaincode
11+
kubectl taint nodes node1 fabric-builder-k8s-role=chaincode:NoSchedule
12+
```
13+
14+
More complex requirements should be handled with Dynamic Admission Control using a Mutating Webhook.
15+
For example, it looks like the namespace-node-affinity webhook could be used to assign node affinity and tolerations to all pods in the FABRIC_K8S_BUILDER_NAMESPACE namespace.

docs/configuring/overview.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ External builders are configured in the `core.yaml` file, for example:
1414
- CORE_PEER_ID
1515
- FABRIC_K8S_BUILDER_DEBUG
1616
- FABRIC_K8S_BUILDER_NAMESPACE
17+
- FABRIC_K8S_BUILDER_NODE_ROLE
1718
- FABRIC_K8S_BUILDER_OBJECT_NAME_PREFIX
1819
- FABRIC_K8S_BUILDER_SERVICE_ACCOUNT
1920
- KUBERNETES_SERVICE_HOST
@@ -30,6 +31,7 @@ The k8s builder is configured using the following environment variables.
3031
| ------------------------------------- | -------------------------------- | ---------------------------------------------------- |
3132
| CORE_PEER_ID | | The Fabric peer ID (required) |
3233
| FABRIC_K8S_BUILDER_NAMESPACE | The peer namespace or `default` | The Kubernetes namespace to run chaincode with |
34+
| FABRIC_K8S_BUILDER_NODE_ROLE | | TBC |
3335
| FABRIC_K8S_BUILDER_OBJECT_NAME_PREFIX | `hlfcc` | Eye-catcher prefix for Kubernetes object names |
3436
| FABRIC_K8S_BUILDER_SERVICE_ACCOUNT | `default` | The Kubernetes service account to run chaincode with |
3537
| FABRIC_K8S_BUILDER_DEBUG | `false` | Set to `true` to enable k8s builder debug messages |

internal/builder/run.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ type Run struct {
1616
PeerID string
1717
KubeconfigPath string
1818
KubeNamespace string
19+
KubeNodeRole string
1920
KubeServiceAccount string
2021
KubeNamePrefix string
2122
}

internal/util/env.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
const (
1111
builderVariablePrefix = "FABRIC_K8S_BUILDER_"
1212
ChaincodeNamespaceVariable = builderVariablePrefix + "NAMESPACE"
13+
ChaincodeNodeRoleVariable = builderVariablePrefix + "NODE_ROLE"
1314
ObjectNamePrefixVariable = builderVariablePrefix + "OBJECT_NAME_PREFIX"
1415
ChaincodeServiceAccountVariable = builderVariablePrefix + "SERVICE_ACCOUNT"
1516
DebugVariable = builderVariablePrefix + "DEBUG"

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ nav:
106106
- Kubernetes permissions: configuring/kubernetes-permissions.md
107107
- Kubernetes namespace: configuring/kubernetes-namespace.md
108108
- Kubernetes service account: configuring/kubernetes-service-account.md
109+
- Dedicated nodes: configuring/dedicated-nodes.md
109110
- Tutorials:
110111
- Developing and debuging chaincode: tutorials/develop-chaincode.md
111112
- Creating a chaincode package: tutorials/package-chaincode.md

0 commit comments

Comments
 (0)