├── .github └── workflows │ ├── generate.yml │ └── release.yml ├── .goreleaser.yaml ├── LICENSE ├── Makefile ├── README.md ├── charts ├── cozystack │ ├── Chart.yaml │ ├── charts │ │ └── talm │ ├── templates │ │ ├── _helpers.tpl │ │ ├── controlplane.yaml │ │ └── worker.yaml │ └── values.yaml ├── generic │ ├── Chart.yaml │ ├── charts │ │ └── talm │ ├── templates │ │ ├── _helpers.tpl │ │ ├── controlplane.yaml │ │ └── worker.yaml │ └── values.yaml └── talm │ ├── Chart.yaml │ └── templates │ └── _helpers.tpl ├── go.mod ├── go.sum ├── internal ├── app │ ├── apid │ │ ├── main.go │ │ └── pkg │ │ │ ├── backend │ │ │ ├── apid.go │ │ │ ├── apid_factory.go │ │ │ ├── apid_factory_test.go │ │ │ ├── apid_test.go │ │ │ └── backend.go │ │ │ ├── director │ │ │ ├── director.go │ │ │ ├── director_test.go │ │ │ ├── local_address.go │ │ │ └── mocks_test.go │ │ │ └── provider │ │ │ ├── provider.go │ │ │ └── provider_test.go │ ├── auditd │ │ └── auditd.go │ ├── dashboard │ │ └── main.go │ ├── machined │ │ ├── internal │ │ │ └── server │ │ │ │ └── v1alpha1 │ │ │ │ ├── v1alpha1_cluster.go │ │ │ │ ├── v1alpha1_images.go │ │ │ │ ├── v1alpha1_inspect.go │ │ │ │ ├── v1alpha1_meta.go │ │ │ │ ├── v1alpha1_monitoring.go │ │ │ │ ├── v1alpha1_server.go │ │ │ │ ├── v1alpha1_time.go │ │ │ │ └── v1alpha1_time_test.go │ │ ├── main.go │ │ ├── pkg │ │ │ ├── adapters │ │ │ │ ├── cluster │ │ │ │ │ ├── cluster.go │ │ │ │ │ ├── identity.go │ │ │ │ │ └── identity_test.go │ │ │ │ ├── hardware │ │ │ │ │ ├── hardware.go │ │ │ │ │ ├── memorymodule.go │ │ │ │ │ ├── processor.go │ │ │ │ │ └── system_information.go │ │ │ │ ├── k8s │ │ │ │ │ ├── k8s.go │ │ │ │ │ ├── manifest.go │ │ │ │ │ ├── manifest_test.go │ │ │ │ │ ├── static_pod.go │ │ │ │ │ ├── static_pod_status.go │ │ │ │ │ └── testdata │ │ │ │ │ │ └── list.yaml │ │ │ │ ├── kubespan │ │ │ │ │ ├── identity.go │ │ │ │ │ ├── identity_test.go │ │ │ │ │ ├── kubespan.go │ │ │ │ │ ├── peer_status.go │ │ │ │ │ └── peer_status_test.go │ │ │ │ ├── network │ │ │ │ │ ├── bond_master_spec.go │ │ │ │ │ ├── bond_master_spec_test.go │ │ │ │ │ ├── bridge_master_spec.go │ │ │ │ │ ├── bridge_master_spec_test.go │ │ │ │ │ ├── ipset.go │ │ │ │ │ ├── ipset_test.go │ │ │ │ │ ├── network.go │ │ │ │ │ ├── nftables_rule.go │ │ │ │ │ ├── nftables_rule_test.go │ │ │ │ │ ├── vlan_spec.go │ │ │ │ │ ├── vlan_spec_test.go │ │ │ │ │ ├── wireguard_spec.go │ │ │ │ │ └── wireguard_spec_test.go │ │ │ │ ├── perf │ │ │ │ │ ├── cpu.go │ │ │ │ │ ├── mem.go │ │ │ │ │ └── perf.go │ │ │ │ └── wireguard │ │ │ │ │ └── wireguard.go │ │ │ ├── controllers │ │ │ │ ├── block │ │ │ │ │ ├── block.go │ │ │ │ │ ├── devices.go │ │ │ │ │ ├── devices_test.go │ │ │ │ │ ├── discovery.go │ │ │ │ │ ├── disks.go │ │ │ │ │ ├── internal │ │ │ │ │ │ ├── inotify │ │ │ │ │ │ │ ├── inotify.go │ │ │ │ │ │ │ └── inotify_test.go │ │ │ │ │ │ ├── kobject │ │ │ │ │ │ │ ├── kobject.go │ │ │ │ │ │ │ └── kobject_test.go │ │ │ │ │ │ ├── sysblock │ │ │ │ │ │ │ ├── sysblock.go │ │ │ │ │ │ │ └── sysblock_test.go │ │ │ │ │ │ └── volumes │ │ │ │ │ │ │ ├── close.go │ │ │ │ │ │ │ ├── disk.go │ │ │ │ │ │ │ ├── disk_test.go │ │ │ │ │ │ │ ├── encrypt.go │ │ │ │ │ │ │ ├── format.go │ │ │ │ │ │ │ ├── grow.go │ │ │ │ │ │ │ ├── grow_test.go │ │ │ │ │ │ │ ├── helpers_test.go │ │ │ │ │ │ │ ├── locate.go │ │ │ │ │ │ │ ├── partition.go │ │ │ │ │ │ │ ├── partition_test.go │ │ │ │ │ │ │ ├── volumes.go │ │ │ │ │ │ │ └── volumes_test.go │ │ │ │ │ ├── lvm.go │ │ │ │ │ ├── system_disk.go │ │ │ │ │ ├── system_disk_test.go │ │ │ │ │ ├── user_disk_config.go │ │ │ │ │ ├── user_disk_config_test.go │ │ │ │ │ ├── volume_config.go │ │ │ │ │ ├── volume_config_test.go │ │ │ │ │ └── volume_manager.go │ │ │ │ ├── cluster │ │ │ │ │ ├── affiliate_merge.go │ │ │ │ │ ├── affiliate_merge_test.go │ │ │ │ │ ├── cluster.go │ │ │ │ │ ├── cluster_test.go │ │ │ │ │ ├── config.go │ │ │ │ │ ├── config_test.go │ │ │ │ │ ├── discovery_service.go │ │ │ │ │ ├── discovery_service_test.go │ │ │ │ │ ├── endpoint.go │ │ │ │ │ ├── endpoint_test.go │ │ │ │ │ ├── info.go │ │ │ │ │ ├── info_test.go │ │ │ │ │ ├── kubernetes_pull.go │ │ │ │ │ ├── kubernetes_push.go │ │ │ │ │ ├── local_affiliate.go │ │ │ │ │ ├── local_affiliate_test.go │ │ │ │ │ ├── member.go │ │ │ │ │ ├── member_test.go │ │ │ │ │ ├── node_identity.go │ │ │ │ │ └── node_identity_test.go │ │ │ │ ├── config │ │ │ │ │ ├── acquire.go │ │ │ │ │ ├── acquire_test.go │ │ │ │ │ ├── config.go │ │ │ │ │ └── machine_type.go │ │ │ │ ├── cri │ │ │ │ │ ├── cri.go │ │ │ │ │ ├── cri_test.go │ │ │ │ │ ├── image_cache_config.go │ │ │ │ │ ├── image_cache_config_test.go │ │ │ │ │ ├── registries_config.go │ │ │ │ │ ├── registries_config_test.go │ │ │ │ │ ├── runc_memfd_bind.go │ │ │ │ │ ├── seccomp_profile.go │ │ │ │ │ ├── seccomp_profile_file.go │ │ │ │ │ ├── seccomp_profile_file_test.go │ │ │ │ │ └── seccomp_profile_test.go │ │ │ │ ├── ctest │ │ │ │ │ ├── assert.go │ │ │ │ │ └── ctest.go │ │ │ │ ├── etcd │ │ │ │ │ ├── advertised_peer.go │ │ │ │ │ ├── config.go │ │ │ │ │ ├── config_test.go │ │ │ │ │ ├── etcd.go │ │ │ │ │ ├── member.go │ │ │ │ │ ├── member_test.go │ │ │ │ │ ├── pki.go │ │ │ │ │ ├── spec.go │ │ │ │ │ └── spec_test.go │ │ │ │ ├── files │ │ │ │ │ ├── cri_base_runtime_spec.go │ │ │ │ │ ├── cri_base_runtime_spec_test.go │ │ │ │ │ ├── cri_config_parts.go │ │ │ │ │ ├── cri_registry_config.go │ │ │ │ │ ├── etcfile.go │ │ │ │ │ ├── etcfile_test.go │ │ │ │ │ └── files.go │ │ │ │ ├── hardware │ │ │ │ │ ├── hardware.go │ │ │ │ │ ├── hardware_test.go │ │ │ │ │ ├── pcidevices.go │ │ │ │ │ ├── system.go │ │ │ │ │ ├── system_test.go │ │ │ │ │ └── testdata │ │ │ │ │ │ └── SuperMicro-Dual-Xeon.dmi │ │ │ │ ├── k8s │ │ │ │ │ ├── address_filter.go │ │ │ │ │ ├── address_filter_test.go │ │ │ │ │ ├── control_plane.go │ │ │ │ │ ├── control_plane_static_pod.go │ │ │ │ │ ├── control_plane_static_pod_test.go │ │ │ │ │ ├── control_plane_test.go │ │ │ │ │ ├── endpoint.go │ │ │ │ │ ├── extra_manifest.go │ │ │ │ │ ├── extra_manifest_test.go │ │ │ │ │ ├── internal │ │ │ │ │ │ ├── nodename │ │ │ │ │ │ │ ├── nodename.go │ │ │ │ │ │ │ └── nodename_test.go │ │ │ │ │ │ └── nodewatch │ │ │ │ │ │ │ └── nodewatch.go │ │ │ │ │ ├── k8s.go │ │ │ │ │ ├── kubelet_config.go │ │ │ │ │ ├── kubelet_config_test.go │ │ │ │ │ ├── kubelet_service.go │ │ │ │ │ ├── kubelet_spec.go │ │ │ │ │ ├── kubelet_spec_test.go │ │ │ │ │ ├── kubelet_static_pod.go │ │ │ │ │ ├── kubeprism.go │ │ │ │ │ ├── kubeprism_config.go │ │ │ │ │ ├── kubeprism_config_test.go │ │ │ │ │ ├── kubeprism_endpoints.go │ │ │ │ │ ├── kubeprism_endpoints_test.go │ │ │ │ │ ├── manifest.go │ │ │ │ │ ├── manifest_apply.go │ │ │ │ │ ├── manifest_test.go │ │ │ │ │ ├── node_annotation_spec.go │ │ │ │ │ ├── node_annotation_spec_test.go │ │ │ │ │ ├── node_apply.go │ │ │ │ │ ├── node_apply_test.go │ │ │ │ │ ├── node_cordoned_spec.go │ │ │ │ │ ├── node_cordoned_spec_test.go │ │ │ │ │ ├── node_label_spec.go │ │ │ │ │ ├── node_label_spec_test.go │ │ │ │ │ ├── node_status.go │ │ │ │ │ ├── node_taint_spec.go │ │ │ │ │ ├── node_taint_spec_test.go │ │ │ │ │ ├── nodeip.go │ │ │ │ │ ├── nodeip_config.go │ │ │ │ │ ├── nodeip_config_test.go │ │ │ │ │ ├── nodeip_test.go │ │ │ │ │ ├── nodename.go │ │ │ │ │ ├── nodename_test.go │ │ │ │ │ ├── render_config_static_pods.go │ │ │ │ │ ├── render_secrets_static_pod.go │ │ │ │ │ ├── static_endpoint.go │ │ │ │ │ ├── static_endpoint_test.go │ │ │ │ │ ├── static_pod_config.go │ │ │ │ │ ├── static_pod_config_test.go │ │ │ │ │ ├── static_pod_server.go │ │ │ │ │ ├── static_pod_server_test.go │ │ │ │ │ ├── templates.go │ │ │ │ │ └── templates │ │ │ │ │ │ ├── core-dns-svc-template.yaml │ │ │ │ │ │ ├── core-dns-template.yaml │ │ │ │ │ │ ├── csr-approver-role-binding-template.yaml │ │ │ │ │ │ ├── csr-node-bootstrap-template.yaml │ │ │ │ │ │ ├── csr-renewal-role-binding-template.yaml │ │ │ │ │ │ ├── kube-config-in-cluster-template.yaml │ │ │ │ │ │ ├── kube-proxy-template.yaml │ │ │ │ │ │ ├── kube-system-encryption-config-template.yaml │ │ │ │ │ │ ├── kubelet-bootstrapping-token-template.yaml │ │ │ │ │ │ ├── pod-security-policy-template.yaml │ │ │ │ │ │ ├── talos-api-service-template.yaml │ │ │ │ │ │ └── talos-service-account-crd-template.yaml │ │ │ │ ├── kubeaccess │ │ │ │ │ ├── config.go │ │ │ │ │ ├── config_test.go │ │ │ │ │ ├── endpoint.go │ │ │ │ │ ├── kubeaccess.go │ │ │ │ │ ├── serviceaccount.go │ │ │ │ │ └── serviceaccount │ │ │ │ │ │ └── crd_controller.go │ │ │ │ ├── kubespan │ │ │ │ │ ├── config.go │ │ │ │ │ ├── config_test.go │ │ │ │ │ ├── endpoint.go │ │ │ │ │ ├── endpoint_test.go │ │ │ │ │ ├── identity.go │ │ │ │ │ ├── identity_test.go │ │ │ │ │ ├── kubespan.go │ │ │ │ │ ├── kubespan_test.go │ │ │ │ │ ├── manager.go │ │ │ │ │ ├── manager_test.go │ │ │ │ │ ├── peer_spec.go │ │ │ │ │ ├── peer_spec_test.go │ │ │ │ │ ├── routing_rules.go │ │ │ │ │ └── routing_rules_test.go │ │ │ │ ├── network │ │ │ │ │ ├── address_config.go │ │ │ │ │ ├── address_config_test.go │ │ │ │ │ ├── address_event.go │ │ │ │ │ ├── address_event_test.go │ │ │ │ │ ├── address_merge.go │ │ │ │ │ ├── address_merge_test.go │ │ │ │ │ ├── address_spec.go │ │ │ │ │ ├── address_spec_test.go │ │ │ │ │ ├── address_status.go │ │ │ │ │ ├── address_status_test.go │ │ │ │ │ ├── cmdline.go │ │ │ │ │ ├── cmdline_test.go │ │ │ │ │ ├── device_config.go │ │ │ │ │ ├── device_config_test.go │ │ │ │ │ ├── dns_resolve_cache.go │ │ │ │ │ ├── dns_resolve_cache_test.go │ │ │ │ │ ├── dns_upstream.go │ │ │ │ │ ├── etcfile.go │ │ │ │ │ ├── etcfile_test.go │ │ │ │ │ ├── hardware_addr.go │ │ │ │ │ ├── hardware_addr_test.go │ │ │ │ │ ├── hostdns_config.go │ │ │ │ │ ├── hostname_config.go │ │ │ │ │ ├── hostname_config_test.go │ │ │ │ │ ├── hostname_merge.go │ │ │ │ │ ├── hostname_merge_test.go │ │ │ │ │ ├── hostname_spec.go │ │ │ │ │ ├── hostname_spec_test.go │ │ │ │ │ ├── internal │ │ │ │ │ │ ├── addressutil │ │ │ │ │ │ │ ├── addressutil.go │ │ │ │ │ │ │ ├── addressutil_test.go │ │ │ │ │ │ │ ├── compare.go │ │ │ │ │ │ │ └── compare_test.go │ │ │ │ │ │ └── probe │ │ │ │ │ │ │ ├── probe.go │ │ │ │ │ │ │ └── probe_test.go │ │ │ │ │ ├── link_config.go │ │ │ │ │ ├── link_config_test.go │ │ │ │ │ ├── link_merge.go │ │ │ │ │ ├── link_merge_test.go │ │ │ │ │ ├── link_spec.go │ │ │ │ │ ├── link_spec_test.go │ │ │ │ │ ├── link_status.go │ │ │ │ │ ├── link_status_test.go │ │ │ │ │ ├── network.go │ │ │ │ │ ├── nftables_chain.go │ │ │ │ │ ├── nftables_chain_config.go │ │ │ │ │ ├── nftables_chain_config_test.go │ │ │ │ │ ├── nftables_chain_test.go │ │ │ │ │ ├── node_address.go │ │ │ │ │ ├── node_address_sort_algorithm.go │ │ │ │ │ ├── node_address_test.go │ │ │ │ │ ├── operator │ │ │ │ │ │ ├── dhcp4.go │ │ │ │ │ │ ├── dhcp6.go │ │ │ │ │ │ ├── operator.go │ │ │ │ │ │ ├── vip.go │ │ │ │ │ │ └── vip │ │ │ │ │ │ │ ├── equinix_metal.go │ │ │ │ │ │ │ ├── equinix_metal_test.go │ │ │ │ │ │ │ ├── hcloud.go │ │ │ │ │ │ │ ├── nop.go │ │ │ │ │ │ │ └── vip.go │ │ │ │ │ ├── operator_config.go │ │ │ │ │ ├── operator_config_test.go │ │ │ │ │ ├── operator_merge.go │ │ │ │ │ ├── operator_merge_test.go │ │ │ │ │ ├── operator_spec.go │ │ │ │ │ ├── operator_spec_test.go │ │ │ │ │ ├── operator_vip_config.go │ │ │ │ │ ├── operator_vip_config_test.go │ │ │ │ │ ├── platform_config.go │ │ │ │ │ ├── platform_config_test.go │ │ │ │ │ ├── probe.go │ │ │ │ │ ├── probe_test.go │ │ │ │ │ ├── resolver_config.go │ │ │ │ │ ├── resolver_config_test.go │ │ │ │ │ ├── resolver_merge.go │ │ │ │ │ ├── resolver_merge_test.go │ │ │ │ │ ├── resolver_spec.go │ │ │ │ │ ├── resolver_spec_test.go │ │ │ │ │ ├── route_config.go │ │ │ │ │ ├── route_config_test.go │ │ │ │ │ ├── route_merge.go │ │ │ │ │ ├── route_merge_test.go │ │ │ │ │ ├── route_spec.go │ │ │ │ │ ├── route_spec_test.go │ │ │ │ │ ├── route_status.go │ │ │ │ │ ├── route_status_test.go │ │ │ │ │ ├── status.go │ │ │ │ │ ├── status_test.go │ │ │ │ │ ├── timeserver_config.go │ │ │ │ │ ├── timeserver_config_test.go │ │ │ │ │ ├── timeserver_merge.go │ │ │ │ │ ├── timeserver_merge_test.go │ │ │ │ │ ├── timeserver_spec.go │ │ │ │ │ ├── timeserver_spec_test.go │ │ │ │ │ ├── utils │ │ │ │ │ │ └── utils.go │ │ │ │ │ └── watch │ │ │ │ │ │ ├── ethtool.go │ │ │ │ │ │ ├── rtnetlink.go │ │ │ │ │ │ ├── trigger.go │ │ │ │ │ │ ├── trigger_test.go │ │ │ │ │ │ └── watch.go │ │ │ │ ├── perf │ │ │ │ │ ├── perf.go │ │ │ │ │ └── perf_test.go │ │ │ │ ├── runtime │ │ │ │ │ ├── common_test.go │ │ │ │ │ ├── cri_image_gc.go │ │ │ │ │ ├── cri_image_gc_test.go │ │ │ │ │ ├── devices_status.go │ │ │ │ │ ├── diagnostics.go │ │ │ │ │ ├── diagnostics_logger.go │ │ │ │ │ ├── drop_upgrade_fallback.go │ │ │ │ │ ├── drop_upgrade_fallback_test.go │ │ │ │ │ ├── events_sink.go │ │ │ │ │ ├── events_sink_config.go │ │ │ │ │ ├── events_sink_config_test.go │ │ │ │ │ ├── events_sink_test.go │ │ │ │ │ ├── export_test.go │ │ │ │ │ ├── extension_service.go │ │ │ │ │ ├── extension_service_config.go │ │ │ │ │ ├── extension_service_config_files.go │ │ │ │ │ ├── extension_service_config_files_test.go │ │ │ │ │ ├── extension_service_config_test.go │ │ │ │ │ ├── extension_service_test.go │ │ │ │ │ ├── extension_status.go │ │ │ │ │ ├── internal │ │ │ │ │ │ └── diagnostics │ │ │ │ │ │ │ ├── address_overlap.go │ │ │ │ │ │ │ ├── address_overlap_test.go │ │ │ │ │ │ │ ├── diagnostic.go │ │ │ │ │ │ │ └── kubelet_csr_not_approved.go │ │ │ │ │ ├── kernel_module_config.go │ │ │ │ │ ├── kernel_module_config_test.go │ │ │ │ │ ├── kernel_module_spec.go │ │ │ │ │ ├── kernel_param_config.go │ │ │ │ │ ├── kernel_param_config_test.go │ │ │ │ │ ├── kernel_param_defaults.go │ │ │ │ │ ├── kernel_param_defaults_test.go │ │ │ │ │ ├── kernel_param_spec.go │ │ │ │ │ ├── kernel_param_spec_test.go │ │ │ │ │ ├── kmsg_log.go │ │ │ │ │ ├── kmsg_log_config.go │ │ │ │ │ ├── kmsg_log_config_test.go │ │ │ │ │ ├── kmsg_log_test.go │ │ │ │ │ ├── machine_status.go │ │ │ │ │ ├── machine_status_publisher.go │ │ │ │ │ ├── machine_status_test.go │ │ │ │ │ ├── maintenance_config.go │ │ │ │ │ ├── maintenance_config_test.go │ │ │ │ │ ├── maintenance_service.go │ │ │ │ │ ├── maintenance_service_test.go │ │ │ │ │ ├── runtime.go │ │ │ │ │ ├── security_state.go │ │ │ │ │ ├── testdata │ │ │ │ │ │ └── extservices │ │ │ │ │ │ │ ├── foo.bar │ │ │ │ │ │ │ ├── frr.yaml │ │ │ │ │ │ │ ├── hello.yaml │ │ │ │ │ │ │ ├── invalid.yaml │ │ │ │ │ │ │ └── zduplicate.yaml │ │ │ │ │ ├── unique_token.go │ │ │ │ │ ├── utils.go │ │ │ │ │ ├── watchdog_timer.go │ │ │ │ │ ├── watchdog_timer_config.go │ │ │ │ │ └── watchdog_timer_config_test.go │ │ │ │ ├── secrets │ │ │ │ │ ├── api.go │ │ │ │ │ ├── api_cert_sans.go │ │ │ │ │ ├── api_cert_sans_test.go │ │ │ │ │ ├── api_test.go │ │ │ │ │ ├── data │ │ │ │ │ │ └── ca-certificates │ │ │ │ │ ├── etcd.go │ │ │ │ │ ├── etcd_test.go │ │ │ │ │ ├── kubelet.go │ │ │ │ │ ├── kubelet_test.go │ │ │ │ │ ├── kubernetes.go │ │ │ │ │ ├── kubernetes_cert_sans.go │ │ │ │ │ ├── kubernetes_cert_sans_test.go │ │ │ │ │ ├── kubernetes_dynamic_certs.go │ │ │ │ │ ├── kubernetes_dynamic_certs_test.go │ │ │ │ │ ├── kubernetes_test.go │ │ │ │ │ ├── maintenance.go │ │ │ │ │ ├── maintenance_cert_sans.go │ │ │ │ │ ├── maintenance_cert_sans_test.go │ │ │ │ │ ├── maintenance_root.go │ │ │ │ │ ├── maintenance_root_test.go │ │ │ │ │ ├── maintenance_test.go │ │ │ │ │ ├── root.go │ │ │ │ │ ├── root_test.go │ │ │ │ │ ├── secrets.go │ │ │ │ │ ├── trustd.go │ │ │ │ │ ├── trustd_test.go │ │ │ │ │ ├── trusted_roots.go │ │ │ │ │ └── trusted_roots_test.go │ │ │ │ ├── siderolink │ │ │ │ │ ├── config.go │ │ │ │ │ ├── config_test.go │ │ │ │ │ ├── manager.go │ │ │ │ │ ├── manager_test.go │ │ │ │ │ ├── siderolink.go │ │ │ │ │ ├── status.go │ │ │ │ │ ├── status_test.go │ │ │ │ │ └── userspace.go │ │ │ │ ├── time │ │ │ │ │ ├── adjtime_status.go │ │ │ │ │ ├── sync.go │ │ │ │ │ ├── sync_test.go │ │ │ │ │ └── time.go │ │ │ │ ├── utils.go │ │ │ │ └── v1alpha1 │ │ │ │ │ ├── service.go │ │ │ │ │ ├── utils.go │ │ │ │ │ └── v1alpha1.go │ │ │ ├── runtime │ │ │ │ ├── board.go │ │ │ │ ├── controller.go │ │ │ │ ├── disk │ │ │ │ │ ├── disk.go │ │ │ │ │ └── options.go │ │ │ │ ├── doc.go │ │ │ │ ├── drainer.go │ │ │ │ ├── drainer_test.go │ │ │ │ ├── emergency │ │ │ │ │ └── emergency.go │ │ │ │ ├── errors.go │ │ │ │ ├── events.go │ │ │ │ ├── logging.go │ │ │ │ ├── logging │ │ │ │ │ ├── circular.go │ │ │ │ │ ├── extract.go │ │ │ │ │ ├── extract_test.go │ │ │ │ │ ├── file.go │ │ │ │ │ ├── logging.go │ │ │ │ │ ├── null.go │ │ │ │ │ ├── sender_jsonlines.go │ │ │ │ │ └── sender_jsonlines_test.go │ │ │ │ ├── mode.go │ │ │ │ ├── mode_test.go │ │ │ │ ├── platform.go │ │ │ │ ├── runtime.go │ │ │ │ ├── sequencer.go │ │ │ │ ├── sequencer_test.go │ │ │ │ ├── state.go │ │ │ │ ├── v1alpha1 │ │ │ │ │ ├── acpi │ │ │ │ │ │ ├── acpi.go │ │ │ │ │ │ └── acpi_test.go │ │ │ │ │ ├── board │ │ │ │ │ │ ├── bananapi_m64 │ │ │ │ │ │ │ └── bananapi_m64.go │ │ │ │ │ │ ├── board.go │ │ │ │ │ │ ├── jetson_nano │ │ │ │ │ │ │ └── jetson_nano.go │ │ │ │ │ │ ├── libretech_all_h3_cc_h5 │ │ │ │ │ │ │ └── libretech_all_h3_cc_h5.go │ │ │ │ │ │ ├── nanopi_r4s │ │ │ │ │ │ │ └── nanopi_r4s.go │ │ │ │ │ │ ├── pine64 │ │ │ │ │ │ │ └── pine64.go │ │ │ │ │ │ ├── rock64 │ │ │ │ │ │ │ └── rock64.go │ │ │ │ │ │ ├── rockpi4 │ │ │ │ │ │ │ └── rockpi4.go │ │ │ │ │ │ ├── rockpi4c │ │ │ │ │ │ │ └── rockpi4c.go │ │ │ │ │ │ └── rpi_generic │ │ │ │ │ │ │ ├── config.txt │ │ │ │ │ │ │ └── rpi_generic.go │ │ │ │ │ ├── bootloader │ │ │ │ │ │ ├── bootloader.go │ │ │ │ │ │ ├── grub │ │ │ │ │ │ │ ├── boot_label.go │ │ │ │ │ │ │ ├── constants.go │ │ │ │ │ │ │ ├── decode.go │ │ │ │ │ │ │ ├── encode.go │ │ │ │ │ │ │ ├── grub.go │ │ │ │ │ │ │ ├── grub_test.go │ │ │ │ │ │ │ ├── install.go │ │ │ │ │ │ │ ├── probe.go │ │ │ │ │ │ │ ├── quote.go │ │ │ │ │ │ │ ├── quote_test.go │ │ │ │ │ │ │ ├── revert.go │ │ │ │ │ │ │ └── testdata │ │ │ │ │ │ │ │ ├── grub_parse_test.cfg │ │ │ │ │ │ │ │ ├── grub_write_no_reset_test.cfg │ │ │ │ │ │ │ │ └── grub_write_test.cfg │ │ │ │ │ │ ├── mount │ │ │ │ │ │ │ └── mount.go │ │ │ │ │ │ ├── options │ │ │ │ │ │ │ └── options.go │ │ │ │ │ │ └── sdboot │ │ │ │ │ │ │ ├── efivars.go │ │ │ │ │ │ │ └── sdboot.go │ │ │ │ │ ├── doc.go │ │ │ │ │ ├── platform │ │ │ │ │ │ ├── akamai │ │ │ │ │ │ │ ├── akamai.go │ │ │ │ │ │ │ ├── akamai_test.go │ │ │ │ │ │ │ └── testdata │ │ │ │ │ │ │ │ ├── expected.yaml │ │ │ │ │ │ │ │ ├── instance.json │ │ │ │ │ │ │ │ └── network.json │ │ │ │ │ │ ├── aws │ │ │ │ │ │ │ ├── aws.go │ │ │ │ │ │ │ ├── aws_test.go │ │ │ │ │ │ │ ├── metadata.go │ │ │ │ │ │ │ └── testdata │ │ │ │ │ │ │ │ ├── expected.yaml │ │ │ │ │ │ │ │ └── metadata.json │ │ │ │ │ │ ├── azure │ │ │ │ │ │ │ ├── azure.go │ │ │ │ │ │ │ ├── azure_test.go │ │ │ │ │ │ │ ├── metadata.go │ │ │ │ │ │ │ ├── register.go │ │ │ │ │ │ │ └── testdata │ │ │ │ │ │ │ │ ├── compute.json │ │ │ │ │ │ │ │ ├── expected.yaml │ │ │ │ │ │ │ │ ├── interfaces.json │ │ │ │ │ │ │ │ └── loadbalancer.json │ │ │ │ │ │ ├── cloudstack │ │ │ │ │ │ │ ├── cloudstack.go │ │ │ │ │ │ │ ├── cloudstack_test.go │ │ │ │ │ │ │ ├── metadata.go │ │ │ │ │ │ │ └── testdata │ │ │ │ │ │ │ │ ├── expected.yaml │ │ │ │ │ │ │ │ └── metadata.json │ │ │ │ │ │ ├── container │ │ │ │ │ │ │ ├── container.go │ │ │ │ │ │ │ └── internal │ │ │ │ │ │ │ │ └── files │ │ │ │ │ │ │ │ ├── hostname.go │ │ │ │ │ │ │ │ ├── hostname_test.go │ │ │ │ │ │ │ │ ├── resolv.go │ │ │ │ │ │ │ │ ├── resolv_test.go │ │ │ │ │ │ │ │ └── testdata │ │ │ │ │ │ │ │ ├── hostname │ │ │ │ │ │ │ │ └── resolv.conf │ │ │ │ │ │ ├── digitalocean │ │ │ │ │ │ │ ├── digitalocean.go │ │ │ │ │ │ │ ├── digitalocean_test.go │ │ │ │ │ │ │ ├── metadata.go │ │ │ │ │ │ │ └── testdata │ │ │ │ │ │ │ │ ├── expected.yaml │ │ │ │ │ │ │ │ └── metadata.json │ │ │ │ │ │ ├── equinixmetal │ │ │ │ │ │ │ ├── equinix.go │ │ │ │ │ │ │ ├── equinix_test.go │ │ │ │ │ │ │ ├── metadata.go │ │ │ │ │ │ │ └── testdata │ │ │ │ │ │ │ │ ├── expected-2bonds.yaml │ │ │ │ │ │ │ │ ├── expected.yaml │ │ │ │ │ │ │ │ ├── metadata-2bonds.json │ │ │ │ │ │ │ │ └── metadata.json │ │ │ │ │ │ ├── errors │ │ │ │ │ │ │ └── errors.go │ │ │ │ │ │ ├── exoscale │ │ │ │ │ │ │ ├── exoscale.go │ │ │ │ │ │ │ ├── exoscale_test.go │ │ │ │ │ │ │ ├── metadata.go │ │ │ │ │ │ │ └── testdata │ │ │ │ │ │ │ │ ├── expected.yaml │ │ │ │ │ │ │ │ └── metadata.json │ │ │ │ │ │ ├── gcp │ │ │ │ │ │ │ ├── gcp.go │ │ │ │ │ │ │ ├── gcp_test.go │ │ │ │ │ │ │ ├── metadata.go │ │ │ │ │ │ │ └── testdata │ │ │ │ │ │ │ │ ├── expected.yaml │ │ │ │ │ │ │ │ ├── interfaces.json │ │ │ │ │ │ │ │ └── metadata.json │ │ │ │ │ │ ├── hcloud │ │ │ │ │ │ │ ├── export_test.go │ │ │ │ │ │ │ ├── hcloud.go │ │ │ │ │ │ │ ├── hcloud_test.go │ │ │ │ │ │ │ ├── metadata.go │ │ │ │ │ │ │ └── testdata │ │ │ │ │ │ │ │ ├── expected.yaml │ │ │ │ │ │ │ │ ├── metadata.yaml │ │ │ │ │ │ │ │ ├── userdata-base64.txt │ │ │ │ │ │ │ │ └── userdata-plain.yaml │ │ │ │ │ │ ├── internal │ │ │ │ │ │ │ ├── address │ │ │ │ │ │ │ │ └── address.go │ │ │ │ │ │ │ └── netutils │ │ │ │ │ │ │ │ └── netutils.go │ │ │ │ │ │ ├── metal │ │ │ │ │ │ │ ├── metal.go │ │ │ │ │ │ │ ├── metal_test.go │ │ │ │ │ │ │ ├── oauth2 │ │ │ │ │ │ │ │ ├── oauth2.go │ │ │ │ │ │ │ │ └── oauth2_test.go │ │ │ │ │ │ │ ├── url │ │ │ │ │ │ │ │ ├── map.go │ │ │ │ │ │ │ │ ├── map_test.go │ │ │ │ │ │ │ │ ├── url.go │ │ │ │ │ │ │ │ ├── url_test.go │ │ │ │ │ │ │ │ ├── value.go │ │ │ │ │ │ │ │ ├── variable.go │ │ │ │ │ │ │ │ └── variable_test.go │ │ │ │ │ │ │ └── url_test.go │ │ │ │ │ │ ├── nocloud │ │ │ │ │ │ │ ├── metadata.go │ │ │ │ │ │ │ ├── nocloud.go │ │ │ │ │ │ │ ├── nocloud_test.go │ │ │ │ │ │ │ └── testdata │ │ │ │ │ │ │ │ ├── expected-v1-pnap.yaml │ │ │ │ │ │ │ │ ├── expected-v1.yaml │ │ │ │ │ │ │ │ ├── expected-v2-serverscom.yaml │ │ │ │ │ │ │ │ ├── expected-v2.yaml │ │ │ │ │ │ │ │ ├── metadata-v1-pnap.yaml │ │ │ │ │ │ │ │ ├── metadata-v1.yaml │ │ │ │ │ │ │ │ ├── metadata-v2-cloud-init.yaml │ │ │ │ │ │ │ │ ├── metadata-v2-nocloud.yaml │ │ │ │ │ │ │ │ └── metadata-v2-serverscom.yaml │ │ │ │ │ │ ├── opennebula │ │ │ │ │ │ │ ├── metadata.go │ │ │ │ │ │ │ ├── opennebula.go │ │ │ │ │ │ │ ├── opennebula_test.go │ │ │ │ │ │ │ └── testdata │ │ │ │ │ │ │ │ ├── expected.yaml │ │ │ │ │ │ │ │ └── metadata.yaml │ │ │ │ │ │ ├── openstack │ │ │ │ │ │ │ ├── metadata.go │ │ │ │ │ │ │ ├── openstack.go │ │ │ │ │ │ │ ├── openstack_test.go │ │ │ │ │ │ │ └── testdata │ │ │ │ │ │ │ │ ├── expected.yaml │ │ │ │ │ │ │ │ ├── metadata.json │ │ │ │ │ │ │ │ └── network.json │ │ │ │ │ │ ├── oracle │ │ │ │ │ │ │ ├── metadata.go │ │ │ │ │ │ │ ├── oracle.go │ │ │ │ │ │ │ ├── oracle_test.go │ │ │ │ │ │ │ └── testdata │ │ │ │ │ │ │ │ ├── expected.yaml │ │ │ │ │ │ │ │ ├── metadata.json │ │ │ │ │ │ │ │ └── metadatanetwork.json │ │ │ │ │ │ ├── platform.go │ │ │ │ │ │ ├── scaleway │ │ │ │ │ │ │ ├── metadata.go │ │ │ │ │ │ │ ├── scaleway.go │ │ │ │ │ │ │ ├── scaleway_test.go │ │ │ │ │ │ │ └── testdata │ │ │ │ │ │ │ │ ├── expected-v1.yaml │ │ │ │ │ │ │ │ ├── expected-v2.yaml │ │ │ │ │ │ │ │ ├── expected-v3.yaml │ │ │ │ │ │ │ │ ├── metadata-v1.json │ │ │ │ │ │ │ │ ├── metadata-v2.json │ │ │ │ │ │ │ │ └── metadata-v3.json │ │ │ │ │ │ ├── upcloud │ │ │ │ │ │ │ ├── metadata.go │ │ │ │ │ │ │ ├── testdata │ │ │ │ │ │ │ │ ├── expected.yaml │ │ │ │ │ │ │ │ └── metadata.json │ │ │ │ │ │ │ ├── upcloud.go │ │ │ │ │ │ │ └── upcloud_test.go │ │ │ │ │ │ ├── vmware │ │ │ │ │ │ │ ├── metadata.go │ │ │ │ │ │ │ ├── testdata │ │ │ │ │ │ │ │ ├── expected-match-by-mac.yaml │ │ │ │ │ │ │ │ ├── expected-match-by-name.yaml │ │ │ │ │ │ │ │ ├── metadata-match-by-mac.yaml │ │ │ │ │ │ │ │ └── metadata-match-by-name.yaml │ │ │ │ │ │ │ ├── vmware.go │ │ │ │ │ │ │ ├── vmware_amd64.go │ │ │ │ │ │ │ ├── vmware_other.go │ │ │ │ │ │ │ └── vmware_test.go │ │ │ │ │ │ └── vultr │ │ │ │ │ │ │ ├── metadata.go │ │ │ │ │ │ │ ├── testdata │ │ │ │ │ │ │ ├── expected.yaml │ │ │ │ │ │ │ └── metadata.json │ │ │ │ │ │ │ ├── vultr.go │ │ │ │ │ │ │ └── vultr_test.go │ │ │ │ │ ├── v1alpha1_controller.go │ │ │ │ │ ├── v1alpha1_controller_test.go │ │ │ │ │ ├── v1alpha1_dbus.go │ │ │ │ │ ├── v1alpha1_events.go │ │ │ │ │ ├── v1alpha1_events_test.go │ │ │ │ │ ├── v1alpha1_priority_lock.go │ │ │ │ │ ├── v1alpha1_priority_lock_test.go │ │ │ │ │ ├── v1alpha1_runtime.go │ │ │ │ │ ├── v1alpha1_sequencer.go │ │ │ │ │ ├── v1alpha1_sequencer_tasks.go │ │ │ │ │ ├── v1alpha1_sequencer_test.go │ │ │ │ │ └── v1alpha1_state.go │ │ │ │ └── v1alpha2 │ │ │ │ │ ├── adapters.go │ │ │ │ │ ├── v1alpha2.go │ │ │ │ │ ├── v1alpha2_controller.go │ │ │ │ │ └── v1alpha2_state.go │ │ │ ├── startup │ │ │ │ ├── cgroups.go │ │ │ │ ├── ima.go │ │ │ │ ├── os_release.go │ │ │ │ ├── startup.go │ │ │ │ └── tasks.go │ │ │ ├── system │ │ │ │ ├── events │ │ │ │ │ ├── events.go │ │ │ │ │ └── events_test.go │ │ │ │ ├── export_test.go │ │ │ │ ├── health │ │ │ │ │ ├── check.go │ │ │ │ │ ├── health_test.go │ │ │ │ │ ├── settings.go │ │ │ │ │ └── status.go │ │ │ │ ├── integration_test.go │ │ │ │ ├── mocks_test.go │ │ │ │ ├── runner │ │ │ │ │ ├── containerd │ │ │ │ │ │ ├── containerd.go │ │ │ │ │ │ ├── containerd_test.go │ │ │ │ │ │ ├── import.go │ │ │ │ │ │ ├── opts.go │ │ │ │ │ │ └── stdin.go │ │ │ │ │ ├── goroutine │ │ │ │ │ │ ├── goroutine.go │ │ │ │ │ │ └── goroutine_test.go │ │ │ │ │ ├── process │ │ │ │ │ │ ├── process.go │ │ │ │ │ │ └── process_test.go │ │ │ │ │ ├── restart │ │ │ │ │ │ ├── restart.go │ │ │ │ │ │ └── restart_test.go │ │ │ │ │ ├── runner.go │ │ │ │ │ └── runner_test.go │ │ │ │ ├── service.go │ │ │ │ ├── service_events.go │ │ │ │ ├── service_runner.go │ │ │ │ ├── service_runner_test.go │ │ │ │ ├── services │ │ │ │ │ ├── apid.go │ │ │ │ │ ├── auditd.go │ │ │ │ │ ├── containerd.go │ │ │ │ │ ├── cri.go │ │ │ │ │ ├── dashboard.go │ │ │ │ │ ├── etcd.go │ │ │ │ │ ├── export_test.go │ │ │ │ │ ├── extension.go │ │ │ │ │ ├── extension_test.go │ │ │ │ │ ├── kubelet.go │ │ │ │ │ ├── machined.go │ │ │ │ │ ├── machined_test.go │ │ │ │ │ ├── mocks │ │ │ │ │ │ └── snapshotter.go │ │ │ │ │ ├── registry │ │ │ │ │ │ ├── app │ │ │ │ │ │ │ └── main.go │ │ │ │ │ │ ├── fs.go │ │ │ │ │ │ ├── params.go │ │ │ │ │ │ ├── readers.go │ │ │ │ │ │ ├── registry.go │ │ │ │ │ │ ├── registry_test.go │ │ │ │ │ │ └── store.go │ │ │ │ │ ├── registryd.go │ │ │ │ │ ├── syslogd.go │ │ │ │ │ ├── trustd.go │ │ │ │ │ ├── udevd.go │ │ │ │ │ └── utils.go │ │ │ │ ├── system.go │ │ │ │ └── system_test.go │ │ │ └── xcontext │ │ │ │ └── xcontext.go │ │ └── revert.go │ ├── maintenance │ │ ├── controller.go │ │ ├── provider.go │ │ └── server.go │ ├── poweroff │ │ ├── main.go │ │ └── poweroff_test.go │ ├── resources │ │ └── access.go │ ├── storaged │ │ └── server.go │ ├── syslogd │ │ ├── internal │ │ │ └── parser │ │ │ │ ├── parse.go │ │ │ │ └── parse_test.go │ │ ├── syslogd.go │ │ └── syslogd_test.go │ └── trustd │ │ ├── internal │ │ ├── provider │ │ │ └── provider.go │ │ └── reg │ │ │ ├── reg.go │ │ │ └── reg_test.go │ │ └── main.go └── pkg │ ├── cache │ └── cache.go │ ├── capability │ └── capability.go │ ├── cgroup │ ├── cgroup.go │ ├── cpu.go │ └── cpu_test.go │ ├── cgroups │ ├── cgroups.go │ ├── raw.go │ ├── tar.go │ ├── tar_test.go │ ├── testdata │ │ └── cgroup.tar.gz │ ├── value.go │ └── value_test.go │ ├── configuration │ └── configuration.go │ ├── console │ └── console.go │ ├── containers │ ├── container.go │ ├── containerd │ │ ├── containerd.go │ │ └── containerd_test.go │ ├── containers_test.go │ ├── cri │ │ ├── containerd │ │ │ ├── config.go │ │ │ ├── config_test.go │ │ │ ├── containerd.go │ │ │ ├── hosts.go │ │ │ ├── hosts_test.go │ │ │ └── testdata │ │ │ │ └── cri.toml │ │ ├── cri.go │ │ └── cri_test.go │ ├── image │ │ ├── image.go │ │ ├── resolver.go │ │ └── resolver_test.go │ ├── inspector.go │ └── pod.go │ ├── cri │ ├── client.go │ ├── containers.go │ ├── cri.go │ ├── cri_test.go │ ├── images.go │ └── pods.go │ ├── ctxutil │ └── ctxutil.go │ ├── dashboard │ ├── apidata │ │ ├── apidata.go │ │ ├── data.go │ │ ├── diff.go │ │ ├── node.go │ │ └── source.go │ ├── components │ │ ├── components.go │ │ ├── diagnostics.go │ │ ├── footer.go │ │ ├── gauges.go │ │ ├── graphs.go │ │ ├── header.go │ │ ├── horizontalline.go │ │ ├── info.go │ │ ├── kubernetesinfo.go │ │ ├── logviewer.go │ │ ├── networkinfo.go │ │ ├── sparklines.go │ │ ├── tables.go │ │ ├── tables_test.go │ │ ├── talosinfo.go │ │ └── termui.go │ ├── configurl.go │ ├── context.go │ ├── dashboard.go │ ├── formdata.go │ ├── formdata_test.go │ ├── logdata │ │ └── logdata.go │ ├── monitor.go │ ├── networkconfig.go │ ├── options.go │ ├── resolver │ │ └── resolver.go │ ├── resourcedata │ │ └── resourcedata.go │ ├── summary.go │ └── util │ │ └── util.go │ ├── discovery │ └── registry │ │ ├── kubernetes.go │ │ ├── kubernetes_test.go │ │ └── registry.go │ ├── dns │ ├── dns.go │ ├── dns_test.go │ ├── manager.go │ └── runnner.go │ ├── encryption │ ├── encryption.go │ ├── encryption_test.go │ ├── helpers │ │ └── helpers.go │ ├── keys │ │ ├── keys.go │ │ ├── kms.go │ │ ├── nodeid.go │ │ ├── options.go │ │ ├── static.go │ │ ├── token.go │ │ └── tpm2.go │ └── node_params.go │ ├── endpoint │ ├── endpoint.go │ └── endpoint_test.go │ ├── environment │ ├── environment.go │ └── environment_test.go │ ├── etcd │ ├── certs.go │ ├── endpoints.go │ ├── etcd.go │ ├── local.go │ └── lock.go │ ├── extensions │ ├── compress.go │ ├── discarder.go │ ├── extensions.go │ ├── extensions_test.go │ ├── kernel_modules.go │ ├── list.go │ ├── list_test.go │ ├── pull.go │ └── testdata │ │ └── good │ │ └── extension1 │ │ ├── manifest.yaml │ │ └── rootfs │ │ ├── lib │ │ └── firmware │ │ │ └── amd │ │ │ └── cpu │ │ ├── lib64 │ │ └── ld-linux-x86-64.so.2 │ │ └── usr │ │ └── local │ │ └── lib │ │ ├── a.so │ │ └── a.so.1 │ ├── install │ ├── install.go │ ├── options.go │ └── pull.go │ ├── logind │ ├── broker.go │ ├── dbus.go │ ├── kubelet_mock_test.go │ ├── logind.go │ ├── logind_test.go │ └── service.go │ ├── meta │ ├── internal │ │ └── adv │ │ │ ├── adv.go │ │ │ ├── syslinux │ │ │ ├── syslinux.go │ │ │ ├── syslinux_test.go │ │ │ └── testdata │ │ │ │ └── adv.sys │ │ │ └── talos │ │ │ ├── talos.go │ │ │ └── talos_test.go │ ├── meta.go │ └── meta_test.go │ ├── miniprocfs │ ├── miniprocfs.go │ ├── processes.go │ ├── processes_test.go │ └── testdata │ │ ├── 1920080 │ │ ├── cmdline │ │ ├── comm │ │ ├── exe │ │ └── stat │ │ ├── 3731034 │ │ ├── cmdline │ │ ├── comm │ │ ├── exe │ │ └── stat │ │ ├── keys │ │ └── kmsg │ ├── mount │ ├── switchroot │ │ ├── switchroot.go │ │ └── switchroot_test.go │ ├── system.go │ └── v2 │ │ ├── all.go │ │ ├── cgroups.go │ │ ├── mount.go │ │ ├── overlay.go │ │ ├── points.go │ │ ├── pseudo.go │ │ ├── repair.go │ │ ├── repair_test.go │ │ ├── squashfs.go │ │ └── unmount.go │ ├── ntp │ ├── consts.go │ ├── interfaces.go │ ├── internal │ │ └── spike │ │ │ ├── spike.go │ │ │ └── spike_test.go │ ├── ntp.go │ └── ntp_test.go │ ├── partition │ ├── constants.go │ ├── format.go │ ├── partition.go │ └── wipe.go │ ├── pcap │ └── pcap.go │ ├── pci │ ├── pci.go │ └── sysfs.go │ ├── secureboot │ ├── database │ │ ├── certs │ │ │ ├── db │ │ │ │ ├── MicCorUEFCA2011_2011-06-27.der │ │ │ │ ├── microsoft option rom uefi ca 2023.der │ │ │ │ └── microsoft uefi ca 2023.der │ │ │ └── kek │ │ │ │ ├── MicCorKEKCA2011_2011-06-24.der │ │ │ │ └── microsoft corporation kek 2k ca 2023.der │ │ └── database.go │ ├── measure │ │ ├── internal │ │ │ └── pcr │ │ │ │ ├── bank_data.go │ │ │ │ ├── bank_data_test.go │ │ │ │ ├── extend.go │ │ │ │ ├── extend_test.go │ │ │ │ ├── sign.go │ │ │ │ ├── sign_test.go │ │ │ │ └── testdata │ │ │ │ ├── a │ │ │ │ ├── b │ │ │ │ └── c │ │ ├── measure.go │ │ ├── measure_test.go │ │ └── testdata │ │ │ └── pcr-signing-key.pem │ ├── pesign │ │ ├── pesign.go │ │ ├── pesign_test.go │ │ └── testdata │ │ │ └── systemd-bootx64.efi │ ├── secureboot.go │ ├── tpm2 │ │ ├── keys.go │ │ ├── pcr.go │ │ ├── pcr_test.go │ │ ├── policy.go │ │ ├── policy_test.go │ │ ├── seal.go │ │ ├── signature.go │ │ ├── testdata │ │ │ └── pcr-signing-crt.pem │ │ ├── tpm2.go │ │ └── unseal.go │ └── uki │ │ ├── assemble.go │ │ ├── generate.go │ │ ├── kernel.go │ │ ├── kernel_test.go │ │ ├── sbat.go │ │ ├── sbat_test.go │ │ ├── testdata │ │ └── kernel │ │ └── uki.go │ ├── selinux │ ├── policy │ │ ├── file_contexts │ │ ├── policy.33 │ │ └── selinux │ │ │ ├── common │ │ │ ├── classmaps.cil │ │ │ ├── files.cil │ │ │ ├── network.cil │ │ │ └── typeattributes.cil │ │ │ ├── immutable │ │ │ ├── classes.cil │ │ │ ├── fs.cil │ │ │ ├── preamble.cil │ │ │ ├── roles.cil │ │ │ └── sids.cil │ │ │ └── services │ │ │ ├── cri.cil │ │ │ ├── dashboard.cil │ │ │ ├── kubelet.cil │ │ │ ├── machined.cil │ │ │ ├── selinux.cil │ │ │ ├── system-containerd.cil │ │ │ ├── system-containers.cil │ │ │ └── udev.cil │ └── selinux.go │ ├── smbios │ └── smbios.go │ ├── timex │ └── timex.go │ ├── toml │ ├── merge.go │ ├── merge_test.go │ ├── testdata │ │ ├── 1.toml │ │ ├── 2.toml │ │ ├── 3.toml │ │ └── expected.toml │ └── toml.go │ └── zboot │ └── zboot.go ├── main.go ├── pkg ├── commands │ ├── apply.go │ ├── imported_bootstrap.go │ ├── imported_containers.go │ ├── imported_copy.go │ ├── imported_dashboard.go │ ├── imported_disks.go │ ├── imported_diskusage.go │ ├── imported_dmesg.go │ ├── imported_edit.go │ ├── imported_etcd.go │ ├── imported_events.go │ ├── imported_get.go │ ├── imported_health.go │ ├── imported_image.go │ ├── imported_kubeconfig.go │ ├── imported_list.go │ ├── imported_logs.go │ ├── imported_memory.go │ ├── imported_meta.go │ ├── imported_mounts.go │ ├── imported_netstat.go │ ├── imported_pcap.go │ ├── imported_processes.go │ ├── imported_read.go │ ├── imported_reboot.go │ ├── imported_reset.go │ ├── imported_restart.go │ ├── imported_rollback.go │ ├── imported_root.go │ ├── imported_rotate-ca.go │ ├── imported_service.go │ ├── imported_shutdown.go │ ├── imported_stats.go │ ├── imported_support.go │ ├── imported_time.go │ ├── imported_version.go │ ├── imported_wipe.go │ ├── init.go │ ├── root.go │ ├── template.go │ ├── track.go │ └── upgrade.go ├── engine │ ├── engine.go │ └── helm │ │ ├── doc.go │ │ ├── engine.go │ │ ├── engine_test.go │ │ ├── files.go │ │ ├── files_test.go │ │ ├── funcs.go │ │ └── funcs_test.go ├── generated │ └── presets.go ├── modeline │ ├── modeline.go │ └── modeline_test.go └── yamltools │ └── yamltools.go └── tools ├── generate_presets.go └── import_commands.go /.github/workflows/generate.yml: -------------------------------------------------------------------------------- 1 | name: Check go generate no changes 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | go-generate-check: 13 | name: Check if go generate changes any files 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Checkout code 18 | uses: actions/checkout@v3 19 | 20 | - name: Set up Go 21 | uses: actions/setup-go@v3 22 | with: 23 | go-version: stable 24 | 25 | - name: Run go generate 26 | run: go generate ./... 27 | 28 | - name: Check for uncommitted changes 29 | run: | 30 | if [ -n "$(git status --porcelain)" ]; then 31 | echo "Error: Files were changed after running 'go generate'" 32 | git status 33 | exit 1 34 | else 35 | echo "Success: No changes detected" 36 | fi 37 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: goreleaser 2 | 3 | on: 4 | pull_request: 5 | push: 6 | tags: 7 | - "v*.*.*" 8 | 9 | permissions: 10 | contents: write 11 | 12 | jobs: 13 | goreleaser: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 0 20 | - name: Set up Go 21 | uses: actions/setup-go@v5 22 | with: 23 | go-version: stable 24 | - name: Run GoReleaser 25 | uses: goreleaser/goreleaser-action@v5 26 | with: 27 | # either 'goreleaser' (default) or 'goreleaser-pro' 28 | distribution: goreleaser 29 | # 'latest', 'nightly', or a semver 30 | version: latest 31 | args: release --clean 32 | env: 33 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 34 | -------------------------------------------------------------------------------- /.goreleaser.yaml: -------------------------------------------------------------------------------- 1 | # This is an example .goreleaser.yml file with some sensible defaults. 2 | # Make sure to check the documentation at https://goreleaser.com 3 | 4 | # The lines below are called `modelines`. See `:help modeline` 5 | # Feel free to remove those if you don't want/need to use them. 6 | # yaml-language-server: $schema=https://goreleaser.com/static/schema.json 7 | # vim: set ts=2 sw=2 tw=0 fo=cnqoj 8 | 9 | version: 1 10 | 11 | before: 12 | hooks: 13 | # You may remove this if you don't use go modules. 14 | - go mod tidy 15 | builds: 16 | - env: 17 | - CGO_ENABLED=0 18 | goos: 19 | - linux 20 | - windows 21 | - darwin 22 | ldflags: 23 | - -X main.Version={{.Version}} 24 | 25 | archives: 26 | - format: binary 27 | # this name template makes the OS and Arch compatible with the results of `uname`. 28 | name_template: >- 29 | {{ .ProjectName }}- 30 | {{- tolower (title .Os) }}- 31 | {{- if eq .Arch "386" }}i386 32 | {{- else }}{{ .Arch }}{{ end }} 33 | {{- if .Arm }}v{{ .Arm }}{{ end }} 34 | 35 | changelog: 36 | sort: asc 37 | filters: 38 | exclude: 39 | - "^docs:" 40 | - "^test:" 41 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | VERSION=$(shell git describe --tags) 2 | TALOS_VERSION=$(shell go list -m github.com/siderolabs/talos | awk '{sub(/^v/, "", $$NF); print $$NF}') 3 | 4 | generate: 5 | go generate 6 | 7 | build: 8 | go build -ldflags="-X 'main.Version=$(VERSION)'" 9 | 10 | import: import-internal import-commands 11 | 12 | import-commands: 13 | go run tools/import_commands.go --talos-version v$(TALOS_VERSION) \ 14 | bootstrap \ 15 | containers \ 16 | dashboard \ 17 | disks \ 18 | dmesg \ 19 | events \ 20 | get \ 21 | health \ 22 | image \ 23 | kubeconfig \ 24 | list \ 25 | logs \ 26 | memory \ 27 | mounts \ 28 | netstat \ 29 | pcap \ 30 | processes \ 31 | read \ 32 | reboot \ 33 | reset \ 34 | restart \ 35 | rollback \ 36 | service \ 37 | shutdown \ 38 | stats \ 39 | time \ 40 | copy \ 41 | meta \ 42 | edit \ 43 | rollback \ 44 | rotate-ca \ 45 | support \ 46 | wipe \ 47 | diskusage \ 48 | version 49 | 50 | import-internal: 51 | rm -rf internal/pkg internal/app 52 | wget -O- https://github.com/siderolabs/talos/archive/refs/tags/v$(TALOS_VERSION).tar.gz | tar --strip=1 -xzf- \ 53 | talos-$(TALOS_VERSION)/internal/app \ 54 | talos-$(TALOS_VERSION)/internal/pkg 55 | rm -rf internal/app/init/ internal/pkg/rng/ internal/pkg/tui/ 56 | sed -i 's|github.com/siderolabs/talos/internal|github.com/cozystack/talm/internal|g' `grep -rl 'github.com/siderolabs/talos/internal' internal` 57 | -------------------------------------------------------------------------------- /charts/cozystack/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: cozystack 3 | type: application 4 | version: 0.1.0 5 | globalOptions: 6 | talosconfig: "talosconfig" 7 | templateOptions: 8 | offline: false 9 | valueFiles: [] 10 | values: [] 11 | stringValues: [] 12 | fileValues: [] 13 | jsonValues: [] 14 | literalValues: [] 15 | talosVersion: "v1.9" 16 | withSecrets: "secrets.yaml" 17 | kubernetesVersion: "" 18 | full: false 19 | applyOptions: 20 | preserve: false 21 | timeout: "1m" 22 | certFingerprints: [] 23 | upgradeOptions: 24 | preserve: false 25 | stage: false 26 | force: false 27 | -------------------------------------------------------------------------------- /charts/cozystack/charts/talm: -------------------------------------------------------------------------------- 1 | ../../talm -------------------------------------------------------------------------------- /charts/cozystack/templates/controlplane.yaml: -------------------------------------------------------------------------------- 1 | {{- $_ := set . "MachineType" "controlplane" -}} 2 | {{- include "talos.config" . }} 3 | -------------------------------------------------------------------------------- /charts/cozystack/templates/worker.yaml: -------------------------------------------------------------------------------- 1 | {{- $_ := set . "MachineType" "worker" -}} 2 | {{- include "talos.config" . }} 3 | -------------------------------------------------------------------------------- /charts/cozystack/values.yaml: -------------------------------------------------------------------------------- 1 | endpoint: "https://192.168.100.10:6443" 2 | clusterDomain: cozy.local 3 | floatingIP: 192.168.100.10 4 | image: "ghcr.io/cozystack/cozystack/talos:v1.9.5" 5 | podSubnets: 6 | - 10.244.0.0/16 7 | serviceSubnets: 8 | - 10.96.0.0/16 9 | advertisedSubnets: 10 | - 192.168.100.0/24 11 | oidcIssuerUrl: "" 12 | certSANs: [] 13 | -------------------------------------------------------------------------------- /charts/generic/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: generic 3 | type: application 4 | version: 0.1.0 5 | globalOptions: 6 | talosconfig: "talosconfig" 7 | templateOptions: 8 | offline: false 9 | valueFiles: [] 10 | values: [] 11 | stringValues: [] 12 | fileValues: [] 13 | jsonValues: [] 14 | literalValues: [] 15 | talosVersion: "" 16 | withSecrets: "secrets.yaml" 17 | kubernetesVersion: "" 18 | full: false 19 | applyOptions: 20 | preserve: false 21 | timeout: "1m" 22 | certFingerprints: [] 23 | upgradeOptions: 24 | preserve: false 25 | stage: false 26 | force: false 27 | -------------------------------------------------------------------------------- /charts/generic/charts/talm: -------------------------------------------------------------------------------- 1 | ../../talm -------------------------------------------------------------------------------- /charts/generic/templates/controlplane.yaml: -------------------------------------------------------------------------------- 1 | {{- $_ := set . "MachineType" "controlplane" -}} 2 | {{- include "talos.config" . }} 3 | -------------------------------------------------------------------------------- /charts/generic/templates/worker.yaml: -------------------------------------------------------------------------------- 1 | {{- $_ := set . "MachineType" "worker" -}} 2 | {{- include "talos.config" . }} 3 | -------------------------------------------------------------------------------- /charts/generic/values.yaml: -------------------------------------------------------------------------------- 1 | endpoint: "https://192.168.100.10:6443" 2 | podSubnets: 3 | - 10.244.0.0/16 4 | serviceSubnets: 5 | - 10.96.0.0/16 6 | advertisedSubnets: 7 | - 192.168.100.0/24 8 | certSANs: [] 9 | -------------------------------------------------------------------------------- /charts/talm/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | type: library 3 | name: talm 4 | version: 0.1.0 5 | description: A library Talm chart for Talos Linux 6 | -------------------------------------------------------------------------------- /internal/app/apid/pkg/backend/backend.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package backend implements backends satisfying proxy.Backend interface 6 | package backend 7 | -------------------------------------------------------------------------------- /internal/app/apid/pkg/director/mocks_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package director_test 6 | 7 | import ( 8 | "context" 9 | 10 | "github.com/siderolabs/grpc-proxy/proxy" 11 | "google.golang.org/grpc" 12 | ) 13 | 14 | type mockBackend struct { 15 | target string 16 | } 17 | 18 | func (m *mockBackend) String() string { 19 | return m.target 20 | } 21 | 22 | func (m *mockBackend) GetConnection(ctx context.Context, fullMethodName string) (context.Context, *grpc.ClientConn, error) { 23 | return ctx, nil, nil 24 | } 25 | 26 | func (m *mockBackend) AppendInfo(streaming bool, resp []byte) ([]byte, error) { 27 | return resp, nil 28 | } 29 | 30 | func (m *mockBackend) BuildError(streaming bool, err error) ([]byte, error) { 31 | return nil, nil 32 | } 33 | 34 | func mockBackendFactory(target string) (proxy.Backend, error) { 35 | return &mockBackend{target: target}, nil 36 | } 37 | 38 | type mockLocalAddressProvider struct { 39 | local map[string]struct{} 40 | } 41 | 42 | func (m *mockLocalAddressProvider) IsLocalTarget(t string) bool { 43 | _, ok := m.local[t] 44 | 45 | return ok 46 | } 47 | -------------------------------------------------------------------------------- /internal/app/apid/pkg/provider/provider_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package provider_test 6 | 7 | import "testing" 8 | 9 | func TestEmpty(t *testing.T) { 10 | // added for accurate coverage estimation 11 | // 12 | // please remove it once any unit-test is added 13 | // for this package 14 | } 15 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/cluster/cluster.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package cluster implements adapters wrapping resources/cluster to provide additional functionality. 6 | package cluster 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/cluster/identity.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package cluster 6 | 7 | import ( 8 | "crypto/rand" 9 | "encoding/hex" 10 | "io" 11 | 12 | "github.com/jxskiss/base62" 13 | 14 | "github.com/siderolabs/talos/pkg/machinery/constants" 15 | "github.com/siderolabs/talos/pkg/machinery/resources/cluster" 16 | ) 17 | 18 | // IdentitySpec adapter provides identity generation. 19 | // 20 | //nolint:revive,golint 21 | func IdentitySpec(r *cluster.IdentitySpec) identity { 22 | return identity{ 23 | IdentitySpec: r, 24 | } 25 | } 26 | 27 | type identity struct { 28 | *cluster.IdentitySpec 29 | } 30 | 31 | // Generate new identity. 32 | func (a identity) Generate() error { 33 | buf := make([]byte, constants.DefaultNodeIdentitySize) 34 | 35 | if _, err := io.ReadFull(rand.Reader, buf); err != nil { 36 | return err 37 | } 38 | 39 | a.IdentitySpec.NodeID = base62.EncodeToString(buf) 40 | 41 | return nil 42 | } 43 | 44 | // ConvertMachineID returns /etc/machine-id compatible representation. 45 | func (a identity) ConvertMachineID() ([]byte, error) { 46 | raw, err := base62.DecodeString(a.IdentitySpec.NodeID) 47 | if err != nil { 48 | return nil, err 49 | } 50 | 51 | buf := make([]byte, 32) 52 | hex.Encode(buf, raw[:16]) 53 | 54 | return buf, nil 55 | } 56 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/cluster/identity_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package cluster_test 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/stretchr/testify/assert" 11 | "github.com/stretchr/testify/require" 12 | 13 | clusteradapter "github.com/cozystack/talm/internal/app/machined/pkg/adapters/cluster" 14 | "github.com/siderolabs/talos/pkg/machinery/resources/cluster" 15 | ) 16 | 17 | func TestIdentityGenerate(t *testing.T) { 18 | var spec1, spec2 cluster.IdentitySpec 19 | 20 | require.NoError(t, clusteradapter.IdentitySpec(&spec1).Generate()) 21 | require.NoError(t, clusteradapter.IdentitySpec(&spec2).Generate()) 22 | 23 | assert.NotEqual(t, spec1, spec2) 24 | 25 | length := len(spec1.NodeID) 26 | 27 | assert.GreaterOrEqual(t, length, 43) 28 | assert.LessOrEqual(t, length, 45) 29 | } 30 | 31 | func TestIdentityConvertMachineID(t *testing.T) { 32 | spec := cluster.IdentitySpec{ 33 | NodeID: "sou7yy34ykX3n373Zw1DXKb8zD7UnyKT6HT3QDsGH6L", 34 | } 35 | 36 | machineID, err := clusteradapter.IdentitySpec(&spec).ConvertMachineID() 37 | require.NoError(t, err) 38 | 39 | assert.Equal(t, "be871ac0d0dd31fa4caca753b0f3f1b2", string(machineID)) 40 | } 41 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/hardware/hardware.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package hardware implements adapters wrapping resources/hardware to provide additional functionality. 6 | package hardware 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/hardware/system_information.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package hardware 6 | 7 | import ( 8 | "github.com/siderolabs/go-smbios/smbios" 9 | 10 | "github.com/siderolabs/talos/pkg/machinery/resources/hardware" 11 | ) 12 | 13 | // SystemInformation adapter provider conversion from smbios.SMBIOS. 14 | // 15 | //nolint:revive,golint 16 | func SystemInformation(p *hardware.SystemInformation) systemInformation { 17 | return systemInformation{ 18 | SystemInformation: p, 19 | } 20 | } 21 | 22 | type systemInformation struct { 23 | *hardware.SystemInformation 24 | } 25 | 26 | // Update current systemInformation info. 27 | func (p systemInformation) Update(systemInformation *smbios.SystemInformation, uuidRewrite string) { 28 | if uuidRewrite == "" { 29 | uuidRewrite = systemInformation.UUID 30 | } 31 | 32 | *p.SystemInformation.TypedSpec() = hardware.SystemInformationSpec{ 33 | Manufacturer: systemInformation.Manufacturer, 34 | ProductName: systemInformation.ProductName, 35 | Version: systemInformation.Version, 36 | SerialNumber: systemInformation.SerialNumber, 37 | UUID: uuidRewrite, 38 | WakeUpType: systemInformation.WakeUpType.String(), 39 | SKUNumber: systemInformation.SKUNumber, 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/k8s/k8s.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package k8s implements adapters wrapping resources/k8s to provide additional functionality. 6 | package k8s 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/k8s/static_pod.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package k8s 6 | 7 | import ( 8 | "encoding/json" 9 | 10 | v1 "k8s.io/api/core/v1" 11 | 12 | "github.com/siderolabs/talos/pkg/machinery/resources/k8s" 13 | ) 14 | 15 | // StaticPod adapter provides conversion from *v1.Pod. 16 | // 17 | //nolint:revive,golint 18 | func StaticPod(r *k8s.StaticPod) staticPod { 19 | return staticPod{ 20 | StaticPod: r, 21 | } 22 | } 23 | 24 | type staticPod struct { 25 | *k8s.StaticPod 26 | } 27 | 28 | // Pod returns native Kubernetes resource. 29 | func (a staticPod) Pod() (*v1.Pod, error) { 30 | var spec v1.Pod 31 | 32 | jsonSerialized, err := json.Marshal(a.StaticPod.TypedSpec().Pod) 33 | if err != nil { 34 | return nil, err 35 | } 36 | 37 | err = json.Unmarshal(jsonSerialized, &spec) 38 | 39 | return &spec, err 40 | } 41 | 42 | // SetPod sets spec from native Kubernetes resource. 43 | func (a staticPod) SetPod(podSpec *v1.Pod) error { 44 | jsonSerialized, err := json.Marshal(podSpec) 45 | if err != nil { 46 | return err 47 | } 48 | 49 | a.StaticPod.TypedSpec().Pod = map[string]any{} 50 | 51 | return json.Unmarshal(jsonSerialized, &a.StaticPod.TypedSpec().Pod) 52 | } 53 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/k8s/static_pod_status.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package k8s 6 | 7 | import ( 8 | "encoding/json" 9 | 10 | v1 "k8s.io/api/core/v1" 11 | 12 | "github.com/siderolabs/talos/pkg/machinery/resources/k8s" 13 | ) 14 | 15 | // StaticPodStatus adapter provides conversion from *v1.PodStatus. 16 | // 17 | //nolint:revive,golint 18 | func StaticPodStatus(r *k8s.StaticPodStatus) staticPodStatus { 19 | return staticPodStatus{ 20 | StaticPodStatus: r, 21 | } 22 | } 23 | 24 | type staticPodStatus struct { 25 | *k8s.StaticPodStatus 26 | } 27 | 28 | // SetStatus sets status from native Kubernetes resource. 29 | func (a staticPodStatus) SetStatus(status *v1.PodStatus) error { 30 | jsonSerialized, err := json.Marshal(status) 31 | if err != nil { 32 | return err 33 | } 34 | 35 | a.StaticPodStatus.TypedSpec().PodStatus = map[string]any{} 36 | 37 | return json.Unmarshal(jsonSerialized, &a.StaticPodStatus.TypedSpec().PodStatus) 38 | } 39 | 40 | // Status gets status from native Kubernetes resource. 41 | func (a staticPodStatus) Status() (*v1.PodStatus, error) { 42 | var spec v1.PodStatus 43 | 44 | jsonSerialized, err := json.Marshal(a.StaticPodStatus.TypedSpec().PodStatus) 45 | if err != nil { 46 | return nil, err 47 | } 48 | 49 | err = json.Unmarshal(jsonSerialized, &spec) 50 | 51 | return &spec, err 52 | } 53 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/k8s/testdata/list.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | items: 3 | - apiVersion: rbac.authorization.k8s.io/v1 4 | kind: ClusterRoleBinding 5 | metadata: 6 | name: system:cloud-node-controller 7 | roleRef: 8 | apiGroup: rbac.authorization.k8s.io 9 | kind: ClusterRole 10 | name: system:cloud-node-controller 11 | subjects: 12 | - kind: ServiceAccount 13 | name: cloud-node-controller 14 | namespace: kube-system 15 | - apiVersion: rbac.authorization.k8s.io/v1 16 | kind: ClusterRoleBinding 17 | metadata: 18 | name: system:cloud-controller-manager 19 | roleRef: 20 | apiGroup: rbac.authorization.k8s.io 21 | kind: ClusterRole 22 | name: system:cloud-controller-manager 23 | subjects: 24 | - kind: ServiceAccount 25 | name: cloud-controller-manager 26 | namespace: kube-system 27 | kind: List 28 | metadata: {} 29 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/kubespan/identity_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package kubespan_test 6 | 7 | import ( 8 | "net" 9 | "testing" 10 | 11 | "github.com/stretchr/testify/assert" 12 | "github.com/stretchr/testify/require" 13 | 14 | kubespanadapter "github.com/cozystack/talm/internal/app/machined/pkg/adapters/kubespan" 15 | "github.com/siderolabs/talos/pkg/machinery/resources/kubespan" 16 | ) 17 | 18 | func TestIdentityGenerateKey(t *testing.T) { 19 | var spec kubespan.IdentitySpec 20 | 21 | assert.NoError(t, kubespanadapter.IdentitySpec(&spec).GenerateKey()) 22 | } 23 | 24 | func TestIdentityUpdateAddress(t *testing.T) { 25 | var spec kubespan.IdentitySpec 26 | 27 | mac, err := net.ParseMAC("2e:1a:b6:53:81:69") 28 | require.NoError(t, err) 29 | 30 | assert.NoError(t, kubespanadapter.IdentitySpec(&spec).UpdateAddress("8XuV9TZHW08DOk3bVxQjH9ih_TBKjnh-j44tsCLSBzo=", mac)) 31 | 32 | assert.Equal(t, "fd7f:175a:b97c:5602:2c1a:b6ff:fe53:8169/128", spec.Address.String()) 33 | assert.Equal(t, "fd7f:175a:b97c:5602::/64", spec.Subnet.String()) 34 | } 35 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/kubespan/kubespan.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package kubespan implements adapters wrapping resources/kubespan to provide additional functionality. 6 | package kubespan 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/network/bond_master_spec_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package network_test 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/stretchr/testify/require" 11 | 12 | networkadapter "github.com/cozystack/talm/internal/app/machined/pkg/adapters/network" 13 | "github.com/siderolabs/talos/pkg/machinery/nethelpers" 14 | "github.com/siderolabs/talos/pkg/machinery/resources/network" 15 | ) 16 | 17 | func TestBondMasterSpec(t *testing.T) { 18 | spec := network.BondMasterSpec{ 19 | Mode: nethelpers.BondModeActiveBackup, 20 | MIIMon: 100, 21 | UpDelay: 200, 22 | DownDelay: 300, 23 | } 24 | 25 | b, err := networkadapter.BondMasterSpec(&spec).Encode() 26 | require.NoError(t, err) 27 | 28 | var decodedSpec network.BondMasterSpec 29 | 30 | require.NoError(t, networkadapter.BondMasterSpec(&decodedSpec).Decode(b)) 31 | 32 | require.Equal(t, spec, decodedSpec) 33 | } 34 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/network/bridge_master_spec_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package network_test 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/stretchr/testify/require" 11 | 12 | networkadapter "github.com/cozystack/talm/internal/app/machined/pkg/adapters/network" 13 | "github.com/siderolabs/talos/pkg/machinery/resources/network" 14 | ) 15 | 16 | func TestBridgeMasterSpec(t *testing.T) { 17 | spec := network.BridgeMasterSpec{ 18 | STP: network.STPSpec{ 19 | Enabled: true, 20 | }, 21 | VLAN: network.BridgeVLANSpec{ 22 | FilteringEnabled: true, 23 | }, 24 | } 25 | 26 | b, err := networkadapter.BridgeMasterSpec(&spec).Encode() 27 | require.NoError(t, err) 28 | 29 | var decodedSpec network.BridgeMasterSpec 30 | 31 | require.NoError(t, networkadapter.BridgeMasterSpec(&decodedSpec).Decode(b)) 32 | 33 | require.Equal(t, spec, decodedSpec) 34 | } 35 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/network/ipset.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package network 6 | 7 | import ( 8 | "net/netip" 9 | 10 | "go4.org/netipx" 11 | ) 12 | 13 | // BuildIPSet builds an IPSet from the given include and exclude prefixes. 14 | func BuildIPSet(include, exclude []netip.Prefix) (*netipx.IPSet, error) { 15 | var builder netipx.IPSetBuilder 16 | 17 | for _, pfx := range include { 18 | builder.AddPrefix(pfx) 19 | } 20 | 21 | for _, pfx := range exclude { 22 | builder.RemovePrefix(pfx) 23 | } 24 | 25 | return builder.IPSet() 26 | } 27 | 28 | // SplitIPSet splits the given IPSet into IPv4 and IPv6 ranges. 29 | func SplitIPSet(set *netipx.IPSet) (ipv4, ipv6 []netipx.IPRange) { 30 | for _, rng := range set.Ranges() { 31 | if rng.From().Is4() { 32 | ipv4 = append(ipv4, rng) 33 | } else { 34 | ipv6 = append(ipv6, rng) 35 | } 36 | } 37 | 38 | return 39 | } 40 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/network/network.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package network implements adapters wrapping resources/network to provide additional functionality. 6 | package network 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/network/vlan_spec_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package network_test 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/stretchr/testify/require" 11 | 12 | networkadapter "github.com/cozystack/talm/internal/app/machined/pkg/adapters/network" 13 | "github.com/siderolabs/talos/pkg/machinery/nethelpers" 14 | "github.com/siderolabs/talos/pkg/machinery/resources/network" 15 | ) 16 | 17 | func TestVLANSpec(t *testing.T) { 18 | spec := network.VLANSpec{ 19 | VID: 25, 20 | Protocol: nethelpers.VLANProtocol8021AD, 21 | } 22 | 23 | b, err := networkadapter.VLANSpec(&spec).Encode() 24 | require.NoError(t, err) 25 | 26 | var decodedSpec network.VLANSpec 27 | 28 | require.NoError(t, networkadapter.VLANSpec(&decodedSpec).Decode(b)) 29 | 30 | require.Equal(t, spec, decodedSpec) 31 | } 32 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/perf/perf.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package perf implements adapters wrapping resources/perf to provide additional functionality. 6 | package perf 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/adapters/wireguard/wireguard.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package wireguard implements common wireguard functionality. 6 | package wireguard 7 | 8 | import "time" 9 | 10 | // PeerDownInterval is the time since last handshake when established peer is considered to be down. 11 | // 12 | // WG whitepaper defines a downed peer as being: 13 | // Handshake Timeout (180s) + Rekey Timeout (5s) + Rekey Attempt Timeout (90s) 14 | // 15 | // This interval is applied when the link is already established. 16 | const PeerDownInterval = (180 + 5 + 90) * time.Second 17 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/block/block.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package block provides the controllers related to blockdevices, mounts, etc. 6 | package block 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/block/devices_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package block_test 6 | 7 | import ( 8 | "os" 9 | "testing" 10 | 11 | "github.com/cosi-project/runtime/pkg/resource/rtestutils" 12 | "github.com/stretchr/testify/assert" 13 | "github.com/stretchr/testify/suite" 14 | 15 | blockctrls "github.com/cozystack/talm/internal/app/machined/pkg/controllers/block" 16 | "github.com/cozystack/talm/internal/app/machined/pkg/controllers/ctest" 17 | "github.com/siderolabs/talos/pkg/machinery/resources/block" 18 | ) 19 | 20 | type DevicesSuite struct { 21 | ctest.DefaultSuite 22 | } 23 | 24 | func TestDevicesSuite(t *testing.T) { 25 | suite.Run(t, new(DevicesSuite)) 26 | } 27 | 28 | func (suite *DevicesSuite) TestDiscover() { 29 | if os.Geteuid() != 0 { 30 | suite.T().Skip("skipping test; must be root to use inotify") 31 | } 32 | 33 | suite.Require().NoError(suite.Runtime().RegisterController(&blockctrls.DevicesController{})) 34 | 35 | // these devices should always exist on Linux 36 | rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), []string{"loop0", "loop1"}, func(r *block.Device, assertions *assert.Assertions) { 37 | assertions.Equal("disk", r.TypedSpec().Type) 38 | }) 39 | } 40 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/block/internal/kobject/kobject_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package kobject_test 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/stretchr/testify/require" 11 | "go.uber.org/zap/zaptest" 12 | 13 | "github.com/cozystack/talm/internal/app/machined/pkg/controllers/block/internal/kobject" 14 | ) 15 | 16 | func TestWatcher(t *testing.T) { 17 | watcher, err := kobject.NewWatcher() 18 | require.NoError(t, err) 19 | 20 | evCh := watcher.Run(zaptest.NewLogger(t)) 21 | 22 | require.NoError(t, watcher.Close()) 23 | 24 | // the evCh should be closed 25 | for range evCh { //nolint:revive 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/block/internal/sysblock/sysblock_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package sysblock_test 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/mdlayher/kobject" 11 | "github.com/stretchr/testify/require" 12 | 13 | "github.com/cozystack/talm/internal/app/machined/pkg/controllers/block/internal/sysblock" 14 | ) 15 | 16 | func TestWalk(t *testing.T) { 17 | events, err := sysblock.Walk("/sys/block") 18 | require.NoError(t, err) 19 | 20 | require.NotEmpty(t, events) 21 | 22 | // there should be at least a single blockdevice and a partition 23 | partitions, disks := 0, 0 24 | 25 | for _, event := range events { 26 | require.Equal(t, "block", event.Subsystem) 27 | require.EqualValues(t, kobject.Add, event.Action) 28 | 29 | require.NotEmpty(t, event.DevicePath) 30 | require.NotEmpty(t, event.Action) 31 | 32 | switch event.Values["DEVTYPE"] { 33 | case "partition": 34 | partitions++ 35 | case "disk": 36 | disks++ 37 | } 38 | } 39 | 40 | require.Greater(t, partitions, 0) 41 | require.Greater(t, disks, 0) 42 | } 43 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/cluster/cluster.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package cluster provides controllers which manage Talos cluster resources. 6 | package cluster 7 | 8 | import ( 9 | "context" 10 | "fmt" 11 | 12 | "github.com/cosi-project/runtime/pkg/controller" 13 | "github.com/cosi-project/runtime/pkg/resource" 14 | "github.com/cosi-project/runtime/pkg/safe" 15 | 16 | "github.com/siderolabs/talos/pkg/machinery/resources/cluster" 17 | ) 18 | 19 | func cleanupAffiliates(ctx context.Context, ctrl controller.Controller, r controller.Runtime, touchedIDs map[resource.ID]struct{}) error { 20 | // list keys for cleanup 21 | list, err := safe.ReaderList[*cluster.Affiliate]( 22 | ctx, 23 | r, 24 | resource.NewMetadata(cluster.RawNamespaceName, cluster.AffiliateType, "", resource.VersionUndefined), 25 | ) 26 | if err != nil { 27 | return fmt.Errorf("error listing resources: %w", err) 28 | } 29 | 30 | for res := range list.All() { 31 | if res.Metadata().Owner() != ctrl.Name() { 32 | continue 33 | } 34 | 35 | if _, ok := touchedIDs[res.Metadata().ID()]; !ok { 36 | if err = r.Destroy(ctx, res.Metadata()); err != nil { 37 | return fmt.Errorf("error cleaning up specs: %w", err) 38 | } 39 | } 40 | } 41 | 42 | return nil 43 | } 44 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/config/config.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package config provides controllers which manage config resources. 6 | package config 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/cri/cri.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package cri provides CRI related controllers. 6 | package cri 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/cri/cri_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package cri_test 6 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/etcd/etcd.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package etcd provides controllers which manage etcd resources. 6 | package etcd 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/files/files.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package files provides controllers which manage file resources. 6 | package files 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/hardware/hardware.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package hardware provides the hardware controller implementation. 6 | package hardware 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/hardware/testdata/SuperMicro-Dual-Xeon.dmi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozystack/talm/10bbb87b0753245d283e1116128d2c968162e142/internal/app/machined/pkg/controllers/hardware/testdata/SuperMicro-Dual-Xeon.dmi -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/k8s/k8s.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package k8s provides controllers which manage Kubernetes resources. 6 | package k8s 7 | 8 | import ( 9 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 10 | ) 11 | 12 | func init() { 13 | // ugly hack, but it doesn't look like there's better API 14 | // cut out error handler which logs error to standard logger 15 | utilruntime.ErrorHandlers = utilruntime.ErrorHandlers[len(utilruntime.ErrorHandlers)-1:] //nolint:reassign 16 | } 17 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/k8s/templates/core-dns-svc-template.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: kube-dns 5 | namespace: kube-system 6 | annotations: 7 | prometheus.io/scrape: "true" 8 | prometheus.io/port: "9153" 9 | labels: 10 | k8s-app: kube-dns 11 | kubernetes.io/cluster-service: "true" 12 | kubernetes.io/name: "CoreDNS" 13 | spec: 14 | selector: 15 | k8s-app: kube-dns 16 | clusterIP: {{ or .DNSServiceIP .DNSServiceIPv6 }} 17 | clusterIPs: 18 | {{- if .DNSServiceIP }} 19 | - {{ .DNSServiceIP }} 20 | {{- end }} 21 | {{- if .DNSServiceIPv6 }} 22 | - {{ .DNSServiceIPv6 }} 23 | {{- end }} 24 | ipFamilies: 25 | {{- if .DNSServiceIP }} 26 | - IPv4 27 | {{- end }} 28 | {{- if .DNSServiceIPv6 }} 29 | - IPv6 30 | {{- end }} 31 | {{- if and .DNSServiceIP .DNSServiceIPv6 }} 32 | ipFamilyPolicy: RequireDualStack 33 | {{- else }} 34 | ipFamilyPolicy: SingleStack 35 | {{- end }} 36 | ports: 37 | - name: dns 38 | port: 53 39 | protocol: UDP 40 | - name: dns-tcp 41 | port: 53 42 | protocol: TCP 43 | - name: metrics 44 | port: 9153 45 | protocol: TCP 46 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/k8s/templates/csr-approver-role-binding-template.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: system-bootstrap-approve-node-client-csr 5 | subjects: 6 | - kind: Group 7 | name: system:bootstrappers:nodes 8 | apiGroup: rbac.authorization.k8s.io 9 | roleRef: 10 | kind: ClusterRole 11 | name: system:certificates.k8s.io:certificatesigningrequests:nodeclient 12 | apiGroup: rbac.authorization.k8s.io 13 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/k8s/templates/csr-node-bootstrap-template.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: system-bootstrap-node-bootstrapper 5 | subjects: 6 | - kind: Group 7 | name: system:bootstrappers:nodes 8 | apiGroup: rbac.authorization.k8s.io 9 | - kind: Group 10 | name: system:nodes 11 | apiGroup: rbac.authorization.k8s.io 12 | roleRef: 13 | kind: ClusterRole 14 | name: system:node-bootstrapper 15 | apiGroup: rbac.authorization.k8s.io 16 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/k8s/templates/csr-renewal-role-binding-template.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: system-bootstrap-node-renewal 5 | subjects: 6 | - kind: Group 7 | name: system:nodes 8 | apiGroup: rbac.authorization.k8s.io 9 | roleRef: 10 | kind: ClusterRole 11 | name: system:certificates.k8s.io:certificatesigningrequests:selfnodeclient 12 | apiGroup: rbac.authorization.k8s.io 13 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/k8s/templates/kube-config-in-cluster-template.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: kubeconfig-in-cluster 5 | namespace: kube-system 6 | data: 7 | kubeconfig: | 8 | apiVersion: v1 9 | clusters: 10 | - name: local 11 | cluster: 12 | server: {{ .Server }} 13 | certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt 14 | users: 15 | - name: service-account 16 | user: 17 | # Use service account token 18 | tokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token 19 | contexts: 20 | - context: 21 | cluster: local 22 | user: service-account 23 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/k8s/templates/kube-system-encryption-config-template.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: EncryptionConfig 3 | resources: 4 | - resources: 5 | - secrets 6 | providers: 7 | {{if .Root.SecretboxEncryptionSecret}} 8 | - secretbox: 9 | keys: 10 | - name: key2 11 | secret: {{ .Root.SecretboxEncryptionSecret }} 12 | {{end}} 13 | {{if .Root.AESCBCEncryptionSecret}} 14 | - aescbc: 15 | keys: 16 | - name: key1 17 | secret: {{ .Root.AESCBCEncryptionSecret }} 18 | {{end}} 19 | - identity: {} 20 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/k8s/templates/kubelet-bootstrapping-token-template.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: bootstrap-token-{{ .Secrets.BootstrapTokenID }} 5 | namespace: kube-system 6 | type: bootstrap.kubernetes.io/token 7 | stringData: 8 | token-id: "{{ .Secrets.BootstrapTokenID }}" 9 | token-secret: "{{ .Secrets.BootstrapTokenSecret }}" 10 | usage-bootstrap-authentication: "true" 11 | 12 | # Extra groups to authenticate the token as. Must start with "system:bootstrappers:" 13 | auth-extra-groups: system:bootstrappers:nodes 14 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/k8s/templates/pod-security-policy-template.yaml: -------------------------------------------------------------------------------- 1 | kind: ClusterRole 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | metadata: 4 | name: psp:privileged 5 | rules: 6 | - apiGroups: ['policy'] 7 | resources: ['podsecuritypolicies'] 8 | verbs: ['use'] 9 | resourceNames: 10 | - privileged 11 | --- 12 | kind: ClusterRoleBinding 13 | apiVersion: rbac.authorization.k8s.io/v1 14 | metadata: 15 | name: psp:privileged 16 | roleRef: 17 | kind: ClusterRole 18 | name: psp:privileged 19 | apiGroup: rbac.authorization.k8s.io 20 | subjects: 21 | # Authorize all service accounts in a namespace: 22 | - kind: Group 23 | apiGroup: rbac.authorization.k8s.io 24 | name: system:serviceaccounts 25 | # Authorize all authenticated users in a namespace: 26 | - kind: Group 27 | apiGroup: rbac.authorization.k8s.io 28 | name: system:authenticated 29 | --- 30 | apiVersion: policy/v1beta1 31 | kind: PodSecurityPolicy 32 | metadata: 33 | name: privileged 34 | annotations: 35 | seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' 36 | spec: 37 | fsGroup: 38 | rule: RunAsAny 39 | privileged: true 40 | runAsUser: 41 | rule: RunAsAny 42 | seLinux: 43 | rule: RunAsAny 44 | supplementalGroups: 45 | rule: RunAsAny 46 | volumes: 47 | - '*' 48 | allowedCapabilities: 49 | - '*' 50 | hostPID: true 51 | hostIPC: true 52 | hostNetwork: true 53 | hostPorts: 54 | - min: 1 55 | max: 65536 56 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/k8s/templates/talos-api-service-template.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | component: apid 6 | provider: talos 7 | name: {{ .KubernetesTalosAPIServiceName }} 8 | namespace: {{ .KubernetesTalosAPIServiceNamespace }} 9 | spec: 10 | ports: 11 | - name: apid 12 | port: {{ .ApidPort }} 13 | protocol: TCP 14 | targetPort: {{ .ApidPort }} 15 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/k8s/templates/talos-service-account-crd-template.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | name: {{ .TalosServiceAccount.ResourcePlural }}.{{ .TalosServiceAccount.Group }} 5 | spec: 6 | conversion: 7 | strategy: None 8 | group: {{ .TalosServiceAccount.Group }} 9 | names: 10 | kind: {{ .TalosServiceAccount.Kind }} 11 | listKind: {{ .TalosServiceAccount.Kind }}List 12 | plural: {{ .TalosServiceAccount.ResourcePlural }} 13 | singular: {{ .TalosServiceAccount.ResourceSingular }} 14 | shortNames: 15 | - {{ .TalosServiceAccount.ShortName }} 16 | scope: Namespaced 17 | versions: 18 | - name: {{ .TalosServiceAccount.Version }} 19 | schema: 20 | openAPIV3Schema: 21 | properties: 22 | spec: 23 | type: object 24 | properties: 25 | roles: 26 | type: array 27 | items: 28 | type: string 29 | status: 30 | type: object 31 | properties: 32 | failureReason: 33 | type: string 34 | type: object 35 | served: true 36 | storage: true 37 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/kubeaccess/kubeaccess.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package kubeaccess provides controllers which manage Talos API access from Kubernetes workloads. 6 | package kubeaccess 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/kubespan/kubespan.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package kubespan provides controllers which manage Talos KubeSpan feature. 6 | package kubespan 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/kubespan/routing_rules_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | package kubespan_test 5 | 6 | import ( 7 | "os" 8 | "testing" 9 | 10 | "github.com/stretchr/testify/assert" 11 | 12 | "github.com/cozystack/talm/internal/app/machined/pkg/controllers/kubespan" 13 | "github.com/siderolabs/talos/pkg/machinery/constants" 14 | ) 15 | 16 | func TestRoutingRules(t *testing.T) { 17 | if os.Geteuid() != 0 { 18 | t.Skip("requires root") 19 | } 20 | 21 | // use a different table/mark to avoid conflicts with running kubespan 22 | mgr := kubespan.NewRulesManager(constants.KubeSpanDefaultRoutingTable+10, constants.KubeSpanDefaultForceFirewallMark<<1, constants.KubeSpanDefaultFirewallMask<<1) 23 | 24 | // cleanup should be fine if nothing is installed 25 | assert.NoError(t, mgr.Cleanup()) 26 | 27 | defer mgr.Cleanup() //nolint:errcheck 28 | 29 | assert.NoError(t, mgr.Install()) 30 | assert.NoError(t, mgr.Cleanup()) 31 | } 32 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/network/operator/operator.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package operator implements network operators. 6 | package operator 7 | 8 | import ( 9 | "context" 10 | 11 | "github.com/siderolabs/talos/pkg/machinery/resources/network" 12 | ) 13 | 14 | // Operator describes common interface of the operators. 15 | type Operator interface { 16 | Run(ctx context.Context, notifyCh chan<- struct{}) 17 | 18 | Prefix() string 19 | 20 | AddressSpecs() []network.AddressSpecSpec 21 | RouteSpecs() []network.RouteSpecSpec 22 | LinkSpecs() []network.LinkSpecSpec 23 | 24 | HostnameSpecs() []network.HostnameSpecSpec 25 | ResolverSpecs() []network.ResolverSpecSpec 26 | TimeServerSpecs() []network.TimeServerSpecSpec 27 | } 28 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/network/operator/vip/nop.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package vip 6 | 7 | import ( 8 | "context" 9 | ) 10 | 11 | // NopHandler does nothing. 12 | type NopHandler struct{} 13 | 14 | // Acquire implements Handler interface. 15 | func (handler NopHandler) Acquire(ctx context.Context) error { 16 | return nil 17 | } 18 | 19 | // Release implements Handler interface. 20 | func (handler NopHandler) Release(ctx context.Context) error { 21 | return nil 22 | } 23 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/network/operator/vip/vip.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package vip contains implementations of specific methods to acquire/release virtual IPs. 6 | package vip 7 | 8 | import "context" 9 | 10 | // Handler implements custom actions to manage virtual IP assignment. 11 | type Handler interface { 12 | Acquire(ctx context.Context) error 13 | Release(ctx context.Context) error 14 | } 15 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/network/watch/rtnetlink.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package watch 6 | 7 | import ( 8 | "fmt" 9 | "sync" 10 | 11 | "github.com/jsimonetti/rtnetlink/v2" 12 | "github.com/mdlayher/netlink" 13 | ) 14 | 15 | type rtnetlinkWatcher struct { 16 | wg sync.WaitGroup 17 | conn *rtnetlink.Conn 18 | } 19 | 20 | // NewRtNetlink starts rtnetlink watch over specified groups. 21 | func NewRtNetlink(trigger Trigger, groups uint32) (Watcher, error) { 22 | watcher := &rtnetlinkWatcher{} 23 | 24 | var err error 25 | 26 | watcher.conn, err = rtnetlink.Dial(&netlink.Config{ 27 | Groups: groups, 28 | }) 29 | if err != nil { 30 | return nil, fmt.Errorf("error dialing watch socket: %w", err) 31 | } 32 | 33 | watcher.wg.Add(1) 34 | 35 | go func() { 36 | defer watcher.wg.Done() 37 | 38 | for { 39 | _, _, watchErr := watcher.conn.Receive() 40 | if watchErr != nil { 41 | return 42 | } 43 | 44 | trigger.QueueReconcile() 45 | } 46 | }() 47 | 48 | return watcher, nil 49 | } 50 | 51 | func (watcher *rtnetlinkWatcher) Done() { 52 | watcher.conn.Close() //nolint:errcheck 53 | 54 | watcher.wg.Wait() 55 | } 56 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/network/watch/trigger_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package watch_test 6 | 7 | import ( 8 | "context" 9 | "sync/atomic" 10 | "testing" 11 | "time" 12 | 13 | "github.com/stretchr/testify/assert" 14 | 15 | "github.com/cozystack/talm/internal/app/machined/pkg/controllers/network/watch" 16 | ) 17 | 18 | type mockTrigger struct { 19 | count atomic.Int64 20 | } 21 | 22 | func (t *mockTrigger) QueueReconcile() { 23 | t.count.Add(1) 24 | } 25 | 26 | func (t *mockTrigger) Get() int64 { 27 | return t.count.Load() 28 | } 29 | 30 | func TestRateLimitedTrigger(t *testing.T) { 31 | mock := &mockTrigger{} 32 | 33 | ctx, cancel := context.WithCancel(context.Background()) 34 | t.Cleanup(cancel) 35 | 36 | trigger := watch.NewRateLimitedTrigger(ctx, mock, 10, 5) 37 | 38 | start := time.Now() 39 | 40 | for time.Since(start) < time.Second { 41 | trigger.QueueReconcile() 42 | } 43 | 44 | assert.InDelta(t, int64(14), mock.Get(), 5) 45 | } 46 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/network/watch/watch.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package watch provides netlink watchers via multicast groups. 6 | package watch 7 | 8 | // Watcher interface allows to stop watching. 9 | type Watcher interface { 10 | Done() 11 | } 12 | 13 | // Trigger is used by watcher to trigger reconcile loops. 14 | type Trigger interface { 15 | QueueReconcile() 16 | } 17 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/runtime/export_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package runtime 6 | 7 | // BuildExpectedImageNames is exported for testing. 8 | var BuildExpectedImageNames = buildExpectedImageNames 9 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/runtime/runtime.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package runtime provides the runtime implementation. 6 | package runtime 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/runtime/testdata/extservices/foo.bar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozystack/talm/10bbb87b0753245d283e1116128d2c968162e142/internal/app/machined/pkg/controllers/runtime/testdata/extservices/foo.bar -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/runtime/testdata/extservices/frr.yaml: -------------------------------------------------------------------------------- 1 | name: frr 2 | container: 3 | entrypoint: ./frr 4 | args: 5 | - --msg 6 | - BGP FRR 7 | depends: 8 | - network: 9 | - addresses 10 | restart: always 11 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/runtime/testdata/extservices/hello.yaml: -------------------------------------------------------------------------------- 1 | name: hello-world 2 | container: 3 | entrypoint: ./hello-world 4 | args: 5 | - --msg 6 | - Talos Linux Extension Service 7 | depends: 8 | - network: 9 | - addresses 10 | restart: always 11 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/runtime/testdata/extservices/invalid.yaml: -------------------------------------------------------------------------------- 1 | name: invalid 2 | container: 3 | entrypoint: ./hello-world 4 | args: 5 | - --msg 6 | - Talos Linux Extension Service 7 | depends: 8 | - nothing: true 9 | restart: random 10 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/runtime/testdata/extservices/zduplicate.yaml: -------------------------------------------------------------------------------- 1 | name: hello-world 2 | container: 3 | entrypoint: ./duplicate 4 | args: 5 | - should not get registered 6 | depends: 7 | - network: 8 | - addresses 9 | restart: always 10 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/secrets/maintenance_root_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package secrets_test 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/cosi-project/runtime/pkg/resource" 11 | "github.com/cosi-project/runtime/pkg/resource/rtestutils" 12 | "github.com/stretchr/testify/assert" 13 | "github.com/stretchr/testify/suite" 14 | 15 | "github.com/cozystack/talm/internal/app/machined/pkg/controllers/ctest" 16 | secretsctrl "github.com/cozystack/talm/internal/app/machined/pkg/controllers/secrets" 17 | "github.com/siderolabs/talos/pkg/machinery/resources/secrets" 18 | ) 19 | 20 | func TestMaintenanceRootSuite(t *testing.T) { 21 | suite.Run(t, &MaintenanceRootSuite{ 22 | DefaultSuite: ctest.DefaultSuite{ 23 | AfterSetup: func(suite *ctest.DefaultSuite) { 24 | suite.Require().NoError(suite.Runtime().RegisterController(&secretsctrl.MaintenanceRootController{})) 25 | }, 26 | }, 27 | }) 28 | } 29 | 30 | type MaintenanceRootSuite struct { 31 | ctest.DefaultSuite 32 | } 33 | 34 | func (suite *MaintenanceRootSuite) TestReconcile() { 35 | rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), []resource.ID{secrets.MaintenanceRootID}, 36 | func(root *secrets.MaintenanceRoot, asrt *assert.Assertions) { 37 | asrt.NotEmpty(root.TypedSpec().CA) 38 | }) 39 | } 40 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/secrets/secrets.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package secrets provides controllers which manage secret resources. 6 | package secrets 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/siderolink/siderolink.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package siderolink provides controllers which manage file resources. 6 | package siderolink 7 | 8 | import ( 9 | "fmt" 10 | "time" 11 | 12 | "github.com/siderolabs/siderolink/pkg/wireguard" 13 | "golang.zx2c4.com/wireguard/wgctrl/wgtypes" 14 | 15 | "github.com/siderolabs/talos/pkg/machinery/constants" 16 | ) 17 | 18 | // WireguardClient allows mocking Wireguard client. 19 | type WireguardClient interface { 20 | Device(string) (*wgtypes.Device, error) 21 | Close() error 22 | } 23 | 24 | func peerDown(wgClient WireguardClient) (bool, error) { 25 | wgDevice, err := wgClient.Device(constants.SideroLinkName) 26 | if err != nil { 27 | return false, fmt.Errorf("error reading Wireguard device: %w", err) 28 | } 29 | 30 | if len(wgDevice.Peers) != 1 { 31 | return false, fmt.Errorf("unexpected number of Wireguard peers: %d", len(wgDevice.Peers)) 32 | } 33 | 34 | peer := wgDevice.Peers[0] 35 | since := time.Since(peer.LastHandshakeTime) 36 | 37 | return since >= wireguard.PeerDownInterval, nil 38 | } 39 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/time/time.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package time contains controllers managing time, synchronization, etc. 6 | package time 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/controllers/v1alpha1/v1alpha1.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package v1alpha1 provides controllers managing v1alpha1 resources. 6 | package v1alpha1 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/board.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package runtime 6 | 7 | import "github.com/siderolabs/go-procfs/procfs" 8 | 9 | // PartitionOptions are the board specific options for customizing the 10 | // partition table. 11 | type PartitionOptions struct { 12 | PartitionsOffset uint64 13 | } 14 | 15 | // BoardInstallOptions are the board specific options for installation of various boot assets. 16 | type BoardInstallOptions struct { 17 | InstallDisk string 18 | MountPrefix string 19 | DTBPath string 20 | UBootPath string 21 | RPiFirmwarePath string 22 | Printf func(string, ...any) 23 | } 24 | 25 | // Board defines the requirements for a SBC. 26 | type Board interface { 27 | Name() string 28 | Install(options BoardInstallOptions) error 29 | KernelArgs() procfs.Parameters 30 | PartitionOptions() *PartitionOptions 31 | } 32 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/disk/disk.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package disk contains abstract utility function to filter disks in MachineState.Disk call. 6 | package disk 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/disk/options.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package disk 6 | 7 | // Option defines a function that can alter MachineState.Disk() method output. 8 | type Option func(options *Options) 9 | 10 | // Options contains disk selection options. 11 | type Options struct { 12 | Label string 13 | } 14 | 15 | // WithPartitionLabel select a disk which has the partition labeled. 16 | func WithPartitionLabel(label string) Option { 17 | return func(opts *Options) { 18 | opts.Label = label 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/doc.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package runtime defines interfaces for accessing runtime specific settings, 6 | // and state. 7 | package runtime 8 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/emergency/emergency.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package emergency provides values to handle emergency (panic/unrecoverable error) handling for machined. 6 | package emergency 7 | 8 | import ( 9 | "sync/atomic" 10 | 11 | "golang.org/x/sys/unix" 12 | ) 13 | 14 | // RebootCmd is a command to reboot the system after an unrecoverable error. 15 | var RebootCmd atomic.Int64 16 | 17 | func init() { 18 | RebootCmd.Store(unix.LINUX_REBOOT_CMD_RESTART) 19 | } 20 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/errors.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package runtime 6 | 7 | import ( 8 | "errors" 9 | "fmt" 10 | ) 11 | 12 | var ( 13 | // ErrLocked indicates that the sequencer is currently locked, and processing 14 | // another sequence. 15 | ErrLocked = errors.New("locked") 16 | 17 | // ErrInvalidSequenceData indicates that the sequencer got data the wrong 18 | // data type for a sequence. 19 | ErrInvalidSequenceData = errors.New("invalid sequence data") 20 | 21 | // ErrUndefinedRuntime indicates that the sequencer's runtime is not defined. 22 | ErrUndefinedRuntime = errors.New("undefined runtime") 23 | ) 24 | 25 | // RebootError encapsulates unix.Reboot() cmd argument. 26 | type RebootError struct { 27 | Cmd int 28 | } 29 | 30 | func (e RebootError) Error() string { 31 | return fmt.Sprintf("unix.Reboot(%x)", e.Cmd) 32 | } 33 | 34 | // IsRebootError checks whether given error is RebootError. 35 | func IsRebootError(err error) bool { 36 | var rebootErr RebootError 37 | 38 | return errors.As(err, &rebootErr) 39 | } 40 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/logging/logging.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package logging provides implementations of runtime.LoggingManager. 6 | package logging 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/logging/null.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package logging 6 | 7 | import ( 8 | "io" 9 | "os" 10 | 11 | "github.com/cozystack/talm/internal/app/machined/pkg/runtime" 12 | ) 13 | 14 | // NullLoggingManager sends all the logs to /dev/null. 15 | type NullLoggingManager struct{} 16 | 17 | // NewNullLoggingManager initializes NullLoggingManager. 18 | func NewNullLoggingManager() *NullLoggingManager { 19 | return &NullLoggingManager{} 20 | } 21 | 22 | // ServiceLog implements LoggingManager. 23 | func (*NullLoggingManager) ServiceLog(id string) runtime.LogHandler { 24 | return &nullLogHandler{} 25 | } 26 | 27 | // SetSenders implements runtime.LoggingManager interface (by doing nothing). 28 | func (*NullLoggingManager) SetSenders([]runtime.LogSender) []runtime.LogSender { 29 | return nil 30 | } 31 | 32 | // RegisteredLogs implements runtime.LoggingManager interface (by doing nothing). 33 | func (*NullLoggingManager) RegisteredLogs() []string { 34 | return nil 35 | } 36 | 37 | type nullLogHandler struct{} 38 | 39 | func (*nullLogHandler) Writer() (io.WriteCloser, error) { 40 | return os.OpenFile(os.DevNull, os.O_WRONLY, 0) 41 | } 42 | 43 | func (*nullLogHandler) Reader(...runtime.LogOption) (io.ReadCloser, error) { 44 | return os.OpenFile(os.DevNull, os.O_RDONLY, 0) 45 | } 46 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/runtime.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package runtime 6 | 7 | import ( 8 | "context" 9 | "time" 10 | 11 | "github.com/siderolabs/talos/pkg/machinery/config" 12 | "github.com/siderolabs/talos/pkg/machinery/resources/hardware" 13 | ) 14 | 15 | // Runtime defines the runtime parameters. 16 | type Runtime interface { //nolint:interfacebloat 17 | Config() config.Config 18 | ConfigContainer() config.Container 19 | RollbackToConfigAfter(time.Duration) error 20 | CancelConfigRollbackTimeout() 21 | SetConfig(config.Provider) error 22 | CanApplyImmediate(config.Provider) error 23 | State() State 24 | Events() EventStream 25 | Logging() LoggingManager 26 | NodeName() (string, error) 27 | IsBootstrapAllowed() bool 28 | GetSystemInformation(ctx context.Context) (*hardware.SystemInformation, error) 29 | } 30 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/board/rpi_generic/config.txt: -------------------------------------------------------------------------------- 1 | # See https://www.raspberrypi.com/documentation/computers/configuration.html 2 | # Reduce GPU memory to give more to CPU. 3 | gpu_mem=32 4 | # Enable maximum compatibility on both HDMI ports; 5 | # only the one closest to the power/USB-C port will work in practice. 6 | hdmi_safe:0=1 7 | hdmi_safe:1=1 8 | # Load U-Boot. 9 | kernel=u-boot.bin 10 | # Forces the kernel loading system to assume a 64-bit kernel. 11 | arm_64bit=1 12 | # Run as fast as firmware / board allows. 13 | arm_boost=1 14 | # Enable the primary/console UART. 15 | enable_uart=1 16 | # Disable Bluetooth. 17 | dtoverlay=disable-bt 18 | # Disable Wireless Lan. 19 | dtoverlay=disable-wifi -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/constants.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package grub 6 | 7 | import ( 8 | "github.com/siderolabs/talos/pkg/machinery/constants" 9 | ) 10 | 11 | // BootLabel represents a boot label, e.g. A or B. 12 | type BootLabel string 13 | 14 | const ( 15 | // ConfigPath is the path to the grub config. 16 | ConfigPath = constants.BootMountPoint + "/grub/grub.cfg" 17 | // BootA is a bootloader label. 18 | BootA BootLabel = "A" 19 | // BootB is a bootloader label. 20 | BootB BootLabel = "B" 21 | // BootReset is a bootloader label. 22 | BootReset BootLabel = "Reset" 23 | ) 24 | 25 | const ( 26 | bootloaderNotInstalled = "bootloader not installed" 27 | ) 28 | 29 | type bootloaderNotInstalledError struct{} 30 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/quote.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package grub 6 | 7 | import ( 8 | "strings" 9 | ) 10 | 11 | // Quote according to (incomplete) GRUB quoting rules. 12 | // 13 | // See https://www.gnu.org/software/grub/manual/grub/html_node/Shell_002dlike-scripting.html 14 | func Quote(s string) string { 15 | for _, c := range `\{}&$|;<>"` { 16 | s = strings.ReplaceAll(s, string(c), `\`+string(c)) 17 | } 18 | 19 | return s 20 | } 21 | 22 | // Unquote according to (incomplete) GRUB quoting rules. 23 | func Unquote(s string) string { 24 | for _, c := range `{}&$|;<>\"` { 25 | s = strings.ReplaceAll(s, `\`+string(c), string(c)) 26 | } 27 | 28 | return s 29 | } 30 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/testdata/grub_parse_test.cfg: -------------------------------------------------------------------------------- 1 | set default="A - v1" 2 | set timeout=3 3 | set fallback="B - v2" 4 | 5 | insmod all_video 6 | 7 | terminal_input console 8 | terminal_output console 9 | 10 | menuentry "A - v1" { 11 | set gfxmode=auto 12 | set gfxpayload=text 13 | linux /A/vmlinuz cmdline A 14 | initrd /A/initramfs.xz 15 | } 16 | 17 | menuentry "B - v2" { 18 | set gfxmode=auto 19 | set gfxpayload=text 20 | linux /B/vmlinuz cmdline B 21 | initrd /B/initramfs.xz 22 | } 23 | 24 | menuentry "Reset Talos installation and return to maintenance mode" { 25 | set gfxmode=auto 26 | set gfxpayload=text 27 | linux /A/vmlinuz cmdline A talos.experimental.wipe=system:EPHEMERAL,STATE 28 | initrd /A/initramfs.xz 29 | } 30 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/testdata/grub_write_no_reset_test.cfg: -------------------------------------------------------------------------------- 1 | set default="A - TestOld v0.0.1" 2 | 3 | set timeout=3 4 | 5 | insmod all_video 6 | 7 | terminal_input console 8 | terminal_output console 9 | 10 | menuentry "A - TestOld v0.0.1" { 11 | set gfxmode=auto 12 | set gfxpayload=text 13 | linux /A/vmlinuz cmdline A 14 | initrd /A/initramfs.xz 15 | } 16 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub/testdata/grub_write_test.cfg: -------------------------------------------------------------------------------- 1 | set default="A - Test v0.0.1" 2 | 3 | set timeout=3 4 | 5 | insmod all_video 6 | 7 | terminal_input console 8 | terminal_output console 9 | 10 | menuentry "A - Test v0.0.1" { 11 | set gfxmode=auto 12 | set gfxpayload=text 13 | linux /A/vmlinuz cmdline A 14 | initrd /A/initramfs.xz 15 | } 16 | menuentry "Reset Talos installation and return to maintenance mode" { 17 | set gfxmode=auto 18 | set gfxpayload=text 19 | linux /A/vmlinuz cmdline A talos.experimental.wipe=system:EPHEMERAL,STATE 20 | initrd /A/initramfs.xz 21 | } 22 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/doc.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package v1alpha1 implements a `Runtime`. 6 | package v1alpha1 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/akamai/akamai_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package akamai_test 6 | 7 | import ( 8 | _ "embed" 9 | "encoding/json" 10 | "testing" 11 | 12 | akametadata "github.com/linode/go-metadata" 13 | "github.com/stretchr/testify/assert" 14 | "github.com/stretchr/testify/require" 15 | "gopkg.in/yaml.v3" 16 | 17 | "github.com/cozystack/talm/internal/app/machined/pkg/runtime/v1alpha1/platform/akamai" 18 | ) 19 | 20 | //go:embed testdata/instance.json 21 | var rawMetadata []byte 22 | 23 | //go:embed testdata/network.json 24 | 25 | var rawNetwork []byte 26 | 27 | //go:embed testdata/expected.yaml 28 | var expectedNetworkConfig string 29 | 30 | func TestParseMetadata(t *testing.T) { 31 | p := &akamai.Akamai{} 32 | 33 | var metadata akametadata.InstanceData 34 | 35 | var interfaceConfig akametadata.NetworkData 36 | 37 | require.NoError(t, json.Unmarshal(rawMetadata, &metadata)) 38 | 39 | require.NoError(t, json.Unmarshal(rawNetwork, &interfaceConfig)) 40 | 41 | networkConfig, err := p.ParseMetadata(&metadata, &interfaceConfig) 42 | require.NoError(t, err) 43 | 44 | marshaled, err := yaml.Marshal(networkConfig) 45 | require.NoError(t, err) 46 | 47 | assert.Equal(t, expectedNetworkConfig, string(marshaled)) 48 | } 49 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/akamai/testdata/expected.yaml: -------------------------------------------------------------------------------- 1 | addresses: 2 | - address: 172.1.2.3/32 3 | linkName: eth0 4 | family: inet4 5 | scope: global 6 | flags: permanent 7 | layer: platform 8 | - address: 192.1.2.3/32 9 | linkName: eth0 10 | family: inet4 11 | scope: global 12 | flags: permanent 13 | layer: platform 14 | - address: 2600:3c05:d011:797::/64 15 | linkName: eth0 16 | family: inet6 17 | scope: global 18 | flags: mngmtmpaddr 19 | layer: platform 20 | - address: fe80::f03c:93ff:fe6e:5cd9/128 21 | linkName: eth0 22 | family: inet6 23 | scope: link 24 | flags: "" 25 | layer: platform 26 | links: [] 27 | routes: 28 | - family: inet6 29 | dst: fe80::f03c:93ff:fe6e:5cd9/128 30 | src: "" 31 | gateway: fe80::1 32 | outLinkName: eth0 33 | table: main 34 | priority: 1024 35 | scope: global 36 | type: unicast 37 | flags: "" 38 | protocol: static 39 | layer: platform 40 | hostnames: 41 | - hostname: talos 42 | domainname: "" 43 | layer: platform 44 | resolvers: [] 45 | timeServers: [] 46 | operators: [] 47 | externalIPs: 48 | - 172.1.2.3 49 | - '2600:3c05:d011:797::' 50 | metadata: 51 | platform: akamai 52 | hostname: talos 53 | region: us-east 54 | instanceType: g6-standard-1 55 | instanceId: "123456" 56 | providerId: linode://123456 57 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/akamai/testdata/instance.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 123456, 3 | "label": "talos", 4 | "region": "us-east", 5 | "type": "g6-standard-1", 6 | "specs": { 7 | "vcpus": 1, 8 | "memory": 2048, 9 | "gpus": 0, 10 | "transfer": 2000, 11 | "disk": 51200 12 | }, 13 | "backups": { 14 | "enabled": false, 15 | "status": null 16 | }, 17 | "host_uuid": "0c2897331ea446f483f754852b18a67c", 18 | "tags": [] 19 | } 20 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/akamai/testdata/network.json: -------------------------------------------------------------------------------- 1 | { 2 | "interfaces": [], 3 | "ipv4": { 4 | "public": [ 5 | "172.1.2.3/32" 6 | ], 7 | "private": [ 8 | "192.1.2.3/32" 9 | ], 10 | "shared": [] 11 | }, 12 | "ipv6": { 13 | "slaac": "2600:3c06::f03c:93ff:fe6e:5cd9/128", 14 | "ranges": [ 15 | "2600:3c05:d011:797::/64" 16 | ], 17 | "link_local": "fe80::f03c:93ff:fe6e:5cd9/128", 18 | "shared_ranges": [] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/aws/aws_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package aws_test 6 | 7 | import ( 8 | _ "embed" 9 | "encoding/json" 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | "github.com/stretchr/testify/require" 14 | "gopkg.in/yaml.v3" 15 | 16 | "github.com/cozystack/talm/internal/app/machined/pkg/runtime/v1alpha1/platform/aws" 17 | ) 18 | 19 | //go:embed testdata/metadata.json 20 | var rawMetadata []byte 21 | 22 | //go:embed testdata/expected.yaml 23 | var expectedNetworkConfig string 24 | 25 | func TestEmpty(t *testing.T) { 26 | p := &aws.AWS{} 27 | 28 | var metadata aws.MetadataConfig 29 | 30 | require.NoError(t, json.Unmarshal(rawMetadata, &metadata)) 31 | 32 | networkConfig, err := p.ParseMetadata(&metadata) 33 | require.NoError(t, err) 34 | 35 | marshaled, err := yaml.Marshal(networkConfig) 36 | require.NoError(t, err) 37 | 38 | assert.Equal(t, expectedNetworkConfig, string(marshaled)) 39 | } 40 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/aws/testdata/expected.yaml: -------------------------------------------------------------------------------- 1 | addresses: [] 2 | links: [] 3 | routes: [] 4 | hostnames: 5 | - hostname: talos 6 | domainname: "" 7 | layer: platform 8 | resolvers: [] 9 | timeServers: [] 10 | operators: [] 11 | externalIPs: 12 | - 1.2.3.4 13 | metadata: 14 | platform: aws 15 | hostname: talos 16 | region: us-east-1 17 | zone: us-east-1a 18 | instanceId: i-0a0a0a0a0a0a0a0a0 19 | providerId: aws:///us-east-1a/i-0a0a0a0a0a0a0a0a0 20 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/aws/testdata/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "hostname": "talos", 3 | "instance-id": "i-0a0a0a0a0a0a0a0a0", 4 | "public-ipv4": "1.2.3.4", 5 | "region": "us-east-1", 6 | "zone": "us-east-1a" 7 | } 8 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/azure/testdata/compute.json: -------------------------------------------------------------------------------- 1 | { 2 | "location": "CentralUS", 3 | "name": "IMDSCanary", 4 | "offer": "RHEL", 5 | "osProfile": { 6 | "computerName": "examplevmname" 7 | }, 8 | "osType": "Linux", 9 | "platformFaultDomain": "0", 10 | "platformUpdateDomain": "0", 11 | "publisher": "RedHat", 12 | "resourceId": "/subscriptions/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourceGroups/Test/providers/Microsoft.Compute/virtualMachines/examplevmname", 13 | "sku": "7.2", 14 | "version": "7.2.20161026", 15 | "vmId": "5c08b38e-4d57-4c23-ac45-aca61037f084", 16 | "vmSize": "Standard_DS2" 17 | } -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/azure/testdata/expected.yaml: -------------------------------------------------------------------------------- 1 | addresses: [] 2 | links: [] 3 | routes: 4 | - family: inet6 5 | dst: "" 6 | src: "" 7 | gateway: fe80::1234:5678:9abc 8 | outLinkName: eth0 9 | table: main 10 | priority: 4096 11 | scope: global 12 | type: unicast 13 | flags: "" 14 | protocol: static 15 | layer: platform 16 | hostnames: 17 | - hostname: some 18 | domainname: fqdn 19 | layer: platform 20 | resolvers: [] 21 | timeServers: [] 22 | operators: 23 | - operator: dhcp6 24 | linkName: eth0 25 | requireUp: true 26 | dhcp6: 27 | routeMetric: 2048 28 | layer: default 29 | externalIPs: 30 | - 1.2.3.4 31 | - 2603:1020:10:5::34 32 | - 20.10.5.34 33 | metadata: 34 | platform: azure 35 | hostname: examplevmname 36 | region: centralus 37 | zone: "0" 38 | instanceType: Standard_DS2 39 | instanceId: /subscriptions/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourceGroups/Test/providers/Microsoft.Compute/virtualMachines/examplevmname 40 | providerId: azure:///subscriptions/xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx/resourceGroups/test/providers/Microsoft.Compute/virtualMachines/examplevmname 41 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/azure/testdata/interfaces.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ipv4": { 4 | "ipAddress": [ 5 | { 6 | "privateIpAddress": "172.18.1.10", 7 | "publicIpAddress": "1.2.3.4" 8 | } 9 | ], 10 | "subnet": [ 11 | { 12 | "address": "172.18.1.0", 13 | "prefix": "24" 14 | } 15 | ] 16 | }, 17 | "ipv6": { 18 | "ipAddress": [ 19 | { 20 | "privateIpAddress": "fd00::10", 21 | "publicIpAddress": "" 22 | } 23 | ] 24 | }, 25 | "macAddress": "000D3AD631EE" 26 | } 27 | ] 28 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/azure/testdata/loadbalancer.json: -------------------------------------------------------------------------------- 1 | { 2 | "loadbalancer": { 3 | "publicIpAddresses": [ 4 | { 5 | "frontendIpAddress": "[2603:1020:10:5::34]", 6 | "privateIpAddress": "[fd00::10]" 7 | }, 8 | { 9 | "frontendIpAddress": "20.10.5.34", 10 | "privateIpAddress": "172.18.1.10" 11 | } 12 | ], 13 | "inboundRules": [ 14 | { 15 | "frontendIpAddress": "[fd60:172:16:88::5]", 16 | "protocol": "Tcp", 17 | "frontendPort": 6443, 18 | "backendPort": 6443, 19 | "privateIpAddress": "[fd00::10]" 20 | }, 21 | { 22 | "frontendIpAddress": "172.16.136.5", 23 | "protocol": "Tcp", 24 | "frontendPort": 6443, 25 | "backendPort": 6443, 26 | "privateIpAddress": "172.18.1.10" 27 | } 28 | ], 29 | "outboundRules": [] 30 | } 31 | } -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/cloudstack/cloudstack_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package cloudstack_test 6 | 7 | import ( 8 | _ "embed" 9 | "encoding/json" 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | "github.com/stretchr/testify/require" 14 | "gopkg.in/yaml.v3" 15 | 16 | "github.com/cozystack/talm/internal/app/machined/pkg/runtime/v1alpha1/platform/cloudstack" 17 | ) 18 | 19 | //go:embed testdata/metadata.json 20 | var rawMetadata []byte 21 | 22 | //go:embed testdata/expected.yaml 23 | var expectedNetworkConfig string 24 | 25 | func TestEmpty(t *testing.T) { 26 | p := &cloudstack.Cloudstack{} 27 | 28 | var m cloudstack.MetadataConfig 29 | 30 | require.NoError(t, json.Unmarshal(rawMetadata, &m)) 31 | 32 | networkConfig, err := p.ParseMetadata(&m) 33 | require.NoError(t, err) 34 | 35 | marshaled, err := yaml.Marshal(networkConfig) 36 | require.NoError(t, err) 37 | 38 | assert.Equal(t, expectedNetworkConfig, string(marshaled)) 39 | } 40 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/cloudstack/testdata/expected.yaml: -------------------------------------------------------------------------------- 1 | addresses: [] 2 | links: [] 3 | routes: [] 4 | hostnames: 5 | - hostname: talos 6 | domainname: fqdn 7 | layer: platform 8 | resolvers: [] 9 | timeServers: [] 10 | operators: [] 11 | externalIPs: 12 | - 1.2.3.4 13 | metadata: 14 | platform: cloudstack 15 | hostname: talos.fqdn 16 | instanceType: standard.tiny 17 | instanceId: 3fe6b28a-669e-4eb2-bffd-4180c572c410 18 | providerId: cloudstack://3fe6b28a-669e-4eb2-bffd-4180c572c410 19 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/cloudstack/testdata/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "local-hostname": "talos.fqdn", 3 | "instance-id": "3fe6b28a-669e-4eb2-bffd-4180c572c410", 4 | "public-ipv4": "1.2.3.4", 5 | "service-offering": "standard.tiny" 6 | } -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/container/internal/files/hostname.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package files provides internal methods to container platform to read files. 6 | package files 7 | 8 | import ( 9 | "bytes" 10 | "os" 11 | 12 | "github.com/siderolabs/talos/pkg/machinery/resources/network" 13 | ) 14 | 15 | // ReadHostname reads and parses /etc/hostname file. 16 | func ReadHostname(path string) (network.HostnameSpecSpec, error) { 17 | hostname, err := os.ReadFile(path) 18 | if err != nil { 19 | return network.HostnameSpecSpec{}, err 20 | } 21 | 22 | hostname = bytes.TrimSpace(hostname) 23 | 24 | hostnameSpec := network.HostnameSpecSpec{ 25 | ConfigLayer: network.ConfigPlatform, 26 | } 27 | 28 | if err = hostnameSpec.ParseFQDN(string(hostname)); err != nil { 29 | return network.HostnameSpecSpec{}, err 30 | } 31 | 32 | return hostnameSpec, nil 33 | } 34 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/container/internal/files/hostname_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package files_test 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/stretchr/testify/require" 11 | 12 | "github.com/cozystack/talm/internal/app/machined/pkg/runtime/v1alpha1/platform/container/internal/files" 13 | ) 14 | 15 | func TestReadHostname(t *testing.T) { 16 | t.Parallel() 17 | 18 | spec, err := files.ReadHostname("testdata/hostname") 19 | require.NoError(t, err) 20 | 21 | require.Equal(t, "foo", spec.Hostname) 22 | require.Equal(t, "example.com", spec.Domainname) 23 | } 24 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/container/internal/files/resolv.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package files 6 | 7 | import ( 8 | "bytes" 9 | "net/netip" 10 | "os" 11 | 12 | "github.com/siderolabs/talos/pkg/machinery/resources/network" 13 | ) 14 | 15 | // ReadResolvConf reads and parses /etc/resolv.conf file. 16 | func ReadResolvConf(path string) (network.ResolverSpecSpec, error) { 17 | resolverSpec := network.ResolverSpecSpec{ 18 | ConfigLayer: network.ConfigPlatform, 19 | } 20 | 21 | resolvers, err := os.ReadFile(path) 22 | if err != nil { 23 | return resolverSpec, err 24 | } 25 | 26 | for _, line := range bytes.Split(resolvers, []byte("\n")) { 27 | line = bytes.TrimSpace(line) 28 | line, _, _ = bytes.Cut(line, []byte("#")) 29 | 30 | if !bytes.HasPrefix(line, []byte("nameserver")) { 31 | continue 32 | } 33 | 34 | line = bytes.TrimSpace(bytes.TrimPrefix(line, []byte("nameserver"))) 35 | 36 | if addr, err := netip.ParseAddr(string(line)); err == nil { 37 | resolverSpec.DNSServers = append(resolverSpec.DNSServers, addr) 38 | } 39 | } 40 | 41 | return resolverSpec, nil 42 | } 43 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/container/internal/files/resolv_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package files_test 6 | 7 | import ( 8 | "net/netip" 9 | "testing" 10 | 11 | "github.com/stretchr/testify/require" 12 | 13 | "github.com/cozystack/talm/internal/app/machined/pkg/runtime/v1alpha1/platform/container/internal/files" 14 | ) 15 | 16 | func TestReadResolvConf(t *testing.T) { 17 | t.Parallel() 18 | 19 | spec, err := files.ReadResolvConf("testdata/resolv.conf") 20 | require.NoError(t, err) 21 | 22 | require.Equal(t, []netip.Addr{ 23 | netip.MustParseAddr("127.0.0.53"), 24 | netip.MustParseAddr("::1"), 25 | }, spec.DNSServers) 26 | } 27 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/container/internal/files/testdata/hostname: -------------------------------------------------------------------------------- 1 | foo.example.com 2 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/container/internal/files/testdata/resolv.conf: -------------------------------------------------------------------------------- 1 | # This is /run/systemd/resolve/stub-resolv.conf managed by man:systemd-resolved(8). 2 | # Do not edit. 3 | 4 | nameserver 127.0.0.53 # v4 one 5 | options edns0 trust-ad 6 | search . 7 | 8 | nameserver ::1 # this is V6 9 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/digitalocean/digitalocean_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package digitalocean_test 6 | 7 | import ( 8 | _ "embed" 9 | "encoding/json" 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | "github.com/stretchr/testify/require" 14 | "gopkg.in/yaml.v3" 15 | 16 | "github.com/cozystack/talm/internal/app/machined/pkg/runtime/v1alpha1/platform/digitalocean" 17 | ) 18 | 19 | //go:embed testdata/metadata.json 20 | var rawMetadata []byte 21 | 22 | //go:embed testdata/expected.yaml 23 | var expectedNetworkConfig string 24 | 25 | func TestParseMetadata(t *testing.T) { 26 | p := &digitalocean.DigitalOcean{} 27 | 28 | var metadata digitalocean.MetadataConfig 29 | 30 | require.NoError(t, json.Unmarshal(rawMetadata, &metadata)) 31 | 32 | networkConfig, err := p.ParseMetadata(&metadata) 33 | require.NoError(t, err) 34 | 35 | marshaled, err := yaml.Marshal(networkConfig) 36 | require.NoError(t, err) 37 | 38 | assert.Equal(t, expectedNetworkConfig, string(marshaled)) 39 | } 40 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/equinixmetal/metadata.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package equinixmetal 6 | 7 | // MetadataConfig holds equinixmetal metadata info. 8 | type MetadataConfig struct { 9 | ID string `json:"id"` 10 | Hostname string `json:"hostname"` 11 | Plan string `json:"plan"` 12 | Metro string `json:"metro"` 13 | Facility string `json:"facility"` 14 | Network Network `json:"network"` 15 | BGPNeighbors []BGPNeighbor `json:"bgp_neighbors"` 16 | PrivateSubnets []string `json:"private_subnets"` 17 | } 18 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/errors/errors.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package errors contains errors used by the platform package. 6 | package errors 7 | 8 | import "errors" 9 | 10 | // ErrNoConfigSource indicates that the platform does not have a configured source for the configuration. 11 | var ErrNoConfigSource = errors.New("no configuration source") 12 | 13 | // ErrNoHostname indicates that the meta server does not have a instance hostname. 14 | var ErrNoHostname = errors.New("failed to fetch hostname from metadata service") 15 | 16 | // ErrNoExternalIPs indicates that the meta server does not have a external addresses. 17 | var ErrNoExternalIPs = errors.New("failed to fetch external addresses from metadata service") 18 | 19 | // ErrNoEventURL indicates that the platform does not have an expected events URL in the kernel params. 20 | var ErrNoEventURL = errors.New("no event URL") 21 | 22 | // ErrMetadataNotReady indicates that the platform does not have metadata yet. 23 | var ErrMetadataNotReady = errors.New("platform metadata is not ready") 24 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/exoscale/exoscale_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package exoscale_test 6 | 7 | import ( 8 | _ "embed" 9 | "encoding/json" 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | "github.com/stretchr/testify/require" 14 | "gopkg.in/yaml.v3" 15 | 16 | "github.com/cozystack/talm/internal/app/machined/pkg/runtime/v1alpha1/platform/exoscale" 17 | ) 18 | 19 | //go:embed testdata/metadata.json 20 | var rawMetadata []byte 21 | 22 | //go:embed testdata/expected.yaml 23 | var expectedNetworkConfig string 24 | 25 | func TestEmpty(t *testing.T) { 26 | p := &exoscale.Exoscale{} 27 | 28 | var m exoscale.MetadataConfig 29 | 30 | require.NoError(t, json.Unmarshal(rawMetadata, &m)) 31 | 32 | networkConfig, err := p.ParseMetadata(&m) 33 | require.NoError(t, err) 34 | 35 | marshaled, err := yaml.Marshal(networkConfig) 36 | require.NoError(t, err) 37 | 38 | assert.Equal(t, expectedNetworkConfig, string(marshaled)) 39 | } 40 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/exoscale/testdata/expected.yaml: -------------------------------------------------------------------------------- 1 | addresses: [] 2 | links: [] 3 | routes: [] 4 | hostnames: 5 | - hostname: talos 6 | domainname: fqdn 7 | layer: platform 8 | resolvers: [] 9 | timeServers: [] 10 | operators: [] 11 | externalIPs: 12 | - 1.2.3.4 13 | metadata: 14 | platform: exoscale 15 | hostname: talos.fqdn 16 | instanceType: standard.tiny 17 | instanceId: 3085c764-b270-45b0-b974-68c55a9c2d53 18 | providerId: exoscale://3085c764-b270-45b0-b974-68c55a9c2d53 19 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/exoscale/testdata/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "local-hostname": "talos.fqdn", 3 | "instance-id": "3085c764-b270-45b0-b974-68c55a9c2d53", 4 | "public-ipv4": "1.2.3.4", 5 | "service-offering": "standard.tiny" 6 | } -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/gcp/gcp_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package gcp_test 6 | 7 | import ( 8 | _ "embed" 9 | "encoding/json" 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | "github.com/stretchr/testify/require" 14 | "gopkg.in/yaml.v3" 15 | 16 | "github.com/cozystack/talm/internal/app/machined/pkg/runtime/v1alpha1/platform/gcp" 17 | ) 18 | 19 | //go:embed testdata/metadata.json 20 | var rawMetadata []byte 21 | 22 | //go:embed testdata/interfaces.json 23 | var rawInterfaces []byte 24 | 25 | //go:embed testdata/expected.yaml 26 | var expectedNetworkConfig string 27 | 28 | func TestParseMetadata(t *testing.T) { 29 | p := &gcp.GCP{} 30 | 31 | var ( 32 | metadata gcp.MetadataConfig 33 | interfaces []gcp.NetworkInterfaceConfig 34 | ) 35 | 36 | require.NoError(t, json.Unmarshal(rawMetadata, &metadata)) 37 | require.NoError(t, json.Unmarshal(rawInterfaces, &interfaces)) 38 | 39 | networkConfig, err := p.ParseMetadata(&metadata, interfaces) 40 | require.NoError(t, err) 41 | 42 | marshaled, err := yaml.Marshal(networkConfig) 43 | require.NoError(t, err) 44 | 45 | assert.Equal(t, expectedNetworkConfig, string(marshaled)) 46 | } 47 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/gcp/testdata/expected.yaml: -------------------------------------------------------------------------------- 1 | addresses: 2 | - address: fd20:172:1610:7003:0:1::/96 3 | linkName: eth0 4 | family: inet6 5 | scope: global 6 | flags: permanent 7 | layer: platform 8 | links: 9 | - name: eth0 10 | logical: false 11 | up: true 12 | mtu: 1500 13 | kind: "" 14 | type: netrom 15 | layer: platform 16 | routes: 17 | - family: inet6 18 | dst: "" 19 | src: "" 20 | gateway: fe80::4001:acff:fe10:1 21 | outLinkName: eth0 22 | table: main 23 | priority: 2048 24 | scope: global 25 | type: unicast 26 | flags: "" 27 | protocol: static 28 | layer: platform 29 | hostnames: 30 | - hostname: talos 31 | domainname: "" 32 | layer: platform 33 | resolvers: 34 | - dnsServers: 35 | - 169.254.169.254 36 | layer: platform 37 | timeServers: 38 | - timeServers: 39 | - metadata.google.internal 40 | layer: platform 41 | operators: 42 | - operator: dhcp4 43 | linkName: eth0 44 | requireUp: true 45 | dhcp4: 46 | routeMetric: 1024 47 | layer: platform 48 | externalIPs: 49 | - 35.1.2.3 50 | metadata: 51 | platform: gcp 52 | hostname: talos 53 | region: us-central1 54 | zone: us-central1-a 55 | instanceType: n1-standard-1 56 | instanceId: "0" 57 | providerId: gce://123/us-central1-a/my-server 58 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/gcp/testdata/interfaces.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "accessConfigs": [ 4 | { 5 | "externalIp": "35.1.2.3", 6 | "type": "ONE_TO_ONE_NAT" 7 | } 8 | ], 9 | "dhcpv6Refresh": "2219726792944608985", 10 | "dnsServers": [ 11 | "169.254.169.254" 12 | ], 13 | "forwardedIps": [ 14 | "172.16.0.230" 15 | ], 16 | "gateway": "172.16.0.1", 17 | "gatewayIpv6": "fe80::4001:acff:fe10:1", 18 | "ip": "172.16.0.4", 19 | "ipAliases": [], 20 | "ipv6": [ 21 | "fd20:172:1610:7003:0:1::/96" 22 | ], 23 | "ipv6s": [ 24 | "fd20:172:1610:7003:0:1:0:0" 25 | ], 26 | "mac": "42:01:ac:10:00:04", 27 | "mtu": 1500, 28 | "network": "projects/123/networks/main", 29 | "subnetmask": "255.255.255.0", 30 | "targetInstanceIps": [] 31 | } 32 | ] -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/gcp/testdata/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "project-id": "123", 3 | "hostname": "talos", 4 | "id": "0", 5 | "zone": "us-central1-a", 6 | "name": "my-server", 7 | "machine-type": "n1-standard-1", 8 | "preempted": "FALSE" 9 | } -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/hcloud/export_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package hcloud 6 | 7 | // MaybeBase64Decode is exported for testing. 8 | func MaybeBase64Decode(data []byte) []byte { 9 | return maybeBase64Decode(data) 10 | } 11 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/hcloud/testdata/expected.yaml: -------------------------------------------------------------------------------- 1 | addresses: 2 | - address: 2a01:4f8:1:2::1/64 3 | linkName: eth0 4 | family: inet6 5 | scope: global 6 | flags: permanent 7 | layer: platform 8 | links: 9 | - name: eth0 10 | logical: false 11 | up: true 12 | mtu: 0 13 | kind: "" 14 | type: netrom 15 | layer: platform 16 | routes: 17 | - family: inet6 18 | dst: "" 19 | src: "" 20 | gateway: fe80::1 21 | outLinkName: eth0 22 | table: main 23 | priority: 1024 24 | scope: global 25 | type: unicast 26 | flags: "" 27 | protocol: static 28 | layer: platform 29 | hostnames: 30 | - hostname: talos 31 | domainname: fqdn 32 | layer: platform 33 | resolvers: [] 34 | timeServers: [] 35 | operators: 36 | - operator: dhcp4 37 | linkName: eth0 38 | requireUp: false 39 | dhcp4: 40 | routeMetric: 1024 41 | layer: platform 42 | externalIPs: 43 | - 1.2.3.4 44 | - 2a01:4f8:1:2::1 45 | metadata: 46 | platform: hcloud 47 | hostname: talos.fqdn 48 | region: hel1 49 | zone: hel1-dc2 50 | instanceId: "0" 51 | providerId: hcloud://0 52 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/hcloud/testdata/metadata.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | - mac_address: 96:00:00:1:2:3 3 | name: eth0 4 | subnets: 5 | - ipv4: true 6 | type: dhcp 7 | - address: 2a01:4f8:1:2::1/64 8 | gateway: fe80::1 9 | ipv6: true 10 | type: static 11 | type: physical 12 | - address: 13 | - 185.12.64.2 14 | - 185.12.64.1 15 | interface: eth0 16 | type: nameserver 17 | version: 1 18 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v1-pnap.yaml: -------------------------------------------------------------------------------- 1 | version: 1 2 | config: 3 | 4 | - type: physical 5 | name: eno1np0 6 | mac_address: "3c:ec:ef:e0:45:28" 7 | mtu: 9000 8 | 9 | - type: physical 10 | name: eno2np1 11 | mac_address: "3c:ec:ef:e0:45:29" 12 | mtu: 9000 13 | 14 | - type: bond 15 | name: bond0 16 | mac_address: "3c:ec:ef:e0:45:28" 17 | mtu: 9000 18 | bond_interfaces: 19 | - eno1np0 20 | - eno2np1 21 | params: 22 | bond-lacp-rate: fast 23 | bond-miimon: 100 24 | bond-mode: 802.3ad 25 | bond-xmit-hash-policy: layer3+4 26 | up-delay: 0 27 | down-delay: 0 28 | 29 | # public frontend MERGED_FRONTEND vlan 2 30 | - type: vlan 31 | name: bond0.2 32 | mtu: 9000 33 | vlan_id: 2 34 | vlan_link: bond0 35 | subnets: 36 | - address: 1.2.3.4/29 37 | gateway: 1.2.3.5 38 | type: static 39 | 40 | # private backend vlan 4 41 | - type: vlan 42 | mtu: 9000 43 | name: bond0.4 44 | vlan_id: 4 45 | vlan_link: bond0 46 | subnets: 47 | - type: static 48 | address: 10.0.0.11/24 49 | 50 | - type: nameserver 51 | address: 52 | - 8.8.8.8 53 | - 8.8.4.4 54 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v1.yaml: -------------------------------------------------------------------------------- 1 | version: 1 2 | config: 3 | - type: physical 4 | name: eth0 5 | mac_address: '68:05:ca:b8:f1:f7' 6 | subnets: 7 | - type: static 8 | address: '192.168.1.11' 9 | netmask: '255.255.255.0' 10 | gateway: '192.168.1.1' 11 | - type: static6 12 | address: '2001:2:3:4:5:6:7:f7/64' 13 | gateway: 'fe80::1' 14 | - type: physical 15 | name: eth1 16 | mac_address: '68:05:ca:b8:f1:f9' 17 | subnets: 18 | - type: static 19 | address: '192.168.2.11' 20 | netmask: '255.255.255.0' 21 | gateway: '192.168.2.1' 22 | - type: static6 23 | address: '2001:2:3:4:5:6:7:f9/64' 24 | gateway: 'fe80::2' 25 | - type: nameserver 26 | address: 27 | - '192.168.1.1' 28 | search: 29 | - 'lan' 30 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v2-serverscom.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | bonds: 3 | aggi: 4 | interfaces: 5 | - int0 6 | - int1 7 | addresses: 8 | - 10.26.98.92/29 9 | parameters: 10 | mode: 802.3ad 11 | lacp-rate: slow 12 | mii-monitor-interval: 100 13 | up-delay: 200 14 | down-delay: 200 15 | transmit-hash-policy: layer3+4 16 | routes: 17 | - to: 10.0.0.0/8 18 | via: 10.26.98.91 19 | - to: 192.168.0.0/16 20 | via: 10.26.98.91 21 | - to: 188.42.208.0/21 22 | via: 10.26.98.91 23 | agge: 24 | interfaces: 25 | - ext0 26 | - ext1 27 | addresses: 28 | - 188.42.48.188/29 29 | parameters: 30 | mode: 802.3ad 31 | lacp-rate: slow 32 | mii-monitor-interval: 100 33 | up-delay: 200 34 | down-delay: 200 35 | transmit-hash-policy: layer3+4 36 | gateway4: 188.42.48.187 37 | ethernets: 38 | int0: 39 | match: 40 | macaddress: 68:05:ca:b8:f1:f8 41 | int1: 42 | match: 43 | macaddress: 68:05:ca:b8:f1:f9 44 | ext0: 45 | match: 46 | macaddress: 3c:ec:EF:e0:45:28 47 | ext1: 48 | match: 49 | macaddress: 3c:EC:ef:e0:45:29 50 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/opennebula/opennebula_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package opennebula_test 6 | 7 | import ( 8 | _ "embed" 9 | "testing" 10 | 11 | "github.com/cosi-project/runtime/pkg/state" 12 | "github.com/cosi-project/runtime/pkg/state/impl/inmem" 13 | "github.com/cosi-project/runtime/pkg/state/impl/namespaced" 14 | "github.com/stretchr/testify/assert" 15 | "github.com/stretchr/testify/require" 16 | "gopkg.in/yaml.v3" 17 | 18 | "github.com/cozystack/talm/internal/app/machined/pkg/runtime/v1alpha1/platform/opennebula" 19 | ) 20 | 21 | //go:embed testdata/metadata.yaml 22 | var oneContextPlain []byte 23 | 24 | //go:embed testdata/expected.yaml 25 | var expectedNetworkConfig string 26 | 27 | func TestParseMetadata(t *testing.T) { 28 | o := &opennebula.OpenNebula{} 29 | st := state.WrapCore(namespaced.NewState(inmem.Build)) 30 | 31 | networkConfig, err := o.ParseMetadata(st, oneContextPlain) 32 | require.NoError(t, err) 33 | 34 | marshaled, err := yaml.Marshal(networkConfig) 35 | require.NoError(t, err) 36 | 37 | t.Log(string(marshaled)) 38 | assert.Equal(t, expectedNetworkConfig, string(marshaled)) 39 | } 40 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/opennebula/testdata/expected.yaml: -------------------------------------------------------------------------------- 1 | addresses: 2 | - address: 192.168.1.92/24 3 | linkName: eth0 4 | family: inet4 5 | scope: global 6 | flags: permanent 7 | layer: platform 8 | links: 9 | - name: eth0 10 | logical: false 11 | up: true 12 | mtu: 0 13 | kind: "" 14 | type: ether 15 | layer: platform 16 | routes: 17 | - family: inet4 18 | dst: "" 19 | src: "" 20 | gateway: 192.168.1.1 21 | outLinkName: eth0 22 | table: main 23 | priority: 1024 24 | scope: global 25 | type: unicast 26 | flags: "" 27 | protocol: static 28 | layer: platform 29 | hostnames: 30 | - hostname: code-server 31 | domainname: "" 32 | layer: platform 33 | resolvers: 34 | - dnsServers: 35 | - 192.168.1.1 36 | - 8.8.8.8 37 | - 1.1.1.1 38 | layer: platform 39 | timeServers: [] 40 | operators: [] 41 | externalIPs: [] 42 | metadata: 43 | platform: opennebula 44 | hostname: code-server 45 | instanceId: "14" 46 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/opennebula/testdata/metadata.yaml: -------------------------------------------------------------------------------- 1 | # Context variables generated by OpenNebula 2 | DISK_ID = "1" 3 | ETH0_DNS = "192.168.1.1 8.8.8.8 1.1.1.1" 4 | ETH0_EXTERNAL = "" 5 | ETH0_GATEWAY = "192.168.1.1" 6 | ETH0_IP = "192.168.1.92" 7 | ETH0_IP6 = "" 8 | ETH0_IP6_GATEWAY = "" 9 | ETH0_IP6_METHOD = "" 10 | ETH0_IP6_METRIC = "" 11 | ETH0_IP6_PREFIX_LENGTH = "" 12 | ETH0_IP6_ULA = "" 13 | ETH0_MAC = "02:00:c0:a8:01:5c" 14 | ETH0_MASK = "255.255.255.0" 15 | ETH0_METHOD = "" 16 | ETH0_METRIC = "" 17 | ETH0_MTU = "" 18 | ETH0_NETWORK = "192.168.1.0" 19 | ETH0_SEARCH_DOMAIN = "" 20 | ETH0_VLAN_ID = "3" 21 | ETH0_VROUTER_IP = "" 22 | ETH0_VROUTER_IP6 = "" 23 | ETH0_VROUTER_MANAGEMENT = "" 24 | NETWORK = "YES" 25 | SSH_PUBLIC_KEY = "" 26 | TARGET = "hda" 27 | VMID = "14" 28 | NAME = "code-server" -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/openstack/testdata/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "availability_zone": "nova", 3 | "devices": [], 4 | "hostname": "talos", 5 | "keys": [], 6 | "launch_index": 0, 7 | "name": "talos", 8 | "project_id": "39073b0a-1234-1234-1234-5e76a4bd64b2", 9 | "public_keys": {}, 10 | "uuid": "39073b0a-1234-1234-1234-5e76a4bd64b2" 11 | } 12 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/oracle/oracle_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package oracle_test 6 | 7 | import ( 8 | _ "embed" 9 | "encoding/json" 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | "github.com/stretchr/testify/require" 14 | "gopkg.in/yaml.v3" 15 | 16 | "github.com/cozystack/talm/internal/app/machined/pkg/runtime/v1alpha1/platform/oracle" 17 | ) 18 | 19 | //go:embed testdata/metadata.json 20 | var rawMetadata []byte 21 | 22 | //go:embed testdata/metadatanetwork.json 23 | var rawMetadataNetwork []byte 24 | 25 | //go:embed testdata/expected.yaml 26 | var expectedNetworkConfig string 27 | 28 | func TestParseMetadata(t *testing.T) { 29 | p := &oracle.Oracle{} 30 | 31 | var metadata oracle.MetadataConfig 32 | 33 | require.NoError(t, json.Unmarshal(rawMetadata, &metadata)) 34 | 35 | var m []oracle.NetworkConfig 36 | 37 | require.NoError(t, json.Unmarshal(rawMetadataNetwork, &m)) 38 | 39 | networkConfig, err := p.ParseMetadata(m, &metadata) 40 | require.NoError(t, err) 41 | 42 | marshaled, err := yaml.Marshal(networkConfig) 43 | require.NoError(t, err) 44 | 45 | assert.Equal(t, expectedNetworkConfig, string(marshaled)) 46 | } 47 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/oracle/testdata/expected.yaml: -------------------------------------------------------------------------------- 1 | addresses: [] 2 | links: [] 3 | routes: 4 | - family: inet6 5 | dst: "" 6 | src: "" 7 | gateway: fe80::a:b:c:d 8 | outLinkName: eth0 9 | table: main 10 | priority: 2048 11 | scope: global 12 | type: unicast 13 | flags: "" 14 | protocol: static 15 | layer: platform 16 | hostnames: 17 | - hostname: talos 18 | domainname: "" 19 | layer: platform 20 | resolvers: 21 | - dnsServers: 22 | - 169.254.169.254 23 | layer: platform 24 | timeServers: 25 | - timeServers: 26 | - 169.254.169.254 27 | layer: platform 28 | operators: 29 | - operator: dhcp6 30 | linkName: eth0 31 | requireUp: true 32 | dhcp6: 33 | routeMetric: 1024 34 | layer: platform 35 | externalIPs: [] 36 | metadata: 37 | platform: oracle 38 | hostname: talos 39 | region: phx 40 | zone: PHX-AD-1 41 | instanceType: VM.Standard.E3.Flex 42 | instanceId: ocid1.instance.oc1.phx.exampleuniqueID 43 | providerId: oci://ocid1.instance.oc1.phx.exampleuniqueID 44 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/oracle/testdata/metadatanetwork.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "vnicId": "ocid1.vnic.oc1.eu-amsterdam-1.asdasd", 4 | "privateIp": "172.16.1.11", 5 | "vlanTag": 1, 6 | "macAddr": "02:00:17:00:00:00", 7 | "virtualRouterIp": "172.16.1.1", 8 | "subnetCidrBlock": "172.16.1.0/24", 9 | "ipv6SubnetCidrBlock": "2603:a:b:c::/64", 10 | "ipv6VirtualRouterIp": "fe80::a:b:c:d", 11 | "ipv6Addresses": [ 12 | "2603:a:b:c::1234" 13 | ] 14 | } 15 | ] -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/scaleway/metadata.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package scaleway 6 | 7 | import ( 8 | "context" 9 | "encoding/json" 10 | "fmt" 11 | 12 | "github.com/scaleway/scaleway-sdk-go/api/instance/v1" 13 | 14 | "github.com/siderolabs/talos/pkg/download" 15 | ) 16 | 17 | const ( 18 | // ScalewayMetadataEndpoint is the local Scaleway endpoint. 19 | ScalewayMetadataEndpoint = "http://169.254.42.42/conf?format=json" 20 | // ScalewayUserDataEndpoint is the local Scaleway endpoint for the config. 21 | ScalewayUserDataEndpoint = "http://169.254.42.42/user_data/cloud-init" 22 | ) 23 | 24 | func (u *Scaleway) getMetadata(ctx context.Context) (*instance.Metadata, error) { 25 | metaConfigDl, err := download.Download(ctx, ScalewayMetadataEndpoint) 26 | if err != nil { 27 | return nil, fmt.Errorf("error fetching metadata: %w", err) 28 | } 29 | 30 | var meta instance.Metadata 31 | if err = json.Unmarshal(metaConfigDl, &meta); err != nil { 32 | return nil, err 33 | } 34 | 35 | return &meta, nil 36 | } 37 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/scaleway/testdata/expected-v3.yaml: -------------------------------------------------------------------------------- 1 | addresses: 2 | - address: 2001:111:222:3333::1/64 3 | linkName: eth0 4 | family: inet6 5 | scope: global 6 | flags: permanent 7 | layer: platform 8 | links: 9 | - name: eth0 10 | logical: false 11 | up: true 12 | mtu: 0 13 | kind: "" 14 | type: netrom 15 | layer: platform 16 | routes: 17 | - family: inet4 18 | dst: 169.254.42.42/32 19 | src: "" 20 | gateway: "" 21 | outLinkName: eth0 22 | table: main 23 | priority: 4096 24 | scope: link 25 | type: unicast 26 | flags: "" 27 | protocol: static 28 | layer: platform 29 | - family: inet6 30 | dst: "" 31 | src: "" 32 | gateway: fe80::dc00:ff:fe12:3456 33 | outLinkName: eth0 34 | table: main 35 | priority: 2048 36 | scope: global 37 | type: unicast 38 | flags: "" 39 | protocol: static 40 | layer: platform 41 | hostnames: 42 | - hostname: scw-talos 43 | domainname: "" 44 | layer: platform 45 | resolvers: [] 46 | timeServers: [] 47 | operators: [] 48 | externalIPs: 49 | - 2001:111:222:3333::1 50 | metadata: 51 | platform: scaleway 52 | hostname: scw-talos 53 | region: nl-ams 54 | zone: nl-ams-1 55 | instanceType: DEV1-S 56 | instanceId: 11111111-1111-1111-1111-111111111111 57 | providerId: scaleway://instance/nl-ams-1/11111111-1111-1111-1111-111111111111 58 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/scaleway/testdata/metadata-v1.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "11111111-1111-1111-1111-111111111111", 3 | "name": "scw-talos", 4 | "commercial_type": "DEV1-S", 5 | "hostname": "scw-talos", 6 | "tags": [], 7 | "state_detail": "booted", 8 | "public_ip": { 9 | "id": "11111111-1111-1111-1111-111111111111", 10 | "address": "11.22.222.222", 11 | "dynamic": false, 12 | "family": "inet" 13 | }, 14 | "public_ips_v4": [ 15 | { 16 | "address": "11.22.222.222", 17 | "dynamic": false, 18 | "family": "inet", 19 | "gateway": null, 20 | "id": "11111111-1111-1111-1111-111111111111", 21 | "ipam_id": null, 22 | "netmask": "32", 23 | "provisioning_mode": "dhcp", 24 | "state": "detached", 25 | "tags": [] 26 | } 27 | ], 28 | "public_ips_v6": [], 29 | "private_ip": "10.00.222.222", 30 | "ipv6": { 31 | "address": "2001:111:222:3333::1", 32 | "gateway": "2001:111:222:3333::", 33 | "netmask": "64" 34 | }, 35 | "location": { 36 | "zone_id": "fr-par-1" 37 | } 38 | } -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/scaleway/testdata/metadata-v2.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "11111111-1111-1111-1111-111111111111", 3 | "name": "scw-talos", 4 | "commercial_type": "DEV1-S", 5 | "hostname": "scw-talos", 6 | "tags": [], 7 | "state_detail": "booted", 8 | "public_ip": { 9 | "id": "11111111-1111-1111-1111-111111111111", 10 | "address": "11.22.222.222", 11 | "dynamic": false, 12 | "family": "inet" 13 | }, 14 | "public_ips_v4": [ 15 | { 16 | "address": "11.22.222.222", 17 | "dynamic": false, 18 | "family": "inet", 19 | "gateway": "11.22.222.1", 20 | "netmask": "32" 21 | } 22 | ], 23 | "public_ips_v6": [ 24 | { 25 | "address": "2001:111:222:3333::1", 26 | "dynamic": false, 27 | "family": "inet6", 28 | "gateway": "fe80::dc00:ff:fe12:3456", 29 | "netmask": "64" 30 | } 31 | ], 32 | "location": { 33 | "zone_id": "fr-par-2" 34 | } 35 | } -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/scaleway/testdata/metadata-v3.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "11111111-1111-1111-1111-111111111111", 3 | "name": "scw-talos", 4 | "commercial_type": "DEV1-S", 5 | "hostname": "scw-talos", 6 | "tags": [], 7 | "state_detail": "booted", 8 | "public_ip": { 9 | "id": "11111111-1111-1111-1111-111111111111", 10 | "address": "2001:111:222:3333::1", 11 | "dynamic": false 12 | }, 13 | "public_ips_v4": [], 14 | "public_ips_v6": [ 15 | { 16 | "address": "2001:111:222:3333::1", 17 | "dynamic": false, 18 | "family": "inet6", 19 | "gateway": "fe80::dc00:ff:fe12:3456", 20 | "netmask": "64" 21 | } 22 | ], 23 | "location": { 24 | "zone_id": "ams1" 25 | } 26 | } -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/upcloud/upcloud_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package upcloud_test 6 | 7 | import ( 8 | _ "embed" 9 | "encoding/json" 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | "github.com/stretchr/testify/require" 14 | "gopkg.in/yaml.v3" 15 | 16 | "github.com/cozystack/talm/internal/app/machined/pkg/runtime/v1alpha1/platform/upcloud" 17 | ) 18 | 19 | //go:embed testdata/metadata.json 20 | var rawMetadata []byte 21 | 22 | //go:embed testdata/expected.yaml 23 | var expectedNetworkConfig string 24 | 25 | func TestParseMetadata(t *testing.T) { 26 | p := &upcloud.UpCloud{} 27 | 28 | var metadata upcloud.MetadataConfig 29 | 30 | require.NoError(t, json.Unmarshal(rawMetadata, &metadata)) 31 | 32 | networkConfig, err := p.ParseMetadata(&metadata) 33 | require.NoError(t, err) 34 | 35 | marshaled, err := yaml.Marshal(networkConfig) 36 | require.NoError(t, err) 37 | 38 | assert.Equal(t, expectedNetworkConfig, string(marshaled)) 39 | } 40 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/vmware/testdata/expected-match-by-mac.yaml: -------------------------------------------------------------------------------- 1 | addresses: 2 | - address: 192.168.0.230/24 3 | linkName: eth2 4 | family: inet4 5 | scope: global 6 | flags: permanent 7 | layer: platform 8 | links: 9 | - name: eth2 10 | logical: false 11 | up: true 12 | mtu: 0 13 | kind: "" 14 | type: netrom 15 | layer: platform 16 | routes: 17 | - family: inet4 18 | dst: "" 19 | src: "" 20 | gateway: 192.168.0.1 21 | outLinkName: eth2 22 | table: main 23 | priority: 1024 24 | scope: global 25 | type: unicast 26 | flags: "" 27 | protocol: static 28 | layer: platform 29 | hostnames: 30 | - hostname: vmware-test-controlplane-zhnhr 31 | domainname: "" 32 | layer: platform 33 | resolvers: [] 34 | timeServers: [] 35 | operators: [] 36 | externalIPs: [] 37 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/vmware/testdata/expected-match-by-name.yaml: -------------------------------------------------------------------------------- 1 | addresses: 2 | - address: 192.168.0.230/24 3 | linkName: eth1 4 | family: inet4 5 | scope: global 6 | flags: permanent 7 | layer: platform 8 | links: 9 | - name: eth1 10 | logical: false 11 | up: true 12 | mtu: 0 13 | kind: "" 14 | type: netrom 15 | layer: platform 16 | routes: 17 | - family: inet4 18 | dst: "" 19 | src: "" 20 | gateway: 192.168.0.1 21 | outLinkName: eth1 22 | table: main 23 | priority: 1024 24 | scope: global 25 | type: unicast 26 | flags: "" 27 | protocol: static 28 | layer: platform 29 | hostnames: 30 | - hostname: vmware-test-controlplane-zhnhr 31 | domainname: "" 32 | layer: platform 33 | resolvers: [] 34 | timeServers: [] 35 | operators: [] 36 | externalIPs: [] 37 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/vmware/testdata/metadata-match-by-mac.yaml: -------------------------------------------------------------------------------- 1 | instance-id: "1" 2 | local-hostname: "vmware-test-controlplane-zhnhr" 3 | wait-on-network: 4 | ipv4: false 5 | ipv6: false 6 | network: 7 | version: 2 8 | ethernets: 9 | id0: 10 | match: 11 | macaddress: "68:05:ca:b8:f1:f9" 12 | set-name: "eth0" 13 | wakeonlan: true 14 | addresses: 15 | - "192.168.0.230/24" 16 | gateway4: "192.168.0.1" -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/vmware/testdata/metadata-match-by-name.yaml: -------------------------------------------------------------------------------- 1 | instance-id: "1" 2 | local-hostname: "vmware-test-controlplane-zhnhr" 3 | wait-on-network: 4 | ipv4: false 5 | ipv6: false 6 | network: 7 | version: 2 8 | ethernets: 9 | id0: 10 | match: 11 | name: "eth1" 12 | set-name: "eth1" 13 | wakeonlan: true 14 | addresses: 15 | - "192.168.0.230/24" 16 | gateway4: "192.168.0.1" -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/vmware/vmware.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package vmware provides the VMware platform implementation. 6 | package vmware 7 | 8 | import ( 9 | "github.com/siderolabs/go-procfs/procfs" 10 | 11 | "github.com/cozystack/talm/internal/app/machined/pkg/runtime" 12 | "github.com/siderolabs/talos/pkg/machinery/constants" 13 | ) 14 | 15 | // VMware is the concrete type that implements the platform.Platform interface. 16 | type VMware struct{} 17 | 18 | // Name implements the platform.Platform interface. 19 | func (v *VMware) Name() string { 20 | return "vmware" 21 | } 22 | 23 | // Mode implements the platform.Platform interface. 24 | func (v *VMware) Mode() runtime.Mode { 25 | return runtime.ModeCloud 26 | } 27 | 28 | // KernelArgs implements the runtime.Platform interface. 29 | func (v *VMware) KernelArgs(arch string) procfs.Parameters { 30 | switch arch { 31 | case "amd64": 32 | return []*procfs.Parameter{ 33 | procfs.NewParameter(constants.KernelParamConfig).Append(constants.ConfigGuestInfo), 34 | procfs.NewParameter("console").Append("tty0").Append("ttyS0"), 35 | procfs.NewParameter("earlyprintk").Append("ttyS0,115200"), 36 | procfs.NewParameter(constants.KernelParamNetIfnames).Append("0"), 37 | } 38 | default: 39 | return nil // not supported on !amd64 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/vmware/vmware_other.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | //go:build !amd64 6 | 7 | package vmware 8 | 9 | import ( 10 | "context" 11 | "errors" 12 | 13 | "github.com/cosi-project/runtime/pkg/state" 14 | 15 | "github.com/cozystack/talm/internal/app/machined/pkg/runtime" 16 | ) 17 | 18 | // Configuration implements the platform.Platform interface. 19 | func (v *VMware) Configuration(context.Context, state.State) ([]byte, error) { 20 | return nil, errors.New("arch not supported") 21 | } 22 | 23 | // NetworkConfiguration implements the runtime.Platform interface. 24 | func (v *VMware) NetworkConfiguration(ctx context.Context, _ state.State, ch chan<- *runtime.PlatformNetworkConfig) error { 25 | return nil 26 | } 27 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/vultr/metadata.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package vultr 6 | 7 | import ( 8 | "context" 9 | "encoding/json" 10 | "fmt" 11 | 12 | "github.com/vultr/metadata" 13 | 14 | "github.com/siderolabs/talos/pkg/download" 15 | ) 16 | 17 | const ( 18 | // VultrMetadataEndpoint is the local Vultr endpoint fot the instance metadata. 19 | VultrMetadataEndpoint = "http://169.254.169.254/v1.json" 20 | // VultrExternalIPEndpoint is the local Vultr endpoint for the external IP. 21 | VultrExternalIPEndpoint = "http://169.254.169.254/latest/meta-data/public-ipv4" 22 | // VultrUserDataEndpoint is the local Vultr endpoint for the config. 23 | VultrUserDataEndpoint = "http://169.254.169.254/latest/user-data" 24 | ) 25 | 26 | func (g *Vultr) getMetadata(ctx context.Context) (*metadata.MetaData, error) { 27 | metaConfigDl, err := download.Download(ctx, VultrMetadataEndpoint) 28 | if err != nil { 29 | return nil, fmt.Errorf("error fetching metadata: %w", err) 30 | } 31 | 32 | var meta metadata.MetaData 33 | if err = json.Unmarshal(metaConfigDl, &meta); err != nil { 34 | return nil, err 35 | } 36 | 37 | return &meta, nil 38 | } 39 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/vultr/testdata/expected.yaml: -------------------------------------------------------------------------------- 1 | addresses: 2 | - address: 95.111.222.111/23 3 | linkName: eth0 4 | family: inet4 5 | scope: global 6 | flags: permanent 7 | layer: platform 8 | - address: 10.7.96.3/20 9 | linkName: eth1 10 | family: inet4 11 | scope: global 12 | flags: permanent 13 | layer: platform 14 | links: 15 | - name: eth0 16 | logical: false 17 | up: true 18 | mtu: 0 19 | kind: "" 20 | type: netrom 21 | layer: platform 22 | - name: eth1 23 | logical: false 24 | up: true 25 | mtu: 1450 26 | kind: "" 27 | type: netrom 28 | layer: platform 29 | routes: 30 | - family: inet4 31 | dst: "" 32 | src: "" 33 | gateway: 95.111.222.1 34 | outLinkName: eth0 35 | table: main 36 | scope: global 37 | type: unicast 38 | flags: "" 39 | protocol: static 40 | layer: platform 41 | hostnames: 42 | - hostname: talos 43 | domainname: "" 44 | layer: platform 45 | resolvers: [] 46 | timeServers: [] 47 | operators: [] 48 | externalIPs: 49 | - 95.111.222.111 50 | - 2001:19f0:5001:2095:1111:2222:3333:4444 51 | metadata: 52 | platform: vultr 53 | hostname: talos 54 | region: AMS 55 | instanceId: 91b07056-af72-4551-b15b-d57d34071be9 56 | providerId: vultr://91b07056-af72-4551-b15b-d57d34071be9 57 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha1/platform/vultr/vultr_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package vultr_test 6 | 7 | import ( 8 | _ "embed" 9 | "encoding/json" 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | "github.com/stretchr/testify/require" 14 | "github.com/vultr/metadata" 15 | "gopkg.in/yaml.v3" 16 | 17 | "github.com/cozystack/talm/internal/app/machined/pkg/runtime/v1alpha1/platform/vultr" 18 | ) 19 | 20 | //go:embed testdata/metadata.json 21 | var rawMetadata []byte 22 | 23 | //go:embed testdata/expected.yaml 24 | var expectedNetworkConfig string 25 | 26 | func TestParseMetadata(t *testing.T) { 27 | p := &vultr.Vultr{} 28 | 29 | var metadata metadata.MetaData 30 | 31 | require.NoError(t, json.Unmarshal(rawMetadata, &metadata)) 32 | 33 | networkConfig, err := p.ParseMetadata(&metadata) 34 | require.NoError(t, err) 35 | 36 | marshaled, err := yaml.Marshal(networkConfig) 37 | require.NoError(t, err) 38 | 39 | assert.Equal(t, expectedNetworkConfig, string(marshaled)) 40 | } 41 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/runtime/v1alpha2/v1alpha2.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package v1alpha2 provides runtime implementation based on os-runtime. 6 | package v1alpha2 7 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/startup/startup.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package startup provides machined startup tasks. 6 | package startup 7 | 8 | import ( 9 | "context" 10 | 11 | "go.uber.org/zap" 12 | 13 | "github.com/cozystack/talm/internal/app/machined/pkg/runtime" 14 | ) 15 | 16 | // Task is a function that performs a startup task. 17 | // 18 | // It is supposed to call the next task in the chain. 19 | type Task func(context.Context, *zap.Logger, runtime.Runtime, NextTaskFunc) error 20 | 21 | // NextTaskFunc is a function which returns the next task in the chain. 22 | type NextTaskFunc func() Task 23 | 24 | // RunTasks runs the given tasks in order. 25 | func RunTasks(ctx context.Context, log *zap.Logger, rt runtime.Runtime, tasks ...Task) error { 26 | var idx int 27 | 28 | nextTaskFunc := func() Task { 29 | idx++ 30 | 31 | return tasks[idx] 32 | } 33 | 34 | return tasks[0](ctx, log, rt, nextTaskFunc) 35 | } 36 | 37 | // DefaultTasks returns the default startup tasks. 38 | func DefaultTasks() []Task { 39 | return []Task{ 40 | LogMode, 41 | MountPseudoLate, 42 | SetupSystemDirectories, 43 | InitVolumeLifecycle, 44 | MountCgroups, 45 | SetRLimit, 46 | SetEnvironmentVariables, 47 | WriteIMAPolicy, 48 | CreateSystemCgroups, 49 | OSRelease, 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/system/export_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package system 6 | 7 | import ( 8 | "github.com/cozystack/talm/internal/app/machined/pkg/runtime" 9 | "github.com/siderolabs/talos/pkg/conditions" 10 | ) 11 | 12 | func NewServices(runtime runtime.Runtime) *singleton { //nolint:revive 13 | return newServices(runtime) 14 | } 15 | 16 | func WaitForServiceWithInstance(instance *singleton, event StateEvent, service string) conditions.Condition { 17 | return waitForService(instance, event, service) 18 | } 19 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/system/health/settings.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package health 6 | 7 | import "time" 8 | 9 | // Settings configures health check 10 | // 11 | // Fields are similar to k8s pod probe definitions. 12 | type Settings struct { 13 | InitialDelay time.Duration 14 | Period time.Duration 15 | Timeout time.Duration 16 | } 17 | 18 | // DefaultSettings provides some default health check settings. 19 | var DefaultSettings = Settings{ 20 | InitialDelay: time.Second, 21 | Period: 5 * time.Second, 22 | Timeout: 500 * time.Millisecond, 23 | } 24 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/system/runner/containerd/opts.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package containerd 6 | 7 | import ( 8 | "context" 9 | 10 | "github.com/containerd/containerd/v2/contrib/seccomp" 11 | "github.com/containerd/containerd/v2/core/containers" 12 | "github.com/containerd/containerd/v2/pkg/oci" 13 | specs "github.com/opencontainers/runtime-spec/specs-go" 14 | ) 15 | 16 | // WithRootfsPropagation sets the root filesystem propagation. 17 | func WithRootfsPropagation(rp string) oci.SpecOpts { 18 | return func(_ context.Context, _ oci.Client, _ *containers.Container, s *specs.Spec) error { 19 | s.Linux.RootfsPropagation = rp 20 | 21 | return nil 22 | } 23 | } 24 | 25 | // WithOOMScoreAdj sets the oom score. 26 | func WithOOMScoreAdj(score int) oci.SpecOpts { 27 | return func(_ context.Context, _ oci.Client, _ *containers.Container, s *specs.Spec) error { 28 | s.Process.OOMScoreAdj = &score 29 | 30 | return nil 31 | } 32 | } 33 | 34 | // WithCustomSeccompProfile allows to override default seccomp profile. 35 | func WithCustomSeccompProfile(override func(*specs.LinuxSeccomp)) oci.SpecOpts { 36 | return func(_ context.Context, _ oci.Client, _ *containers.Container, s *specs.Spec) error { 37 | s.Linux.Seccomp = seccomp.DefaultProfile(s) 38 | 39 | override(s.Linux.Seccomp) 40 | 41 | return nil 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/system/runner/containerd/stdin.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package containerd 6 | 7 | import ( 8 | "context" 9 | "io" 10 | 11 | containerd "github.com/containerd/containerd/v2/client" 12 | ) 13 | 14 | // StdinCloser wraps io.Reader providing a signal when reader is read till EOF. 15 | type StdinCloser struct { 16 | Stdin io.Reader 17 | Closer chan struct{} 18 | } 19 | 20 | func (s *StdinCloser) Read(p []byte) (int, error) { 21 | n, err := s.Stdin.Read(p) 22 | if err == io.EOF { 23 | close(s.Closer) 24 | } 25 | 26 | return n, err 27 | } 28 | 29 | // WaitAndClose closes containerd task stdin when StdinCloser is exhausted. 30 | func (s *StdinCloser) WaitAndClose(ctx context.Context, task containerd.Task) { 31 | select { 32 | case <-ctx.Done(): 33 | return 34 | case <-s.Closer: 35 | //nolint:errcheck 36 | task.CloseIO(ctx, containerd.WithStdinCloser) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/system/runner/runner_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package runner_test 6 | 7 | import "testing" 8 | 9 | func TestEmpty(t *testing.T) { 10 | // added for accurate coverage estimation 11 | // 12 | // please remove it once any unit-test is added 13 | // for this package 14 | } 15 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/system/services/export_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package services 6 | 7 | import "github.com/containerd/containerd/v2/pkg/oci" 8 | 9 | // GetOCIOptions gets all OCI options from an Extension. 10 | func (svc *Extension) GetOCIOptions() ([]oci.SpecOpts, error) { 11 | envVars, err := svc.parseEnvironment() 12 | if err != nil { 13 | return nil, err 14 | } 15 | 16 | return svc.getOCIOptions(envVars, svc.Spec.Container.Mounts), nil 17 | } 18 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/system/services/registry/app/main.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package main 6 | 7 | import ( 8 | "context" 9 | "fmt" 10 | "os" 11 | "os/signal" 12 | "path/filepath" 13 | 14 | "go.uber.org/zap" 15 | 16 | "github.com/cozystack/talm/internal/app/machined/pkg/system/services/registry" 17 | ) 18 | 19 | func main() { 20 | if err := app(); err != nil { 21 | fmt.Fprintf(os.Stderr, "error: %v\n", err) 22 | os.Exit(1) 23 | } 24 | } 25 | 26 | func app() error { 27 | ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) 28 | defer cancel() 29 | 30 | development, err := zap.NewDevelopment() 31 | if err != nil { 32 | return fmt.Errorf("failed to create development logger: %w", err) 33 | } 34 | 35 | homeDir, err := os.UserHomeDir() 36 | if err != nil { 37 | return fmt.Errorf("failed to get user home directory: %w", err) 38 | } 39 | 40 | it := func(yield func(string) bool) { 41 | for _, root := range []string{"registry-cache-2", "registry-cache"} { 42 | if !yield(filepath.Join(homeDir, root)) { 43 | return 44 | } 45 | } 46 | } 47 | 48 | return registry.NewService(registry.NewMultiPathFS(it), development).Run(ctx) 49 | } 50 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/system/services/utils.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package services 6 | 7 | import ( 8 | "fmt" 9 | "os" 10 | "path/filepath" 11 | 12 | "golang.org/x/sys/unix" 13 | 14 | "github.com/siderolabs/talos/pkg/machinery/constants" 15 | ) 16 | 17 | // prepareRootfs creates /system/libexec/ rootfs and bind-mounts /sbin/init there. 18 | func prepareRootfs(id string) error { 19 | rootfsPath := filepath.Join(constants.SystemLibexecPath, id) 20 | 21 | if err := os.MkdirAll(rootfsPath, 0o711); err != nil { // rwx--x--x, non-root programs should be able to follow path 22 | return fmt.Errorf("failed to create rootfs %q: %w", rootfsPath, err) 23 | } 24 | 25 | executablePath := filepath.Join(rootfsPath, id) 26 | 27 | if err := os.WriteFile(executablePath, nil, 0o555); err != nil { // r-xr-xr-x, non-root programs should be able to execute & read 28 | return fmt.Errorf("failed to create empty executable %q: %w", executablePath, err) 29 | } 30 | 31 | if err := unix.Mount("/sbin/init", executablePath, "", unix.MS_BIND, ""); err != nil { 32 | return fmt.Errorf("failed to create bind mount for %q: %w", executablePath, err) 33 | } 34 | 35 | return nil 36 | } 37 | -------------------------------------------------------------------------------- /internal/app/machined/pkg/xcontext/xcontext.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package xcontext provides a small utils for context package 6 | package xcontext 7 | 8 | import "context" 9 | 10 | // AfterFuncSync is like [context.AfterFunc] but it blocks until the function is executed. 11 | func AfterFuncSync(ctx context.Context, fn func()) func() bool { 12 | stopChan := make(chan struct{}) 13 | 14 | stop := context.AfterFunc(ctx, func() { 15 | defer close(stopChan) 16 | 17 | fn() 18 | }) 19 | 20 | return func() bool { 21 | result := stop() 22 | if !result { 23 | <-stopChan 24 | } 25 | 26 | return result 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /internal/app/maintenance/controller.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package maintenance 6 | 7 | import "github.com/cozystack/talm/internal/app/machined/pkg/runtime" 8 | 9 | var runtimeController runtime.Controller 10 | 11 | // InjectController is used to pass the controller into the maintenance service. 12 | func InjectController(c runtime.Controller) { 13 | runtimeController = c 14 | } 15 | -------------------------------------------------------------------------------- /internal/pkg/cgroups/raw.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package cgroups 6 | 7 | import ( 8 | "bufio" 9 | "io" 10 | ) 11 | 12 | // RawValue is a raw cgroup value (without any parsing). 13 | type RawValue string 14 | 15 | // ParseRawValue parses the raw cgroup value. 16 | func ParseRawValue(r io.Reader) (RawValue, error) { 17 | scanner := bufio.NewScanner(r) 18 | 19 | if !scanner.Scan() { 20 | return RawValue(""), nil 21 | } 22 | 23 | line := scanner.Text() 24 | 25 | if err := scanner.Err(); err != nil { 26 | return RawValue(""), err 27 | } 28 | 29 | return RawValue(line), nil 30 | } 31 | -------------------------------------------------------------------------------- /internal/pkg/cgroups/tar.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package cgroups 6 | 7 | import ( 8 | "archive/tar" 9 | "compress/gzip" 10 | "fmt" 11 | "io" 12 | "path/filepath" 13 | ) 14 | 15 | // TreeFromTarGz builds a crgroup tree from the tar.gz reader. 16 | // 17 | // It is assumed to work with output of `talosctl cp /sys/fs/cgroup -`. 18 | func TreeFromTarGz(r io.Reader) (*Tree, error) { 19 | gzReader, err := gzip.NewReader(r) 20 | if err != nil { 21 | return nil, err 22 | } 23 | 24 | defer gzReader.Close() //nolint:errcheck 25 | 26 | tarReader := tar.NewReader(gzReader) 27 | 28 | tree := &Tree{ 29 | Root: &Node{}, 30 | } 31 | 32 | for { 33 | header, err := tarReader.Next() 34 | if err == io.EOF { 35 | break 36 | } 37 | 38 | if err != nil { 39 | return nil, err 40 | } 41 | 42 | if header.Typeflag != tar.TypeReg { 43 | continue 44 | } 45 | 46 | directory, filename := filepath.Split(header.Name) 47 | 48 | node := tree.Find(directory) 49 | 50 | if err = node.Parse(filename, tarReader); err != nil { 51 | return nil, fmt.Errorf("failed to parse %q: %w", header.Name, err) 52 | } 53 | } 54 | 55 | return tree, nil 56 | } 57 | -------------------------------------------------------------------------------- /internal/pkg/cgroups/tar_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package cgroups_test 6 | 7 | import ( 8 | "os" 9 | "testing" 10 | 11 | "github.com/stretchr/testify/assert" 12 | "github.com/stretchr/testify/require" 13 | 14 | "github.com/cozystack/talm/internal/pkg/cgroups" 15 | ) 16 | 17 | func TestTreeFromTarGz(t *testing.T) { 18 | t.Parallel() 19 | 20 | tarFile, err := os.Open("testdata/cgroup.tar.gz") 21 | require.NoError(t, err) 22 | 23 | t.Cleanup(func() { 24 | assert.NoError(t, tarFile.Close()) 25 | }) 26 | 27 | tree, err := cgroups.TreeFromTarGz(tarFile) 28 | require.NoError(t, err) 29 | 30 | assert.Equal(t, []string{"init", "kubepods", "podruntime", "system"}, tree.Root.SortedChildren()) 31 | assert.Equal(t, "114712576", tree.Find("init").MemoryCurrent.String()) 32 | } 33 | -------------------------------------------------------------------------------- /internal/pkg/cgroups/testdata/cgroup.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozystack/talm/10bbb87b0753245d283e1116128d2c968162e142/internal/pkg/cgroups/testdata/cgroup.tar.gz -------------------------------------------------------------------------------- /internal/pkg/containers/containers_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package containers_test 6 | 7 | import ( 8 | "testing" 9 | ) 10 | 11 | func TestEmpty(t *testing.T) { 12 | // replace with real test 13 | } 14 | -------------------------------------------------------------------------------- /internal/pkg/containers/cri/containerd/config.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package containerd 6 | 7 | // AuthConfig represents the registry auth options. 8 | type AuthConfig struct { 9 | Username string `toml:"username"` 10 | Password string `toml:"password"` 11 | Auth string `toml:"auth"` 12 | IdentityToken string `toml:"identitytoken"` 13 | } 14 | 15 | // RegistryConfig represents a registry. 16 | type RegistryConfig struct { 17 | Auth *AuthConfig `toml:"auth"` 18 | } 19 | 20 | // Registry represents the registry configuration. 21 | type Registry struct { 22 | ConfigPath string `toml:"config_path"` 23 | Configs map[string]RegistryConfig `toml:"configs"` 24 | } 25 | 26 | // CRIConfig represents the CRI config. 27 | type CRIConfig struct { 28 | Registry Registry `toml:"registry"` 29 | } 30 | 31 | // PluginsConfig represents the CRI plugins config. 32 | type PluginsConfig struct { 33 | CRI CRIConfig `toml:"io.containerd.cri.v1.images"` 34 | } 35 | 36 | // Config represnts the containerd config. 37 | type Config struct { 38 | Plugins PluginsConfig `toml:"plugins"` 39 | } 40 | -------------------------------------------------------------------------------- /internal/pkg/containers/cri/containerd/testdata/cri.toml: -------------------------------------------------------------------------------- 1 | [plugins] 2 | [plugins.'io.containerd.cri.v1.images'] 3 | [plugins.'io.containerd.cri.v1.images'.registry] 4 | config_path = '/etc/cri/conf.d/hosts' 5 | 6 | [plugins.'io.containerd.cri.v1.images'.registry.configs] 7 | [plugins.'io.containerd.cri.v1.images'.registry.configs.'some.host:123'] 8 | [plugins.'io.containerd.cri.v1.images'.registry.configs.'some.host:123'.auth] 9 | username = 'root' 10 | password = 'secret' 11 | auth = 'auth' 12 | identitytoken = 'token' 13 | -------------------------------------------------------------------------------- /internal/pkg/containers/inspector.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package containers 6 | 7 | import "syscall" 8 | 9 | // Inspector gather information about pods & containers. 10 | type Inspector interface { 11 | // Pods collects information about running pods & containers. 12 | Pods() ([]*Pod, error) 13 | // Container returns info about a single container. 14 | Container(id string) (*Container, error) 15 | // Close frees associated resources. 16 | Close() error 17 | // Returns path to the container's stderr pipe 18 | GetProcessStderr(ID string) (string, error) 19 | // Kill sends signal to container's process 20 | Kill(ID string, isPodSandbox bool, signal syscall.Signal) error 21 | } 22 | -------------------------------------------------------------------------------- /internal/pkg/containers/pod.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package containers 6 | 7 | // Pod presents information about a pod, including a list of containers. 8 | type Pod struct { 9 | Name string 10 | Sandbox string 11 | 12 | Containers []*Container 13 | } 14 | -------------------------------------------------------------------------------- /internal/pkg/cri/cri.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package cri provides minimal CRI client. 6 | package cri 7 | 8 | // This client is based on k8s version in https://github.com/kubernetes/kubernetes/tree/master/pkg/kubelet/remote, 9 | // but it doesn't depend on k8s libs. 10 | -------------------------------------------------------------------------------- /internal/pkg/ctxutil/ctxutil.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package ctxutil provides utilities for working with contexts. 6 | package ctxutil 7 | 8 | import "context" 9 | 10 | // Cause returns the cause of the context error, or nil if there is no error or the error is a usual context error. 11 | func Cause(ctx context.Context) error { 12 | if c := context.Cause(ctx); c != ctx.Err() { 13 | return c 14 | } 15 | 16 | return nil 17 | } 18 | -------------------------------------------------------------------------------- /internal/pkg/dashboard/apidata/apidata.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package apidata implements the types and the data sources for the data sourced from various Talos APIs. 6 | package apidata 7 | -------------------------------------------------------------------------------- /internal/pkg/dashboard/apidata/data.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package apidata implements types to handle monitoring data, calculate values from it, etc. 6 | package apidata 7 | 8 | import ( 9 | "time" 10 | ) 11 | 12 | const maxPoints = 1000 13 | 14 | // Data represents the monitoring data retrieved via Talos API. 15 | // 16 | // Data structure is sent over the channel each interval. 17 | type Data struct { 18 | // Data per each node. 19 | Nodes map[string]*Node 20 | 21 | Timestamp time.Time 22 | Interval time.Duration 23 | } 24 | 25 | // CalculateDiff with data from previous iteration. 26 | func (data *Data) CalculateDiff(oldData *Data) { 27 | data.Interval = data.Timestamp.Sub(oldData.Timestamp) 28 | 29 | for node, nodeData := range data.Nodes { 30 | oldNodeData := oldData.Nodes[node] 31 | if oldNodeData == nil { 32 | continue 33 | } 34 | 35 | nodeData.UpdateDiff(oldNodeData) 36 | nodeData.UpdateSeries(oldNodeData) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /internal/pkg/dashboard/components/horizontalline.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package components 6 | 7 | import ( 8 | "github.com/gdamore/tcell/v2" 9 | "github.com/rivo/tview" 10 | ) 11 | 12 | // HorizontalLine is a widget that draws a horizontal line. 13 | type HorizontalLine struct { 14 | tview.TextView 15 | 16 | label []rune 17 | } 18 | 19 | // NewHorizontalLine initializes HorizontalLine. 20 | func NewHorizontalLine(label string) *HorizontalLine { 21 | widget := &HorizontalLine{ 22 | TextView: *tview.NewTextView(), 23 | label: []rune(" " + label + " "), 24 | } 25 | 26 | const leftGap = 2 27 | 28 | // set the background to be a horizontal line 29 | widget.SetDrawFunc(func(screen tcell.Screen, x, y, width, height int) (int, int, int, int) { 30 | labelLength := len(widget.label) 31 | 32 | for i := x; i < x+width; i++ { 33 | for j := y; j < y+height; j++ { 34 | if j == y && i >= leftGap && i-leftGap < labelLength { 35 | screen.SetContent(i, j, widget.label[i-leftGap], nil, tcell.StyleDefault.Foreground(tcell.ColorYellow)) 36 | } else { 37 | screen.SetContent(i, j, tview.BoxDrawingsLightHorizontal, nil, tcell.StyleDefault.Foreground(tcell.ColorWhite)) 38 | } 39 | } 40 | } 41 | 42 | return x, y, width, height 43 | }) 44 | 45 | return widget 46 | } 47 | -------------------------------------------------------------------------------- /internal/pkg/dashboard/components/tables_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package components_test 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/cozystack/talm/internal/pkg/dashboard/apidata" 11 | "github.com/cozystack/talm/internal/pkg/dashboard/components" 12 | "github.com/siderolabs/talos/pkg/machinery/api/machine" 13 | ) 14 | 15 | func TestUpdate(t *testing.T) { 16 | testProcessTable := components.NewProcessTable() 17 | 18 | testData := &apidata.Data{ 19 | Nodes: map[string]*apidata.Node{ 20 | "node1": { 21 | Processes: &machine.Process{ 22 | Processes: []*machine.ProcessInfo{}, 23 | }, 24 | ProcsDiff: map[int32]*machine.ProcessInfo{ 25 | 1: {}, 26 | }, 27 | Series: map[string][]float64{}, 28 | }, 29 | "node2": { 30 | ProcsDiff: map[int32]*machine.ProcessInfo{ 31 | 1: {}, 32 | }, 33 | }, 34 | }, 35 | } 36 | testProcessTable.OnAPIDataChange("node1", testData) 37 | // Node2 does not have processes, without the check it panics 38 | testProcessTable.OnAPIDataChange("node2", testData) 39 | } 40 | -------------------------------------------------------------------------------- /internal/pkg/dashboard/context.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package dashboard 6 | 7 | import ( 8 | "context" 9 | 10 | "google.golang.org/grpc/metadata" 11 | 12 | "github.com/siderolabs/talos/pkg/machinery/client" 13 | ) 14 | 15 | func nodeContext(ctx context.Context, selectedNode string) context.Context { 16 | md, mdOk := metadata.FromOutgoingContext(ctx) 17 | if mdOk { 18 | md.Delete("nodes") 19 | 20 | ctx = metadata.NewOutgoingContext(ctx, md) 21 | } 22 | 23 | if selectedNode != "" { 24 | ctx = client.WithNode(ctx, selectedNode) 25 | } 26 | 27 | return ctx 28 | } 29 | -------------------------------------------------------------------------------- /internal/pkg/dashboard/options.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package dashboard 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | type options struct { 12 | interval time.Duration 13 | allowExitKeys bool 14 | screens []Screen 15 | } 16 | 17 | func defaultOptions() *options { 18 | return &options{ 19 | interval: 5 * time.Second, 20 | allowExitKeys: true, 21 | screens: []Screen{ 22 | ScreenSummary, 23 | ScreenMonitor, 24 | ScreenNetworkConfig, 25 | }, 26 | } 27 | } 28 | 29 | // Option is a functional option for Dashboard. 30 | type Option func(*options) 31 | 32 | // WithInterval sets the interval for the dashboard. 33 | func WithInterval(interval time.Duration) Option { 34 | return func(o *options) { 35 | o.interval = interval 36 | } 37 | } 38 | 39 | // WithAllowExitKeys sets whether the dashboard should allow exit keys (Ctrl + C). 40 | func WithAllowExitKeys(allowExitKeys bool) Option { 41 | return func(o *options) { 42 | o.allowExitKeys = allowExitKeys 43 | } 44 | } 45 | 46 | // WithScreens sets the screens to display. 47 | // The order is preserved. 48 | func WithScreens(screens ...Screen) Option { 49 | return func(o *options) { 50 | o.screens = screens 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /internal/pkg/dashboard/resolver/resolver.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package resolver resolves the node names. 6 | package resolver 7 | 8 | // Resolver resolves the node names. 9 | type Resolver struct { 10 | db map[string]string 11 | } 12 | 13 | // New creates a new Resolver. 14 | func New(db map[string]string) Resolver { 15 | return Resolver{ 16 | db: db, 17 | } 18 | } 19 | 20 | // Resolve attempts to resolve the node name. 21 | func (n *Resolver) Resolve(node string) string { 22 | if resolved, ok := n.db[node]; ok { 23 | return resolved 24 | } 25 | 26 | return node 27 | } 28 | -------------------------------------------------------------------------------- /internal/pkg/discovery/registry/registry.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package registry provides code to push and pull Affiliates to different registries. 6 | package registry 7 | -------------------------------------------------------------------------------- /internal/pkg/encryption/encryption_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package encryption_test 6 | 7 | import ( 8 | "testing" 9 | ) 10 | 11 | func TestEmpty(t *testing.T) { 12 | // added for accurate coverage estimation 13 | // 14 | // please remove it once any unit-test is added 15 | // for this package 16 | } 17 | -------------------------------------------------------------------------------- /internal/pkg/encryption/helpers/helpers.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package helpers defines encryption handlers. 6 | package helpers 7 | 8 | import ( 9 | "context" 10 | 11 | "github.com/siderolabs/talos/pkg/machinery/resources/hardware" 12 | ) 13 | 14 | // SystemInformationGetter defines the closure which can be used in key handlers to get the node UUID. 15 | type SystemInformationGetter func(context.Context) (*hardware.SystemInformation, error) 16 | -------------------------------------------------------------------------------- /internal/pkg/encryption/keys/options.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package keys 6 | 7 | import "github.com/cozystack/talm/internal/pkg/encryption/helpers" 8 | 9 | // KeyOption represents key option callback used in KeyHandler.GetKey func. 10 | type KeyOption func(o *KeyOptions) error 11 | 12 | // KeyOptions set of options to be used in KeyHandler.GetKey func. 13 | type KeyOptions struct { 14 | VolumeID string 15 | GetSystemInformation helpers.SystemInformationGetter 16 | } 17 | 18 | // WithVolumeID passes the partition label to the key handler. 19 | func WithVolumeID(label string) KeyOption { 20 | return func(o *KeyOptions) error { 21 | o.VolumeID = label 22 | 23 | return nil 24 | } 25 | } 26 | 27 | // WithSystemInformationGetter passes the node UUID to the key handler. 28 | func WithSystemInformationGetter(getter helpers.SystemInformationGetter) KeyOption { 29 | return func(o *KeyOptions) error { 30 | o.GetSystemInformation = getter 31 | 32 | return nil 33 | } 34 | } 35 | 36 | // NewDefaultOptions creates new KeyOptions. 37 | func NewDefaultOptions(options []KeyOption) (*KeyOptions, error) { 38 | var opts KeyOptions 39 | 40 | for _, o := range options { 41 | err := o(&opts) 42 | if err != nil { 43 | return nil, err 44 | } 45 | } 46 | 47 | return &opts, nil 48 | } 49 | -------------------------------------------------------------------------------- /internal/pkg/encryption/keys/static.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package keys 6 | 7 | import ( 8 | "context" 9 | 10 | "github.com/siderolabs/go-blockdevice/v2/encryption" 11 | "github.com/siderolabs/go-blockdevice/v2/encryption/token" 12 | ) 13 | 14 | // StaticKeyHandler just handles the static key value all the time. 15 | type StaticKeyHandler struct { 16 | KeyHandler 17 | data []byte 18 | } 19 | 20 | // NewStaticKeyHandler creates new EphemeralKeyHandler. 21 | func NewStaticKeyHandler(key KeyHandler, data []byte) *StaticKeyHandler { 22 | return &StaticKeyHandler{ 23 | KeyHandler: key, 24 | data: data, 25 | } 26 | } 27 | 28 | // NewKey implements Handler interface. 29 | func (h *StaticKeyHandler) NewKey(ctx context.Context) (*encryption.Key, token.Token, error) { 30 | k, err := h.GetKey(ctx, nil) 31 | 32 | return k, nil, err 33 | } 34 | 35 | // GetKey implements Handler interface. 36 | func (h *StaticKeyHandler) GetKey(context.Context, token.Token) (*encryption.Key, error) { 37 | return encryption.NewKey(h.slot, h.data), nil 38 | } 39 | -------------------------------------------------------------------------------- /internal/pkg/encryption/keys/token.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package keys 6 | 7 | const ( 8 | // TokenTypeKMS is KMS assisted encryption token. 9 | TokenTypeKMS = "sideroKMS" 10 | // TokenTypeTPM is TPM assisted encryption token. 11 | TokenTypeTPM = "talos-tpm2" 12 | ) 13 | -------------------------------------------------------------------------------- /internal/pkg/encryption/node_params.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package encryption 6 | 7 | // NodeParams contains node information relevant for the encryption handler. 8 | type NodeParams struct { 9 | UUID string 10 | } 11 | -------------------------------------------------------------------------------- /internal/pkg/endpoint/endpoint.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package endpoint has common tools for parsing http API endpoints. 6 | package endpoint 7 | 8 | import ( 9 | "net/url" 10 | "regexp" 11 | ) 12 | 13 | var urlSchemeMatcher = regexp.MustCompile(`[a-zA-z]+://`) 14 | 15 | // Endpoint defines all params parsed from the API endpoint. 16 | type Endpoint struct { 17 | Host string 18 | Insecure bool 19 | params url.Values 20 | } 21 | 22 | // Parse parses the endpoint from string. 23 | func Parse(sideroLinkParam string) (Endpoint, error) { 24 | if !urlSchemeMatcher.MatchString(sideroLinkParam) { 25 | sideroLinkParam = "grpc://" + sideroLinkParam 26 | } 27 | 28 | u, err := url.Parse(sideroLinkParam) 29 | if err != nil { 30 | return Endpoint{}, err 31 | } 32 | 33 | result := Endpoint{ 34 | Host: u.Host, 35 | Insecure: u.Scheme == "grpc", 36 | params: u.Query(), 37 | } 38 | 39 | if u.Port() == "" && u.Scheme == "https" { 40 | result.Host += ":443" 41 | } 42 | 43 | return result, nil 44 | } 45 | 46 | // GetParam reads param from the query. 47 | func (e *Endpoint) GetParam(name string) string { 48 | return e.params.Get(name) 49 | } 50 | -------------------------------------------------------------------------------- /internal/pkg/environment/environment.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package environment provides a set of functions to get environment variables. 6 | package environment 7 | 8 | import ( 9 | "github.com/siderolabs/go-procfs/procfs" 10 | 11 | "github.com/siderolabs/talos/pkg/machinery/config" 12 | "github.com/siderolabs/talos/pkg/machinery/constants" 13 | ) 14 | 15 | // Get the desired set of the environment variables based on kernel cmdline and machine config. 16 | // 17 | // The returned value is a list of strings in the form of "key=value". 18 | func Get(cfg config.Config) []string { 19 | return GetCmdline(procfs.ProcCmdline(), cfg) 20 | } 21 | 22 | // GetCmdline the desired set of the environment variables based on kernel cmdline. 23 | func GetCmdline(cmdline *procfs.Cmdline, cfg config.Config) []string { 24 | var result []string 25 | 26 | param := cmdline.Get(constants.KernelParamEnvironment) 27 | 28 | for idx := 0; ; idx++ { 29 | val := param.Get(idx) 30 | if val == nil { 31 | break 32 | } 33 | 34 | result = append(result, *val) 35 | } 36 | 37 | if cfg != nil && cfg.Machine() != nil { 38 | for k, v := range cfg.Machine().Env() { 39 | result = append(result, k+"="+v) 40 | } 41 | } 42 | 43 | return result 44 | } 45 | -------------------------------------------------------------------------------- /internal/pkg/etcd/local.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package etcd 6 | 7 | import ( 8 | "context" 9 | "fmt" 10 | "time" 11 | 12 | "github.com/cosi-project/runtime/pkg/safe" 13 | "github.com/cosi-project/runtime/pkg/state" 14 | 15 | "github.com/siderolabs/talos/pkg/machinery/resources/etcd" 16 | ) 17 | 18 | // GetLocalMemberID gets the etcd member id of the local node via resources. 19 | func GetLocalMemberID(ctx context.Context, s state.State) (uint64, error) { 20 | ctx, cancel := context.WithTimeout(ctx, 3*time.Minute) 21 | defer cancel() 22 | 23 | member, err := safe.StateWatchFor[*etcd.Member]( 24 | ctx, 25 | s, 26 | etcd.NewMember(etcd.NamespaceName, etcd.LocalMemberID).Metadata(), 27 | state.WithEventTypes(state.Created), 28 | ) 29 | if err != nil { 30 | return 0, fmt.Errorf("failed to get local etcd member ID: %w", err) 31 | } 32 | 33 | return etcd.ParseMemberID(member.TypedSpec().MemberID) 34 | } 35 | -------------------------------------------------------------------------------- /internal/pkg/extensions/discarder.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package extensions 6 | 7 | import ( 8 | "errors" 9 | "io" 10 | ) 11 | 12 | // discarder is used to implement ReadAt from a Reader 13 | // by reading, and discarding, data until the offset 14 | // is reached. It can only go forward. It is designed 15 | // for pipe-like files. 16 | type discarder struct { 17 | r io.Reader 18 | pos int64 19 | } 20 | 21 | // ReadAt implements ReadAt for a discarder. 22 | // It is an error for the offset to be negative. 23 | func (r *discarder) ReadAt(p []byte, off int64) (int, error) { 24 | if off-r.pos < 0 { 25 | return 0, errors.New("negative seek on discarder not allowed") 26 | } 27 | 28 | if off != r.pos { 29 | i, err := io.Copy(io.Discard, io.LimitReader(r.r, off-r.pos)) 30 | if err != nil || i != off-r.pos { 31 | return 0, err 32 | } 33 | 34 | r.pos += i 35 | } 36 | 37 | n, err := io.ReadFull(r.r, p) 38 | if err != nil { 39 | return n, err 40 | } 41 | 42 | r.pos += int64(n) 43 | 44 | return n, err 45 | } 46 | 47 | var _ io.ReaderAt = &discarder{} 48 | -------------------------------------------------------------------------------- /internal/pkg/extensions/extensions.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package extensions provides function to manage system extensions. 6 | package extensions 7 | 8 | import ( 9 | "github.com/siderolabs/talos/pkg/machinery/extensions" 10 | ) 11 | 12 | // Extension wraps the extensions.Extension type with additional methods. 13 | type Extension struct { 14 | *extensions.Extension 15 | } 16 | -------------------------------------------------------------------------------- /internal/pkg/extensions/extensions_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package extensions_test 6 | 7 | import ( 8 | "os/exec" 9 | "path/filepath" 10 | "testing" 11 | 12 | "github.com/stretchr/testify/assert" 13 | "github.com/stretchr/testify/require" 14 | 15 | "github.com/cozystack/talm/internal/pkg/extensions" 16 | "github.com/siderolabs/talos/pkg/machinery/imager/quirks" 17 | ) 18 | 19 | func TestCompress(t *testing.T) { 20 | // Compress is going to change contents of the extension, copy to some temporary directory 21 | extDir := t.TempDir() 22 | 23 | require.NoError(t, exec.Command("cp", "-r", "testdata/good/extension1", extDir).Run()) 24 | 25 | exts, err := extensions.List(extDir) 26 | require.NoError(t, err) 27 | 28 | require.Len(t, exts, 1) 29 | 30 | ext := exts[0] 31 | 32 | squashDest, initramfsDest := t.TempDir(), t.TempDir() 33 | squashFile, err := ext.Compress(squashDest, initramfsDest, quirks.New("")) 34 | assert.NoError(t, err) 35 | 36 | assert.FileExists(t, squashFile) 37 | assert.FileExists(t, filepath.Join(initramfsDest, "lib", "firmware", "amd", "cpu")) 38 | } 39 | -------------------------------------------------------------------------------- /internal/pkg/extensions/list.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package extensions 6 | 7 | import ( 8 | "cmp" 9 | "fmt" 10 | "os" 11 | "path/filepath" 12 | "slices" 13 | 14 | "github.com/siderolabs/talos/pkg/machinery/extensions" 15 | ) 16 | 17 | // List prepared unpacked extensions under rootPath. 18 | func List(rootPath string) ([]*Extension, error) { 19 | items, err := os.ReadDir(rootPath) 20 | if err != nil { 21 | if os.IsNotExist(err) { 22 | return nil, nil 23 | } 24 | 25 | return nil, err 26 | } 27 | 28 | if len(items) == 0 { 29 | return nil, nil 30 | } 31 | 32 | slices.SortFunc(items, func(a, b os.DirEntry) int { return cmp.Compare(a.Name(), b.Name()) }) 33 | 34 | result := make([]*Extension, 0, len(items)) 35 | 36 | for _, item := range items { 37 | if !item.IsDir() { 38 | return nil, fmt.Errorf("unexpected non-directory entry: %q", item.Name()) 39 | } 40 | 41 | ext, err := extensions.Load(filepath.Join(rootPath, item.Name())) 42 | if err != nil { 43 | return nil, fmt.Errorf("error loading extension %s: %w", item.Name(), err) 44 | } 45 | 46 | result = append(result, &Extension{ext}) 47 | } 48 | 49 | return result, nil 50 | } 51 | -------------------------------------------------------------------------------- /internal/pkg/extensions/list_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package extensions_test 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/stretchr/testify/assert" 11 | "github.com/stretchr/testify/require" 12 | 13 | "github.com/cozystack/talm/internal/pkg/extensions" 14 | ) 15 | 16 | func TestList(t *testing.T) { 17 | extensions, err := extensions.List("testdata/good/") 18 | require.NoError(t, err) 19 | 20 | require.Len(t, extensions, 1) 21 | 22 | assert.Equal(t, "gvisor", extensions[0].Manifest.Metadata.Name) 23 | } 24 | -------------------------------------------------------------------------------- /internal/pkg/extensions/testdata/good/extension1/manifest.yaml: -------------------------------------------------------------------------------- 1 | version: v1alpha1 2 | metadata: 3 | name: gvisor 4 | version: 20220117.0-v1.0.0 5 | author: Andrew Rynhard 6 | description: > 7 | This system extension provides gVisor using containerd's runtime handler. 8 | compatibility: 9 | talos: 10 | version: ">= v1.0.0" 11 | -------------------------------------------------------------------------------- /internal/pkg/extensions/testdata/good/extension1/rootfs/lib/firmware/amd/cpu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozystack/talm/10bbb87b0753245d283e1116128d2c968162e142/internal/pkg/extensions/testdata/good/extension1/rootfs/lib/firmware/amd/cpu -------------------------------------------------------------------------------- /internal/pkg/extensions/testdata/good/extension1/rootfs/lib64/ld-linux-x86-64.so.2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozystack/talm/10bbb87b0753245d283e1116128d2c968162e142/internal/pkg/extensions/testdata/good/extension1/rootfs/lib64/ld-linux-x86-64.so.2 -------------------------------------------------------------------------------- /internal/pkg/extensions/testdata/good/extension1/rootfs/usr/local/lib/a.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozystack/talm/10bbb87b0753245d283e1116128d2c968162e142/internal/pkg/extensions/testdata/good/extension1/rootfs/usr/local/lib/a.so -------------------------------------------------------------------------------- /internal/pkg/extensions/testdata/good/extension1/rootfs/usr/local/lib/a.so.1: -------------------------------------------------------------------------------- 1 | a.so -------------------------------------------------------------------------------- /internal/pkg/logind/dbus.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package logind 6 | 7 | import "github.com/godbus/dbus/v5" 8 | 9 | const ( 10 | dbusPath = dbus.ObjectPath("/org/freedesktop/DBus") 11 | dbusInterface = "org.freedesktop.DBus" 12 | ) 13 | 14 | type dbusMock struct{} 15 | 16 | func (dbusMock) Hello() (string, *dbus.Error) { 17 | return "id", nil 18 | } 19 | 20 | func (dbusMock) AddMatch(_ string) *dbus.Error { 21 | return nil 22 | } 23 | -------------------------------------------------------------------------------- /internal/pkg/meta/internal/adv/adv.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package adv provides common interfaces to access ADV data. 6 | package adv 7 | 8 | // ADV describes implementation which stores tag-value data. 9 | type ADV interface { 10 | ReadTag(t uint8) (val string, ok bool) 11 | ReadTagBytes(t uint8) (val []byte, ok bool) 12 | SetTag(t uint8, val string) (ok bool) 13 | SetTagBytes(t uint8, val []byte) (ok bool) 14 | DeleteTag(t uint8) (ok bool) 15 | ListTags() (tags []uint8) 16 | Bytes() ([]byte, error) 17 | } 18 | 19 | const ( 20 | // End is the noop tag. 21 | End = iota 22 | _ 23 | _ 24 | // Reserved1 is a reserved tag. 25 | Reserved1 26 | // Reserved2 is a reserved tag. 27 | Reserved2 28 | // Reserved3 is a reserved tag. 29 | Reserved3 30 | ) 31 | -------------------------------------------------------------------------------- /internal/pkg/meta/internal/adv/syslinux/testdata/adv.sys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozystack/talm/10bbb87b0753245d283e1116128d2c968162e142/internal/pkg/meta/internal/adv/syslinux/testdata/adv.sys -------------------------------------------------------------------------------- /internal/pkg/miniprocfs/miniprocfs.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package miniprocfs contains optimized small interface to access /proc filesystem. 6 | package miniprocfs 7 | -------------------------------------------------------------------------------- /internal/pkg/miniprocfs/testdata/1920080/cmdline: -------------------------------------------------------------------------------- 1 | -fish -------------------------------------------------------------------------------- /internal/pkg/miniprocfs/testdata/1920080/comm: -------------------------------------------------------------------------------- 1 | fish 2 | -------------------------------------------------------------------------------- /internal/pkg/miniprocfs/testdata/1920080/exe: -------------------------------------------------------------------------------- 1 | usr/bin/fish -------------------------------------------------------------------------------- /internal/pkg/miniprocfs/testdata/1920080/stat: -------------------------------------------------------------------------------- 1 | 1920080 (fish) S 1920079 1920080 1920080 34817 497247 4194304 290636 24169180 15 32793 1888 426 1313442 30669 20 0 2 0 127957791 465002496 5805 18446744073709551615 93935540826112 93935542596848 140726024906784 0 0 0 0 2625540 135356435 0 0 0 17 15 0 0 7 0 0 93935542601152 93935542624320 93935548821504 140726024912137 140726024912143 140726024912143 140726024912874 0 2 | -------------------------------------------------------------------------------- /internal/pkg/miniprocfs/testdata/3731034/cmdline: -------------------------------------------------------------------------------- 1 | tail-F/home/smira/.talos/clusters/talos-default/talos-default-master-1.log/home/smira/.talos/clusters/talos-default/talos-default-master-2.log/home/smira/.talos/clusters/talos-default/talos-default-master-3.log/home/smira/.talos/clusters/talos-default/talos-default-worker-1.log/home/smira/.talos/clusters/talos-default/talos-default-worker-2.log -------------------------------------------------------------------------------- /internal/pkg/miniprocfs/testdata/3731034/comm: -------------------------------------------------------------------------------- 1 | tail 2 | -------------------------------------------------------------------------------- /internal/pkg/miniprocfs/testdata/3731034/exe: -------------------------------------------------------------------------------- 1 | usr/bin/tail -------------------------------------------------------------------------------- /internal/pkg/miniprocfs/testdata/3731034/stat: -------------------------------------------------------------------------------- 1 | 3731034 (tail) S 1919986 3731034 1919986 34816 3731034 4194304 106 0 0 0 44 243 0 0 20 0 1 0 139625799 8593408 230 18446744073709551615 94174076493824 94174076538145 140729409375152 0 0 0 0 0 0 1 0 0 17 1 0 0 0 0 0 94174076561648 94174076563648 94174079950848 140729409379084 140729409379437 140729409379437 140729409380330 0 2 | -------------------------------------------------------------------------------- /internal/pkg/miniprocfs/testdata/keys: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozystack/talm/10bbb87b0753245d283e1116128d2c968162e142/internal/pkg/miniprocfs/testdata/keys -------------------------------------------------------------------------------- /internal/pkg/miniprocfs/testdata/kmsg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozystack/talm/10bbb87b0753245d283e1116128d2c968162e142/internal/pkg/miniprocfs/testdata/kmsg -------------------------------------------------------------------------------- /internal/pkg/mount/switchroot/switchroot_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package switchroot_test 6 | 7 | import "testing" 8 | 9 | func TestEmpty(t *testing.T) { 10 | // added for accurate coverage estimation 11 | // 12 | // please remove it once any unit-test is added 13 | // for this package 14 | } 15 | -------------------------------------------------------------------------------- /internal/pkg/mount/v2/overlay.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package mount 6 | 7 | import ( 8 | "github.com/siderolabs/gen/xslices" 9 | "golang.org/x/sys/unix" 10 | 11 | "github.com/siderolabs/talos/pkg/machinery/constants" 12 | ) 13 | 14 | // OverlayMountPoints returns the mountpoints required to boot the system. 15 | // These mountpoints are used as overlays on top of the read only rootfs. 16 | func OverlayMountPoints() Points { 17 | return xslices.Map(constants.Overlays, func(target constants.SELinuxLabeledPath) *Point { 18 | return NewVarOverlay([]string{target.Path}, target.Path, WithFlags(unix.MS_I_VERSION), WithSelinuxLabel(target.Label)) 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /internal/pkg/mount/v2/repair.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package mount 6 | 7 | import ( 8 | "fmt" 9 | 10 | "github.com/siderolabs/talos/pkg/makefs" 11 | ) 12 | 13 | // repair a filesystem. 14 | func (p *Point) repair(printerOptions PrinterOptions) error { 15 | printerOptions.Printf("filesystem on %s needs cleaning, running repair", p.source) 16 | 17 | if err := makefs.XFSRepair(p.source, p.fstype); err != nil { 18 | return fmt.Errorf("xfs_repair: %w", err) 19 | } 20 | 21 | printerOptions.Printf("filesystem successfully repaired on %s", p.source) 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /internal/pkg/mount/v2/squashfs.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package mount 6 | 7 | import ( 8 | "github.com/freddierice/go-losetup/v2" 9 | "golang.org/x/sys/unix" 10 | ) 11 | 12 | // Squashfs binds the squashfs to the loop device and returns the mountpoint for it to the specified target. 13 | func Squashfs(target, squashfsFile string) (*Point, error) { 14 | dev, err := losetup.Attach(squashfsFile, 0, true) 15 | if err != nil { 16 | return nil, err 17 | } 18 | 19 | return NewPoint(dev.Path(), target, "squashfs", WithFlags(unix.MS_RDONLY|unix.MS_I_VERSION), WithShared()), nil 20 | } 21 | -------------------------------------------------------------------------------- /internal/pkg/ntp/consts.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package ntp 6 | 7 | import "time" 8 | 9 | const ( 10 | // MinAllowablePoll is the minimum time allowed for a client to query a time server. 11 | MinAllowablePoll = 32 * time.Second 12 | // MaxAllowablePoll is the maximum allowed interval for querying a time server. 13 | MaxAllowablePoll = 2048 * time.Second 14 | // RetryPoll is the interval between retries if the error is not Kiss-o-Death. 15 | RetryPoll = time.Second 16 | // AdjustTimeLimit is a maximum time drift to compensate via adjtimex(). 17 | // 18 | // Deltas smaller than AdjustTimeLimit are gradually adjusted (slewed) to approach the network time. 19 | // Deltas larger than AdjustTimeLimit are set by letting the system time jump. 20 | AdjustTimeLimit = 400 * time.Millisecond 21 | // EpochLimit is a minimum time difference to signal that change as epoch change. 22 | EpochLimit = 15 * time.Minute 23 | // ExpectedAccuracy is the expected time sync accuracy, used to adjust poll interval. 24 | ExpectedAccuracy = 200 * time.Millisecond 25 | ) 26 | -------------------------------------------------------------------------------- /internal/pkg/ntp/interfaces.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package ntp 6 | 7 | import ( 8 | "syscall" 9 | "time" 10 | 11 | "github.com/beevik/ntp" 12 | "golang.org/x/sys/unix" 13 | 14 | "github.com/cozystack/talm/internal/pkg/timex" 15 | ) 16 | 17 | // CurrentTimeFunc provides a function which returns current time. 18 | type CurrentTimeFunc func() time.Time 19 | 20 | // QueryFunc provides a function which performs NTP query. 21 | type QueryFunc func(server string) (*ntp.Response, error) 22 | 23 | // SetTimeFunc provides a function to set system time. 24 | type SetTimeFunc func(tv *syscall.Timeval) error 25 | 26 | // AdjustTimeFunc provides a function to adjust time. 27 | type AdjustTimeFunc func(buf *unix.Timex) (state timex.State, err error) 28 | -------------------------------------------------------------------------------- /internal/pkg/pci/pci.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package pci provides methods to access PCI-related data. 6 | package pci 7 | 8 | import ( 9 | "github.com/siderolabs/go-pcidb/pkg/pcidb" 10 | ) 11 | 12 | // Device describes PCI device. 13 | type Device struct { 14 | VendorID uint16 15 | ProductID uint16 16 | 17 | Vendor string 18 | Product string 19 | } 20 | 21 | // LookupDB looks up device info in the PCI database. 22 | func (d *Device) LookupDB() { 23 | d.Vendor, _ = pcidb.LookupVendor(d.VendorID) 24 | d.Product, _ = pcidb.LookupProduct(d.VendorID, d.ProductID) 25 | } 26 | -------------------------------------------------------------------------------- /internal/pkg/pci/sysfs.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package pci 6 | 7 | import ( 8 | "bytes" 9 | "errors" 10 | "fmt" 11 | "io/fs" 12 | "os" 13 | "strconv" 14 | ) 15 | 16 | const sysfsPath = "/sys/bus/pci/devices/%s/%s" 17 | 18 | func readID(busPath, name string) (uint16, error) { 19 | contents, err := os.ReadFile(fmt.Sprintf(sysfsPath, busPath, name)) 20 | if err != nil { 21 | return 0, err 22 | } 23 | 24 | v, err := strconv.ParseUint(string(bytes.TrimSpace(contents)), 0, 16) 25 | 26 | return uint16(v), err 27 | } 28 | 29 | // SysfsDeviceInfo looks up vendor and product ID from sysfs. 30 | func SysfsDeviceInfo(busPath string) (*Device, error) { 31 | var ( 32 | d Device 33 | err error 34 | ) 35 | 36 | d.ProductID, err = readID(busPath, "device") 37 | if err != nil { 38 | if errors.Is(err, fs.ErrNotExist) { 39 | return nil, nil 40 | } 41 | 42 | return nil, err 43 | } 44 | 45 | d.VendorID, err = readID(busPath, "vendor") 46 | if err != nil { 47 | if errors.Is(err, fs.ErrNotExist) { 48 | return nil, nil 49 | } 50 | 51 | return nil, err 52 | } 53 | 54 | return &d, err 55 | } 56 | -------------------------------------------------------------------------------- /internal/pkg/secureboot/database/certs/db/MicCorUEFCA2011_2011-06-27.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozystack/talm/10bbb87b0753245d283e1116128d2c968162e142/internal/pkg/secureboot/database/certs/db/MicCorUEFCA2011_2011-06-27.der -------------------------------------------------------------------------------- /internal/pkg/secureboot/database/certs/db/microsoft option rom uefi ca 2023.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozystack/talm/10bbb87b0753245d283e1116128d2c968162e142/internal/pkg/secureboot/database/certs/db/microsoft option rom uefi ca 2023.der -------------------------------------------------------------------------------- /internal/pkg/secureboot/database/certs/db/microsoft uefi ca 2023.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozystack/talm/10bbb87b0753245d283e1116128d2c968162e142/internal/pkg/secureboot/database/certs/db/microsoft uefi ca 2023.der -------------------------------------------------------------------------------- /internal/pkg/secureboot/database/certs/kek/MicCorKEKCA2011_2011-06-24.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozystack/talm/10bbb87b0753245d283e1116128d2c968162e142/internal/pkg/secureboot/database/certs/kek/MicCorKEKCA2011_2011-06-24.der -------------------------------------------------------------------------------- /internal/pkg/secureboot/database/certs/kek/microsoft corporation kek 2k ca 2023.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozystack/talm/10bbb87b0753245d283e1116128d2c968162e142/internal/pkg/secureboot/database/certs/kek/microsoft corporation kek 2k ca 2023.der -------------------------------------------------------------------------------- /internal/pkg/secureboot/measure/internal/pcr/extend.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package pcr 6 | 7 | import ( 8 | "crypto" 9 | ) 10 | 11 | // Digest implements the PCR extension algorithm. 12 | // 13 | // Each time `Extend` is called, the hash of the previous data is 14 | // prepended to the hash of new data and hashed together. 15 | // 16 | // The initial hash value is all zeroes. 17 | type Digest struct { 18 | alg crypto.Hash 19 | hash []byte 20 | } 21 | 22 | // NewDigest creates a new Digest with the speified hash algorithm. 23 | func NewDigest(alg crypto.Hash) *Digest { 24 | return &Digest{ 25 | alg: alg, 26 | hash: make([]byte, alg.Size()), 27 | } 28 | } 29 | 30 | // Hash returns the current hash value. 31 | func (d *Digest) Hash() []byte { 32 | return d.hash 33 | } 34 | 35 | // Extend extends the current hash with the specified data. 36 | func (d *Digest) Extend(data []byte) { 37 | // create hash of incoming data 38 | hash := d.alg.New() 39 | hash.Write(data) 40 | hashSum := hash.Sum(nil) 41 | 42 | // extend hash with previous data and hashed incoming data 43 | hash.Reset() 44 | hash.Write(d.hash) 45 | hash.Write(hashSum) 46 | 47 | // set sum as new hash 48 | d.hash = hash.Sum(nil) 49 | } 50 | -------------------------------------------------------------------------------- /internal/pkg/secureboot/measure/internal/pcr/extend_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package pcr_test 6 | 7 | import ( 8 | "crypto" 9 | "testing" 10 | 11 | "github.com/stretchr/testify/assert" 12 | 13 | "github.com/cozystack/talm/internal/pkg/secureboot/measure/internal/pcr" 14 | ) 15 | 16 | func TestExtend(t *testing.T) { 17 | t.Parallel() 18 | 19 | hash := pcr.NewDigest(crypto.SHA256) 20 | 21 | assert.Equal(t, make([]byte, 32), hash.Hash()) 22 | 23 | hash.Extend([]byte("foo")) 24 | 25 | assert.Equal(t, 26 | []byte{0x42, 0x48, 0x16, 0xd0, 0x20, 0xcf, 0x3d, 0x79, 0x3a, 0xc0, 0x21, 0xda, 0x47, 0x37, 0x9b, 0xdf, 0x60, 0x80, 0x80, 0xa8, 0x3e, 0xb9, 0x36, 0x4a, 0x7f, 0xbe, 0xb, 0xdf, 0xa8, 0x71, 0x11, 0xd7}, 27 | hash.Hash(), 28 | ) 29 | 30 | hash.Extend([]byte("bar")) 31 | 32 | assert.Equal(t, 33 | []byte{0x63, 0x5c, 0x18, 0xb1, 0x5e, 0xf5, 0xc5, 0xd6, 0xc0, 0x20, 0xe7, 0x23, 0x39, 0xdd, 0xef, 0xd8, 0xb0, 0x5c, 0x4c, 0x4a, 0x44, 0xb3, 0x4e, 0xff, 0x8c, 0xef, 0x22, 0x6f, 0x89, 0x2, 0x77, 0x2}, 34 | hash.Hash(), 35 | ) 36 | } 37 | -------------------------------------------------------------------------------- /internal/pkg/secureboot/measure/internal/pcr/sign.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package pcr contains code that handles PCR operations. 6 | package pcr 7 | 8 | import ( 9 | "crypto" 10 | "encoding/base64" 11 | "encoding/hex" 12 | "fmt" 13 | ) 14 | 15 | // Signature returns the hashed signature digest and base64 encoded signature. 16 | type Signature struct { 17 | Digest string 18 | SignatureBase64 string 19 | } 20 | 21 | // Sign the digest using specified hash and key. 22 | func Sign(digest []byte, hash crypto.Hash, key crypto.Signer) (*Signature, error) { 23 | digestToHash := hash.New() 24 | digestToHash.Write(digest) 25 | digestHashed := digestToHash.Sum(nil) 26 | 27 | // sign policy digest 28 | signedData, err := key.Sign(nil, digestHashed, hash) 29 | if err != nil { 30 | return nil, fmt.Errorf("signing failed: %v", err) 31 | } 32 | 33 | return &Signature{ 34 | Digest: hex.EncodeToString(digest), 35 | SignatureBase64: base64.StdEncoding.EncodeToString(signedData), 36 | }, nil 37 | } 38 | -------------------------------------------------------------------------------- /internal/pkg/secureboot/measure/internal/pcr/testdata/a: -------------------------------------------------------------------------------- 1 | aaaa 2 | -------------------------------------------------------------------------------- /internal/pkg/secureboot/measure/internal/pcr/testdata/b: -------------------------------------------------------------------------------- 1 | bbbb 2 | -------------------------------------------------------------------------------- /internal/pkg/secureboot/measure/internal/pcr/testdata/c: -------------------------------------------------------------------------------- 1 | cccc 2 | -------------------------------------------------------------------------------- /internal/pkg/secureboot/pesign/testdata/systemd-bootx64.efi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozystack/talm/10bbb87b0753245d283e1116128d2c968162e142/internal/pkg/secureboot/pesign/testdata/systemd-bootx64.efi -------------------------------------------------------------------------------- /internal/pkg/secureboot/tpm2/pcr_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package tpm2 provides TPM2.0 related functionality helpers. 6 | package tpm2_test 7 | 8 | import ( 9 | "testing" 10 | 11 | "github.com/stretchr/testify/require" 12 | 13 | tpm2internal "github.com/cozystack/talm/internal/pkg/secureboot/tpm2" 14 | ) 15 | 16 | func TestGetSelection(t *testing.T) { 17 | t.Parallel() 18 | 19 | for _, tt := range []struct { 20 | name string 21 | pcrs []int 22 | expected []byte 23 | }{ 24 | { 25 | name: "empty", 26 | expected: []byte{0, 0, 0}, 27 | }, 28 | { 29 | name: "1, 3, 5", 30 | pcrs: []int{1, 3, 5}, 31 | expected: []byte{42, 0, 0}, 32 | }, 33 | { 34 | name: "21, 22, 23", 35 | pcrs: []int{21, 22, 23}, 36 | expected: []byte{0, 0, 0xe0}, 37 | }, 38 | } { 39 | t.Run(tt.name, func(t *testing.T) { 40 | t.Parallel() 41 | 42 | actual, err := tpm2internal.CreateSelector(tt.pcrs) 43 | require.NoError(t, err) 44 | 45 | require.Equal(t, tt.expected, actual) 46 | }) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /internal/pkg/secureboot/tpm2/testdata/pcr-signing-crt.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA7qhAkdtZxqkIP79DDGin 3 | 9eaJBeNlJsClJTcbaXbNfk2QJGT3lqo9ErXQQftwYWLGo+kVd8puhnHGPkLW9apT 4 | 1/ZmUJEFwxV5xws0RllGVPhUga+1oubHUqhEiy707S4RrUEMk/o9wqmtnl2hY5Fx 5 | MeQn2o7xrpcNhm8FtHpvQrT0MsbC1cS1ytZH/hwPy/QIB9bx+ugOha6wtQBnpgix 6 | 1BhHC/NwDIYPg+ONpQSCu9gkXVtLGlKfmjscUANQtBuVKa5NflrjkHw7NAdKYdKp 7 | Mnmzr0yu6Tn/2oNmUiJAwHz0BXpfb4Yn8n/IoKJQ5Tv1g6d30wxxpBd0lbwSe9ML 8 | RchIDJ5aFRybyRxaPGT17U3yEVzbV78kIFtocaqkc1ise8remZ0wxHzuolbTZD6o 9 | swt7C9jMLvfMAQ7JtENXrpDM//XzdRLzyTWKOjhG0YmKKRY6cIrPkugM0PHGCE3R 10 | MSH1FmPMrWWBNAMwS0Zba0Wm1b7vdw5fKeE8txH+IpA3IaE9AytYk0ig98ZgmXmB 11 | V0sgxmJ/94scEF+sDg65LIkSEJMzf6q30UghbJJoP7eKOoDX9KBrR+POEsWm/EcU 12 | 5jTEQTHMU+qKtj5KD6TUn8R8yi4wCnyZ7uJLUqm8Ou8MzEZWbrsrbMvrewPDAHn0 13 | QQvb2tDtBgn6oH192jpkzckCAwEAAQ== 14 | -----END PUBLIC KEY----- 15 | -------------------------------------------------------------------------------- /internal/pkg/secureboot/tpm2/tpm2.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package tpm2 provides TPM2.0 related functionality helpers. 6 | package tpm2 7 | 8 | // SealedResponse is the response from the TPM2.0 Seal operation. 9 | type SealedResponse struct { 10 | SealedBlobPrivate []byte 11 | SealedBlobPublic []byte 12 | KeyName []byte 13 | PolicyDigest []byte 14 | } 15 | -------------------------------------------------------------------------------- /internal/pkg/secureboot/uki/kernel_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package uki_test 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/stretchr/testify/assert" 11 | "github.com/stretchr/testify/require" 12 | 13 | "github.com/cozystack/talm/internal/pkg/secureboot/uki" 14 | ) 15 | 16 | func TestKernelVersion(t *testing.T) { 17 | version, err := uki.DiscoverKernelVersion("testdata/kernel") 18 | require.NoError(t, err) 19 | 20 | assert.Equal(t, "6.1.58-talos", version) 21 | } 22 | -------------------------------------------------------------------------------- /internal/pkg/secureboot/uki/sbat.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package uki 6 | 7 | import ( 8 | "debug/pe" 9 | "errors" 10 | 11 | "github.com/cozystack/talm/internal/pkg/secureboot" 12 | ) 13 | 14 | // GetSBAT returns the SBAT section from the PE file. 15 | func GetSBAT(path string) ([]byte, error) { 16 | pefile, err := pe.Open(path) 17 | if err != nil { 18 | return nil, err 19 | } 20 | 21 | defer pefile.Close() //nolint:errcheck 22 | 23 | for _, section := range pefile.Sections { 24 | if section.Name == string(secureboot.SBAT) { 25 | data, err := section.Data() 26 | if err != nil { 27 | return nil, err 28 | } 29 | 30 | return data[:section.VirtualSize], nil 31 | } 32 | } 33 | 34 | return nil, errors.New("could not find SBAT section") 35 | } 36 | -------------------------------------------------------------------------------- /internal/pkg/secureboot/uki/sbat_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package uki_test 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/stretchr/testify/require" 11 | 12 | "github.com/cozystack/talm/internal/pkg/secureboot/uki" 13 | ) 14 | 15 | func TestGetSBAT(t *testing.T) { 16 | t.Parallel() 17 | 18 | data, err := uki.GetSBAT("../pesign/testdata/systemd-bootx64.efi") 19 | require.NoError(t, err) 20 | 21 | require.Equal(t, 22 | "sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md\nsystemd,1,The systemd Developers,systemd,254,https://systemd.io/\nsystemd.talos,1,Talos Linux,systemd,254,https://github.com/siderolabs/tools/issues\n\x00", //nolint:lll 23 | string(data), 24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /internal/pkg/secureboot/uki/testdata/kernel: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozystack/talm/10bbb87b0753245d283e1116128d2c968162e142/internal/pkg/secureboot/uki/testdata/kernel -------------------------------------------------------------------------------- /internal/pkg/selinux/policy/file_contexts: -------------------------------------------------------------------------------- 1 | /etc(/.*)? system_u:object_r:etc_t:s0 2 | /opt(/.*)? system_u:object_r:opt_t:s0 3 | /sbin(/.*)? system_u:object_r:sbin_exec_t:s0 4 | /etc/cni(/.*)? system_u:object_r:cni_conf_t:s0 5 | /opt/cni(/.*)? system_u:object_r:cni_plugin_t:s0 6 | /usr/sbin(/.*)? system_u:object_r:sbin_exec_t:s0 7 | /usr/lib/udev(/.*)? system_u:object_r:udev_exec_t:s0 8 | /etc/kubernetes(/.*)? system_u:object_r:k8s_conf_t:s0 9 | /opt/containerd(/.*)? system_u:object_r:containerd_plugin_t:s0 10 | /usr/share/zoneinfo(/.*)? system_u:object_r:etc_t:s0 11 | /usr/lib/udev/rules.d(/.*)? system_u:object_r:udev_rules_t:s0 12 | /usr/libexec/kubernetes(/.*)? system_u:object_r:k8s_plugin_t:s0 13 | / system_u:object_r:rootfs_t:s0 14 | /bin/runc system_u:object_r:containerd_exec_t:s0 15 | /sbin/init -- system_u:object_r:init_exec_t:s0 16 | /sbin/udevadm -l system_u:object_r:udev_exec_t:s0 17 | /sbin/poweroff system_u:object_r:init_exec_t:s0 18 | /sbin/shutdown system_u:object_r:init_exec_t:s0 19 | /sbin/modprobe -- system_u:object_r:modprobe_exec_t:s0 20 | /bin/containerd system_u:object_r:containerd_exec_t:s0 21 | /sbin/dashboard system_u:object_r:init_exec_t:s0 22 | /usr/bin/udevadm -- system_u:object_r:udev_exec_t:s0 23 | /sbin/systemd-udevd -- system_u:object_r:udev_exec_t:s0 24 | /bin/containerd-shim-runc-v2 system_u:object_r:containerd_exec_t:s0 25 | -------------------------------------------------------------------------------- /internal/pkg/selinux/policy/policy.33: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozystack/talm/10bbb87b0753245d283e1116128d2c968162e142/internal/pkg/selinux/policy/policy.33 -------------------------------------------------------------------------------- /internal/pkg/selinux/policy/selinux/common/files.cil: -------------------------------------------------------------------------------- 1 | ; Runtime and mounted filesystems 2 | (type system_t) 3 | (call filesystem_f (system_t)) 4 | (allow system_t tmpfs_t (filesystem (associate))) 5 | 6 | (type etc_t) 7 | (call system_f (etc_t)) 8 | (allow etc_t fs_t (filesystem (associate))) 9 | (allow etc_t tmpfs_t (filesystem (associate))) 10 | (context etc_t (system_u object_r etc_t (systemLow systemLow))) 11 | (filecon "/etc(/.*)?" any etc_t) 12 | (filecon "/usr/share/zoneinfo(/.*)?" any etc_t) 13 | 14 | (type system_var_t) 15 | (call system_f (system_var_t)) 16 | (allow system_var_t fs_t (filesystem (associate))) 17 | (allow system_var_t tmpfs_t (filesystem (associate))) 18 | 19 | (type ephemeral_t) 20 | (call filesystem_f (ephemeral_t)) 21 | (type system_state_t) 22 | (call filesystem_f (system_state_t)) 23 | 24 | (type run_t) 25 | (call filesystem_f (run_t)) 26 | (allow run_t tmpfs_t (filesystem (associate))) 27 | 28 | (type opt_t) 29 | (call filesystem_f (opt_t)) 30 | (filecon "/opt(/.*)?" any (system_u object_r opt_t (systemLow systemLow))) 31 | -------------------------------------------------------------------------------- /internal/pkg/selinux/policy/selinux/immutable/preamble.cil: -------------------------------------------------------------------------------- 1 | (sensitivity s0) 2 | (sensitivityorder (s0)) 3 | (level systemLow (s0)) 4 | (handleunknown deny) 5 | (mls true) 6 | (policycap open_perms) 7 | (policycap extended_socket_class) 8 | (policycap cgroup_seclabel) 9 | (policycap nnp_nosuid_transition) 10 | (policycap ioctl_skip_cloexec) 11 | -------------------------------------------------------------------------------- /internal/pkg/selinux/policy/selinux/immutable/roles.cil: -------------------------------------------------------------------------------- 1 | (role object_r) 2 | (type object_r) 3 | (roletype object_r object_r) 4 | 5 | (role system_r) 6 | (type system_r) 7 | (roletype system_r system_r) 8 | 9 | (user system_u) 10 | (userrange system_u (systemLow systemLow)) 11 | (userlevel system_u systemLow) 12 | (userrole system_u object_r) 13 | (userrole system_u system_r) 14 | -------------------------------------------------------------------------------- /internal/pkg/selinux/policy/selinux/services/dashboard.cil: -------------------------------------------------------------------------------- 1 | (type dashboard_t) 2 | (call service_p (dashboard_t init_exec_t)) 3 | -------------------------------------------------------------------------------- /internal/pkg/selinux/policy/selinux/services/kubelet.cil: -------------------------------------------------------------------------------- 1 | (type kubelet_t) 2 | (call pod_p (kubelet_t)) 3 | ; FIXME: insecure as anyone with access to the pod containerd may obtain this domain 4 | (allow kubelet_t containerd_state_t (file (entrypoint execute_no_trans))) 5 | 6 | (type k8s_conf_t) 7 | (call filesystem_f (k8s_conf_t)) 8 | (filecon "/etc/kubernetes(/.*)?" any (system_u object_r k8s_conf_t (systemLow systemLow))) 9 | 10 | (type k8s_plugin_t) 11 | (call filesystem_f (k8s_plugin_t)) 12 | (filecon "/usr/libexec/kubernetes(/.*)?" any (system_u object_r k8s_plugin_t (systemLow systemLow))) 13 | 14 | (type kubelet_state_t) 15 | (call system_f (kubelet_state_t)) 16 | -------------------------------------------------------------------------------- /internal/pkg/selinux/policy/selinux/services/selinux.cil: -------------------------------------------------------------------------------- 1 | (allow kernel_t security_t (security (setbool setsecparam))) 2 | (allow init_t security_t (security (setbool setsecparam))) 3 | ; Policy is loaded by initramfs init and mustn't be modified 4 | ; The only way to set mode to permissive is setting enforcing=0 in kernel cmdline 5 | (neverallow any_p security_t (security (load_policy setenforce))) 6 | (allow any_p security_t (security ( 7 | check_context 8 | compute_av 9 | compute_create 10 | compute_member 11 | compute_relabel 12 | compute_user 13 | read_policy 14 | setcheckreqprot 15 | validate_trans 16 | ))) 17 | -------------------------------------------------------------------------------- /internal/pkg/selinux/policy/selinux/services/system-containerd.cil: -------------------------------------------------------------------------------- 1 | (type containerd_exec_t) 2 | (call system_f (containerd_exec_t)) 3 | (context containerd_exec_t (system_u object_r containerd_exec_t (systemLow systemLow))) 4 | (filecon "/bin/containerd" any containerd_exec_t) 5 | (filecon "/bin/containerd-shim-runc-v2" any containerd_exec_t) 6 | (filecon "/bin/runc" any containerd_exec_t) 7 | 8 | ; System containerd 9 | (type sys_containerd_t) 10 | (call service_p (sys_containerd_t containerd_exec_t)) 11 | 12 | (type sys_containerd_socket_t) 13 | (call system_socket_f (sys_containerd_socket_t)) 14 | (typetransition sys_containerd_t system_t sock_file sys_containerd_socket_t) 15 | 16 | (allow sys_containerd_t system_container_p (process2 (nnp_transition nosuid_transition))) 17 | (allow sys_containerd_t system_container_p (process (transition))) 18 | 19 | ; Typically a system extension 20 | ; Possibly a service misconfigured by machined 21 | (type unconfined_container_t) 22 | (call system_container_p (unconfined_container_t)) 23 | 24 | ; Talos installer 25 | (type installer_t) 26 | (call system_container_p (installer_t)) 27 | (allow installer_t system_var_t (file (entrypoint execute_no_trans))) 28 | -------------------------------------------------------------------------------- /internal/pkg/selinux/policy/selinux/services/system-containers.cil: -------------------------------------------------------------------------------- 1 | (type apid_t) 2 | (call system_container_p (apid_t)) 3 | (allow apid_t init_exec_t (file (entrypoint execute))) 4 | 5 | (type apid_socket_t) 6 | (call system_socket_f (apid_socket_t)) 7 | (type apid_runtime_socket_t) 8 | (call system_socket_f (apid_runtime_socket_t)) 9 | (allow apid_t apid_socket_t (sock_file (relabelto))) 10 | (allow apid_t apid_runtime_socket_t (sock_file (relabelto))) 11 | 12 | (type trustd_t) 13 | (call system_container_p (trustd_t)) 14 | (allow trustd_t init_exec_t (file (entrypoint execute))) 15 | 16 | (type trustd_runtime_socket_t) 17 | (call system_socket_f (trustd_runtime_socket_t)) 18 | (allow trustd_t trustd_runtime_socket_t (sock_file (write))) 19 | (allow trustd_t trustd_runtime_socket_t (sock_file (relabelto))) 20 | -------------------------------------------------------------------------------- /internal/pkg/smbios/smbios.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package smbios provides access to SMBIOS information. 6 | package smbios 7 | 8 | import ( 9 | "sync" 10 | 11 | "github.com/siderolabs/go-smbios/smbios" 12 | ) 13 | 14 | var ( 15 | syncSMBIOS sync.Once 16 | connSMBIOS *smbios.SMBIOS 17 | errSMBIOS error 18 | ) 19 | 20 | // GetSMBIOSInfo returns the SMBIOS info. 21 | func GetSMBIOSInfo() (*smbios.SMBIOS, error) { 22 | syncSMBIOS.Do(func() { 23 | connSMBIOS, errSMBIOS = smbios.New() 24 | }) 25 | 26 | return connSMBIOS, errSMBIOS 27 | } 28 | -------------------------------------------------------------------------------- /internal/pkg/toml/merge_test.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package toml_test 6 | 7 | import ( 8 | _ "embed" 9 | "testing" 10 | 11 | "github.com/stretchr/testify/assert" 12 | "github.com/stretchr/testify/require" 13 | 14 | "github.com/cozystack/talm/internal/pkg/toml" 15 | ) 16 | 17 | //go:embed testdata/expected.toml 18 | var expected []byte 19 | 20 | func TestMerge(t *testing.T) { 21 | out, err := toml.Merge([]string{ 22 | "testdata/1.toml", 23 | "testdata/2.toml", 24 | "testdata/3.toml", 25 | }) 26 | require.NoError(t, err) 27 | 28 | assert.Equal(t, expected, out) 29 | } 30 | -------------------------------------------------------------------------------- /internal/pkg/toml/testdata/1.toml: -------------------------------------------------------------------------------- 1 | version = 2 2 | 3 | [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] 4 | runtime_type = "io.containerd.runc.v2" 5 | discard_unpacked_layers = true 6 | -------------------------------------------------------------------------------- /internal/pkg/toml/testdata/2.toml: -------------------------------------------------------------------------------- 1 | [plugins] 2 | [plugins."io.containerd.grpc.v1.cri"] 3 | [plugins."io.containerd.grpc.v1.cri".registry] 4 | config_path = "/etc/cri/conf.d/hosts" 5 | [plugins."io.containerd.grpc.v1.cri".registry.configs] 6 | -------------------------------------------------------------------------------- /internal/pkg/toml/testdata/3.toml: -------------------------------------------------------------------------------- 1 | [metrics] 2 | address = "0.0.0.0:11234" 3 | 4 | [plugins] 5 | [plugins."io.containerd.grpc.v1.cri"] 6 | sandbox_image = "registry.k8s.io/pause:3.8" 7 | -------------------------------------------------------------------------------- /internal/pkg/toml/testdata/expected.toml: -------------------------------------------------------------------------------- 1 | ## testdata/1.toml 2 | ## testdata/2.toml 3 | ## testdata/3.toml 4 | 5 | version = 2 6 | 7 | [metrics] 8 | address = '0.0.0.0:11234' 9 | 10 | [plugins] 11 | [plugins.'io.containerd.grpc.v1.cri'] 12 | sandbox_image = 'registry.k8s.io/pause:3.8' 13 | 14 | [plugins.'io.containerd.grpc.v1.cri'.containerd] 15 | [plugins.'io.containerd.grpc.v1.cri'.containerd.runtimes] 16 | [plugins.'io.containerd.grpc.v1.cri'.containerd.runtimes.runc] 17 | discard_unpacked_layers = true 18 | runtime_type = 'io.containerd.runc.v2' 19 | 20 | [plugins.'io.containerd.grpc.v1.cri'.registry] 21 | config_path = '/etc/cri/conf.d/hosts' 22 | 23 | [plugins.'io.containerd.grpc.v1.cri'.registry.configs] 24 | -------------------------------------------------------------------------------- /internal/pkg/toml/toml.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Package toml provides utility functions for TOML handling. 6 | package toml 7 | -------------------------------------------------------------------------------- /pkg/commands/track.go: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | package commands 6 | 7 | import ( 8 | "time" 9 | 10 | "github.com/spf13/cobra" 11 | ) 12 | 13 | type trackableActionCmdFlags struct { 14 | wait bool 15 | debug bool 16 | timeout time.Duration 17 | } 18 | 19 | func (f *trackableActionCmdFlags) addTrackActionFlags(cmd *cobra.Command) { 20 | cmd.Flags().BoolVar(&f.wait, "wait", true, "wait for the operation to complete, tracking its progress. always set to true when --debug is set") 21 | cmd.Flags().BoolVar(&f.debug, "debug", false, "debug operation from kernel logs. --wait is set to true when this flag is set") 22 | cmd.Flags().DurationVar(&f.timeout, "timeout", 30*time.Minute, "time to wait for the operation is complete if --debug or --wait is set") 23 | } 24 | -------------------------------------------------------------------------------- /pkg/engine/helm/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Helm Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | /* 18 | Package engine implements the Go text template engine as needed for Helm. 19 | 20 | When Helm renders templates it does so with additional functions and different 21 | modes (e.g., strict, lint mode). This package handles the helm specific 22 | implementation. 23 | */ 24 | package engine // import "helm.sh/helm/v3/pkg/engine" 25 | --------------------------------------------------------------------------------