weaveworks / cluster-api-provider-existinginfra Goto Github PK
View Code? Open in Web Editor NEWManage existing infrastructure with Cluster API using this provider.
License: Apache License 2.0
Manage existing infrastructure with Cluster API using this provider.
License: Apache License 2.0
It tries to kubeadm join
itself, but at this point kubelet
is not running and so it fails. With an LB kubeadm join
is routed to another control plane node and succeeds.
#44 introduces an error message explaining this.
It might be nice to support this case w/out an LB. Need to add some more logic around the kubeadm join
?
Which pushes, using Github Actions, the docker image for every commit (maybe even PR?).
Possibly we'd also have a ":main" moving tag (which always need to be re-pulled from wksctl's perspective, or just tag the images with output from git describe
or the Git SHA.
For this we need to add the push credentials for the bot to this repo's secrets.
cc @bboreham
The controller is looking for -assets configmap and assets
key. If the configmap is missing the code generates a NPE and the container restarts.
Since this is used to override image locations, we shouldn't fail if the configmap is missing.
The capi controller currently logs these errors:
E0907 10:42:04.090249 1 controller.go:248] controller-runtime/controller "msg"="Reconciler error" "error"="error fetching REST client config for remote cluster: failed to retrieve kubeconfig secret for Cluster weavek8sops/test-multimaster: Secret \"test-multimaster-kubeconfig\" not found" "controller"="machine" "name"="master-3" "namespace"="weavek8sops"
As noted here, we should create a secret containing kubeconfig to connect to the new cluster.
This could be done by the bootstrap controller proposed at #11
The default behaviour of drain.Helper is to delete immediately; we need a line like this:
https://github.com/kubernetes/kubernetes/blob/540e41c825f7/staging/src/k8s.io/kubectl/pkg/cmd/drain/drain.go#L148
Same issue as kubereboot/kured#236
Amazon has release a new k8s distribution and CAPEI needs to be able to install those clusters. This likely involves
As of #3, they are:
pkg/plan/plan.go:899: Function 'processResource' is too long (67 > 60) (funlen)
func (p *Plan) processResource(
pkg/plan/state.go:42: Function 'toPlan' is too long (67 > 60) (funlen)
func (s State) toPlan() Plan {
pkg/plan/runners/ssh/ssh.go:80: Function 'handleSessionIO' is too long (62 > 60) (funlen)
func (c *Client) handleSessionIO(action func(*ssh.Session) error) (string, error) {
pkg/plan/recipe/install_plans.go:66: Function 'BuildCRIPlan' is too long (87 > 60) (funlen)
func BuildCRIPlan(criSpec *existinginfrav1.ContainerRuntime, cfg *envcfg.EnvSpecificConfig, pkgType resource.PkgType) plan.Resource {
pkg/plan/recipe/install_plans.go:157: Function 'BuildK8SPlan' has too many statements (61 > 40) (funlen)
func BuildK8SPlan(kubernetesVersion string, kubeletNodeIP string, seLinuxInstalled, setSELinuxPermissive, disableSwap, lockYUMPkgs bool, pkgType resource.PkgType, cloudProvider string, extraArgs map[string]string) plan.Resource {
pkg/plan/recipe/upgrade_plans.go:21: Function 'BuildUpgradePlan' is too long (90 > 60) (funlen)
func BuildUpgradePlan(pkgType resource.PkgType, k8sVersion string, ntype NodeType) (plan.Resource, error) {
pkg/utilities/manifest/manifest.go:17: Function 'WithNamespace' is too long (65 > 60) (funlen)
func WithNamespace(rc io.ReadCloser, namespace string) ([]byte, error) {
controllers/cluster.weave.works/existinginframachine_controller.go:85: Function 'Reconcile' has too many statements (47 > 40) (funlen)
func (r *ExistingInfraMachineReconciler) Reconcile(req ctrl.Request) (_ ctrl.Result, reterr error) {
controllers/cluster.weave.works/existinginframachine_controller.go:379: Function 'update' has too many statements (78 > 40) (funlen)
func (a *ExistingInfraMachineReconciler) update(ctx context.Context, c *existinginfrav1.ExistingInfraCluster, machine *clusterv1.Machine, eim *existinginfrav1.ExistingInfraMachine) error {
pkg/plan/plan.go:58:2: `dummyPlan` is a global variable (gochecknoglobals)
dummyPlan Resource = RegisterResource(&Plan{})
^
pkg/plan/plan.go:59:2: `planTypeName` is a global variable (gochecknoglobals)
planTypeName = extractResourceTypeName(dummyPlan)
^
pkg/plan/plan.go:128:5: `toValidityString` is a global variable (gochecknoglobals)
var toValidityString = map[Validity]string{
^
pkg/plan/plan.go:134:5: `toValidityID` is a global variable (gochecknoglobals)
var toValidityID = map[string]Validity{
^
pkg/plan/plan.go:165:5: `toReasonString` is a global variable (gochecknoglobals)
var toReasonString = map[InvalidityReason]string{
^
pkg/plan/plan.go:175:5: `toReasonID` is a global variable (gochecknoglobals)
var toReasonID = map[string]InvalidityReason{
^
pkg/plan/plan.go:408:5: `resourcePackageName` is a global variable (gochecknoglobals)
var resourcePackageName = filepath.Join(reflect.ValueOf(EmptyState).Type().PkgPath(), "resource")
^
pkg/plan/plan.go:412:5: `resourceTypes` is a global variable (gochecknoglobals)
var resourceTypes = make(map[string]resourceType)
^
pkg/plan/state.go:19:5: `EmptyState` is a global variable (gochecknoglobals)
var EmptyState = State(nil)
^
pkg/plan/resource/dir.go:22:5: `protectedDirs` is a global variable (gochecknoglobals)
var protectedDirs = make(map[string]struct{})
^
pkg/plan/resource/os.go:104:2: `machineIDParams` is a global variable (gochecknoglobals)
machineIDParams = newFactGatheringParams("MachineID", "/etc/machine-id", "/var/lib/dbus/machine-id")
^
pkg/plan/resource/os.go:105:2: `sysUuidParams` is a global variable (gochecknoglobals)
sysUuidParams = newFactGatheringParams("SystemUUID", "/sys/class/dmi/id/product_uuid", "/etc/machine-id")
^
pkg/plan/resource/os.go:114:5: `gatherFuncs` is a global variable (gochecknoglobals)
var gatherFuncs []GatherFactFunc = []GatherFactFunc{
^
pkg/plan/resource/rpm.go:149:5: `undoAction` is a global variable (gochecknoglobals)
var undoAction = func(p *RPM, r plan.Runner, current plan.State, pkgDescription string) error {
^
apis/cluster.weave.works/v1alpha3/groupversion_info.go:29:2: `GroupVersion` is a global variable (gochecknoglobals)
GroupVersion = schema.GroupVersion{Group: "cluster.weave.works", Version: "v1alpha3"}
^
apis/cluster.weave.works/v1alpha3/groupversion_info.go:32:2: `SchemeBuilder` is a global variable (gochecknoglobals)
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
^
apis/cluster.weave.works/v1alpha3/groupversion_info.go:35:2: `AddToScheme` is a global variable (gochecknoglobals)
AddToScheme = SchemeBuilder.AddToScheme
^
apis/baremetalproviderspec/v1alpha1/conversion.go:26:5: `downgradingConversionError` is a global variable (gochecknoglobals)
var downgradingConversionError = errors.New("invalid conversion, downgrading conversions are not supported")
^
apis/baremetalproviderspec/v1alpha1/groupversion_info.go:30:2: `GroupVersion` is a global variable (gochecknoglobals)
GroupVersion = schema.GroupVersion{Group: "baremetalproviderspec", Version: "v1alpha1"}
^
apis/baremetalproviderspec/v1alpha1/groupversion_info.go:33:2: `SchemeBuilder` is a global variable (gochecknoglobals)
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
^
apis/baremetalproviderspec/v1alpha1/groupversion_info.go:36:2: `AddToScheme` is a global variable (gochecknoglobals)
AddToScheme = SchemeBuilder.AddToScheme
^
apis/baremetalproviderspec/v1alpha1/groupversion_info.go:39:2: `localSchemeBuilder` is a global variable (gochecknoglobals)
localSchemeBuilder = &SchemeBuilder.SchemeBuilder
^
pkg/apis/wksprovider/machine/os/os.go:214:5: `osIDRegexp` is a global variable (gochecknoglobals)
var osIDRegexp = regexp.MustCompile("(?m)^ID=(.+)")
^
pkg/kubernetes/drain/facade.go:17:5: `DefaultTimeOut` is a global variable (gochecknoglobals)
var DefaultTimeOut = 1 * time.Minute
^
main.go:36:2: `scheme` is a global variable (gochecknoglobals)
scheme = runtime.NewScheme()
^
main.go:37:2: `setupLog` is a global variable (gochecknoglobals)
setupLog = ctrl.Log.WithName("setup")
^
pkg/plan/resource/dir.go:24:1: don't use `init` function (gochecknoinits)
func init() {
^
apis/cluster.weave.works/v1alpha3/existinginfracluster_types.go:127:1: don't use `init` function (gochecknoinits)
func init() {
^
apis/cluster.weave.works/v1alpha3/existinginframachine_types.go:67:1: don't use `init` function (gochecknoinits)
func init() {
^
pkg/plan/resource/service.go:91:62: string `inactive` has 3 occurrences, but such constant `ServiceInactive` already exists (goconst)
if p.Status == ServiceActive && current.String("status") == "inactive" {
^
pkg/plan/resource/rpm.go:133:2: ifElseChain: rewrite if-else to switch statement (gocritic)
if diff.CurrentState.IsEmpty() {
^
pkg/plan/recipe/install_plans.go:70:2: singleCaseSwitch: should rewrite switch statement to if statement (gocritic)
switch pkgType {
^
controllers/cluster.weave.works/existinginframachine_controller.go:258:88: captLocal: `ID' should not be capitalized (gocritic)
func (a *ExistingInfraMachineReconciler) updateKubeadmJoinSecrets(ctx context.Context, ID string, secret *corev1.Secret) error {
^
controllers/cluster.weave.works/existinginframachine_controller.go:270:69: captLocal: `ID' should not be capitalized (gocritic)
func (a *ExistingInfraMachineReconciler) token(ctx context.Context, ID string) (string, error) {
^
controllers/cluster.weave.works/existinginframachine_controller.go:283:9: elseif: can replace 'else {if cond {}}' with 'else if cond {}' (gocritic)
} else {
^
controllers/cluster.weave.works/existinginframachine_controller.go:472:4: ifElseChain: rewrite if-else to switch statement (gocritic)
if isController {
^
test/plan/testutils/runner_mock.go:5:38: Top level comment should end in a period (godot)
// MockRunner needed for testing plans
^
test/plan/testutils/runner_mock.go:21:65: Top level comment should end in a period (godot)
//SetRunCommand allows you to configure the output for RunCommand
^
test/plan/testutils/runner_mock.go:26:63: Top level comment should end in a period (godot)
//ClearRunCommand undoes any output configured by SetRunCommand
^
pkg/plan/plan.go:490:9: `if` block ends with a `return` statement, so drop this `else` and outdent its block (golint)
} else {
^
pkg/plan/plan.go:960:10: `if` block ends with a `return` statement, so drop this `else` and outdent its block (golint)
} else {
^
pkg/plan/resource/run.go:45:10: `if` block ends with a `return` statement, so drop this `else` and outdent its block (golint)
} else {
^
pkg/utilities/envcfg/environment_config.go:23:2: don't use underscores in Go names; const FC_bridge_nf_call_iptables should be FCBridgeNfCallIptables (golint)
FC_bridge_nf_call_iptables = `FileContent--proc-sys-net-bridge-bridge-nf-call-iptables`
^
apis/baremetalproviderspec/v1alpha1/conversion.go:28:6: don't use underscores in Go names; func Convert_v1alpha1_APIServer_To_v1alpha3_APIServer should be ConvertV1alpha1APIServerToV1alpha3APIServer (golint)
func Convert_v1alpha1_APIServer_To_v1alpha3_APIServer(_ *APIServer, _ *v1alpha3.APIServer, _ conversion.Scope) error {
^
apis/baremetalproviderspec/v1alpha1/conversion.go:33:6: don't use underscores in Go names; func Convert_v1alpha1_ClusterSpec_To_v1alpha3_ClusterSpec should be ConvertV1alpha1ClusterSpecToV1alpha3ClusterSpec (golint)
func Convert_v1alpha1_ClusterSpec_To_v1alpha3_ClusterSpec(in *ClusterSpec, out *v1alpha3.ClusterSpec, s conversion.Scope) error {
^
apis/baremetalproviderspec/v1alpha1/conversion.go:38:6: don't use underscores in Go names; func Convert_v1alpha3_ClusterSpec_To_v1alpha1_ClusterSpec should be ConvertV1alpha3ClusterSpecToV1alpha1ClusterSpec (golint)
func Convert_v1alpha3_ClusterSpec_To_v1alpha1_ClusterSpec(_ *v1alpha3.ClusterSpec, _ *ClusterSpec, _ conversion.Scope) error {
^
apis/baremetalproviderspec/v1alpha1/conversion.go:43:6: don't use underscores in Go names; func Convert_v1alpha1_MachineSpec_To_v1alpha3_MachineSpec should be ConvertV1alpha1MachineSpecToV1alpha3MachineSpec (golint)
func Convert_v1alpha1_MachineSpec_To_v1alpha3_MachineSpec(in *MachineSpec, out *v1alpha3.MachineSpec, s conversion.Scope) error {
^
apis/baremetalproviderspec/v1alpha1/conversion.go:52:6: don't use underscores in Go names; func Convert_v1alpha3_MachineSpec_To_v1alpha1_MachineSpec should be ConvertV1alpha3MachineSpecToV1alpha1MachineSpec (golint)
func Convert_v1alpha3_MachineSpec_To_v1alpha1_MachineSpec(_ *v1alpha3.MachineSpec, _ *MachineSpec, _ conversion.Scope) error {
^
controllers/cluster.weave.works/existinginframachine_controller.go:168:1: receiver name a should be consistent with previous receiver name r for ExistingInfraMachineReconciler (golint)
func (a *ExistingInfraMachineReconciler) create(ctx context.Context, installer *os.OS, c *existinginfrav1.ExistingInfraCluster, machine *clusterv1.Machine, eim *existinginfrav1.ExistingInfraMachine) error {
^
controllers/cluster.weave.works/existinginframachine_controller.go:200:1: receiver name a should be consistent with previous receiver name r for ExistingInfraMachineReconciler (golint)
func (a *ExistingInfraMachineReconciler) connectTo(ctx context.Context, c *existinginfrav1.ExistingInfraCluster, m *existinginfrav1.ExistingInfraMachine) (*os.OS, io.Closer, error) {
^
controllers/cluster.weave.works/existinginframachine_controller.go:222:1: receiver name a should be consistent with previous receiver name r for ExistingInfraMachineReconciler (golint)
func (a *ExistingInfraMachineReconciler) sshKey(ctx context.Context) ([]byte, error) {
^
pkg/utilities/ssh/ssh.go:47:10: G106: Use of ssh InsecureIgnoreHostKey should be audited (gosec)
return ssh.InsecureIgnoreHostKey()
^
pkg/plan/resource/apt.go:96:26: G404: Use of weak random number generator (math/rand instead of crypto/rand) (gosec)
sleep := time.Duration(rand.Intn(10000)) * time.Millisecond
^
pkg/plan/resource/file.go:4:2: G501: Blocklisted import crypto/md5: weak cryptographic primitive (gosec)
"crypto/md5"
^
pkg/plan/resource/file.go:63:7: G401: Use of weak cryptographic primitive (gosec)
h := md5.New()
^
pkg/plan/resource/file.go:72:7: G401: Use of weak cryptographic primitive (gosec)
h := md5.New()
^
controllers/cluster.weave.works/existinginframachine_controller.go:66:2: G101: Potential hardcoded credentials (gosec)
controllerSecret string = "wks-controller-secrets"
^
controllers/cluster.weave.works/existinginframachine_controller.go:922:15: G601: Implicit memory aliasing in for loop. (gosec)
if isMaster(&node) {
^
pkg/plan/runners/ssh/ssh.go:17:19: struct of size 88 bytes could be of size 80 bytes (maligned)
type ClientParams struct {
^
pkg/utilities/version/version.go:32:40: parseVersion - result 2 (int) is never used (unparam)
func parseVersion(s string) (int, int, int, error) {
^
pkg/plan/graph.go:15:15: `newGraph` - `cap` is unused (unparam)
func newGraph(cap int) *graph {
^
controllers/cluster.weave.works/existinginframachine_controller.go:554:2: `(*ExistingInfraMachineReconciler).performActualUpdate` - `cluster` is unused (unparam)
cluster *existinginfrav1.ExistingInfraCluster) error {
^
pkg/plan/resource/rpm.go:74: unnecessary trailing newline (whitespace)
}
pkg/utilities/manifest/manifest.go:64: unnecessary trailing newline (whitespace)
} else {
pkg/utilities/manifest/manifest.go:60: unnecessary trailing newline (whitespace)
}, "items"); err != nil {
pkg/plan/builder.go:56:10: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"graph node %s is not a valid resource\", n)" (goerr113)
err := fmt.Errorf("graph node %s is not a valid resource", n)
^
pkg/plan/builder.go:82:19: err113: do not define dynamic errors, use wrapped static errors instead: "errors.New(errs.String())" (goerr113)
return *b.plan, errors.New(errs.String())
^
pkg/plan/plan.go:284:10: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"plan: resource %q already in the plan\", id)" (goerr113)
return fmt.Errorf("plan: resource %q already in the plan", id)
^
pkg/plan/plan.go:677:10: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"Partial undo completed due to the following errors:\\n%s\", formatNestedErrors(errors))" (goerr113)
return fmt.Errorf("Partial undo completed due to the following errors:\n%s", formatNestedErrors(errors))
^
pkg/plan/plan.go:919:10: err113: do not define dynamic errors, use wrapped static errors instead: "errors.New(\"Failing (Bad Upstream Resource)\")" (goerr113)
return errors.New("Failing (Bad Upstream Resource)")
^
pkg/plan/state.go:152:16: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"invalid path (key not found): %s\", strings.Join(parts[:i+1], \".\"))" (goerr113)
return nil, fmt.Errorf("invalid path (key not found): %s", strings.Join(parts[:i+1], "."))
^
pkg/plan/state.go:169:15: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"invalid path (key isn't a map): %s\", strings.Join(parts[:i+1], \".\"))" (goerr113)
return nil, fmt.Errorf("invalid path (key isn't a map): %s", strings.Join(parts[:i+1], "."))
^
pkg/plan/state.go:173:14: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"invalid path (eek!): %s\", path)" (goerr113)
return nil, fmt.Errorf("invalid path (eek!): %s", path)
^
pkg/plan/state.go:191:16: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"cannot convert %q to bool\", v)" (goerr113)
return false, fmt.Errorf("cannot convert %q to bool", v)
^
pkg/plan/state.go:215:12: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"cannot convert %q to float64\", v)" (goerr113)
return 0, fmt.Errorf("cannot convert %q to float64", v)
^
pkg/plan/state.go:233:13: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"cannot convert %q to string\", v)" (goerr113)
return "", fmt.Errorf("cannot convert %q to string", v)
^
pkg/plan/state.go:251:21: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"cannot convert %q to State\", v)" (goerr113)
return NewState(), fmt.Errorf("cannot convert %q to State", v)
^
pkg/plan/resource/apt.go:27:10: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"command %q failed: %v; output: %s\", cmd, err, out)" (goerr113)
return fmt.Errorf("command %q failed: %v; output: %s", cmd, err, out)
^
pkg/plan/resource/apt.go:36:10: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"command %q failed: %v; output: %s\", cmd, err, out)" (goerr113)
return fmt.Errorf("command %q failed: %v; output: %s", cmd, err, out)
^
pkg/plan/resource/apt.go:51:10: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"command %q failed: %v; output: %s\", cmd, err, out)" (goerr113)
return fmt.Errorf("command %q failed: %v; output: %s", cmd, err, out)
^
pkg/plan/resource/deb.go:44:17: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"update cache failed: %v\", err)" (goerr113)
return false, fmt.Errorf("update cache failed: %v", err)
^
pkg/plan/resource/dir.go:53:10: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"deletion aborted because dir is blacklisted for deletion: %s\", path)" (goerr113)
return fmt.Errorf("deletion aborted because dir is blacklisted for deletion: %s", path)
^
pkg/plan/resource/dpkg.go:42:15: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"dpkg: command %q failed: %v\", cmd, err)" (goerr113)
return nil, fmt.Errorf("dpkg: command %q failed: %v", cmd, err)
^
pkg/plan/resource/dpkg.go:52:16: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"cannot parse output line (bad number of fields): %v\", line)" (goerr113)
return nil, fmt.Errorf("cannot parse output line (bad number of fields): %v", line)
^
pkg/plan/resource/file.go:48:27: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"Query file %s failed: %v -- %s\", f.Destination, err, output)" (goerr113)
return plan.EmptyState, fmt.Errorf("Query file %s failed: %v -- %s", f.Destination, err, output)
^
pkg/plan/resource/rpm.go:90:27: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"Query rpm %s failed: %v -- %s\", p.label(), err, output)" (goerr113)
return plan.EmptyState, fmt.Errorf("Query rpm %s failed: %v -- %s", p.label(), err, output)
^
pkg/plan/resource/service.go:85:17: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"%s: %s\", output, err.Error())" (goerr113)
return false, fmt.Errorf("%s: %s", output, err.Error())
^
pkg/plan/resource/service.go:97:17: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"%s: %s\", output, err.Error())" (goerr113)
return false, fmt.Errorf("%s: %s", output, err.Error())
^
pkg/plan/resource/service.go:111:11: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"%s: %s\", output, err.Error())" (goerr113)
return fmt.Errorf("%s: %s", output, err.Error())
^
pkg/apis/wksprovider/machine/os/os.go:64:16: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"No config data for filespec: %v\", file)" (goerr113)
return nil, fmt.Errorf("No config data for filespec: %v", file)
^
pkg/apis/wksprovider/machine/os/os.go:210:15: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"unknown operating system %q\", osID)" (goerr113)
return nil, fmt.Errorf("unknown operating system %q", osID)
^
pkg/kubernetes/drain/facade.go:39:10: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"policy group version not found in the API server; eviction is not supported\")" (goerr113)
return fmt.Errorf("policy group version not found in the API server; eviction is not supported")
^
pkg/kubernetes/drain/facade.go:81:11: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"timed out (after %s) waiting for node %q to be drain\", timeOut, node.Name)" (goerr113)
return fmt.Errorf("timed out (after %s) waiting for node %q to be drain", timeOut, node.Name)
^
pkg/kubernetes/drain/facade.go:100:14: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"errors: %v\", errs)" (goerr113)
return -1, fmt.Errorf("errors: %v", errs) // TODO: improve formatting
^
pkg/utilities/kubeadm/bootstrap_token.go:27:15: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"invalid kubeadm bootstrap token: %s\", token)" (goerr113)
return nil, fmt.Errorf("invalid kubeadm bootstrap token: %s", token)
^
controllers/cluster.weave.works/existinginfracluster_controller.go:98:25: err113: do not define dynamic errors, use wrapped static errors instead: "errors.New(\"ClusterReconciler#Delete not implemented\")" (goerr113)
return ctrl.Result{}, errors.New("ClusterReconciler#Delete not implemented")
^
controllers/cluster.weave.works/existinginframachine_controller.go:362:10: err113: do not define dynamic errors, use wrapped static errors instead: "errors.New(\"there should be at least one master\")" (goerr113)
return errors.New("there should be at least one master")
^
controllers/cluster.weave.works/existinginframachine_controller.go:464:11: err113: do not define dynamic errors, use wrapped static errors instead: "errors.New(\"Master nodes must be upgraded before worker nodes\")" (goerr113)
return errors.New("Master nodes must be upgraded before worker nodes")
^
controllers/cluster.weave.works/existinginframachine_controller.go:693:10: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"Downgrade not supported. Machine version: %s is less than node version: %s\", mVersion, nVersion)" (goerr113)
return fmt.Errorf("Downgrade not supported. Machine version: %s is less than node version: %s", mVersion, nVersion)
^
controllers/cluster.weave.works/existinginframachine_controller.go:700:10: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"Upgrades can only be performed between patch versions of a single minor version or between \"+\n\t\"minor versions differing by no more than 1 - machine version: %s, node version: %s\", mVersion, nVersion)" (goerr113)
return fmt.Errorf("Upgrades can only be performed between patch versions of a single minor version or between "+
^
controllers/cluster.weave.works/existinginframachine_controller.go:744:15: err113: do not define dynamic errors, use wrapped static errors instead: "errors.New(\"No master found\")" (goerr113)
return nil, errors.New("No master found")
^
controllers/cluster.weave.works/existinginframachine_controller.go:873:9: err113: do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"Fewer than %d control-plane nodes would be available\", quorum)" (goerr113)
return fmt.Errorf("Fewer than %d control-plane nodes would be available", quorum)
^
controllers/cluster.weave.works/existinginframachine_controller.go:944:14: err113: do not define dynamic errors, use wrapped static errors instead: "errors.New(\"Could not find controller node\")" (goerr113)
return nil, errors.New("Could not find controller node")
^
controllers/cluster.weave.works/existinginframachine_controller.go:980:13: err113: do not define dynamic errors, use wrapped static errors instead: "errors.New(\"no InternalIP address found\")" (goerr113)
return "", errors.New("no InternalIP address found")
^
pkg/plan/plan.go:277:23: mnd: Magic number: 16, in <argument> detected (gomnd)
graph: newGraph(16),
^
pkg/plan/resource/apt.go:72:12: mnd: Magic number: 30, in <assign> detected (gomnd)
Retries: 30,
^
pkg/kubernetes/drain/facade.go:115:36: mnd: Magic number: 5, in <argument> detected (gomnd)
time.Sleep(min(remainingTime, max(5*time.Second, timeOut/10)))
^
pkg/utilities/ssh/ssh.go:72:21: mnd: Magic number: 3, in <condition> detected (gomnd)
if len(fields) != 3 {
^
pkg/utilities/kubeadm/bootstrap_token.go:48:78: mnd: Magic number: 24, in <argument> detected (gomnd)
bootstrapapi.BootstrapTokenExpirationKey: time.Now().Add(time.Hour * 24).Format(time.RFC3339),
^
pkg/utilities/kubeadm/bootstrap_token.go:24:25: mnd: Magic number: 2, in <condition> detected (gomnd)
if len(idAndSecret) != 2 {
^
controllers/cluster.weave.works/existinginframachine_controller.go:861:31: mnd: Magic number: 2, in <operation> detected (gomnd)
quorum := (len(nodes) + 1) / 2
^
controllers/cluster.weave.works/existinginframachine_controller.go:607:29: mnd: Magic number: 6443, in <assign> detected (gomnd)
MasterPort: 6443, // TODO: read this dynamically, from somewhere.
^
main.go:62:23: mnd: Magic number: 9443, in <assign> detected (gomnd)
Port: 9443,
^
When the first node is prepared by wksctl
, the ExistingInfraMachine status is not set, but the plan is. When reconciling, the controller will never set that resource ready status, preventing the capi controller from reconciling that machine.
$ kubectl get machines
NAMESPACE NAME PROVIDERID PHASE
weavek8sops master-b3d5c existingInfra://ip-10-0-194-68.us-west-2.compute.internal Pending
weavek8sops master-ny94n existingInfra://ip-10-0-195-96.us-west-2.compute.internal Pending
weavek8sops master-vj22r Pending
weavek8sops worker-0cnnv existingInfra://ip-10-0-130-187.us-west-2.compute.internal Pending
weavek8sops worker-4wwcm existingInfra://ip-10-0-131-199.us-west-2.compute.internal Pending
weavek8sops worker-ify5a existingInfra://ip-10-0-128-18.us-west-2.compute.internal Pending
weavek8sops worker-y0bh1 existingInfra://ip-10-0-130-46.us-west-2.compute.internal Pending
$ kubectl get existinginframachines
NAMESPACE NAME READY
weavek8sops master-b3d5c true
weavek8sops master-ny94n true
weavek8sops master-vj22r
weavek8sops worker-0cnnv true
weavek8sops worker-4wwcm true
weavek8sops worker-ify5a true
weavek8sops worker-y0bh1 true
In this example, master-vj22r was the first (master) machine defined in the machines.yaml.
Docker has been deprecated as a container runtime since kubernetes 1.20. Add containerd as an option for the cri configuration.
I really like the idea of this provider as it could be really useful, but there appears to have been no changes or responses to issues and PRs for months. Is it still being maintained or actively worked on?
Evidence:
containers:
- args:
- --verbose
env:
- name: EXISTINGINFRA_CONTROLLER_IMAGE
value: docker.io/weaveworks/cluster-api-existinginfra-controller:v0.0.6
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
image: docker.io/weaveworks/cluster-api-existinginfra-controller:v0.1.0
I suspect the bug is here:
cluster-api-provider-existinginfra/pkg/apis/wksprovider/machine/os/os.go
Lines 578 to 583 in e84a7fd
When this repo is published
Currently CAPEI uses a structure reminiscent of v1alpha1
with APIs from v1alpha3
. To comply with the clusterctl provider contract, more controllers need to be implemented (e.g. the bootstrap controller, of which there is a skeleton in the code), and some functional changes are needed. This is not an immediate priority.
The CAPEI source code is nearly 1-to-1 moved over from https://github.com/weaveworks/wksctl, with little in terms of changes to improve integration/functionality as a standalone CAPI provider/set of controllers. With this separation now done also on the wksctl side (weaveworks/wksctl#286) it should be more straightforward to start restructuring the project for easier maintainability and better code quality.
A single buffer is added to two io.MultiWriter
s
cluster-api-provider-existinginfra/pkg/plan/runners/ssh/ssh.go
Lines 96 to 104 in 3ead92b
which are then written from two goroutines:
cluster-api-provider-existinginfra/pkg/plan/runners/ssh/ssh.go
Lines 111 to 118 in 3ead92b
This is the same error fixed at weaveworks/launcher#313
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.