refactor: improve machined

This is a rewrite of machined. It addresses some of the limitations and
complexity in the implementation. This introduces the idea of a
controller. A controller is responsible for managing the runtime, the
sequencer, and a new state type introduced in this PR.

A few highlights are:

- no more event bus
- functional approach to tasks (no more types defined for each task)
  - the task function definition now offers a lot more context, like
    access to raw API requests, the current sequence, a logger, the new
    state interface, and the runtime interface.
- no more panics to handle reboots
- additional initialize and reboot sequences
- graceful gRPC server shutdown on critical errors
- config is now stored at install time to avoid having to download it at
  install time and at boot time
- upgrades now use the local config instead of downloading it
- the upgrade API's preserve option takes precedence over the config's
  install force option

Additionally, this pulls various packes in under machined to make the
code easier to navigate.

Signed-off-by: Andrew Rynhard <andrew@andrewrynhard.com>
This commit is contained in:
Andrew Rynhard 2020-04-23 21:12:44 -07:00
parent 55dcbbc8d0
commit 49307d554d
233 changed files with 5721 additions and 5876 deletions

View File

@ -17,7 +17,7 @@ KUBECTL_URL ?= https://storage.googleapis.com/kubernetes-release/release/v1.18.0
SONOBUOY_VERSION ?= 0.18.0
SONOBUOY_URL ?= https://github.com/heptio/sonobuoy/releases/download/v$(SONOBUOY_VERSION)/sonobuoy_$(SONOBUOY_VERSION)_$(OPERATING_SYSTEM)_amd64.tar.gz
TESTPKGS ?= ./...
RELEASES ?= v0.3.3 v0.4.0-beta.1
RELEASES ?= v0.3.3 v0.4.1
BUILD := docker buildx build
PLATFORM ?= linux/amd64
@ -154,7 +154,7 @@ boot: ## Creates a compressed tarball that includes vmlinuz and initramfs.xz. No
.PHONY: fmt
fmt: ## Formats the source code.
@docker run --rm -it -v $(PWD):/src -w /src golang:$(GO_VERSION) bash -c "export GO111MODULE=on; export GOPROXY=https://proxy.golang.org; cd /tmp && go mod init tmp && go get mvdan.cc/gofumpt/gofumports && cd - && gofumports -w -local github.com/talos-systems/talos ."
@docker run --rm -it -v $(PWD):/src -w /src golang:$(GO_VERSION) bash -c "export GO111MODULE=on; export GOPROXY=https://proxy.golang.org; cd /tmp && go mod init tmp && go get mvdan.cc/gofumpt/gofumports@aaa7156f4122b1055c466e26e77812fa32bac1d9 && cd - && gofumports -w -local github.com/talos-systems/talos ."
lint-%: ## Runs the specified linter. Valid options are go, protobuf, and markdown (e.g. lint-go).
@$(MAKE) target-lint-$*

View File

@ -2205,102 +2205,100 @@ func init() {
func init() { proto.RegisterFile("machine/machine.proto", fileDescriptor_84b4f59d98cc997c) }
var fileDescriptor_84b4f59d98cc997c = []byte{
// 1520 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0xcd, 0x73, 0xdb, 0x44,
0x14, 0x1f, 0x39, 0x8e, 0x63, 0x3f, 0x27, 0x4e, 0x50, 0x9b, 0x44, 0xa4, 0xe9, 0x97, 0xf8, 0x68,
0x27, 0xb4, 0x4e, 0x9a, 0x42, 0xa7, 0x10, 0x0a, 0xd3, 0x26, 0xa5, 0xed, 0xb4, 0xa1, 0x41, 0x01,
0x0e, 0x5c, 0xcc, 0xda, 0x5a, 0xcb, 0x3b, 0x95, 0xb4, 0x42, 0xbb, 0x4e, 0x27, 0x0c, 0x7f, 0x00,
0xc3, 0x8d, 0xe1, 0xc6, 0x95, 0xff, 0x91, 0x33, 0xb3, 0x9f, 0x52, 0xac, 0xb8, 0xd4, 0x33, 0x3d,
0x79, 0xf7, 0xed, 0xef, 0x7d, 0x3f, 0xbd, 0x7d, 0x6b, 0x58, 0x4d, 0xd0, 0x60, 0x44, 0x52, 0xbc,
0xad, 0x7f, 0xbb, 0x59, 0x4e, 0x39, 0x75, 0x17, 0xf4, 0x76, 0xe3, 0x52, 0x44, 0x69, 0x14, 0xe3,
0x6d, 0x49, 0xee, 0x8f, 0x87, 0xdb, 0x38, 0xc9, 0xf8, 0xa9, 0x42, 0x6d, 0x5c, 0x9d, 0x3c, 0xe4,
0x24, 0xc1, 0x8c, 0xa3, 0x24, 0xd3, 0x80, 0x0b, 0x03, 0x9a, 0x24, 0x34, 0xdd, 0x56, 0x3f, 0x8a,
0xe8, 0xdf, 0x83, 0x46, 0x80, 0xfb, 0x94, 0x72, 0xf7, 0x16, 0x34, 0x13, 0xcc, 0x51, 0x88, 0x38,
0xf2, 0x9c, 0x6b, 0xce, 0xcd, 0xf6, 0xee, 0x4a, 0x57, 0x43, 0x0f, 0x35, 0x3d, 0xb0, 0x08, 0xff,
0x01, 0x74, 0x14, 0x5f, 0x80, 0x59, 0x46, 0x53, 0x86, 0xdd, 0x4f, 0x04, 0x3f, 0x63, 0x28, 0xc2,
0xcc, 0x73, 0xae, 0xcd, 0xdd, 0x6c, 0xef, 0x2e, 0x77, 0x8d, 0x1f, 0x1a, 0x6a, 0x01, 0xfe, 0x23,
0x58, 0x0c, 0x30, 0xc3, 0x3c, 0xc0, 0xbf, 0x8c, 0x31, 0xe3, 0xee, 0x06, 0x34, 0xa3, 0x1c, 0x0d,
0xf0, 0x70, 0x1c, 0x4b, 0xe5, 0xcd, 0xc0, 0xee, 0xdd, 0x35, 0x68, 0xe4, 0x92, 0xdf, 0xab, 0xc9,
0x13, 0xbd, 0xf3, 0x3f, 0x83, 0x79, 0x29, 0x63, 0x46, 0xcb, 0xf7, 0x60, 0x49, 0xab, 0xd6, 0x86,
0x6f, 0x55, 0x0c, 0xef, 0x94, 0x0c, 0x17, 0xc8, 0xc2, 0xee, 0xfb, 0xd0, 0x3c, 0x1e, 0x8d, 0x79,
0x48, 0x5f, 0xa7, 0x33, 0xaa, 0x7d, 0x08, 0x2b, 0x86, 0xd3, 0x6a, 0xbe, 0x5d, 0xd1, 0xfc, 0x9e,
0xd5, 0x6c, 0xc1, 0xe5, 0xa0, 0x75, 0x7e, 0xc8, 0xa2, 0x1c, 0x85, 0xd8, 0x84, 0xed, 0x22, 0xcc,
0x93, 0x04, 0x45, 0x58, 0xea, 0x6f, 0x05, 0x6a, 0x23, 0x82, 0x99, 0xe5, 0x98, 0xe1, 0xfc, 0x04,
0xeb, 0x90, 0xd9, 0xbd, 0xff, 0x0c, 0x16, 0xb4, 0x8c, 0xd9, 0xec, 0x77, 0x57, 0x60, 0x0e, 0x0d,
0x5e, 0x49, 0x79, 0xad, 0x40, 0x2c, 0xfd, 0xaf, 0x61, 0xd9, 0x9a, 0xa3, 0x1d, 0xba, 0x55, 0x71,
0x68, 0xc5, 0x3a, 0x64, 0xb0, 0x85, 0x3f, 0x09, 0xb4, 0x8f, 0x71, 0x7e, 0x42, 0x06, 0xf8, 0x05,
0x61, 0x33, 0xa6, 0xd1, 0xdd, 0x81, 0x26, 0x53, 0xcc, 0xcc, 0xab, 0x49, 0x55, 0x17, 0x8b, 0xd8,
0xa9, 0x83, 0x67, 0xe9, 0x90, 0x06, 0x16, 0xe5, 0x3f, 0x81, 0x0b, 0x25, 0x75, 0xd6, 0xe6, 0x9d,
0x8a, 0xcd, 0x15, 0x41, 0x12, 0x5f, 0xd8, 0xfd, 0x97, 0x63, 0x0d, 0x17, 0x2a, 0xdc, 0x0e, 0xd4,
0x48, 0xa8, 0x53, 0x50, 0x23, 0xa1, 0xc8, 0x0a, 0xe3, 0x88, 0x63, 0x1d, 0x2c, 0xb5, 0x71, 0xbb,
0xd0, 0xc0, 0x27, 0x38, 0xe5, 0xcc, 0x9b, 0x93, 0xce, 0xad, 0x4d, 0x6a, 0x79, 0x2c, 0x4f, 0x03,
0x8d, 0x12, 0xf8, 0x11, 0x46, 0x31, 0x1f, 0x79, 0xf5, 0xf3, 0xf1, 0x4f, 0xe5, 0x69, 0xa0, 0x51,
0xfe, 0x57, 0xb0, 0x74, 0x46, 0x90, 0x7b, 0xdb, 0x2a, 0x54, 0x6e, 0xad, 0x9e, 0xab, 0xd0, 0xe8,
0xf3, 0xfb, 0xb0, 0x58, 0xa6, 0x8b, 0x84, 0x27, 0x2c, 0xd2, 0x6e, 0x89, 0xe5, 0x14, 0xbf, 0xb6,
0xa0, 0x66, 0x7d, 0xda, 0xe8, 0xaa, 0x26, 0xd4, 0x35, 0x4d, 0xa8, 0xfb, 0xbd, 0x69, 0x42, 0x41,
0x8d, 0x33, 0xff, 0x1f, 0xc7, 0x1a, 0xa9, 0xac, 0x77, 0x3d, 0x58, 0x18, 0xa7, 0xaf, 0x52, 0xfa,
0x3a, 0xd5, 0xdf, 0xbd, 0xd9, 0x8a, 0x13, 0xe5, 0xd9, 0xa9, 0x2e, 0x62, 0xb3, 0x75, 0xaf, 0xc3,
0x62, 0x8c, 0x18, 0xef, 0xe9, 0x84, 0x48, 0xdd, 0xad, 0xa0, 0x2d, 0x68, 0x87, 0x8a, 0xe4, 0xee,
0x81, 0xdc, 0xf6, 0x06, 0x23, 0x94, 0x46, 0x58, 0x47, 0xf0, 0x4d, 0xd6, 0x81, 0x80, 0xef, 0x4b,
0xb4, 0xff, 0x91, 0x2d, 0x94, 0x63, 0x8e, 0x72, 0xdb, 0xa3, 0x26, 0xd2, 0xec, 0x1f, 0xd9, 0x80,
0x49, 0xd8, 0x8c, 0xf5, 0xeb, 0x42, 0x3d, 0xc7, 0x2c, 0xd3, 0xb1, 0x94, 0x6b, 0xff, 0x19, 0x5c,
0x3c, 0xab, 0x58, 0x97, 0xe8, 0x9d, 0x4a, 0x89, 0x56, 0x72, 0xa9, 0x18, 0x8a, 0x1a, 0xfd, 0x10,
0x5c, 0x7b, 0x42, 0xb3, 0x69, 0x2e, 0xbc, 0xb4, 0x85, 0x2c, 0x50, 0xef, 0xc0, 0x83, 0x27, 0xa5,
0xd0, 0x09, 0xb5, 0x6f, 0xff, 0x8d, 0x49, 0x7c, 0x61, 0xff, 0x0d, 0x58, 0xd5, 0x07, 0x81, 0xc8,
0xd0, 0xf4, 0x2c, 0x04, 0xd0, 0x39, 0x0b, 0x7c, 0x07, 0x5e, 0x1c, 0xc2, 0xda, 0xa4, 0x72, 0xed,
0xc8, 0xdd, 0x8a, 0x23, 0xeb, 0x93, 0x8e, 0x18, 0x96, 0xc2, 0x17, 0x1f, 0x16, 0xdf, 0x54, 0x48,
0x5f, 0xd4, 0x3c, 0xc7, 0xbf, 0x01, 0x4b, 0x67, 0x73, 0x6e, 0xec, 0x72, 0x0a, 0xbb, 0x24, 0xf0,
0x3a, 0xb4, 0xdf, 0x90, 0x51, 0x09, 0xf9, 0x58, 0xe8, 0x2b, 0x45, 0x7f, 0x9a, 0xa8, 0x2d, 0x68,
0xef, 0xd3, 0xec, 0xd4, 0x88, 0xba, 0x04, 0xad, 0x9c, 0x52, 0xde, 0xcb, 0x10, 0x1f, 0x69, 0x6c,
0x53, 0x10, 0x8e, 0x10, 0x1f, 0xf9, 0x21, 0xb4, 0x55, 0xd7, 0x54, 0x58, 0x21, 0x52, 0xdc, 0xc8,
0x46, 0xa4, 0x18, 0x20, 0x3c, 0x58, 0xc8, 0xf1, 0x60, 0x9c, 0x33, 0x73, 0xeb, 0x98, 0xad, 0x7b,
0x03, 0x96, 0xd5, 0x92, 0xd0, 0xb4, 0x17, 0xe2, 0x8c, 0x8f, 0xe4, 0x37, 0x3b, 0x1f, 0x74, 0x2c,
0xf9, 0x40, 0x50, 0xfd, 0x7f, 0x1d, 0x68, 0x7e, 0x43, 0x62, 0xd5, 0x56, 0x67, 0xce, 0x63, 0x8a,
0x12, 0xd3, 0x9b, 0xe4, 0x5a, 0xd0, 0x18, 0xf9, 0x55, 0x35, 0x88, 0xb9, 0x40, 0xae, 0x05, 0x2d,
0xa1, 0xa1, 0x6a, 0x09, 0x4b, 0x81, 0x5c, 0x8b, 0x0b, 0x33, 0xa1, 0x21, 0x19, 0x12, 0x1c, 0x7a,
0xf3, 0x12, 0x6b, 0xf7, 0xee, 0x2a, 0x34, 0x08, 0xeb, 0x85, 0x24, 0xf7, 0x1a, 0xd2, 0xa9, 0x79,
0xc2, 0x0e, 0x48, 0x2e, 0x7a, 0x21, 0xce, 0x73, 0x9a, 0x7b, 0x0b, 0xaa, 0x17, 0xca, 0x8d, 0x10,
0x1e, 0x93, 0xf4, 0x95, 0xd7, 0x54, 0x46, 0x88, 0xb5, 0xfb, 0x01, 0x2c, 0xe5, 0x38, 0x46, 0x9c,
0x9c, 0xe0, 0x9e, 0xb4, 0xb0, 0x25, 0x0f, 0x17, 0x0d, 0xf1, 0x5b, 0x94, 0x60, 0xff, 0x67, 0x68,
0x1c, 0xd2, 0xb1, 0xe8, 0xda, 0xb3, 0x79, 0x7d, 0x53, 0xb5, 0x64, 0x73, 0x05, 0xba, 0xb6, 0x18,
0xa5, 0xb4, 0x63, 0x8e, 0xb8, 0x6a, 0xd3, 0x4c, 0x0c, 0x6c, 0x4a, 0xc3, 0x5b, 0x0d, 0x6c, 0x1a,
0x5a, 0xd4, 0xf0, 0x6f, 0xd0, 0xb2, 0x22, 0xdd, 0x2b, 0x00, 0x43, 0x12, 0x63, 0x76, 0xca, 0x38,
0x4e, 0x74, 0x0d, 0x94, 0x28, 0x36, 0xee, 0x22, 0x17, 0x75, 0x1d, 0xf7, 0x4d, 0x68, 0xa1, 0x13,
0x44, 0x62, 0xd4, 0x8f, 0x55, 0x42, 0xea, 0x41, 0x41, 0x70, 0x2f, 0x03, 0x24, 0x42, 0x3c, 0x0e,
0x7b, 0x34, 0x95, 0xb9, 0x69, 0x05, 0x2d, 0x4d, 0x79, 0x99, 0xfa, 0x7f, 0x3b, 0xb0, 0xf0, 0x23,
0x96, 0x85, 0x32, 0x63, 0x80, 0xba, 0xb0, 0x70, 0xa2, 0x18, 0xa5, 0x35, 0xe5, 0xc6, 0xa3, 0x05,
0xca, 0x29, 0xc1, 0x80, 0x44, 0xab, 0xcd, 0x62, 0xc4, 0x87, 0x34, 0x4f, 0xf4, 0x9d, 0x56, 0xb4,
0xda, 0x23, 0x7d, 0xa0, 0xe6, 0x0a, 0x03, 0x13, 0x73, 0x90, 0x16, 0xf5, 0x56, 0x73, 0x90, 0xc1,
0x16, 0xb1, 0xfd, 0xc3, 0x81, 0x76, 0xc9, 0x18, 0x71, 0xf3, 0x72, 0x64, 0x6f, 0x5e, 0x8e, 0x22,
0x41, 0x61, 0x23, 0x64, 0x86, 0x2f, 0x36, 0x42, 0xa2, 0xfe, 0xfa, 0x63, 0x12, 0x73, 0x7d, 0xf9,
0xa9, 0x8d, 0x08, 0x63, 0x44, 0x7b, 0xc6, 0x61, 0x1d, 0xc6, 0x88, 0x9a, 0xd0, 0x75, 0xa0, 0x46,
0x99, 0xac, 0xf0, 0x56, 0x50, 0xa3, 0x4c, 0xe4, 0x09, 0xe5, 0x83, 0x91, 0xac, 0xec, 0x56, 0x20,
0xd7, 0xfe, 0x3d, 0x58, 0x2c, 0xfb, 0x69, 0xbf, 0x2b, 0xe7, 0xec, 0x77, 0x25, 0xbf, 0x21, 0xfd,
0xad, 0x89, 0xb5, 0xb8, 0xda, 0xdb, 0x2f, 0x68, 0xc4, 0x4c, 0x87, 0xd8, 0x84, 0x96, 0xc0, 0xb2,
0x0c, 0x0d, 0x0c, 0x73, 0x41, 0xd0, 0x6d, 0xab, 0x66, 0x47, 0xa6, 0x6d, 0x68, 0x84, 0x39, 0x39,
0xc1, 0xb9, 0xf4, 0xa7, 0xb3, 0xbb, 0x6e, 0x52, 0xba, 0x4f, 0x53, 0x8e, 0x48, 0x8a, 0xf3, 0x03,
0x79, 0x1c, 0x68, 0x98, 0x78, 0x14, 0x0c, 0x69, 0x1c, 0xd3, 0xd7, 0xd2, 0xcb, 0x66, 0xa0, 0x77,
0x22, 0x02, 0x1c, 0x91, 0xb8, 0x17, 0x93, 0x14, 0x2b, 0x57, 0xe7, 0x83, 0x96, 0xa0, 0xbc, 0x10,
0x04, 0xd1, 0x3d, 0x03, 0x8c, 0xc2, 0x52, 0x1b, 0x2b, 0x75, 0x3b, 0xb9, 0xde, 0xfd, 0xb3, 0x09,
0x9d, 0x43, 0x95, 0x2b, 0xdd, 0xd1, 0xdd, 0x5b, 0x50, 0x17, 0x8d, 0xd2, 0x2d, 0x6a, 0xa7, 0xd4,
0x37, 0x37, 0x16, 0x8d, 0xad, 0x07, 0x88, 0xa3, 0x1d, 0xc7, 0xfd, 0x14, 0xe0, 0xf9, 0xb8, 0x8f,
0x07, 0x34, 0x1d, 0x92, 0xc8, 0x5d, 0xab, 0x0c, 0x1d, 0x8f, 0xc5, 0xa3, 0xad, 0xc2, 0x75, 0x07,
0xea, 0x72, 0x0a, 0x2e, 0x74, 0x94, 0xfa, 0xed, 0x46, 0xf1, 0x2e, 0x30, 0xed, 0x71, 0xc7, 0x11,
0x66, 0x89, 0x88, 0x97, 0x59, 0x8a, 0x04, 0x54, 0x14, 0x7c, 0x6e, 0x5b, 0xcc, 0x34, 0x93, 0xd6,
0x27, 0x3f, 0xff, 0xa2, 0x9c, 0xeb, 0x22, 0x6a, 0x25, 0x45, 0xa5, 0x20, 0x9e, 0xa7, 0x48, 0x3f,
0x29, 0xff, 0x5f, 0xd1, 0xc4, 0x1b, 0xf2, 0x9e, 0x79, 0xd2, 0xad, 0x4e, 0xbc, 0xc0, 0xb4, 0xaa,
0xb5, 0x49, 0xb2, 0xe6, 0xdb, 0x3f, 0xfb, 0x92, 0x98, 0xa6, 0x77, 0xf3, 0xdc, 0xc1, 0xde, 0x08,
0xf9, 0xae, 0x32, 0x49, 0x5c, 0x99, 0x76, 0xb7, 0x6b, 0x73, 0xae, 0x4e, 0x3d, 0xd7, 0x22, 0x9f,
0x4f, 0x8c, 0x88, 0x9b, 0xe7, 0x8f, 0x6d, 0x5a, 0xdc, 0xe5, 0x29, 0xa7, 0x5a, 0xd8, 0xd3, 0xb3,
0xc3, 0xda, 0xa5, 0x73, 0x27, 0x28, 0x2d, 0x6a, 0xf3, 0xfc, 0x43, 0x2d, 0xe9, 0x41, 0xe9, 0x15,
0x3b, 0x2d, 0x56, 0xef, 0x57, 0x5f, 0xa2, 0x86, 0xfd, 0xcb, 0xe2, 0x0d, 0xb9, 0x5e, 0x79, 0xde,
0x69, 0x03, 0xbc, 0xea, 0x81, 0xe6, 0xde, 0x83, 0x79, 0x15, 0x8c, 0xd2, 0x0c, 0x5b, 0x8e, 0xc2,
0xda, 0x24, 0x59, 0xf1, 0xf9, 0x73, 0xbf, 0xd7, 0x1c, 0xf7, 0x3e, 0xd4, 0xa5, 0xf3, 0xa5, 0xf1,
0xb1, 0xe4, 0xf5, 0xea, 0x04, 0xb5, 0xcc, 0xb9, 0x57, 0xdc, 0x20, 0xd3, 0x5c, 0xf6, 0x2a, 0x3d,
0x5a, 0x4b, 0x78, 0xf4, 0x1c, 0x96, 0x07, 0x34, 0xb1, 0xc7, 0x28, 0x23, 0x8f, 0x40, 0xf7, 0x88,
0x87, 0x19, 0x39, 0x72, 0x7e, 0xda, 0x8a, 0x08, 0x1f, 0x8d, 0xfb, 0xe2, 0x4b, 0xd8, 0xe6, 0x28,
0xa6, 0xec, 0xb6, 0xba, 0x0a, 0x99, 0xda, 0x6d, 0xa3, 0x8c, 0x98, 0x3f, 0x75, 0xfa, 0x0d, 0xa9,
0xf6, 0xee, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc2, 0xaf, 0xdf, 0x04, 0xee, 0x11, 0x00, 0x00,
// 1484 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x5b, 0x73, 0xdb, 0x44,
0x14, 0x1e, 0x39, 0x89, 0x2f, 0xc7, 0x89, 0x13, 0xd4, 0x26, 0x11, 0x69, 0x7a, 0x13, 0x97, 0x76,
0x42, 0xeb, 0xa4, 0x29, 0x74, 0x80, 0x52, 0x98, 0x36, 0x29, 0x6d, 0xa7, 0x0d, 0x0d, 0x0a, 0xf0,
0xc0, 0x8b, 0x59, 0x5b, 0x6b, 0x79, 0xa7, 0x92, 0x56, 0x68, 0xd7, 0xe9, 0x84, 0xe1, 0x17, 0xf0,
0xca, 0x5b, 0x5f, 0xf9, 0x8f, 0x3c, 0x33, 0x7b, 0x95, 0x62, 0xd9, 0xa5, 0x9e, 0xe9, 0x93, 0x77,
0xcf, 0xf9, 0xf6, 0xdc, 0x75, 0xf6, 0xac, 0x61, 0x3d, 0x41, 0x83, 0x11, 0x49, 0xf1, 0xae, 0xfe,
0xed, 0x66, 0x39, 0xe5, 0xd4, 0x6d, 0xe8, 0xed, 0xd6, 0xa5, 0x88, 0xd2, 0x28, 0xc6, 0xbb, 0x92,
0xdc, 0x1f, 0x0f, 0x77, 0x71, 0x92, 0xf1, 0x33, 0x85, 0xda, 0xba, 0x3a, 0xc9, 0xe4, 0x24, 0xc1,
0x8c, 0xa3, 0x24, 0xd3, 0x80, 0x0b, 0x03, 0x9a, 0x24, 0x34, 0xdd, 0x55, 0x3f, 0x8a, 0xe8, 0xdf,
0x83, 0x7a, 0x80, 0xfb, 0x94, 0x72, 0xf7, 0x16, 0x34, 0x13, 0xcc, 0x51, 0x88, 0x38, 0xf2, 0x9c,
0x6b, 0xce, 0xcd, 0xf6, 0xfe, 0x5a, 0x57, 0x43, 0x8f, 0x34, 0x3d, 0xb0, 0x08, 0xff, 0x01, 0x74,
0xd4, 0xb9, 0x00, 0xb3, 0x8c, 0xa6, 0x0c, 0xbb, 0x9f, 0x89, 0xf3, 0x8c, 0xa1, 0x08, 0x33, 0xcf,
0xb9, 0xb6, 0x70, 0xb3, 0xbd, 0xbf, 0xda, 0x35, 0x7e, 0x68, 0xa8, 0x05, 0xf8, 0x8f, 0x60, 0x39,
0xc0, 0x0c, 0xf3, 0x00, 0xff, 0x3e, 0xc6, 0x8c, 0xbb, 0x5b, 0xd0, 0x8c, 0x72, 0x34, 0xc0, 0xc3,
0x71, 0x2c, 0x95, 0x37, 0x03, 0xbb, 0x77, 0x37, 0xa0, 0x9e, 0xcb, 0xf3, 0x5e, 0x4d, 0x72, 0xf4,
0xce, 0xff, 0x02, 0x96, 0xa4, 0x8c, 0x39, 0x2d, 0xbf, 0x0f, 0x2b, 0x5a, 0xb5, 0x36, 0x7c, 0xa7,
0x62, 0x78, 0xa7, 0x64, 0xb8, 0x40, 0x16, 0x76, 0x7f, 0x09, 0xcd, 0x93, 0xd1, 0x98, 0x87, 0xf4,
0x75, 0x3a, 0xa7, 0xda, 0x87, 0xb0, 0x66, 0x4e, 0x5a, 0xcd, 0xb7, 0x2b, 0x9a, 0x3f, 0xb0, 0x9a,
0x2d, 0xb8, 0x1c, 0xb4, 0xce, 0xcf, 0x59, 0x94, 0xa3, 0x10, 0x9b, 0xb0, 0x5d, 0x84, 0x25, 0x92,
0xa0, 0x08, 0x4b, 0xfd, 0xad, 0x40, 0x6d, 0x44, 0x30, 0xb3, 0x1c, 0x33, 0x9c, 0x9f, 0x62, 0x1d,
0x32, 0xbb, 0xf7, 0x9f, 0x41, 0x43, 0xcb, 0x98, 0xcf, 0x7e, 0x77, 0x0d, 0x16, 0xd0, 0xe0, 0x95,
0x94, 0xd7, 0x0a, 0xc4, 0xd2, 0xff, 0x0e, 0x56, 0xad, 0x39, 0xda, 0xa1, 0x5b, 0x15, 0x87, 0xd6,
0xac, 0x43, 0x06, 0x5b, 0xf8, 0x93, 0x40, 0xfb, 0x04, 0xe7, 0xa7, 0x64, 0x80, 0x5f, 0x10, 0x36,
0x67, 0x1a, 0xdd, 0x3d, 0x68, 0x32, 0x75, 0x98, 0x79, 0x35, 0xa9, 0xea, 0x62, 0x11, 0x3b, 0xc5,
0x78, 0x96, 0x0e, 0x69, 0x60, 0x51, 0xfe, 0x13, 0xb8, 0x50, 0x52, 0x67, 0x6d, 0xde, 0xab, 0xd8,
0x5c, 0x11, 0x24, 0xf1, 0x85, 0xdd, 0x7f, 0x3b, 0xd6, 0x70, 0xa1, 0xc2, 0xed, 0x40, 0x8d, 0x84,
0x3a, 0x05, 0x35, 0x12, 0x8a, 0xac, 0x30, 0x8e, 0x38, 0xd6, 0xc1, 0x52, 0x1b, 0xb7, 0x0b, 0x75,
0x7c, 0x8a, 0x53, 0xce, 0xbc, 0x05, 0xe9, 0xdc, 0xc6, 0xa4, 0x96, 0xc7, 0x92, 0x1b, 0x68, 0x94,
0xc0, 0x8f, 0x30, 0x8a, 0xf9, 0xc8, 0x5b, 0x9c, 0x8e, 0x7f, 0x2a, 0xb9, 0x81, 0x46, 0xf9, 0xdf,
0xc2, 0xca, 0x39, 0x41, 0xee, 0x6d, 0xab, 0x50, 0xb9, 0xb5, 0x3e, 0x55, 0xa1, 0xd1, 0xe7, 0xf7,
0x61, 0xb9, 0x4c, 0x17, 0x09, 0x4f, 0x58, 0xa4, 0xdd, 0x12, 0xcb, 0x19, 0x7e, 0xed, 0x40, 0xcd,
0xfa, 0xb4, 0xd5, 0x55, 0x4d, 0xa8, 0x6b, 0x9a, 0x50, 0xf7, 0x27, 0xd3, 0x84, 0x82, 0x1a, 0x67,
0xfe, 0x3f, 0x8e, 0x35, 0x52, 0x59, 0xef, 0x7a, 0xd0, 0x18, 0xa7, 0xaf, 0x52, 0xfa, 0x3a, 0xd5,
0xdf, 0xbd, 0xd9, 0x0a, 0x8e, 0xf2, 0xec, 0x4c, 0x17, 0xb1, 0xd9, 0xba, 0xd7, 0x61, 0x39, 0x46,
0x8c, 0xf7, 0x74, 0x42, 0xa4, 0xee, 0x56, 0xd0, 0x16, 0xb4, 0x23, 0x45, 0x72, 0xef, 0x83, 0xdc,
0xf6, 0x06, 0x23, 0x94, 0x46, 0x58, 0x47, 0xf0, 0x6d, 0xd6, 0x81, 0x80, 0x1f, 0x48, 0xb4, 0xff,
0x89, 0x2d, 0x94, 0x13, 0x8e, 0x72, 0xdb, 0xa3, 0x26, 0xd2, 0xec, 0x1f, 0xdb, 0x80, 0x49, 0xd8,
0x9c, 0xf5, 0xeb, 0xc2, 0x62, 0x8e, 0x59, 0xa6, 0x63, 0x29, 0xd7, 0xfe, 0x33, 0xb8, 0x78, 0x5e,
0xb1, 0x2e, 0xd1, 0x3b, 0x95, 0x12, 0xad, 0xe4, 0x52, 0x1d, 0x28, 0x6a, 0xf4, 0x63, 0x70, 0x2d,
0x87, 0x66, 0xb3, 0x5c, 0x78, 0x69, 0x0b, 0x59, 0xa0, 0xde, 0x83, 0x07, 0x4f, 0x4a, 0xa1, 0x13,
0x6a, 0xdf, 0xfd, 0x1b, 0x93, 0xf8, 0xc2, 0xfe, 0x1b, 0xb0, 0xae, 0x19, 0x81, 0xc8, 0xd0, 0xec,
0x2c, 0x04, 0xd0, 0x39, 0x0f, 0x7c, 0x0f, 0x5e, 0x1c, 0xc1, 0xc6, 0xa4, 0x72, 0xed, 0xc8, 0xdd,
0x8a, 0x23, 0x9b, 0x93, 0x8e, 0x98, 0x23, 0x85, 0x2f, 0x3e, 0x2c, 0xbf, 0xad, 0x90, 0xbe, 0xae,
0x79, 0x8e, 0x7f, 0x03, 0x56, 0xce, 0xe7, 0xdc, 0xd8, 0xe5, 0x14, 0x76, 0x49, 0xe0, 0x75, 0x68,
0xbf, 0x25, 0xa3, 0x12, 0xf2, 0xa9, 0xd0, 0x57, 0x8a, 0xfe, 0x2c, 0x51, 0x3b, 0xd0, 0x3e, 0xa0,
0xd9, 0x99, 0x11, 0x75, 0x09, 0x5a, 0x39, 0xa5, 0xbc, 0x97, 0x21, 0x3e, 0xd2, 0xd8, 0xa6, 0x20,
0x1c, 0x23, 0x3e, 0xf2, 0x43, 0x68, 0xab, 0xae, 0xa9, 0xb0, 0x42, 0xa4, 0xb8, 0x91, 0x8d, 0x48,
0x31, 0x40, 0x78, 0xd0, 0xc8, 0xf1, 0x60, 0x9c, 0x33, 0x73, 0xeb, 0x98, 0xad, 0x7b, 0x03, 0x56,
0xd5, 0x92, 0xd0, 0xb4, 0x17, 0xe2, 0x8c, 0x8f, 0xe4, 0x37, 0xbb, 0x14, 0x74, 0x2c, 0xf9, 0x50,
0x50, 0xfd, 0x7f, 0x1d, 0x68, 0x7e, 0x4f, 0x62, 0xd5, 0x56, 0xe7, 0xce, 0x63, 0x8a, 0x12, 0xd3,
0x9b, 0xe4, 0x5a, 0xd0, 0x18, 0xf9, 0x43, 0x35, 0x88, 0x85, 0x40, 0xae, 0x05, 0x2d, 0xa1, 0xa1,
0x6a, 0x09, 0x2b, 0x81, 0x5c, 0x8b, 0x0b, 0x33, 0xa1, 0x21, 0x19, 0x12, 0x1c, 0x7a, 0x4b, 0x12,
0x6b, 0xf7, 0xee, 0x3a, 0xd4, 0x09, 0xeb, 0x85, 0x24, 0xf7, 0xea, 0xd2, 0xa9, 0x25, 0xc2, 0x0e,
0x49, 0x2e, 0x7a, 0x21, 0xce, 0x73, 0x9a, 0x7b, 0x0d, 0xd5, 0x0b, 0xe5, 0x46, 0x08, 0x8f, 0x49,
0xfa, 0xca, 0x6b, 0x2a, 0x23, 0xc4, 0xda, 0xfd, 0x08, 0x56, 0x72, 0x1c, 0x23, 0x4e, 0x4e, 0x71,
0x4f, 0x5a, 0xd8, 0x92, 0xcc, 0x65, 0x43, 0xfc, 0x01, 0x25, 0xd8, 0xff, 0x0d, 0xea, 0x47, 0x74,
0x2c, 0xba, 0xf6, 0x7c, 0x5e, 0xdf, 0x54, 0x2d, 0xd9, 0x5c, 0x81, 0xae, 0x2d, 0x46, 0x29, 0xed,
0x84, 0x23, 0xae, 0xda, 0x34, 0x13, 0x03, 0x9b, 0xd2, 0xf0, 0x4e, 0x03, 0x9b, 0x86, 0x16, 0x35,
0xfc, 0x27, 0xb4, 0xac, 0x48, 0xf7, 0x0a, 0xc0, 0x90, 0xc4, 0x98, 0x9d, 0x31, 0x8e, 0x13, 0x5d,
0x03, 0x25, 0x8a, 0x8d, 0xbb, 0xc8, 0xc5, 0xa2, 0x8e, 0xfb, 0x36, 0xb4, 0xd0, 0x29, 0x22, 0x31,
0xea, 0xc7, 0x2a, 0x21, 0x8b, 0x41, 0x41, 0x70, 0x2f, 0x03, 0x24, 0x42, 0x3c, 0x0e, 0x7b, 0x34,
0x95, 0xb9, 0x69, 0x05, 0x2d, 0x4d, 0x79, 0x99, 0xfa, 0x6f, 0x1c, 0x68, 0xfc, 0x82, 0x65, 0xa1,
0xcc, 0x19, 0xa0, 0x2e, 0x34, 0x4e, 0xd5, 0x41, 0x69, 0x4d, 0xb9, 0xf1, 0x68, 0x81, 0x72, 0x4a,
0x30, 0x20, 0xd1, 0x6a, 0xb3, 0x18, 0xf1, 0x21, 0xcd, 0x13, 0x7d, 0xa7, 0x15, 0xad, 0xf6, 0x58,
0x33, 0xd4, 0x5c, 0x61, 0x60, 0x62, 0x0e, 0xd2, 0xa2, 0xde, 0x69, 0x0e, 0x32, 0xd8, 0x22, 0xb6,
0x7f, 0x39, 0xd0, 0x2e, 0x19, 0x23, 0x6e, 0x5e, 0x8e, 0xec, 0xcd, 0xcb, 0x51, 0x24, 0x28, 0x6c,
0x84, 0xcc, 0xf0, 0xc5, 0x46, 0x48, 0xd4, 0x5f, 0x7f, 0x4c, 0x62, 0xae, 0x2f, 0x3f, 0xb5, 0x11,
0x61, 0x8c, 0x68, 0xcf, 0x38, 0xac, 0xc3, 0x18, 0x51, 0x13, 0xba, 0x0e, 0xd4, 0x28, 0x93, 0x15,
0xde, 0x0a, 0x6a, 0x94, 0x89, 0x3c, 0xa1, 0x7c, 0x30, 0x92, 0x95, 0xdd, 0x0a, 0xe4, 0xda, 0xbf,
0x07, 0xcb, 0x65, 0x3f, 0xed, 0x77, 0xe5, 0x9c, 0xff, 0xae, 0xe4, 0x37, 0xa4, 0xbf, 0x35, 0xb1,
0x16, 0x57, 0x7b, 0xfb, 0x05, 0x8d, 0x98, 0xe9, 0x10, 0xdb, 0xd0, 0x12, 0x58, 0x96, 0xa1, 0x81,
0x39, 0x5c, 0x10, 0x74, 0xdb, 0xaa, 0xd9, 0x91, 0x69, 0x17, 0xea, 0x61, 0x4e, 0x4e, 0x71, 0x2e,
0xfd, 0xe9, 0xec, 0x6f, 0x9a, 0x94, 0x1e, 0xd0, 0x94, 0x23, 0x92, 0xe2, 0xfc, 0x50, 0xb2, 0x03,
0x0d, 0x13, 0x8f, 0x82, 0x21, 0x8d, 0x63, 0xfa, 0x5a, 0x7a, 0xd9, 0x0c, 0xf4, 0x4e, 0x44, 0x80,
0x23, 0x12, 0xf7, 0x62, 0x92, 0x62, 0xe5, 0xea, 0x52, 0xd0, 0x12, 0x94, 0x17, 0x82, 0x20, 0xba,
0x67, 0x80, 0x51, 0x58, 0x6a, 0x63, 0xa5, 0x6e, 0x27, 0xd7, 0xfb, 0x6f, 0x1a, 0xd0, 0x39, 0x52,
0xb9, 0xd2, 0x1d, 0xdd, 0xbd, 0x05, 0x8b, 0xa2, 0x51, 0xba, 0x45, 0xed, 0x94, 0xfa, 0xe6, 0xd6,
0xb2, 0xb1, 0xf5, 0x10, 0x71, 0xb4, 0xe7, 0xb8, 0x9f, 0x03, 0x3c, 0x1f, 0xf7, 0xf1, 0x80, 0xa6,
0x43, 0x12, 0xb9, 0x1b, 0x95, 0xa1, 0xe3, 0xb1, 0x78, 0xb4, 0x55, 0x4e, 0xdd, 0x81, 0x45, 0x39,
0x05, 0x17, 0x3a, 0x4a, 0xfd, 0x76, 0xab, 0x78, 0x17, 0x98, 0xf6, 0xb8, 0xe7, 0x08, 0xb3, 0x44,
0xc4, 0xcb, 0x47, 0x8a, 0x04, 0x54, 0x14, 0x7c, 0x65, 0x5b, 0xcc, 0x2c, 0x93, 0x36, 0x27, 0x3f,
0xff, 0xa2, 0x9c, 0x17, 0x45, 0xd4, 0x4a, 0x8a, 0x4a, 0x41, 0x9c, 0xa6, 0x48, 0x3f, 0x29, 0xff,
0x5f, 0xd1, 0xc4, 0x1b, 0xf2, 0x9e, 0x79, 0xd2, 0xad, 0x4f, 0xbc, 0xc0, 0xb4, 0xaa, 0x8d, 0x49,
0xb2, 0x3e, 0x77, 0x70, 0xfe, 0x25, 0x31, 0x4b, 0xef, 0xf6, 0xd4, 0xc1, 0xde, 0x08, 0xf9, 0xb1,
0x32, 0x49, 0x5c, 0x99, 0x75, 0xb7, 0x6b, 0x73, 0xae, 0xce, 0xe4, 0x6b, 0x91, 0xcf, 0x27, 0x46,
0xc4, 0xed, 0xe9, 0x63, 0x9b, 0x16, 0x77, 0x79, 0x06, 0x57, 0x0b, 0x7b, 0x7a, 0x7e, 0x58, 0xbb,
0x34, 0x75, 0x82, 0xd2, 0xa2, 0xb6, 0xa7, 0x33, 0xb5, 0xa4, 0x07, 0xa5, 0x57, 0xec, 0xac, 0x58,
0x7d, 0x58, 0x7d, 0x89, 0x9a, 0xe3, 0xdf, 0x14, 0x6f, 0xc8, 0xcd, 0xca, 0xf3, 0x4e, 0x1b, 0xe0,
0x55, 0x19, 0xfa, 0xf4, 0xfd, 0xa2, 0x95, 0xcf, 0xd2, 0xed, 0x55, 0x9a, 0xa5, 0x3e, 0xfc, 0xe8,
0x39, 0xac, 0x0e, 0x68, 0x62, 0xd9, 0x28, 0x23, 0x8f, 0x40, 0x7f, 0xac, 0x0f, 0x33, 0x72, 0xec,
0xfc, 0xba, 0x13, 0x11, 0x3e, 0x1a, 0xf7, 0x45, 0x49, 0xee, 0x72, 0x14, 0x53, 0x76, 0x5b, 0xdd,
0x49, 0x4c, 0xed, 0x76, 0x51, 0x46, 0xcc, 0xbf, 0x2b, 0xfd, 0xba, 0x54, 0x7b, 0xf7, 0xbf, 0x00,
0x00, 0x00, 0xff, 0xff, 0xe9, 0x7e, 0xca, 0xfb, 0x77, 0x11, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@ -2331,8 +2329,6 @@ type MachineServiceClient interface {
ServiceStop(ctx context.Context, in *ServiceStopRequest, opts ...grpc.CallOption) (*ServiceStopResponse, error)
Shutdown(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*ShutdownResponse, error)
Upgrade(ctx context.Context, in *UpgradeRequest, opts ...grpc.CallOption) (*UpgradeResponse, error)
Start(ctx context.Context, in *StartRequest, opts ...grpc.CallOption) (*StartResponse, error)
Stop(ctx context.Context, in *StopRequest, opts ...grpc.CallOption) (*StopResponse, error)
Version(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*VersionResponse, error)
}
@ -2585,26 +2581,6 @@ func (c *machineServiceClient) Upgrade(ctx context.Context, in *UpgradeRequest,
return out, nil
}
// Deprecated: Do not use.
func (c *machineServiceClient) Start(ctx context.Context, in *StartRequest, opts ...grpc.CallOption) (*StartResponse, error) {
out := new(StartResponse)
err := c.cc.Invoke(ctx, "/machine.MachineService/Start", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Deprecated: Do not use.
func (c *machineServiceClient) Stop(ctx context.Context, in *StopRequest, opts ...grpc.CallOption) (*StopResponse, error) {
out := new(StopResponse)
err := c.cc.Invoke(ctx, "/machine.MachineService/Stop", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *machineServiceClient) Version(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*VersionResponse, error) {
out := new(VersionResponse)
err := c.cc.Invoke(ctx, "/machine.MachineService/Version", in, out, opts...)
@ -2630,8 +2606,6 @@ type MachineServiceServer interface {
ServiceStop(context.Context, *ServiceStopRequest) (*ServiceStopResponse, error)
Shutdown(context.Context, *empty.Empty) (*ShutdownResponse, error)
Upgrade(context.Context, *UpgradeRequest) (*UpgradeResponse, error)
Start(context.Context, *StartRequest) (*StartResponse, error)
Stop(context.Context, *StopRequest) (*StopResponse, error)
Version(context.Context, *empty.Empty) (*VersionResponse, error)
}
@ -2906,42 +2880,6 @@ func _MachineService_Upgrade_Handler(srv interface{}, ctx context.Context, dec f
return interceptor(ctx, in, info, handler)
}
func _MachineService_Start_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(StartRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MachineServiceServer).Start(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/machine.MachineService/Start",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MachineServiceServer).Start(ctx, req.(*StartRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MachineService_Stop_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(StopRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(MachineServiceServer).Stop(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/machine.MachineService/Stop",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(MachineServiceServer).Stop(ctx, req.(*StopRequest))
}
return interceptor(ctx, in, info, handler)
}
func _MachineService_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(empty.Empty)
if err := dec(in); err != nil {
@ -3000,14 +2938,6 @@ var _MachineService_serviceDesc = grpc.ServiceDesc{
MethodName: "Upgrade",
Handler: _MachineService_Upgrade_Handler,
},
{
MethodName: "Start",
Handler: _MachineService_Start_Handler,
},
{
MethodName: "Stop",
Handler: _MachineService_Stop_Handler,
},
{
MethodName: "Version",
Handler: _MachineService_Version_Handler,

View File

@ -27,14 +27,6 @@ service MachineService {
rpc ServiceStop(ServiceStopRequest) returns (ServiceStopResponse);
rpc Shutdown(google.protobuf.Empty) returns (ShutdownResponse);
rpc Upgrade(UpgradeRequest) returns (UpgradeResponse);
rpc Start(StartRequest) returns (StartResponse) {
option deprecated = true;
};
rpc Stop(StopRequest) returns (StopResponse) {
option deprecated = true;
};
rpc Version(google.protobuf.Empty) returns (VersionResponse);
}

View File

@ -12,12 +12,12 @@ import (
"github.com/spf13/cobra"
"github.com/talos-systems/talos/cmd/installer/pkg"
"github.com/talos-systems/talos/cmd/installer/pkg/install"
"github.com/talos-systems/talos/cmd/installer/pkg/ova"
"github.com/talos-systems/talos/cmd/installer/pkg/qemuimg"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/internal/pkg/runtime/platform"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/platform"
"github.com/talos-systems/talos/pkg/cmd"
"github.com/talos-systems/talos/pkg/config/types/v1alpha1"
"github.com/talos-systems/talos/pkg/constants"
)
@ -71,20 +71,6 @@ func runImageCmd() (err error) {
}
}()
config := &v1alpha1.Config{
ClusterConfig: &v1alpha1.ClusterConfig{
ControlPlane: &v1alpha1.ControlPlaneConfig{},
},
MachineConfig: &v1alpha1.MachineConfig{
MachineInstall: &v1alpha1.InstallConfig{
InstallForce: true,
InstallBootloader: options.Bootloader,
InstallDisk: options.Disk,
InstallExtraKernelArgs: options.ExtraKernelArgs,
},
},
}
if options.ConfigSource == "" {
switch p.Name() {
case "aws", "azure", "digital-ocean", "gcp":
@ -95,7 +81,7 @@ func runImageCmd() (err error) {
}
}
if err = pkg.Install(p, config, runtime.None, options); err != nil {
if err = install.Install(p, runtime.SequenceNoop, options); err != nil {
return err
}

View File

@ -5,17 +5,11 @@
package cmd
import (
"fmt"
"log"
"strings"
"github.com/spf13/cobra"
"github.com/talos-systems/talos/cmd/installer/pkg"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/internal/pkg/runtime/platform"
machineconfig "github.com/talos-systems/talos/pkg/config"
"github.com/talos-systems/talos/pkg/config/types/v1alpha1"
"github.com/talos-systems/talos/cmd/installer/pkg/install"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/platform"
)
// installCmd represents the install command
@ -39,51 +33,18 @@ func init() {
}
func runInstallCmd() (err error) {
var config runtime.Configurator
seq := runtime.SequenceInstall
p, err := platform.CurrentPlatform()
if err == nil {
if !strings.EqualFold(p.Name(), options.Platform) {
return fmt.Errorf("platform mismatch (%s != %s)", p.Name(), options.Platform)
}
var b []byte
b, err = p.Configuration()
if err != nil {
return err
}
config, err = machineconfig.NewFromBytes(b)
if err != nil {
return err
}
}
if config == nil {
log.Printf("failed to source config from platform; falling back to defaults")
config = &v1alpha1.Config{
ClusterConfig: &v1alpha1.ClusterConfig{
ControlPlane: &v1alpha1.ControlPlaneConfig{},
},
MachineConfig: &v1alpha1.MachineConfig{
MachineInstall: &v1alpha1.InstallConfig{
InstallForce: options.Force,
InstallBootloader: options.Bootloader,
InstallDisk: options.Disk,
InstallExtraKernelArgs: options.ExtraKernelArgs,
},
},
}
}
sequence := runtime.None
if options.Upgrade {
sequence = runtime.Upgrade
seq = runtime.SequenceUpgrade
}
if err = pkg.Install(p, config, sequence, options); err != nil {
p, err := platform.NewPlatform(options.Platform)
if err != nil {
return err
}
if err = install.Install(p, seq, options); err != nil {
return err
}

View File

@ -10,7 +10,7 @@ import (
"github.com/spf13/cobra"
"github.com/talos-systems/talos/cmd/installer/pkg"
"github.com/talos-systems/talos/cmd/installer/pkg/install"
"github.com/talos-systems/talos/pkg/constants"
)
@ -30,15 +30,15 @@ func Execute() {
}
}
var options = &pkg.InstallOptions{}
var options = &install.Options{}
func init() {
rootCmd.PersistentFlags().StringVar(&options.ConfigSource, "config", "", "The value of "+constants.KernelParamConfig)
rootCmd.PersistentFlags().MarkHidden("config") //nolint: errcheck
rootCmd.PersistentFlags().StringVar(&options.Disk, "disk", "", "The path to the disk to install to")
rootCmd.PersistentFlags().StringVar(&options.Platform, "platform", "", "The value of "+constants.KernelParamPlatform)
rootCmd.PersistentFlags().StringArrayVar(&options.ExtraKernelArgs, "extra-kernel-arg", []string{}, "Extra argument to pass to the kernel")
rootCmd.PersistentFlags().BoolVar(&options.Bootloader, "bootloader", true, "Install a booloader to the specified disk")
rootCmd.PersistentFlags().BoolVar(&options.Upgrade, "upgrade", false, "Indicates that the install is being performed by an upgrade")
rootCmd.PersistentFlags().BoolVar(&options.Force, "force", false, "Indicates that the install should forcefully format the partition")
rootCmd.PersistentFlags().BoolVar(&options.Zero, "zero", false, "Indicates that the install should write zeros to the disk before installing")
}

View File

@ -1,56 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package pkg
import (
"log"
"github.com/talos-systems/go-procfs/procfs"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/constants"
"github.com/talos-systems/talos/pkg/version"
)
// InstallOptions represents the set of options available for an install.
type InstallOptions struct {
ConfigSource string
Disk string
Platform string
ExtraKernelArgs []string
Bootloader bool
Upgrade bool
Force bool
}
// Install installs Talos.
func Install(p runtime.Platform, config runtime.Configurator, sequence runtime.Sequence, opts *InstallOptions) (err error) {
cmdline := procfs.NewCmdline("")
cmdline.Append(constants.KernelParamPlatform, p.Name())
cmdline.Append(constants.KernelParamConfig, opts.ConfigSource)
if err = cmdline.AppendAll(p.KernelArgs().Strings()); err != nil {
return err
}
if err = cmdline.AppendAll(config.Machine().Install().ExtraKernelArgs()); err != nil {
return err
}
cmdline.AppendDefaults()
i, err := NewInstaller(cmdline, sequence, config.Machine().Install())
if err != nil {
return err
}
if err = i.Install(sequence); err != nil {
return err
}
log.Printf("installation of %s complete", version.Tag)
return nil
}

View File

@ -2,7 +2,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package pkg
package install
import (
"fmt"
@ -12,30 +12,68 @@ import (
"path/filepath"
"unsafe"
"github.com/talos-systems/go-procfs/procfs"
"golang.org/x/sys/unix"
"github.com/talos-systems/go-procfs/procfs"
"github.com/talos-systems/talos/cmd/installer/pkg/bootloader/syslinux"
"github.com/talos-systems/talos/cmd/installer/pkg/manifest"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/bootloader/syslinux"
"github.com/talos-systems/talos/internal/pkg/mount"
"github.com/talos-systems/talos/internal/pkg/mount/manager"
"github.com/talos-systems/talos/internal/pkg/mount/manager/owned"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/blockdevice"
"github.com/talos-systems/talos/pkg/blockdevice/probe"
"github.com/talos-systems/talos/pkg/blockdevice/table"
"github.com/talos-systems/talos/pkg/blockdevice/util"
"github.com/talos-systems/talos/pkg/config/machine"
"github.com/talos-systems/talos/pkg/constants"
"github.com/talos-systems/talos/pkg/version"
)
// Options represents the set of options available for an install.
type Options struct {
ConfigSource string
Disk string
Platform string
ExtraKernelArgs []string
Bootloader bool
Upgrade bool
Force bool
Zero bool
}
// Install installs Talos.
func Install(p runtime.Platform, seq runtime.Sequence, opts *Options) (err error) {
cmdline := procfs.NewCmdline("")
cmdline.Append(constants.KernelParamPlatform, p.Name())
cmdline.Append(constants.KernelParamConfig, opts.ConfigSource)
if err = cmdline.AppendAll(p.KernelArgs().Strings()); err != nil {
return err
}
if err = cmdline.AppendAll(opts.ExtraKernelArgs); err != nil {
return err
}
cmdline.AppendDefaults()
i, err := NewInstaller(cmdline, seq, opts)
if err != nil {
return err
}
if err = i.Install(seq); err != nil {
return err
}
log.Printf("installation of %s complete", version.Tag)
return nil
}
// Installer represents the installer logic. It serves as the entrypoint to all
// installation methods.
type Installer struct {
cmdline *procfs.Cmdline
install machine.Install
manifest *manifest.Manifest
options *Options
manifest *Manifest
Current string
Next string
@ -45,10 +83,10 @@ type Installer struct {
// NewInstaller initializes and returns an Installer.
//
// nolint: gocyclo
func NewInstaller(cmdline *procfs.Cmdline, sequence runtime.Sequence, install machine.Install) (i *Installer, err error) {
func NewInstaller(cmdline *procfs.Cmdline, seq runtime.Sequence, opts *Options) (i *Installer, err error) {
i = &Installer{
cmdline: cmdline,
install: install,
options: opts,
}
var dev *probe.ProbedBlockDevice
@ -61,7 +99,7 @@ func NewInstaller(cmdline *procfs.Cmdline, sequence runtime.Sequence, install ma
i.bootPartitionFound = true
}
if sequence == runtime.Upgrade && i.bootPartitionFound {
if seq == runtime.SequenceUpgrade && i.bootPartitionFound {
if err = os.MkdirAll("/boot", 0777); err != nil {
return nil, err
}
@ -78,11 +116,11 @@ func NewInstaller(cmdline *procfs.Cmdline, sequence runtime.Sequence, install ma
label := i.Current
if sequence == runtime.Upgrade && i.bootPartitionFound {
if seq == runtime.SequenceUpgrade && i.bootPartitionFound {
label = i.Next
}
i.manifest, err = manifest.NewManifest(label, sequence, install)
i.manifest, err = NewManifest(label, seq, i.options)
if err != nil {
return nil, fmt.Errorf("failed to create installation manifest: %w", err)
}
@ -94,9 +132,9 @@ func NewInstaller(cmdline *procfs.Cmdline, sequence runtime.Sequence, install ma
// to the target locations.
//
// nolint: gocyclo
func (i *Installer) Install(sequence runtime.Sequence) (err error) {
if sequence != runtime.Upgrade || !i.bootPartitionFound {
if i.install.Zero() {
func (i *Installer) Install(seq runtime.Sequence) (err error) {
if seq != runtime.SequenceUpgrade || !i.bootPartitionFound {
if i.options.Zero {
if err = zero(i.manifest); err != nil {
return fmt.Errorf("failed to wipe device(s): %w", err)
}
@ -114,7 +152,7 @@ func (i *Installer) Install(sequence runtime.Sequence) (err error) {
for dev := range i.manifest.Targets {
var mp *mount.Points
mp, err = owned.MountPointsForDevice(dev)
mp, err = mount.SystemMountPointsForDevice(dev)
if err != nil {
return err
}
@ -125,16 +163,15 @@ func (i *Installer) Install(sequence runtime.Sequence) (err error) {
}
}
m := manager.NewManager(mountpoints)
if err = m.MountAll(); err != nil {
if err = mount.Mount(mountpoints); err != nil {
return err
}
// nolint: errcheck
defer m.UnmountAll()
defer mount.Unmount(mountpoints)
}
if sequence == runtime.Upgrade && i.bootPartitionFound && i.install.Force() {
if seq == runtime.SequenceUpgrade && i.bootPartitionFound && i.options.Force {
for dev, targets := range i.manifest.Targets {
var bd *blockdevice.BlockDevice
@ -193,11 +230,11 @@ func (i *Installer) Install(sequence runtime.Sequence) (err error) {
// Install the bootloader.
if !i.install.WithBootloader() {
if !i.options.Bootloader {
return nil
}
if sequence != runtime.Upgrade || !i.bootPartitionFound {
if seq != runtime.SequenceUpgrade || !i.bootPartitionFound {
i.cmdline.Append("initrd", filepath.Join("/", i.Current, constants.InitramfsAsset))
syslinuxcfg := &syslinux.Cfg{
@ -212,7 +249,7 @@ func (i *Installer) Install(sequence runtime.Sequence) (err error) {
},
}
if err = syslinux.Install("", syslinuxcfg, sequence, i.bootPartitionFound); err != nil {
if err = syslinux.Install("", syslinuxcfg, seq, i.bootPartitionFound); err != nil {
return err
}
} else {
@ -236,7 +273,7 @@ func (i *Installer) Install(sequence runtime.Sequence) (err error) {
},
}
if err = syslinux.Install(i.Current, syslinuxcfg, sequence, i.bootPartitionFound); err != nil {
if err = syslinux.Install(i.Current, syslinuxcfg, seq, i.bootPartitionFound); err != nil {
return err
}
}
@ -244,7 +281,7 @@ func (i *Installer) Install(sequence runtime.Sequence) (err error) {
return nil
}
func zero(manifest *manifest.Manifest) (err error) {
func zero(manifest *Manifest) (err error) {
var zero *os.File
if zero, err = os.Open("/dev/zero"); err != nil {

View File

@ -2,7 +2,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package manifest
package install
import (
"fmt"
@ -11,14 +11,13 @@ import (
"os"
"path/filepath"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/pkg/blockdevice"
"github.com/talos-systems/talos/pkg/blockdevice/filesystem/vfat"
"github.com/talos-systems/talos/pkg/blockdevice/filesystem/xfs"
"github.com/talos-systems/talos/pkg/blockdevice/table"
"github.com/talos-systems/talos/pkg/blockdevice/table/gpt/partition"
"github.com/talos-systems/talos/pkg/blockdevice/util"
"github.com/talos-systems/talos/pkg/config/machine"
"github.com/talos-systems/talos/pkg/constants"
)
@ -48,19 +47,19 @@ type Asset struct {
}
// NewManifest initializes and returns a Manifest.
func NewManifest(label string, sequence runtime.Sequence, install machine.Install) (manifest *Manifest, err error) {
func NewManifest(label string, sequence runtime.Sequence, opts *Options) (manifest *Manifest, err error) {
manifest = &Manifest{
Targets: map[string][]*Target{},
}
// Verify that the target device(s) can satisify the requested options.
if sequence != runtime.Upgrade {
if err = VerifyDataDevice(install); err != nil {
if sequence != runtime.SequenceUpgrade {
if err = VerifyEphemeralPartition(opts); err != nil {
return nil, fmt.Errorf("failed to prepare ephemeral partition: %w", err)
}
if err = VerifyBootDevice(install); err != nil {
if err = VerifyBootPartition(opts); err != nil {
return nil, fmt.Errorf("failed to prepare boot partition: %w", err)
}
}
@ -68,14 +67,15 @@ func NewManifest(label string, sequence runtime.Sequence, install machine.Instal
// Initialize any slices we need. Note that a boot paritition is not
// required.
if manifest.Targets[install.Disk()] == nil {
manifest.Targets[install.Disk()] = []*Target{}
if manifest.Targets[opts.Disk] == nil {
manifest.Targets[opts.Disk] = []*Target{}
}
var bootTarget *Target
if install.WithBootloader() {
if opts.Bootloader {
bootTarget = &Target{
Device: install.Disk(),
Device: opts.Disk,
Label: constants.BootPartitionLabel,
Size: 512 * 1024 * 1024,
Force: true,
@ -94,7 +94,7 @@ func NewManifest(label string, sequence runtime.Sequence, install machine.Instal
}
ephemeralTarget := &Target{
Device: install.Disk(),
Device: opts.Disk,
Label: constants.EphemeralPartitionLabel,
Size: 0,
Force: true,

View File

@ -2,7 +2,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package manifest
package install
import (
"io/ioutil"

View File

@ -2,45 +2,44 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package manifest
package install
import (
"errors"
"fmt"
"github.com/talos-systems/talos/pkg/blockdevice/probe"
"github.com/talos-systems/talos/pkg/config/machine"
"github.com/talos-systems/talos/pkg/constants"
)
// VerifyDataDevice verifies the supplied data device options.
func VerifyDataDevice(install machine.Install) (err error) {
if install.Disk() == "" {
// VerifyEphemeralPartition verifies the supplied data device options.
func VerifyEphemeralPartition(opts *Options) (err error) {
if opts.Disk == "" {
return errors.New("missing disk")
}
if install.Force() {
if opts.Force {
return nil
}
if err = VerifyDiskAvailability(install.Disk(), constants.EphemeralPartitionLabel); err != nil {
if err = VerifyDiskAvailability(opts.Disk, constants.EphemeralPartitionLabel); err != nil {
return fmt.Errorf("failed to verify disk availability: %w", err)
}
return nil
}
// VerifyBootDevice verifies the supplied boot device options.
func VerifyBootDevice(install machine.Install) (err error) {
if !install.WithBootloader() {
// VerifyBootPartition verifies the supplied boot device options.
func VerifyBootPartition(opts *Options) (err error) {
if opts.Bootloader {
return nil
}
if install.Force() {
if opts.Force {
return nil
}
if err = VerifyDiskAvailability(install.Disk(), constants.BootPartitionLabel); err != nil {
if err = VerifyDiskAvailability(opts.Disk, constants.BootPartitionLabel); err != nil {
return fmt.Errorf("failed to verify disk availability: %w", err)
}

View File

@ -2,7 +2,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package manifest
package install
import (
"testing"

View File

@ -17,11 +17,11 @@ import (
"github.com/spf13/cobra"
"github.com/talos-systems/talos/cmd/talosctl/pkg/mgmt/helpers"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/internal/pkg/cluster/check"
"github.com/talos-systems/talos/internal/pkg/provision"
"github.com/talos-systems/talos/internal/pkg/provision/access"
"github.com/talos-systems/talos/internal/pkg/provision/providers"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/cli"
clientconfig "github.com/talos-systems/talos/pkg/client/config"
"github.com/talos-systems/talos/pkg/config"

View File

@ -16,8 +16,8 @@ import (
"gopkg.in/yaml.v2"
"github.com/talos-systems/talos/cmd/talosctl/pkg/mgmt/helpers"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/pkg/config"
"github.com/talos-systems/talos/pkg/config/machine"
"github.com/talos-systems/talos/pkg/config/types/v1alpha1/generate"
"github.com/talos-systems/talos/pkg/constants"
)
@ -107,24 +107,24 @@ func genV1Alpha1Config(args []string) error {
return fmt.Errorf("failed to generate config bundle: %w", err)
}
for _, t := range []machine.Type{machine.TypeInit, machine.TypeControlPlane, machine.TypeWorker} {
for _, t := range []runtime.MachineType{runtime.MachineTypeInit, runtime.MachineTypeControlPlane, runtime.MachineTypeJoin} {
name := strings.ToLower(t.String()) + ".yaml"
fullFilePath := filepath.Join(outputDir, name)
var configString string
switch t {
case machine.TypeInit:
case runtime.MachineTypeInit:
configString, err = configBundle.Init().String()
if err != nil {
return err
}
case machine.TypeControlPlane:
case runtime.MachineTypeControlPlane:
configString, err = configBundle.ControlPlane().String()
if err != nil {
return err
}
case machine.TypeWorker:
case runtime.MachineTypeJoin:
configString, err = configBundle.Join().String()
if err != nil {
return err

View File

@ -9,7 +9,7 @@ import (
"github.com/spf13/cobra"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/pkg/cli"
"github.com/talos-systems/talos/pkg/config"
)
@ -31,7 +31,7 @@ var validateCmd = &cobra.Command{
return err
}
mode, err := runtime.ModeFromString(validateModeArg)
mode, err := runtime.ParseMode(validateModeArg)
if err != nil {
return err
}

View File

@ -10,10 +10,10 @@ import (
"github.com/spf13/cobra"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/internal/pkg/cluster"
"github.com/talos-systems/talos/internal/pkg/cluster/check"
"github.com/talos-systems/talos/pkg/client"
"github.com/talos-systems/talos/pkg/config/machine"
)
type clusterNodes struct {
@ -26,13 +26,13 @@ func (cluster *clusterNodes) Nodes() []string {
return append([]string{cluster.InitNode}, append(cluster.ControlPlaneNodes, cluster.WorkerNodes...)...)
}
func (cluster *clusterNodes) NodesByType(t machine.Type) []string {
func (cluster *clusterNodes) NodesByType(t runtime.MachineType) []string {
switch t {
case machine.TypeInit:
case runtime.MachineTypeInit:
return []string{cluster.InitNode}
case machine.TypeControlPlane:
case runtime.MachineTypeControlPlane:
return cluster.ControlPlaneNodes
case machine.TypeWorker:
case runtime.MachineTypeJoin:
return cluster.WorkerNodes
default:
panic("unsupported machine type")

4
go.mod
View File

@ -45,8 +45,8 @@ require (
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/kubernetes-sigs/bootkube v0.14.1-0.20200421144856-831deff0541a
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7 // indirect
github.com/mdlayher/genetlink v0.0.0-20190313224034-60417448a851
github.com/mdlayher/netlink v0.0.0-20191009155606-de872b0d824b
github.com/mdlayher/genetlink v1.0.0
github.com/mdlayher/netlink v1.0.0
github.com/mdlayher/raw v0.0.0-20190606144222-a54781e5f38f // indirect
github.com/onsi/gomega v1.8.1 // indirect
github.com/opencontainers/go-digest v1.0.0-rc1 // indirect

10
go.sum
View File

@ -434,13 +434,12 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7 h1:lez6TS6aAau+8wXUP3G9I3TGlmPFEq2CTxBaRqY6AGE=
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQobyTjI/tJyq2HG+i/dfSoFUt8/aZCM+GKtmFk/Y=
github.com/mdlayher/genetlink v0.0.0-20190313224034-60417448a851 h1:QYJTEbSDJvDBQenHYMxoiBQPgZ4QUcm75vACe3dkW7o=
github.com/mdlayher/genetlink v0.0.0-20190313224034-60417448a851/go.mod h1:EsbsAEUEs15qC1cosAwxgCWV0Qhd8TmkxnA9Kw1Vhl4=
github.com/mdlayher/netlink v0.0.0-20190313131330-258ea9dff42c/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
github.com/mdlayher/genetlink v1.0.0 h1:OoHN1OdyEIkScEmRgxLEe2M9U8ClMytqA5niynLtfj0=
github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc=
github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
github.com/mdlayher/netlink v0.0.0-20191008140946-2a17fd90af51/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
github.com/mdlayher/netlink v0.0.0-20191009155606-de872b0d824b h1:W3er9pI7mt2gOqOWzwvx20iJ8Akiqz1mUMTxU6wdvl8=
github.com/mdlayher/netlink v0.0.0-20191009155606-de872b0d824b/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
github.com/mdlayher/netlink v1.0.0 h1:vySPY5Oxnn/8lxAPn2cK6kAzcZzYJl3KriSLO46OT18=
github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
github.com/mdlayher/raw v0.0.0-20190606144222-a54781e5f38f h1:Xjvm7UTnKTwrlhbs+8qA6I0v1iX77rY3QxftSgvOVRk=
github.com/mdlayher/raw v0.0.0-20190606144222-a54781e5f38f/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
@ -701,7 +700,6 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190419010253-1f3472d942ba/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=

View File

@ -17,7 +17,7 @@ import (
apidbackend "github.com/talos-systems/talos/internal/app/apid/pkg/backend"
"github.com/talos-systems/talos/internal/app/apid/pkg/director"
"github.com/talos-systems/talos/internal/app/apid/pkg/provider"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/pkg/config"
"github.com/talos-systems/talos/pkg/constants"
"github.com/talos-systems/talos/pkg/grpc/factory"

View File

@ -11,7 +11,7 @@ import (
stdlibtls "crypto/tls"
stdlibnet "net"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/pkg/constants"
"github.com/talos-systems/talos/pkg/grpc/tls"
"github.com/talos-systems/talos/pkg/net"

View File

@ -23,7 +23,7 @@ import (
"github.com/kubernetes-sigs/bootkube/pkg/tlsutil"
"github.com/talos-systems/bootkube-plugin/pkg/asset"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/pkg/constants"
tnet "github.com/talos-systems/talos/pkg/net"
)

View File

@ -18,9 +18,7 @@ import (
"github.com/talos-systems/go-procfs/procfs"
"github.com/talos-systems/talos/internal/pkg/kmsg"
"github.com/talos-systems/talos/internal/pkg/mount/manager"
"github.com/talos-systems/talos/internal/pkg/mount/manager/pseudo"
"github.com/talos-systems/talos/internal/pkg/mount/manager/squashfs"
"github.com/talos-systems/talos/internal/pkg/mount"
"github.com/talos-systems/talos/internal/pkg/mount/switchroot"
"github.com/talos-systems/talos/pkg/constants"
"github.com/talos-systems/talos/pkg/version"
@ -29,13 +27,12 @@ import (
// nolint: gocyclo
func run() (err error) {
// Mount the pseudo devices.
mountpoints, err := pseudo.MountPoints()
pseudo, err := mount.PseudoMountPoints()
if err != nil {
return err
}
pseudo := manager.NewManager(mountpoints)
if err = pseudo.MountAll(); err != nil {
if err = mount.Mount(pseudo); err != nil {
return err
}
@ -50,13 +47,12 @@ func run() (err error) {
// Mount the rootfs.
log.Println("mounting the rootfs")
mountpoints, err = squashfs.MountPoints(constants.NewRoot)
squashfs, err := mount.SquashfsMountPoints(constants.NewRoot)
if err != nil {
return err
}
squashfs := manager.NewManager(mountpoints)
if err = squashfs.MountAll(); err != nil {
if err = mount.Mount(squashfs); err != nil {
return err
}

View File

@ -1,45 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package api
import (
"context"
"io"
"github.com/talos-systems/talos/internal/app/machined/internal/api/reg"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/constants"
"github.com/talos-systems/talos/pkg/grpc/factory"
)
// Service wraps machined API server
type Service struct{}
// NewService creates new Service
func NewService() *Service {
return &Service{}
}
// Main is an entrypoint the the API service
func (s *Service) Main(ctx context.Context, config runtime.Configurator, logWriter io.Writer) error {
api := reg.NewRegistrator(config)
server := factory.NewServer(api, factory.WithLog("machined ", logWriter))
listener, err := factory.NewListener(factory.Network("unix"), factory.SocketPath(constants.MachineSocketPath))
if err != nil {
return err
}
defer server.Stop()
go func() {
// nolint: errcheck
server.Serve(listener)
}()
<-ctx.Done()
return nil
}

View File

@ -1,21 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package cni
import (
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// Mounts returns the set of mounts required by the requested CNI plugin. All
// paths are relative to the root file system after switching the root.
func Mounts(config runtime.Configurator) ([]specs.Mount, error) {
mounts := []specs.Mount{
{Type: "bind", Destination: "/etc/cni", Source: "/etc/cni", Options: []string{"rbind", "rshared", "rw"}},
}
return mounts, nil
}

View File

@ -20,15 +20,16 @@ import (
"github.com/talos-systems/go-procfs/procfs"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/internal/pkg/containers/image"
"github.com/talos-systems/talos/internal/pkg/kmsg"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/constants"
)
// RunInstallerContainer performs an installation via the installer container.
//
//nolint: gocyclo
func RunInstallerContainer(r runtime.Runtime, opts ...Option) error {
func RunInstallerContainer(disk, platform, ref string, reg runtime.Registries, opts ...Option) error {
options := DefaultInstallOptions()
for _, opt := range opts {
@ -44,17 +45,17 @@ func RunInstallerContainer(r runtime.Runtime, opts ...Option) error {
return err
}
log.Printf("pulling installer container image: %q", r.Config().Machine().Install().Image())
var img containerd.Image
if options.ImagePull {
img, err = image.Pull(ctx, r.Config().Machine().Registries(), client, r.Config().Machine().Install().Image())
if options.Pull {
log.Printf("pulling %q", ref)
img, err = image.Pull(ctx, reg, client, ref)
if err != nil {
return err
}
} else {
img, err = client.GetImage(ctx, r.Config().Machine().Install().Image())
img, err = client.GetImage(ctx, ref)
if err != nil {
return err
}
@ -71,22 +72,22 @@ func RunInstallerContainer(r runtime.Runtime, opts ...Option) error {
return fmt.Errorf("no config option was found")
}
upgrade := "false"
if r.Sequence() == runtime.Upgrade {
upgrade = "true"
}
upgrade := strconv.FormatBool(options.Upgrade)
force := strconv.FormatBool(options.Force)
zero := strconv.FormatBool(options.Zero)
args := []string{
"/bin/installer",
"install",
"--disk=" + r.Config().Machine().Install().Disk(),
"--platform=" + r.Platform().Name(),
"--disk=" + disk,
"--platform=" + platform,
"--config=" + *config,
"--upgrade=" + upgrade,
"--force=" + strconv.FormatBool(!options.Preserve),
"--force=" + force,
"--zero=" + zero,
}
for _, arg := range r.Config().Machine().Install().ExtraKernelArgs() {
for _, arg := range options.ExtraKernelArgs {
args = append(args, []string{"--extra-kernel-arg", arg}...)
}
@ -101,6 +102,7 @@ func RunInstallerContainer(r runtime.Runtime, opts ...Option) error {
oci.WithParentCgroupDevices,
oci.WithPrivileged,
}
containerOpts := []containerd.NewContainerOpts{
containerd.WithImage(img),
containerd.WithNewSnapshot("upgrade", img),

View File

@ -0,0 +1,69 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package install
// Option is a functional option.
type Option func(o *Options) error
// Options describes the install options.
type Options struct {
Pull bool
Force bool
Upgrade bool
Zero bool
ExtraKernelArgs []string
}
// DefaultInstallOptions returns default options.
func DefaultInstallOptions() Options {
return Options{
Pull: true,
}
}
// WithPull sets the pull option.
func WithPull(b bool) Option {
return func(o *Options) error {
o.Pull = b
return nil
}
}
// WithForce sets the force option.
func WithForce(b bool) Option {
return func(o *Options) error {
o.Force = b
return nil
}
}
// WithUpgrade sets the upgrade option.
func WithUpgrade(b bool) Option {
return func(o *Options) error {
o.Upgrade = b
return nil
}
}
// WithZero sets the zero option.
func WithZero(b bool) Option {
return func(o *Options) error {
o.Zero = b
return nil
}
}
// WithExtraKernelArgs sets the extra args.
func WithExtraKernelArgs(s []string) Option {
return func(o *Options) error {
o.ExtraKernelArgs = s
return nil
}
}

View File

@ -1,98 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package config
import (
"bytes"
"compress/gzip"
"fmt"
"io/ioutil"
"log"
"net/http"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/config"
"github.com/talos-systems/talos/pkg/constants"
)
// Task represents the Task task.
type Task struct {
cfgBytes *[]byte
}
// NewConfigTask initializes and returns a Task task.
func NewConfigTask(cfgBytes *[]byte) phase.Task {
return &Task{
cfgBytes: cfgBytes,
}
}
// TaskFunc returns the runtime function.
func (task *Task) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return task.standard
}
func (task *Task) standard(r runtime.Runtime) (err error) {
cfg, err := config.NewFromFile(constants.ConfigPath)
if err != nil || !cfg.Persist() {
log.Printf("failed to read config from file or persistence disabled. re-pulling config")
var cfgBytes []byte
cfgBytes, err = fetchConfig(r)
if err != nil {
return err
}
*task.cfgBytes = cfgBytes
return nil
}
log.Printf("using existing config on disk")
cfgBytes, err := cfg.Bytes()
if err != nil {
return err
}
*task.cfgBytes = cfgBytes
return nil
}
func fetchConfig(r runtime.Runtime) (out []byte, err error) {
var b []byte
if b, err = r.Platform().Configuration(); err != nil {
return nil, err
}
// Detect if config is a gzip archive and unzip it if so
contentType := http.DetectContentType(b)
if contentType == "application/x-gzip" {
var gzipReader *gzip.Reader
gzipReader, err = gzip.NewReader(bytes.NewReader(b))
if err != nil {
return nil, fmt.Errorf("error creating gzip reader: %w", err)
}
// nolint: errcheck
defer gzipReader.Close()
var unzippedData []byte
unzippedData, err = ioutil.ReadAll(gzipReader)
if err != nil {
return nil, fmt.Errorf("error unzipping machine config: %w", err)
}
b = unzippedData
}
return b, nil
}

View File

@ -1,106 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package config
import (
"log"
"golang.org/x/sys/unix"
"github.com/talos-systems/talos/cmd/installer/pkg/manifest"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/mount"
"github.com/talos-systems/talos/internal/pkg/mount/manager"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/blockdevice/probe"
"github.com/talos-systems/talos/pkg/blockdevice/util"
)
// ExtraDisks represents the ExtraDisks task.
type ExtraDisks struct{}
// NewExtraDisksTask initializes and returns an ExtraDisks task.
func NewExtraDisksTask() phase.Task {
return &ExtraDisks{}
}
// TaskFunc returns the runtime function.
func (task *ExtraDisks) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return task.runtime
}
func (task *ExtraDisks) runtime(r runtime.Runtime) (err error) {
if err = partitionAndFormatDisks(r); err != nil {
return err
}
return mountDisks(r)
}
func partitionAndFormatDisks(r runtime.Runtime) (err error) {
m := &manifest.Manifest{
Targets: map[string][]*manifest.Target{},
}
for _, disk := range r.Config().Machine().Disks() {
if m.Targets[disk.Device] == nil {
m.Targets[disk.Device] = []*manifest.Target{}
}
for _, part := range disk.Partitions {
extraTarget := &manifest.Target{
Device: disk.Device,
Size: part.Size,
Force: true,
Test: false,
}
m.Targets[disk.Device] = append(m.Targets[disk.Device], extraTarget)
}
}
probed, err := probe.All()
if err != nil {
return err
}
// TODO(andrewrynhard): This is disgusting, but it works. We should revisit
// this at a later time.
for _, p := range probed {
for _, disk := range r.Config().Machine().Disks() {
for i := range disk.Partitions {
partname := util.PartPath(disk.Device, i+1)
if p.Path == partname {
log.Printf(("found existing partitions for %q"), disk.Device)
return nil
}
}
}
}
if err = m.ExecuteManifest(); err != nil {
return err
}
return nil
}
func mountDisks(r runtime.Runtime) (err error) {
mountpoints := mount.NewMountPoints()
for _, extra := range r.Config().Machine().Disks() {
for i, part := range extra.Partitions {
partname := util.PartPath(extra.Device, i+1)
mountpoints.Set(partname, mount.NewMountPoint(partname, part.MountPoint, "xfs", unix.MS_NOATIME, ""))
}
}
extras := manager.NewManager(mountpoints)
if err = extras.MountAll(); err != nil {
return err
}
return nil
}

View File

@ -1,36 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package config
import (
"log"
"os"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// ExtraEnvVars represents the ExtraEnvVars task.
type ExtraEnvVars struct{}
// NewExtraEnvVarsTask initializes and returns an ExtraEnvVars task.
func NewExtraEnvVarsTask() phase.Task {
return &ExtraEnvVars{}
}
// TaskFunc returns the runtime function.
func (task *ExtraEnvVars) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return task.runtime
}
func (task *ExtraEnvVars) runtime(r runtime.Runtime) (err error) {
for key, val := range r.Config().Machine().Env() {
if err = os.Setenv(key, val); err != nil {
log.Printf("WARNING failed to set enivronment variable: %v", err)
}
}
return nil
}

View File

@ -1,148 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package config
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/hashicorp/go-multierror"
"golang.org/x/sys/unix"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// ExtraFiles represents the ExtraFiles task.
type ExtraFiles struct{}
// NewExtraFilesTask initializes and returns an ExtraFiles task.
func NewExtraFilesTask() phase.Task {
return &ExtraFiles{}
}
// TaskFunc returns the runtime function.
func (task *ExtraFiles) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return task.runtime
}
// nolint: gocyclo
func (task *ExtraFiles) runtime(r runtime.Runtime) (err error) {
var result *multierror.Error
files, err := r.Config().Machine().Files()
if err != nil {
return fmt.Errorf("error generating extra files: %w", err)
}
for _, f := range files {
content := f.Content
switch f.Op {
case "create":
if err = doesNotExists(f.Path); err != nil {
result = multierror.Append(result, fmt.Errorf("file must not exist: %q", f.Path))
continue
}
case "overwrite":
if err = existsAndIsFile(f.Path); err != nil {
result = multierror.Append(result, err)
continue
}
case "append":
if err = existsAndIsFile(f.Path); err != nil {
result = multierror.Append(result, err)
continue
}
var existingFileContents []byte
existingFileContents, err = ioutil.ReadFile(f.Path)
if err != nil {
result = multierror.Append(result, err)
continue
}
content = string(existingFileContents) + "\n" + f.Content
default:
result = multierror.Append(result, fmt.Errorf("unknown operation for file %q: %q", f.Path, f.Op))
continue
}
// Determine if supplied path is in /var or not.
// If not, we'll write it to /var anyways and bind mount below
p := f.Path
inVar := true
explodedPath := strings.Split(
strings.TrimLeft(f.Path, "/"),
string(os.PathSeparator),
)
if explodedPath[0] != "var" {
p = filepath.Join("/var", f.Path)
inVar = false
}
// We do not want to support creating new files anywhere outside of
// /var. If a valid use case comes up, we can reconsider then.
if !inVar && f.Op == "create" {
return fmt.Errorf("create operation not allowed outside of /var: %q", f.Path)
}
if err = os.MkdirAll(filepath.Dir(p), os.ModeDir); err != nil {
result = multierror.Append(result, err)
continue
}
if err = ioutil.WriteFile(p, []byte(content), f.Permissions); err != nil {
result = multierror.Append(result, err)
continue
}
// File path was not /var/... so we assume a bind mount is wanted
if !inVar {
if err = unix.Mount(p, f.Path, "", unix.MS_BIND|unix.MS_RDONLY, ""); err != nil {
result = multierror.Append(result, fmt.Errorf("failed to create bind mount for %s: %w", p, err))
}
}
}
return result.ErrorOrNil()
}
func doesNotExists(p string) (err error) {
_, err = os.Stat(p)
if err != nil {
if os.IsNotExist(err) {
return nil
}
return err
}
return fmt.Errorf("file exists")
}
func existsAndIsFile(p string) (err error) {
var info os.FileInfo
info, err = os.Stat(p)
if err != nil {
if !os.IsNotExist(err) {
return err
}
return fmt.Errorf("file must exist: %q", p)
}
if !info.Mode().IsRegular() {
return fmt.Errorf("invalid mode: %q", info.Mode().String())
}
return nil
}

View File

@ -1,42 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package config
import (
"io/ioutil"
"log"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/constants"
)
// SaveConfig represents the SaveConfig task.
type SaveConfig struct{}
// NewSaveConfigTask initializes and returns an Config task.
func NewSaveConfigTask() phase.Task {
return &SaveConfig{}
}
// TaskFunc returns the runtime function.
func (task *SaveConfig) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return task.runtime
}
func (task *SaveConfig) runtime(r runtime.Runtime) (err error) {
log.Printf("saving config %s to disk\n", r.Config().Version())
b, err := r.Config().Bytes()
if err != nil {
return err
}
if err = ioutil.WriteFile(constants.ConfigPath, b, 0644); err != nil {
return err
}
return nil
}

View File

@ -1,38 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package config
import (
"github.com/hashicorp/go-multierror"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/sysctl"
)
// Sysctls represents the Sysctls task.
type Sysctls struct{}
// NewSysctlsTask initializes and returns a Sysctls task.
func NewSysctlsTask() phase.Task {
return &Sysctls{}
}
// TaskFunc returns the runtime function.
func (task *Sysctls) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return task.runtime
}
func (task *Sysctls) runtime(r runtime.Runtime) (err error) {
var result *multierror.Error
for k, v := range r.Config().Machine().Sysctls() {
if err = sysctl.WriteSystemProperty(&sysctl.SystemProperty{Key: k, Value: v}); err != nil {
return err
}
}
return result.ErrorOrNil()
}

View File

@ -1,14 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package config_test
import "testing"
func TestEmpty(t *testing.T) {
// added for accurate coverage estimation
//
// please remove it once any unit-test is added
// for this package
}

View File

@ -1,35 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package disk
import (
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/blockdevice"
)
// ResetSystemDisk represents the task for stop all containerd tasks in the
// k8s.io namespace.
type ResetSystemDisk struct {
devname string
}
// NewResetSystemDiskTask initializes and returns an Services task.
func NewResetSystemDiskTask(devname string) phase.Task {
return &ResetSystemDisk{
devname: devname,
}
}
// TaskFunc returns the runtime function.
func (task *ResetSystemDisk) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return func(r runtime.Runtime) error {
return task.standard()
}
}
func (task *ResetSystemDisk) standard() (err error) {
return blockdevice.ResetDevice(task.devname)
}

View File

@ -1,97 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package disk
import (
"errors"
"fmt"
"io"
"log"
"os"
"time"
"golang.org/x/sys/unix"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/retry"
)
// VerifyDiskAvailability represents the task for verifying that the system
// disk is not in use.
type VerifyDiskAvailability struct {
devname string
}
// NewVerifyDiskAvailabilityTask initializes and returns a
// VerifyDiskAvailability task.
func NewVerifyDiskAvailabilityTask(devname string) phase.Task {
return &VerifyDiskAvailability{
devname: devname,
}
}
// TaskFunc returns the runtime function.
func (task *VerifyDiskAvailability) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return func(r runtime.Runtime) error {
// We only need to verify system disk availability if we are going to
// reformat the ephemeral partition.
if r.Config().Machine().Install().Force() {
return task.standard()
}
return nil
}
}
func (task *VerifyDiskAvailability) standard() (err error) {
if _, err = os.Stat(task.devname); errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("system disk not found: %w", err)
}
mountsReported := false
return retry.Constant(3*time.Minute, retry.WithUnits(500*time.Millisecond)).Retry(func() error {
if err = tryLock(task.devname); err != nil {
if err == unix.EBUSY {
if !mountsReported {
// if disk is busy, report mounts for debugging purposes but just once
// otherwise console might be flooded with messages
dumpMounts()
mountsReported = true
}
return retry.ExpectedError(errors.New("system disk in use"))
}
return retry.UnexpectedError(fmt.Errorf("failed to verify system disk not in use: %w", err))
}
return nil
})
}
func tryLock(devname string) error {
fd, errno := unix.Open(devname, unix.O_RDONLY|unix.O_EXCL|unix.O_CLOEXEC, 0)
// nolint: errcheck
defer unix.Close(fd)
return errno
}
func dumpMounts() {
mounts, err := os.Open("/proc/mounts")
if err != nil {
log.Printf("failed to read mounts: %s", err)
return
}
defer mounts.Close() //nolint: errcheck
log.Printf("contents of /proc/mounts:")
_, _ = io.Copy(log.Writer(), mounts) //nolint: errcheck
}

View File

@ -1,49 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package kubernetes
import (
"os"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/kubernetes"
)
// CordonAndDrain represents the task for stop all containerd tasks in the
// k8s.io namespace.
type CordonAndDrain struct{}
// NewCordonAndDrainTask initializes and returns an Services task.
func NewCordonAndDrainTask() phase.Task {
return &CordonAndDrain{}
}
// TaskFunc returns the runtime function.
func (task *CordonAndDrain) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return func(r runtime.Runtime) error {
return task.standard()
}
}
func (task *CordonAndDrain) standard() (err error) {
var hostname string
if hostname, err = os.Hostname(); err != nil {
return err
}
var kubeHelper *kubernetes.Client
if kubeHelper, err = kubernetes.NewClientFromKubeletKubeconfig(); err != nil {
return err
}
if err = kubeHelper.CordonAndDrain(hostname); err != nil {
return err
}
return nil
}

View File

@ -1,64 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package kubernetes
import (
"context"
"time"
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/app/machined/pkg/system"
"github.com/talos-systems/talos/internal/pkg/cri"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/constants"
)
// RemoveAllPods represents the task for stopping all pods.
type RemoveAllPods struct{}
// NewRemoveAllPodsTask initializes and returns an Services task.
func NewRemoveAllPodsTask() phase.Task {
return &RemoveAllPods{}
}
// TaskFunc returns the runtime function.
func (task *RemoveAllPods) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return func(r runtime.Runtime) error {
return task.standard()
}
}
func (task *RemoveAllPods) standard() (err error) {
if err = system.Services(nil).Stop(context.Background(), "kubelet"); err != nil {
return err
}
client, err := cri.NewClient("unix://"+constants.ContainerdAddress, 10*time.Second)
if err != nil {
return err
}
// nolint: errcheck
defer client.Close()
// We remove pods with POD network mode first so that the CNI can perform
// any cleanup tasks. If we don't do this, we run the risk of killing the
// CNI, preventing the CRI from cleaning up the pod's netwokring.
if err = client.RemovePodSandboxes(runtimeapi.NamespaceMode_POD, runtimeapi.NamespaceMode_CONTAINER); err != nil {
return err
}
// With the POD network mode pods out of the way, we kill the remaining
// pods.
if err = client.RemovePodSandboxes(); err != nil {
return err
}
return nil
}

View File

@ -1,39 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package limits
import (
"golang.org/x/sys/unix"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// FileLimitTask represents the FileLimitTask task.
type FileLimitTask struct{}
// NewFileLimitTask initializes and returns a FileLimitTask task.
func NewFileLimitTask() phase.Task {
return &FileLimitTask{}
}
// TaskFunc returns the runtime function.
func (task *FileLimitTask) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.standard
}
}
func (task *FileLimitTask) standard(r runtime.Runtime) (err error) {
// TODO(andrewrynhard): Should we read limit from /proc/sys/fs/nr_open?
if err = unix.Setrlimit(unix.RLIMIT_NOFILE, &unix.Rlimit{Cur: 1048576, Max: 1048576}); err != nil {
return err
}
return nil
}

View File

@ -1,14 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package limits_test
import "testing"
func TestEmpty(t *testing.T) {
// added for accurate coverage estimation
//
// please remove it once any unit-test is added
// for this package
}

View File

@ -1,42 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package network
import (
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/app/networkd/pkg/networkd"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// InitialNetworkSetup represents the task for setting up the initial network.
type InitialNetworkSetup struct{}
// NewInitialNetworkSetupTask initializes and returns an InitialNetworkSetup task.
func NewInitialNetworkSetupTask() phase.Task {
return &InitialNetworkSetup{}
}
// TaskFunc returns the runtime function.
func (task *InitialNetworkSetup) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.runtime
}
}
func (task *InitialNetworkSetup) runtime(r runtime.Runtime) (err error) {
nwd, err := networkd.New(r.Config())
if err != nil {
return err
}
if err = nwd.Configure(); err != nil {
return err
}
return nil
}

View File

@ -1,14 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package network_test
import "testing"
func TestEmpty(t *testing.T) {
// added for accurate coverage estimation
//
// please remove it once any unit-test is added
// for this package
}

View File

@ -1,41 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package network
import (
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/app/networkd/pkg/networkd"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// ResetNetworkNetwork represents the ResetNetworkNetwork task.
type ResetNetworkNetwork struct{}
// NewResetNetworkTask initializes and returns an ResetNetworkNetwork task.
func NewResetNetworkTask() phase.Task {
return &ResetNetworkNetwork{}
}
// TaskFunc returns the runtime function.
func (task *ResetNetworkNetwork) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.runtime
}
}
// nolint: gocyclo
func (task *ResetNetworkNetwork) runtime(r runtime.Runtime) (err error) {
nwd, err := networkd.New(r.Config())
if err != nil {
return err
}
nwd.Reset()
return nil
}

View File

@ -1,178 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package phase
import (
"errors"
"fmt"
"log"
"time"
goruntime "runtime"
"github.com/hashicorp/go-multierror"
"github.com/talos-systems/talos/internal/pkg/kmsg"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/internal/pkg/runtime/platform"
)
// RuntimeArgs represents the set of arguments passed into a TaskFunc.
type RuntimeArgs struct {
platform runtime.Platform
config runtime.Configurator
}
// TaskFunc defines the function that a task must return. The function
// envelopes the task logic for a given runtime mode.
type TaskFunc func(runtime.Runtime) error
// Task represents a task within a Phase.
type Task interface {
TaskFunc(runtime.Mode) TaskFunc
}
// Phase represents a phase in the boot process.
type Phase struct {
description string
tasks []Task
}
// Runner represents a management layer for phases.
type Runner struct {
phases []*Phase
runtime runtime.Runtime
}
// NewRunner initializes and returns a Runner.
func NewRunner(config runtime.Configurator, sequence runtime.Sequence) (*Runner, error) {
platform, err := platform.CurrentPlatform()
if err != nil {
return nil, err
}
switch platform.Mode() {
case runtime.Metal:
fallthrough
case runtime.Cloud:
// Setup logging to /dev/kmsg.
if err = kmsg.Setup("[talos]", true); err != nil {
return nil, fmt.Errorf("failed to setup logging: %w", err)
}
}
runner := &Runner{
runtime: runtime.NewRuntime(platform, config, sequence),
}
return runner, nil
}
// Platform returns the platform.
func (r *RuntimeArgs) Platform() runtime.Platform {
return r.platform
}
// Config returns the config.
func (r *RuntimeArgs) Config() runtime.Configurator {
return r.config
}
// Run executes sequentially all phases known to a Runner.
//
// If any phase fails, Runner aborts immediately.
func (r *Runner) Run() error {
for _, phase := range r.phases {
if err := r.runPhase(phase); err != nil {
return fmt.Errorf("error running phase %q: %w", phase.description, err)
}
}
return nil
}
// runPhase runs a phase by running all phase tasks concurrently.
func (r *Runner) runPhase(phase *Phase) error {
errCh := make(chan error)
start := time.Now()
log.Printf("[phase]: %s", phase.description)
for _, task := range phase.tasks {
go r.runTask(task, errCh)
}
var (
result *multierror.Error
reboot bool
)
for range phase.tasks {
err := <-errCh
if err != nil {
if errors.Is(err, runtime.ErrReboot) {
reboot = true
} else {
log.Printf("[phase]: %s error running task: %s", phase.description, err)
}
}
result = multierror.Append(result, err)
}
log.Printf("[phase]: %s done, %s", phase.description, time.Since(start))
if reboot {
return runtime.ErrReboot
}
return result.ErrorOrNil()
}
func (r *Runner) runTask(task Task, errCh chan<- error) {
var err error
defer func() {
errCh <- err
}()
defer func() {
if r := recover(); r != nil {
// don't generate traceback for reboot error
if r == runtime.ErrReboot {
err = r.(error) //nolint: errcheck
return
}
buf := make([]byte, 8192)
n := goruntime.Stack(buf, false)
err = fmt.Errorf("panic recovered: %v\n%s", r, string(buf[:n]))
}
}()
var f TaskFunc
if f = task.TaskFunc(r.runtime.Platform().Mode()); f == nil {
// A task is not defined for this runtime mode.
return
}
err = f(r.runtime)
}
// Add adds a phase to a Runner.
func (r *Runner) Add(phase ...*Phase) {
r.phases = append(r.phases, phase...)
}
// NewPhase initializes and returns a Phase.
func NewPhase(description string, tasks ...Task) *Phase {
tasks = append([]Task{}, tasks...)
return &Phase{
description: description,
tasks: tasks,
}
}

View File

@ -1,115 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package phase_test
import (
"errors"
"os"
"testing"
"github.com/stretchr/testify/suite"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
type PhaseSuite struct {
suite.Suite
platformExists bool
platformValue string
}
type regularTask struct {
errCh <-chan error
}
func (t *regularTask) TaskFunc(runtime.Mode) phase.TaskFunc {
return func(runtime.Runtime) error {
return <-t.errCh
}
}
type nilTask struct{}
func (t *nilTask) TaskFunc(runtime.Mode) phase.TaskFunc {
return nil
}
type panicTask struct{}
func (t *panicTask) TaskFunc(runtime.Mode) phase.TaskFunc {
return func(runtime.Runtime) error {
panic("in task")
}
}
func (suite *PhaseSuite) SetupSuite() {
suite.platformValue, suite.platformExists = os.LookupEnv("PLATFORM")
suite.Require().NoError(os.Setenv("PLATFORM", "container"))
}
func (suite *PhaseSuite) TearDownSuite() {
if !suite.platformExists {
suite.Require().NoError(os.Unsetenv("PLATFORM"))
} else {
suite.Require().NoError(os.Setenv("PLATFORM", suite.platformValue))
}
}
func (suite *PhaseSuite) TestRunSuccess() {
r, err := phase.NewRunner(nil, runtime.None)
suite.Require().NoError(err)
taskErr := make(chan error)
r.Add(phase.NewPhase("empty"))
r.Add(phase.NewPhase("phase1", &regularTask{errCh: taskErr}, &regularTask{errCh: taskErr}))
r.Add(phase.NewPhase("phase2", &regularTask{errCh: taskErr}, &nilTask{}))
errCh := make(chan error)
go func() {
errCh <- r.Run()
}()
taskErr <- nil
taskErr <- nil
select {
case <-errCh:
suite.Require().Fail("should be still running")
default:
}
taskErr <- nil
suite.Require().NoError(<-errCh)
}
func (suite *PhaseSuite) TestRunFailures() {
r, err := phase.NewRunner(nil, runtime.None)
suite.Require().NoError(err)
taskErr := make(chan error, 1)
r.Add(phase.NewPhase("empty"))
r.Add(phase.NewPhase("failphase", &panicTask{}, &regularTask{errCh: taskErr}, &nilTask{}))
r.Add(phase.NewPhase("neverreached",
&regularTask{}, // should never be reached
))
taskErr <- errors.New("test error")
err = r.Run()
suite.Require().Error(err)
suite.Assert().Contains(err.Error(), "2 errors occurred")
suite.Assert().Contains(err.Error(), "test error")
suite.Assert().Contains(err.Error(), "panic recovered: in task")
}
func TestPhaseSuite(t *testing.T) {
suite.Run(t, new(PhaseSuite))
}

View File

@ -1,61 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package platform
import (
"log"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/internal/pkg/runtime/initializer"
)
// Platform represents the Platform task.
type Platform struct{}
// NewPlatformTask initializes and returns an Platform task.
func NewPlatformTask() phase.Task {
return &Platform{}
}
// TaskFunc returns the runtime function.
func (task *Platform) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return task.runtime
}
func (task *Platform) runtime(r runtime.Runtime) (err error) {
i, err := initializer.New(r.Platform().Mode())
if err != nil {
return err
}
if err = i.Initialize(r); err != nil {
return err
}
hostname, err := r.Platform().Hostname()
if err != nil {
return err
}
if hostname != nil {
r.Config().Machine().Network().SetHostname(string(hostname))
}
addrs, err := r.Platform().ExternalIPs()
if err != nil {
log.Printf("certificates will be created without external IPs: %v\n", err)
}
sans := make([]string, 0, len(addrs))
for _, addr := range addrs {
sans = append(sans, addr.String())
}
r.Config().Machine().Security().SetCertSANs(sans)
r.Config().Cluster().SetCertSANs(sans)
return nil
}

View File

@ -1,14 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package platform_test
import "testing"
func TestEmpty(t *testing.T) {
// added for accurate coverage estimation
//
// please remove it once any unit-test is added
// for this package
}

View File

@ -1,49 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs
import (
"fmt"
"github.com/talos-systems/talos/cmd/installer/pkg/bootloader/syslinux"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// CheckInstall represents the CheckInstall task.
type CheckInstall struct{}
// NewCheckInstallTask initializes and returns a CheckInstall task.
func NewCheckInstallTask() phase.Task {
return &CheckInstall{}
}
// TaskFunc returns the runtime function.
func (task *CheckInstall) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.standard
}
}
func (task *CheckInstall) standard(r runtime.Runtime) (err error) {
var (
current string
next string
)
current, next, err = syslinux.Labels()
if err != nil {
return err
}
if current == "" && next == "" {
return fmt.Errorf("syslinux.cfg is not configured")
}
return err
}

View File

@ -1,105 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package etc
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"strings"
"text/template"
"github.com/talos-systems/talos/pkg/version"
"golang.org/x/sys/unix"
)
const osReleaseTemplate = `
NAME="{{ .Name }}"
ID={{ .ID }}
VERSION_ID={{ .Version }}
PRETTY_NAME="{{ .Name }} ({{ .Version }})"
HOME_URL="https://docs.talos-systems.com/"
BUG_REPORT_URL="https://github.com/talos-systems/talos/issues"
`
// Hosts creates a persistent and writable /etc/hosts file.
func Hosts() (err error) {
return createBindMount("/run/system/etc/hosts", "/etc/hosts")
}
// ResolvConf creates a persistent and writable /etc/resolv.conf file.
func ResolvConf() (err error) {
return createBindMount("/run/system/etc/resolv.conf", "/etc/resolv.conf")
}
// OSRelease renders a valid /etc/os-release file and writes it to disk. The
// node's OS Image field is reported by the node from /etc/os-release.
func OSRelease() (err error) {
if err = createBindMount("/run/system/etc/os-release", "/etc/os-release"); err != nil {
return err
}
var (
v string
tmpl *template.Template
)
switch version.Tag {
case "none":
v = version.SHA
default:
v = version.Tag
}
data := struct {
Name string
ID string
Version string
}{
Name: version.Name,
ID: strings.ToLower(version.Name),
Version: v,
}
tmpl, err = template.New("").Parse(osReleaseTemplate)
if err != nil {
return err
}
var buf []byte
writer := bytes.NewBuffer(buf)
err = tmpl.Execute(writer, data)
if err != nil {
return err
}
return ioutil.WriteFile("/run/system/etc/os-release", writer.Bytes(), 0644)
}
// createBindMount creates a common way to create a writable source file with a
// bind mounted destination. This is most commonly used for well known files
// under /etc that need to be adjusted during startup.
func createBindMount(src, dst string) (err error) {
var f *os.File
if f, err = os.OpenFile(src, os.O_WRONLY|os.O_CREATE, 0644); err != nil {
return err
}
// nolint: errcheck
if err = f.Close(); err != nil {
return err
}
if err = unix.Mount(src, dst, "", unix.MS_BIND, ""); err != nil {
return fmt.Errorf("failed to create bind mount for %s: %w", dst, err)
}
return nil
}

View File

@ -1,47 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs
import (
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/mount"
"github.com/talos-systems/talos/internal/pkg/mount/manager"
"github.com/talos-systems/talos/internal/pkg/mount/manager/bpffs"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// MountBPFFS represents the MountBPFFS task.
type MountBPFFS struct{}
// NewMountBPFFSTask initializes and returns an MountBPFFS task.
func NewMountBPFFSTask() phase.Task {
return &MountBPFFS{}
}
// TaskFunc returns the runtime function.
func (task *MountBPFFS) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.runtime
}
}
func (task *MountBPFFS) runtime(r runtime.Runtime) (err error) {
var mountpoints *mount.Points
mountpoints, err = bpffs.MountPoints()
if err != nil {
return err
}
m := manager.NewManager(mountpoints)
if err = m.MountAll(); err != nil {
return err
}
return nil
}

View File

@ -1,67 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs
import (
"fmt"
"io/ioutil"
"os"
"path"
"strconv"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/mount"
"github.com/talos-systems/talos/internal/pkg/mount/manager"
"github.com/talos-systems/talos/internal/pkg/mount/manager/cgroups"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
const (
memoryCgroup = "memory"
memoryUseHierarchy = "memory.use_hierarchy"
memoryUseHierarchyPermissions = os.FileMode(400)
)
var memoryUseHierarchyContents = []byte(strconv.Itoa(1))
// MountCgroups represents the MountCgroups task.
type MountCgroups struct{}
// NewMountCgroupsTask initializes and returns an MountCgroups task.
func NewMountCgroupsTask() phase.Task {
return &MountCgroups{}
}
// TaskFunc returns the runtime function.
func (task *MountCgroups) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.runtime
}
}
func (task *MountCgroups) runtime(r runtime.Runtime) (err error) {
var mountpoints *mount.Points
mountpoints, err = cgroups.MountPoints()
if err != nil {
return err
}
m := manager.NewManager(mountpoints)
if err = m.MountAll(); err != nil {
return err
}
// See https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt
target := path.Join("/sys/fs/cgroup", memoryCgroup, memoryUseHierarchy)
if err = ioutil.WriteFile(target, memoryUseHierarchyContents, memoryUseHierarchyPermissions); err != nil {
return fmt.Errorf("failed to enable memory hierarchy support: %w", err)
}
return nil
}

View File

@ -1,47 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs
import (
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/mount"
"github.com/talos-systems/talos/internal/pkg/mount/manager"
"github.com/talos-systems/talos/internal/pkg/mount/manager/overlay"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// MountOverlay represents the MountOverlay task.
type MountOverlay struct{}
// NewMountOverlayTask initializes and returns an MountOverlay task.
func NewMountOverlayTask() phase.Task {
return &MountOverlay{}
}
// TaskFunc returns the runtime function.
func (task *MountOverlay) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.standard
}
}
func (task *MountOverlay) standard(r runtime.Runtime) (err error) {
var mountpoints *mount.Points
mountpoints, err = overlay.MountPoints()
if err != nil {
return err
}
m := manager.NewManager(mountpoints)
if err = m.MountAll(); err != nil {
return err
}
return nil
}

View File

@ -1,41 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs
import (
"golang.org/x/sys/unix"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// MountShared represents the MountShared task.
type MountShared struct{}
// NewMountSharedTask initializes and returns an MountShared task.
func NewMountSharedTask() phase.Task {
return &MountShared{}
}
// TaskFunc returns the runtime function.
func (task *MountShared) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return task.container
default:
return nil
}
}
func (task *MountShared) container(r runtime.Runtime) (err error) {
targets := []string{"/", "/var/lib/kubelet", "/etc/cni", "/run"}
for _, t := range targets {
if err = unix.Mount("", t, "", unix.MS_SHARED|unix.MS_REC, ""); err != nil {
return err
}
}
return nil
}

View File

@ -1,47 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs
import (
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/mount"
"github.com/talos-systems/talos/internal/pkg/mount/manager"
"github.com/talos-systems/talos/internal/pkg/mount/manager/pseudo"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// MountSubDevices represents the MountSubDevices task.
type MountSubDevices struct{}
// NewMountSubDevicesTask initializes and returns an MountSubDevices task.
func NewMountSubDevicesTask() phase.Task {
return &MountSubDevices{}
}
// TaskFunc returns the runtime function.
func (task *MountSubDevices) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.runtime
}
}
func (task *MountSubDevices) runtime(r runtime.Runtime) (err error) {
var mountpoints *mount.Points
mountpoints, err = pseudo.SubMountPoints()
if err != nil {
return err
}
m := manager.NewManager(mountpoints)
if err = m.MountAll(); err != nil {
return err
}
return nil
}

View File

@ -1,64 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs
import (
"log"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/mount"
"github.com/talos-systems/talos/internal/pkg/mount/manager"
"github.com/talos-systems/talos/internal/pkg/mount/manager/owned"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// MountSystemDisks represents the MountSystemDisks task.
type MountSystemDisks struct {
devlabel string
opts []mount.Option
}
// NewMountSystemDisksTask initializes and returns an MountSystemDisks task.
func NewMountSystemDisksTask(devlabel string, opts ...mount.Option) phase.Task {
return &MountSystemDisks{
devlabel: devlabel,
opts: opts,
}
}
// TaskFunc returns the runtime function.
func (task *MountSystemDisks) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.runtime
}
}
func (task *MountSystemDisks) runtime(r runtime.Runtime) (err error) {
mountpoints := mount.NewMountPoints()
log.Printf("fetching mountpoint for label %q\n", task.devlabel)
mountpoint, err := owned.MountPointForLabel(task.devlabel, task.opts...)
if err != nil {
return err
}
if mountpoint == nil {
log.Printf("could not find boot partition with label %q\n", task.devlabel)
return nil
}
mountpoints.Set(task.devlabel, mountpoint)
m := manager.NewManager(mountpoints)
if err = m.MountAll(); err != nil {
return err
}
return nil
}

View File

@ -1,43 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs
import (
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/app/machined/internal/phase/rootfs/etc"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// NetworkConfiguration represents the NetworkConfiguration task.
type NetworkConfiguration struct{}
// NewNetworkConfigurationTask initializes and returns an NetworkConfiguration task.
func NewNetworkConfigurationTask() phase.Task {
return &NetworkConfiguration{}
}
// TaskFunc returns the runtime function.
func (task *NetworkConfiguration) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.runtime
}
}
func (task *NetworkConfiguration) runtime(r runtime.Runtime) (err error) {
// Create /etc/resolv.conf.
if err = etc.ResolvConf(); err != nil {
return err
}
// Create /etc/hosts
if err = etc.Hosts(); err != nil {
return err
}
return nil
}

View File

@ -1,29 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs
import (
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/app/machined/internal/phase/rootfs/etc"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// OSRelease represents the OSRelease task.
type OSRelease struct{}
// NewOSReleaseTask initializes and returns an OSRelease task.
func NewOSReleaseTask() phase.Task {
return &OSRelease{}
}
// TaskFunc returns the runtime function.
func (task *OSRelease) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return task.runtime
}
func (task *OSRelease) runtime(r runtime.Runtime) (err error) {
// Create /etc/os-release.
return etc.OSRelease()
}

View File

@ -1,14 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs_test
import "testing"
func TestEmpty(t *testing.T) {
// added for accurate coverage estimation
//
// please remove it once any unit-test is added
// for this package
}

View File

@ -1,57 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs
import (
"log"
"os"
"github.com/talos-systems/talos/cmd/installer/pkg/bootloader/syslinux"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// Syslinux represents the Syslinux task.
type Syslinux struct{}
// NewSyslinuxTask initializes and returns a ClearOnce task.
func NewSyslinuxTask() phase.Task {
return &Syslinux{}
}
// TaskFunc returns the runtime function.
func (task *Syslinux) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.standard
}
}
func (task *Syslinux) standard(r runtime.Runtime) (err error) {
f, err := os.OpenFile(syslinux.SyslinuxLdlinux, os.O_RDWR, 0700)
if err != nil {
return err
}
// nolint: errcheck
defer f.Close()
adv, err := syslinux.NewADV(f)
if err != nil {
return err
}
if ok := adv.DeleteTag(syslinux.AdvUpgrade); ok {
log.Println("removing fallback")
}
if _, err = f.Write(adv); err != nil {
return err
}
return nil
}

View File

@ -1,37 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs
import (
"os"
"path/filepath"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/constants"
)
// SystemDirectory represents the SystemDirectory task.
type SystemDirectory struct{}
// NewSystemDirectoryTask initializes and returns an SystemDirectory task.
func NewSystemDirectoryTask() phase.Task {
return &SystemDirectory{}
}
// TaskFunc returns the runtime function.
func (task *SystemDirectory) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return task.runtime
}
func (task *SystemDirectory) runtime(r runtime.Runtime) (err error) {
for _, p := range []string{"etc", "log"} {
if err = os.MkdirAll(filepath.Join(constants.SystemRunPath, p), 0700); err != nil {
return err
}
}
return nil
}

View File

@ -1,47 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs
import (
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/mount"
"github.com/talos-systems/talos/internal/pkg/mount/manager"
"github.com/talos-systems/talos/internal/pkg/mount/manager/overlay"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// UnmountOverlay represents the UnmountOverlay task.
type UnmountOverlay struct{}
// NewUnmountOverlayTask initializes and returns an UnmountOverlay task.
func NewUnmountOverlayTask() phase.Task {
return &UnmountOverlay{}
}
// TaskFunc returns the runtime function.
func (task *UnmountOverlay) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.standard
}
}
func (task *UnmountOverlay) standard(r runtime.Runtime) (err error) {
var mountpoints *mount.Points
mountpoints, err = overlay.MountPoints()
if err != nil {
return err
}
m := manager.NewManager(mountpoints)
if err = m.UnmountAll(); err != nil {
return err
}
return nil
}

View File

@ -1,72 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs
import (
"bufio"
"bytes"
"fmt"
"io/ioutil"
"log"
"strings"
"golang.org/x/sys/unix"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/constants"
)
// UnmountPodMounts represents the UnmountPodMounts task.
type UnmountPodMounts struct{}
// NewUnmountPodMountsTask initializes and returns an UnmountPodMounts task.
func NewUnmountPodMountsTask() phase.Task {
return &UnmountPodMounts{}
}
// TaskFunc returns the runtime function.
func (task *UnmountPodMounts) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.standard
}
}
func (task *UnmountPodMounts) standard(r runtime.Runtime) (err error) {
var b []byte
if b, err = ioutil.ReadFile("/proc/self/mounts"); err != nil {
return err
}
rdr := bytes.NewReader(b)
scanner := bufio.NewScanner(rdr)
for scanner.Scan() {
fields := strings.Fields(scanner.Text())
if len(fields) < 2 {
continue
}
mountpoint := fields[1]
if strings.HasPrefix(mountpoint, constants.EphemeralMountPoint+"/") {
log.Printf("unmounting %s\n", mountpoint)
if err = unix.Unmount(mountpoint, 0); err != nil {
return fmt.Errorf("error unmounting %s: %w", mountpoint, err)
}
}
}
if err = scanner.Err(); err != nil {
return err
}
return nil
}

View File

@ -1,71 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs
import (
"bufio"
"fmt"
"log"
"os"
"strings"
"golang.org/x/sys/unix"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// UnmountSystemDiskBindMounts represents the UnmountSystemDiskBindMounts task.
type UnmountSystemDiskBindMounts struct {
devname string
}
// NewUnmountSystemDiskBindMountsTask initializes and returns an UnmountSystemDiskBindMounts task.
func NewUnmountSystemDiskBindMountsTask(devname string) phase.Task {
return &UnmountSystemDiskBindMounts{
devname: devname,
}
}
// TaskFunc returns the runtime function.
func (task *UnmountSystemDiskBindMounts) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.standard
}
}
func (task *UnmountSystemDiskBindMounts) standard(r runtime.Runtime) (err error) {
f, err := os.Open("/proc/mounts")
if err != nil {
return err
}
defer f.Close() //nolint: errcheck
scanner := bufio.NewScanner(f)
for scanner.Scan() {
fields := strings.Fields(scanner.Text())
if len(fields) < 2 {
continue
}
device := fields[0]
mountpoint := fields[1]
if strings.HasPrefix(device, task.devname) {
log.Printf("unmounting %s\n", mountpoint)
if err = unix.Unmount(mountpoint, 0); err != nil {
return fmt.Errorf("error unmounting %s: %w", mountpoint, err)
}
}
}
return scanner.Err()
}

View File

@ -1,59 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs
import (
"fmt"
"golang.org/x/sys/unix"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/mount"
"github.com/talos-systems/talos/internal/pkg/mount/manager"
"github.com/talos-systems/talos/internal/pkg/mount/manager/owned"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// UnmountSystemDisks represents the UnmountSystemDisks task.
type UnmountSystemDisks struct {
devlabel string
}
// NewUnmountSystemDisksTask initializes and returns an UnmountSystemDisks task.
func NewUnmountSystemDisksTask(devlabel string) phase.Task {
return &UnmountSystemDisks{
devlabel: devlabel,
}
}
// TaskFunc returns the runtime function.
func (task *UnmountSystemDisks) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.standard
}
}
func (task *UnmountSystemDisks) standard(r runtime.Runtime) (err error) {
mountpoints := mount.NewMountPoints()
mountpoint, err := owned.MountPointForLabel(task.devlabel)
if err != nil {
return err
}
mountpoints.Set(task.devlabel, mountpoint)
unix.Sync()
m := manager.NewManager(mountpoints)
if err = m.UnmountAll(); err != nil {
return fmt.Errorf("error unmounting %q partition: %w", task.devlabel, err)
}
return nil
}

View File

@ -1,54 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs
import (
"io/ioutil"
"os"
"strconv"
"strings"
"time"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// ValidateConfig represents the ValidateConfig task.
type ValidateConfig struct{}
// NewValidateConfigTask initializes and returns a ValidateConfig task.
func NewValidateConfigTask() phase.Task {
return &ValidateConfig{}
}
// TaskFunc returns the runtime function.
func (task *ValidateConfig) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return task.standard
}
func (task *ValidateConfig) standard(r runtime.Runtime) (err error) {
file := "/sys/module/usb_storage/parameters/delay_use"
_, err = os.Stat(file)
if os.IsNotExist(err) {
return r.Config().Validate(r.Platform().Mode())
}
b, err := ioutil.ReadFile(file)
if err != nil {
return err
}
val := strings.TrimSuffix(string(b), "\n")
i, err := strconv.Atoi(val)
if err != nil {
return err
}
time.Sleep(time.Duration(i) * time.Second)
return r.Config().Validate(r.Platform().Mode())
}

View File

@ -1,35 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package rootfs
import (
"os"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// VarDirectories represents the VarDirectories task.
type VarDirectories struct{}
// NewVarDirectoriesTask initializes and returns an VarDirectories task.
func NewVarDirectoriesTask() phase.Task {
return &VarDirectories{}
}
// TaskFunc returns the runtime function.
func (task *VarDirectories) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return task.runtime
}
func (task *VarDirectories) runtime(r runtime.Runtime) (err error) {
for _, p := range []string{"/var/log/pods", "/var/lib/kubelet", "/var/run/lock"} {
if err = os.MkdirAll(p, 0700); err != nil {
return err
}
}
return nil
}

View File

@ -1,78 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package security
import (
"fmt"
"os"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// See https://www.kernel.org/doc/Documentation/ABI/testing/ima_policy
var rules = []string{
"dont_measure fsmagic=0x9fa0", // PROC_SUPER_MAGIC
"dont_measure fsmagic=0x62656572", // SYSFS_MAGIC
"dont_measure fsmagic=0x64626720", // DEBUGFS_MAGIC
"dont_measure fsmagic=0x1021994", // TMPFS_MAGIC
"dont_measure fsmagic=0x1cd1", // DEVPTS_SUPER_MAGIC
"dont_measure fsmagic=0x42494e4d", // BINFMTFS_MAGIC
"dont_measure fsmagic=0x73636673", // SECURITYFS_MAGIC
"dont_measure fsmagic=0xf97cff8c", // SELINUX_MAGIC
"dont_measure fsmagic=0x43415d53", // SMACK_MAGIC
"dont_measure fsmagic=0x27e0eb", // CGROUP_SUPER_MAGIC
"dont_measure fsmagic=0x63677270", // CGROUP2_SUPER_MAGIC
"dont_measure fsmagic=0x6e736673", // NSFS_MAGIC
"dont_measure fsmagic=0xde5e81e4", // EFIVARFS_MAGIC
"dont_measure fsmagic=0x58465342", // XFS_MAGIC
"dont_measure fsmagic=0x794c7630", // OVERLAYFS_SUPER_MAGIC
"measure func=MMAP_CHECK mask=MAY_EXEC",
"measure func=BPRM_CHECK mask=MAY_EXEC",
"measure func=FILE_CHECK mask=^MAY_READ euid=0",
"measure func=FILE_CHECK mask=^MAY_READ uid=0",
"measure func=MODULE_CHECK",
"measure func=FIRMWARE_CHECK",
"measure func=POLICY_CHECK",
}
// IMA represents the IMA task.
type IMA struct{}
// NewIMATask initializes and returns an IMA task.
func NewIMATask() phase.Task {
return &IMA{}
}
// TaskFunc returns the runtime function.
func (task *IMA) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.runtime
}
}
func (task *IMA) runtime(r runtime.Runtime) (err error) {
if _, err = os.Stat("/sys/kernel/security/ima/policy"); os.IsNotExist(err) {
return fmt.Errorf("policy file does not exist: %w", err)
}
f, err := os.OpenFile("/sys/kernel/security/ima/policy", os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
return err
}
defer f.Close() //nolint: errcheck
for _, line := range rules {
if _, err = f.WriteString(line + "\n"); err != nil {
return fmt.Errorf("rule %q is invalid", err)
}
}
return nil
}

View File

@ -1,41 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package security
import (
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/kernel/kspp"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// Security represents the Security task.
type Security struct{}
// NewSecurityTask initializes and returns an Security task.
func NewSecurityTask() phase.Task {
return &Security{}
}
// TaskFunc returns the runtime function.
func (task *Security) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.runtime
}
}
func (task *Security) runtime(r runtime.Runtime) (err error) {
if err = kspp.EnforceKSPPKernelParameters(); err != nil {
return err
}
if err = kspp.EnforceKSPPSysctls(); err != nil {
return err
}
return nil
}

View File

@ -1,14 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package security_test
import "testing"
func TestEmpty(t *testing.T) {
// added for accurate coverage estimation
//
// please remove it once any unit-test is added
// for this package
}

View File

@ -1,60 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package services
import (
"fmt"
"os"
"time"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/config/machine"
"github.com/talos-systems/talos/pkg/kubernetes"
"github.com/talos-systems/talos/pkg/retry"
)
// LabelNodeAsMaster represents the LabelNodeAsMaster task.
type LabelNodeAsMaster struct{}
// NewLabelNodeAsMasterTask initializes and returns an Services task.
func NewLabelNodeAsMasterTask() phase.Task {
return &LabelNodeAsMaster{}
}
// TaskFunc returns the runtime function.
func (task *LabelNodeAsMaster) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return task.standard
}
func (task *LabelNodeAsMaster) standard(r runtime.Runtime) (err error) {
if r.Config().Machine().Type() == machine.TypeWorker {
return nil
}
h, err := kubernetes.NewTemporaryClientFromPKI(r.Config().Cluster().CA(), r.Config().Cluster().Endpoint())
if err != nil {
return err
}
hostname, err := os.Hostname()
if err != nil {
return err
}
err = retry.Constant(10*time.Minute, retry.WithUnits(3*time.Second)).Retry(func() error {
if err = h.LabelNodeAsMaster(hostname); err != nil {
return retry.ExpectedError(err)
}
return nil
})
if err != nil {
return fmt.Errorf("failed to label node as master: %w", err)
}
return nil
}

View File

@ -1,14 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package services_test
import "testing"
func TestEmpty(t *testing.T) {
// added for accurate coverage estimation
//
// please remove it once any unit-test is added
// for this package
}

View File

@ -1,39 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package services
import (
"context"
"time"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/app/machined/pkg/system"
"github.com/talos-systems/talos/internal/app/machined/pkg/system/services"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// StartContainerd represents the task to start system containerd.
type StartContainerd struct{}
// NewStartContainerdTask initializes and returns an Services task.
func NewStartContainerdTask() phase.Task {
return &StartContainerd{}
}
// TaskFunc returns the runtime function.
func (task *StartContainerd) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return task.standard
}
func (task *StartContainerd) standard(r runtime.Runtime) (err error) {
svc := &services.Containerd{}
system.Services(r.Config()).LoadAndStart(svc)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
return system.WaitForService(system.StateEventUp, svc.ID(r.Config())).Wait(ctx)
}

View File

@ -1,104 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package services
import (
"context"
"time"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/app/machined/pkg/system"
"github.com/talos-systems/talos/internal/app/machined/pkg/system/services"
"github.com/talos-systems/talos/internal/pkg/conditions"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/config/machine"
)
// StartServices represents the StartServices task.
type StartServices struct{}
// NewStartServicesTask initializes and returns an Services task.
func NewStartServicesTask() phase.Task {
return &StartServices{}
}
// TaskFunc returns the runtime function.
func (task *StartServices) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return task.standard
}
func (task *StartServices) standard(r runtime.Runtime) (err error) {
task.loadSystemServices(r)
task.loadKubernetesServices(r)
system.Services(r.Config()).StartAll()
return task.wait(r)
}
func (task *StartServices) loadSystemServices(r runtime.Runtime) {
svcs := system.Services(r.Config())
// Start the services common to all nodes.
svcs.Load(
&services.MachinedAPI{},
&services.CRI{},
&services.APID{},
&services.OSD{},
&services.Networkd{},
&services.Routerd{},
)
if r.Platform().Mode() != runtime.Container {
// udevd-trigger is causing stalls/unresponsive stuff when running in local mode
// TODO: investigate root cause, but workaround for now is to skip it in container mode
svcs.Load(
&services.Timed{},
&services.Udevd{},
&services.UdevdTrigger{},
)
}
// Start the services common to all control plane nodes.
switch r.Config().Machine().Type() {
case machine.TypeInit:
fallthrough
case machine.TypeControlPlane:
svcs.Load(
&services.Etcd{},
&services.Trustd{},
)
}
}
func (task *StartServices) loadKubernetesServices(r runtime.Runtime) {
svcs := system.Services(r.Config())
svcs.Load(
&services.Kubelet{},
)
if r.Config().Machine().Type() == machine.TypeInit {
svcs.Load(
&services.Bootkube{},
)
}
}
func (task *StartServices) wait(r runtime.Runtime) (err error) {
svcs := system.Services(r.Config()).List()
all := []conditions.Condition{}
for _, svc := range svcs {
cond := system.WaitForService(system.StateEventUp, svc.AsProto().GetId())
all = append(all, cond)
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
return conditions.WaitForAll(all...).Wait(ctx)
}

View File

@ -1,46 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package services
import (
"context"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/app/machined/pkg/system"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// StopServices represents the StopServices task.
type StopServices struct {
services []string
}
// NewStopServicesTask initializes and returns an Services task.
func NewStopServicesTask(services ...string) phase.Task {
return &StopServices{
services: services,
}
}
// TaskFunc returns the runtime function.
func (task *StopServices) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return task.standard
}
func (task *StopServices) standard(r runtime.Runtime) (err error) {
if len(task.services) > 0 {
for _, service := range task.services {
if err = system.Services(nil).Stop(context.Background(), service); err != nil {
return err
}
}
return nil
}
system.Services(nil).Shutdown()
return nil
}

View File

@ -1,49 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package signal
import (
"log"
"os"
"os/signal"
"syscall"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/event"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
// Handler represents the signal handler task.
type Handler struct{}
// NewHandlerTask initializes and returns a signal handler task.
func NewHandlerTask() phase.Task {
return &Handler{}
}
// TaskFunc returns the runtime function.
func (task *Handler) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return task.container
default:
return nil
}
}
func (task *Handler) container(r runtime.Runtime) (err error) {
termCh := make(chan os.Signal, 1)
signal.Notify(termCh, syscall.SIGTERM)
go func() {
<-termCh
signal.Stop(termCh)
log.Printf("shutdown via SIGTERM received")
event.Bus().Notify(event.Event{Type: event.Shutdown})
}()
return nil
}

View File

@ -1,14 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package signal_test
import "testing"
func TestEmpty(t *testing.T) {
// added for accurate coverage estimation
//
// please remove it once any unit-test is added
// for this package
}

View File

@ -1,77 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package sysctls
import (
"fmt"
"github.com/hashicorp/go-multierror"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/sysctl"
)
// Task represents the Task task.
type Task struct{}
// NewSysctlsTask initializes and returns a Task task.
func NewSysctlsTask() phase.Task {
return &Task{}
}
// TaskFunc returns the runtime function.
func (task *Task) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return task.container
default:
return task.standard
}
}
func (task *Task) standard(r runtime.Runtime) error {
var multiErr *multierror.Error
if err := sysctl.WriteSystemProperty(&sysctl.SystemProperty{Key: "net.ipv4.ip_forward", Value: "1"}); err != nil {
multiErr = multierror.Append(multiErr, fmt.Errorf("failed to set net.ipv4.ip_forward: %w", err))
}
if err := sysctl.WriteSystemProperty(&sysctl.SystemProperty{Key: "net.bridge.bridge-nf-call-iptables", Value: "1"}); err != nil {
multiErr = multierror.Append(multiErr, fmt.Errorf("failed to set net.bridge.bridge-nf-call-iptables: %w", err))
}
if err := sysctl.WriteSystemProperty(&sysctl.SystemProperty{Key: "net.bridge.bridge-nf-call-ip6tables", Value: "1"}); err != nil {
multiErr = multierror.Append(multiErr, fmt.Errorf("failed to set net.bridge.bridge-nf-call-ip6tables: %w", err))
}
if err := sysctl.WriteSystemProperty(&sysctl.SystemProperty{Key: "net.ipv6.conf.default.forwarding", Value: "1"}); err != nil {
multiErr = multierror.Append(multiErr, fmt.Errorf("failed to set net.ipv6.conf.default.forwarding: %w", err))
}
if err := sysctl.WriteSystemProperty(&sysctl.SystemProperty{Key: "kernel.pid_max", Value: "262144"}); err != nil {
multiErr = multierror.Append(multiErr, fmt.Errorf("failed to set kernel.pid_max: %w", err))
}
return multiErr.ErrorOrNil()
}
func (task *Task) container(r runtime.Runtime) error {
var multiErr *multierror.Error
if err := sysctl.WriteSystemProperty(&sysctl.SystemProperty{Key: "net.ipv4.ip_forward", Value: "1"}); err != nil {
multiErr = multierror.Append(multiErr, fmt.Errorf("failed to set net.ipv4.ip_forward: %w", err))
}
if err := sysctl.WriteSystemProperty(&sysctl.SystemProperty{Key: "net.ipv6.conf.default.forwarding", Value: "1"}); err != nil {
multiErr = multierror.Append(multiErr, fmt.Errorf("failed to set net.ipv6.conf.default.forwarding: %w", err))
}
if err := sysctl.WriteSystemProperty(&sysctl.SystemProperty{Key: "kernel.pid_max", Value: "262144"}); err != nil {
multiErr = multierror.Append(multiErr, fmt.Errorf("failed to set kernel.pid_max: %w", err))
}
return multiErr.ErrorOrNil()
}

View File

@ -1,14 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package sysctls_test
import "testing"
func TestEmpty(t *testing.T) {
// added for accurate coverage estimation
//
// please remove it once any unit-test is added
// for this package
}

View File

@ -1,93 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package upgrade
import (
"context"
"fmt"
"log"
"os"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/app/machined/pkg/system"
"github.com/talos-systems/talos/internal/pkg/etcd"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/config/machine"
"github.com/talos-systems/talos/pkg/constants"
)
// LeaveEtcd represents the task for removing a control plane node from etcd.
type LeaveEtcd struct {
preserve bool
}
// NewLeaveEtcdTask initializes and returns a LeaveEtcd task.
func NewLeaveEtcdTask(preserve bool) phase.Task {
return &LeaveEtcd{preserve: preserve}
}
// TaskFunc returns the runtime function.
func (task *LeaveEtcd) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return task.standard
}
// nolint: gocyclo
func (task *LeaveEtcd) standard(r runtime.Runtime) (err error) {
if r.Config().Machine().Type() == machine.TypeWorker {
return nil
}
if task.preserve {
return nil
}
hostname, err := os.Hostname()
if err != nil {
return err
}
client, err := etcd.NewClientFromControlPlaneIPs(r.Config().Cluster().CA(), r.Config().Cluster().Endpoint())
if err != nil {
return err
}
// nolint: errcheck
defer client.Close()
resp, err := client.MemberList(context.Background())
if err != nil {
return err
}
var id *uint64
for _, member := range resp.Members {
if member.Name == hostname {
id = &member.ID
}
}
if id == nil {
return fmt.Errorf("failed to find %q in list of etcd members", hostname)
}
log.Println("leaving etcd cluster")
_, err = client.MemberRemove(context.Background(), *id)
if err != nil {
return err
}
if err = system.Services(nil).Stop(context.Background(), "etcd"); err != nil {
return err
}
// Once the member is removed, the data is no longer valid.
if err = os.RemoveAll(constants.EtcdDataPath); err != nil {
return err
}
return nil
}

View File

@ -1,56 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package upgrade
import (
"log"
machineapi "github.com/talos-systems/talos/api/machine"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/install"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/config/types/v1alpha1"
)
// Upgrade represents the task for stop all containerd tasks in the
// k8s.io namespace.
type Upgrade struct {
disk string
image string
preserve bool
}
// NewUpgradeTask initializes and returns an Services task.
func NewUpgradeTask(devname string, req *machineapi.UpgradeRequest) phase.Task {
return &Upgrade{
disk: devname,
image: req.Image,
preserve: req.Preserve,
}
}
// TaskFunc returns the runtime function.
func (task *Upgrade) TaskFunc(mode runtime.Mode) phase.TaskFunc {
return task.standard
}
func (task *Upgrade) standard(r runtime.Runtime) (err error) {
log.Printf("performing upgrade via %q", task.image)
c := r.Config()
if cfg, ok := c.(*v1alpha1.Config); ok {
cfg.MachineConfig.MachineInstall.InstallDisk = task.disk
cfg.MachineConfig.MachineInstall.InstallImage = task.image
r = runtime.NewRuntime(r.Platform(), runtime.Configurator(cfg), runtime.Upgrade)
}
// We pull the installer image when we receive an upgrade request. No need to re-pull inside of installer container
if err = install.RunInstallerContainer(r, install.WithImagePull(false), install.WithPreserve(task.preserve)); err != nil {
return err
}
return nil
}

View File

@ -1,36 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package sequencer
import (
machineapi "github.com/talos-systems/talos/api/machine"
"github.com/talos-systems/talos/internal/app/machined/internal/sequencer/v1alpha1"
)
// Sequencer describes the boot, shutdown, and upgrade events.
type Sequencer interface {
Boot() error
Shutdown() error
Upgrade(*machineapi.UpgradeRequest) error
Reset(*machineapi.ResetRequest) error
}
// Version represents the sequencer version.
type Version int
const (
// V1Alpha1 is the v1alpha1 sequencer.
V1Alpha1 = iota
)
// New initializes and returns a sequencer based on the specified version.
func New(v Version) Sequencer {
switch v {
case V1Alpha1:
return &v1alpha1.Sequencer{}
default:
return nil
}
}

View File

@ -1,344 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package v1alpha1
import (
"fmt"
machineapi "github.com/talos-systems/talos/api/machine"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/app/machined/internal/phase/acpi"
configtask "github.com/talos-systems/talos/internal/app/machined/internal/phase/config"
"github.com/talos-systems/talos/internal/app/machined/internal/phase/disk"
"github.com/talos-systems/talos/internal/app/machined/internal/phase/kubernetes"
"github.com/talos-systems/talos/internal/app/machined/internal/phase/limits"
"github.com/talos-systems/talos/internal/app/machined/internal/phase/network"
"github.com/talos-systems/talos/internal/app/machined/internal/phase/platform"
"github.com/talos-systems/talos/internal/app/machined/internal/phase/rootfs"
"github.com/talos-systems/talos/internal/app/machined/internal/phase/security"
"github.com/talos-systems/talos/internal/app/machined/internal/phase/services"
"github.com/talos-systems/talos/internal/app/machined/internal/phase/signal"
"github.com/talos-systems/talos/internal/app/machined/internal/phase/sysctls"
"github.com/talos-systems/talos/internal/app/machined/internal/phase/upgrade"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/pkg/blockdevice/probe"
"github.com/talos-systems/talos/pkg/blockdevice/util"
"github.com/talos-systems/talos/pkg/config"
"github.com/talos-systems/talos/pkg/constants"
)
// Sequencer represents the v1alpha1 sequencer.
type Sequencer struct{}
// Boot implements the Sequencer interface.
func (d *Sequencer) Boot() error {
phaserunner, err := phase.NewRunner(nil, runtime.Boot)
if err != nil {
return err
}
cfgBytes := []byte{}
phaserunner.Add(
phase.NewPhase(
"system requirements",
security.NewSecurityTask(),
rootfs.NewSystemDirectoryTask(),
rootfs.NewMountBPFFSTask(),
rootfs.NewMountCgroupsTask(),
rootfs.NewMountSubDevicesTask(),
sysctls.NewSysctlsTask(),
limits.NewFileLimitTask(),
),
phase.NewPhase(
"configure Integrity Measurement Architecture",
security.NewIMATask(),
),
phase.NewPhase(
"basic system configuration",
rootfs.NewNetworkConfigurationTask(),
rootfs.NewOSReleaseTask(),
),
phase.NewPhase(
"discover network",
network.NewInitialNetworkSetupTask(),
),
phase.NewPhase(
"mount /boot",
rootfs.NewMountSystemDisksTask(constants.BootPartitionLabel),
),
phase.NewPhase(
"config",
configtask.NewConfigTask(&cfgBytes),
),
)
if err = phaserunner.Run(); err != nil {
return err
}
cfg, err := config.NewFromBytes(cfgBytes)
if err != nil {
return fmt.Errorf("failed to parse config: %w", err)
}
phaserunner, err = phase.NewRunner(cfg, runtime.Boot)
if err != nil {
return err
}
phaserunner.Add(
phase.NewPhase(
"config validation",
rootfs.NewValidateConfigTask(),
),
phase.NewPhase(
"network reset",
network.NewResetNetworkTask(),
configtask.NewExtraEnvVarsTask(),
),
phase.NewPhase(
"initial network",
network.NewInitialNetworkSetupTask(),
),
phase.NewPhase(
"start containerd",
services.NewStartContainerdTask(),
),
phase.NewPhase(
"platform tasks",
platform.NewPlatformTask(),
),
phase.NewPhase(
"installation verification",
rootfs.NewCheckInstallTask(),
),
phase.NewPhase(
"overlay mounts",
rootfs.NewMountOverlayTask(),
rootfs.NewMountSharedTask(),
),
phase.NewPhase(
"setup /var",
rootfs.NewVarDirectoriesTask(),
),
phase.NewPhase(
"save config",
configtask.NewSaveConfigTask(),
),
phase.NewPhase(
"mount extra disks",
configtask.NewExtraDisksTask(),
),
phase.NewPhase(
"user requests",
configtask.NewExtraFilesTask(),
configtask.NewSysctlsTask(),
),
phase.NewPhase(
"start services",
acpi.NewHandlerTask(),
services.NewStartServicesTask(),
signal.NewHandlerTask(),
),
phase.NewPhase(
"post startup tasks",
services.NewLabelNodeAsMasterTask(),
),
phase.NewPhase(
"update bootloader",
rootfs.NewSyslinuxTask(),
),
)
return phaserunner.Run()
}
// Shutdown implements the Sequencer interface.
func (d *Sequencer) Shutdown() (err error) {
var dev *probe.ProbedBlockDevice
dev, err = probe.GetDevWithFileSystemLabel(constants.EphemeralPartitionLabel)
if err != nil {
return err
}
devname := dev.Device().Name()
if err = dev.Close(); err != nil {
return err
}
phaserunner, err := phase.NewRunner(nil, runtime.Shutdown)
if err != nil {
return err
}
phaserunner.Add(
phase.NewPhase(
"stop services",
services.NewStopServicesTask(),
),
phase.NewPhase(
"unmount system disk submounts",
rootfs.NewUnmountOverlayTask(),
rootfs.NewUnmountPodMountsTask(),
),
phase.NewPhase(
"unmount system disks",
rootfs.NewUnmountSystemDisksTask(constants.BootPartitionLabel),
rootfs.NewUnmountSystemDisksTask(constants.EphemeralPartitionLabel),
),
phase.NewPhase(
"unmount system disk bind mounts",
rootfs.NewUnmountSystemDiskBindMountsTask(devname),
),
)
return phaserunner.Run()
}
// Upgrade implements the Sequencer interface.
func (d *Sequencer) Upgrade(req *machineapi.UpgradeRequest) error {
config, err := config.NewFromFile(constants.ConfigPath)
if err != nil {
return err
}
phaserunner, err := phase.NewRunner(config, runtime.Upgrade)
if err != nil {
return err
}
var dev *probe.ProbedBlockDevice
dev, err = probe.GetDevWithFileSystemLabel(constants.EphemeralPartitionLabel)
if err != nil {
return err
}
devname := dev.Device().Name()
// TODO(andrewrynhard): This should be more dynamic. If we ever change the
// partition scheme there is the chance that 2 is not the correct parition to
// check.
partname := util.PartPath(dev.Device().Name(), 2)
if err := dev.Close(); err != nil {
return err
}
phaserunner.Add(
phase.NewPhase(
"cordon and drain node",
kubernetes.NewCordonAndDrainTask(),
),
phase.NewPhase(
"handle control plane requirements",
upgrade.NewLeaveEtcdTask(req.GetPreserve()),
),
phase.NewPhase(
"remove all pods",
kubernetes.NewRemoveAllPodsTask(),
),
phase.NewPhase(
"stop services",
services.NewStopServicesTask("cri", "udevd"),
),
phase.NewPhase(
"unmount system disk submounts",
rootfs.NewUnmountOverlayTask(),
rootfs.NewUnmountPodMountsTask(),
),
phase.NewPhase(
"unmount system disks",
rootfs.NewUnmountSystemDisksTask(constants.BootPartitionLabel),
rootfs.NewUnmountSystemDisksTask(constants.EphemeralPartitionLabel),
),
phase.NewPhase(
"unmount system disk bind mounts",
rootfs.NewUnmountSystemDiskBindMountsTask(devname),
),
phase.NewPhase(
"verify system disk not in use",
disk.NewVerifyDiskAvailabilityTask(partname),
),
phase.NewPhase(
"upgrade",
upgrade.NewUpgradeTask(devname, req),
),
phase.NewPhase(
"stop all services",
services.NewStopServicesTask(),
),
)
return phaserunner.Run()
}
// Reset implements the Sequencer interface.
func (d *Sequencer) Reset(req *machineapi.ResetRequest) error {
config, err := config.NewFromFile(constants.ConfigPath)
if err != nil {
return err
}
phaserunner, err := phase.NewRunner(config, runtime.Reset)
if err != nil {
return err
}
var dev *probe.ProbedBlockDevice
dev, err = probe.GetDevWithFileSystemLabel(constants.EphemeralPartitionLabel)
if err != nil {
return err
}
devname := dev.Device().Name()
if err := dev.Close(); err != nil {
return err
}
if req.GetGraceful() {
phaserunner.Add(
phase.NewPhase(
"cordon and drain node",
kubernetes.NewCordonAndDrainTask(),
),
phase.NewPhase(
"handle control plane requirements",
upgrade.NewLeaveEtcdTask(false),
),
phase.NewPhase(
"remove all pods",
kubernetes.NewRemoveAllPodsTask(),
),
)
}
phaserunner.Add(
phase.NewPhase(
"stop all services",
services.NewStopServicesTask(),
),
phase.NewPhase(
"unmount system disk submounts",
rootfs.NewUnmountOverlayTask(),
rootfs.NewUnmountPodMountsTask(),
),
phase.NewPhase(
"unmount system disk",
rootfs.NewUnmountSystemDisksTask(constants.EphemeralPartitionLabel),
),
phase.NewPhase(
"reset system disk",
disk.NewResetSystemDiskTask(devname),
),
)
return phaserunner.Run()
}

View File

@ -2,7 +2,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package reg
package runtime
import (
"archive/tar"
@ -30,23 +30,20 @@ import (
"google.golang.org/grpc"
"github.com/talos-systems/talos/api/common"
machineapi "github.com/talos-systems/talos/api/machine"
"github.com/talos-systems/talos/api/machine"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
"github.com/talos-systems/talos/internal/app/machined/pkg/system"
"github.com/talos-systems/talos/internal/pkg/containers"
taloscontainerd "github.com/talos-systems/talos/internal/pkg/containers/containerd"
"github.com/talos-systems/talos/internal/pkg/containers/cri"
"github.com/talos-systems/talos/internal/pkg/containers/image"
"github.com/talos-systems/talos/internal/pkg/etcd"
"github.com/talos-systems/talos/internal/pkg/event"
"github.com/talos-systems/talos/internal/pkg/kubeconfig"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/talos/internal/pkg/runtime/platform"
"github.com/talos-systems/talos/internal/pkg/tail"
"github.com/talos-systems/talos/pkg/archiver"
"github.com/talos-systems/talos/pkg/chunker"
filechunker "github.com/talos-systems/talos/pkg/chunker/file"
"github.com/talos-systems/talos/pkg/chunker/stream"
machinecfg "github.com/talos-systems/talos/pkg/config/machine"
"github.com/talos-systems/talos/pkg/constants"
"github.com/talos-systems/talos/pkg/version"
)
@ -54,65 +51,81 @@ import (
// OSPathSeparator is the string version of the os.PathSeparator
const OSPathSeparator = string(os.PathSeparator)
// Registrator is the concrete type that implements the factory.Registrator and
// machineapi.Machine interfaces.
type Registrator struct {
config runtime.Configurator
platform runtime.Platform
}
// Server implements the gRPC service server.
type Server struct {
Controller runtime.Controller
// NewRegistrator builds new Registrator instance
func NewRegistrator(config runtime.Configurator) *Registrator {
platform, err := platform.CurrentPlatform()
if err != nil {
// should never happen
log.Printf("failed discovering platform: %v", err)
}
return &Registrator{
config: config,
platform: platform,
}
server *grpc.Server
}
// Register implements the factory.Registrator interface.
func (r *Registrator) Register(s *grpc.Server) {
machineapi.RegisterMachineServiceServer(s, r)
func (s *Server) Register(obj *grpc.Server) {
s.server = obj
machine.RegisterMachineServiceServer(obj, s)
}
// Reboot implements the machineapi.MachineServer interface.
func (r *Registrator) Reboot(ctx context.Context, in *empty.Empty) (reply *machineapi.RebootResponse, err error) {
reply = &machineapi.RebootResponse{
Messages: []*machineapi.Reboot{
{},
},
}
// Reboot implements the machine.MachineServer interface.
//
// nolint: dupl
func (s *Server) Reboot(ctx context.Context, in *empty.Empty) (reply *machine.RebootResponse, err error) {
log.Printf("reboot via API received")
event.Bus().Notify(event.Event{Type: event.Reboot})
return
}
go func() {
if err := s.Controller.Run(runtime.SequenceReboot, in); err != nil {
log.Println("reboot failed:", err)
// Shutdown implements the machineapi.MachineServer interface.
func (r *Registrator) Shutdown(ctx context.Context, in *empty.Empty) (reply *machineapi.ShutdownResponse, err error) {
reply = &machineapi.ShutdownResponse{
Messages: []*machineapi.Shutdown{
if err != runtime.ErrLocked {
// NB: Stopping the gRPC server will trigger machined's reboot mechanism.
s.server.GracefulStop()
}
}
}()
reply = &machine.RebootResponse{
Messages: []*machine.Reboot{
{},
},
}
log.Printf("shutdown via API received")
event.Bus().Notify(event.Event{Type: event.Shutdown})
return reply, nil
}
return
// Shutdown implements the machine.MachineServer interface.
//
// nolint: dupl
func (s *Server) Shutdown(ctx context.Context, in *empty.Empty) (reply *machine.ShutdownResponse, err error) {
log.Printf("shutdown via API received")
go func() {
if err := s.Controller.Run(runtime.SequenceShutdown, in); err != nil {
log.Println("shutdown failed:", err)
if err != runtime.ErrLocked {
// NB: Stopping the gRPC server will trigger machined's reboot mechanism.
s.server.GracefulStop()
}
}
}()
reply = &machine.ShutdownResponse{
Messages: []*machine.Shutdown{
{},
},
}
return reply, nil
}
// Upgrade initiates an upgrade.
func (r *Registrator) Upgrade(ctx context.Context, in *machineapi.UpgradeRequest) (data *machineapi.UpgradeResponse, err error) {
//
// nolint: dupl
func (s *Server) Upgrade(ctx context.Context, in *machine.UpgradeRequest) (reply *machine.UpgradeResponse, err error) {
log.Printf("upgrade request received")
log.Printf("validating %q", in.GetImage())
if err = pullAndValidateInstallerImage(ctx, r.config.Machine().Registries(), in.GetImage()); err != nil {
if err = pullAndValidateInstallerImage(ctx, s.Controller.Runtime().Config().Machine().Registries(), in.GetImage()); err != nil {
return nil, err
}
@ -120,38 +133,62 @@ func (r *Registrator) Upgrade(ctx context.Context, in *machineapi.UpgradeRequest
return nil, err
}
event.Bus().Notify(event.Event{Type: event.Upgrade, Data: in})
go func() {
if err := s.Controller.Run(runtime.SequenceUpgrade, in); err != nil {
log.Println("upgrade failed:", err)
data = &machineapi.UpgradeResponse{
Messages: []*machineapi.Upgrade{
if err != runtime.ErrLocked {
// NB: Stopping the gRPC server will trigger machined's reboot mechanism.
s.server.GracefulStop()
}
}
}()
reply = &machine.UpgradeResponse{
Messages: []*machine.Upgrade{
{
Ack: "Upgrade request received",
},
},
}
return data, err
return reply, nil
}
// Reset resets the node.
func (r *Registrator) Reset(ctx context.Context, in *machineapi.ResetRequest) (data *machineapi.ResetResponse, err error) {
event.Bus().Notify(event.Event{Type: event.Reset, Data: in})
//
// nolint: dupl
func (s *Server) Reset(ctx context.Context, in *machine.ResetRequest) (reply *machine.ResetResponse, err error) {
log.Printf("reset request received")
return &machineapi.ResetResponse{
Messages: []*machineapi.Reset{
go func() {
if err := s.Controller.Run(runtime.SequenceReset, in); err != nil {
log.Println("reset failed:", err)
if err != runtime.ErrLocked {
// NB: Stopping the gRPC server will trigger machined's reboot mechanism.
s.server.GracefulStop()
}
}
}()
reply = &machine.ResetResponse{
Messages: []*machine.Reset{
{},
},
}, err
}
return reply, nil
}
// ServiceList returns list of the registered services and their status
func (r *Registrator) ServiceList(ctx context.Context, in *empty.Empty) (result *machineapi.ServiceListResponse, err error) {
services := system.Services(r.config).List()
func (s *Server) ServiceList(ctx context.Context, in *empty.Empty) (result *machine.ServiceListResponse, err error) {
services := system.Services(s.Controller.Runtime()).List()
result = &machineapi.ServiceListResponse{
Messages: []*machineapi.ServiceList{
result = &machine.ServiceListResponse{
Messages: []*machine.ServiceList{
{
Services: make([]*machineapi.ServiceInfo, len(services)),
Services: make([]*machine.ServiceInfo, len(services)),
},
},
}
@ -163,15 +200,15 @@ func (r *Registrator) ServiceList(ctx context.Context, in *empty.Empty) (result
return result, nil
}
// ServiceStart implements the machineapi.MachineServer interface and starts a
// ServiceStart implements the machine.MachineServer interface and starts a
// service running on Talos.
func (r *Registrator) ServiceStart(ctx context.Context, in *machineapi.ServiceStartRequest) (reply *machineapi.ServiceStartResponse, err error) {
if err = system.Services(r.config).APIStart(ctx, in.Id); err != nil {
return &machineapi.ServiceStartResponse{}, err
func (s *Server) ServiceStart(ctx context.Context, in *machine.ServiceStartRequest) (reply *machine.ServiceStartResponse, err error) {
if err = system.Services(s.Controller.Runtime()).APIStart(ctx, in.Id); err != nil {
return &machine.ServiceStartResponse{}, err
}
reply = &machineapi.ServiceStartResponse{
Messages: []*machineapi.ServiceStart{
reply = &machine.ServiceStartResponse{
Messages: []*machine.ServiceStart{
{
Resp: fmt.Sprintf("Service %q started", in.Id),
},
@ -181,45 +218,15 @@ func (r *Registrator) ServiceStart(ctx context.Context, in *machineapi.ServiceSt
return reply, err
}
// Start implements deprecated Start method which forwards to 'ServiceStart'.
//nolint: staticcheck
func (r *Registrator) Start(ctx context.Context, in *machineapi.StartRequest) (reply *machineapi.StartResponse, err error) {
var rep *machineapi.ServiceStartResponse
rep, err = r.ServiceStart(ctx, &machineapi.ServiceStartRequest{Id: in.Id})
if rep != nil {
reply = &machineapi.StartResponse{
Resp: rep.Messages[0].Resp,
}
}
return
}
// Stop implements deprecated Stop method which forwards to 'ServiceStop'.
//nolint: staticcheck
func (r *Registrator) Stop(ctx context.Context, in *machineapi.StopRequest) (reply *machineapi.StopResponse, err error) {
var rep *machineapi.ServiceStopResponse
rep, err = r.ServiceStop(ctx, &machineapi.ServiceStopRequest{Id: in.Id})
if rep != nil {
reply = &machineapi.StopResponse{
Resp: rep.Messages[0].Resp,
}
}
return
}
// ServiceStop implements the machineapi.MachineServer interface and stops a
// ServiceStop implements the machine.MachineServer interface and stops a
// service running on Talos.
func (r *Registrator) ServiceStop(ctx context.Context, in *machineapi.ServiceStopRequest) (reply *machineapi.ServiceStopResponse, err error) {
if err = system.Services(r.config).APIStop(ctx, in.Id); err != nil {
return &machineapi.ServiceStopResponse{}, err
func (s *Server) ServiceStop(ctx context.Context, in *machine.ServiceStopRequest) (reply *machine.ServiceStopResponse, err error) {
if err = system.Services(s.Controller.Runtime()).APIStop(ctx, in.Id); err != nil {
return &machine.ServiceStopResponse{}, err
}
reply = &machineapi.ServiceStopResponse{
Messages: []*machineapi.ServiceStop{
reply = &machine.ServiceStopResponse{
Messages: []*machine.ServiceStop{
{
Resp: fmt.Sprintf("Service %q stopped", in.Id),
},
@ -229,15 +236,15 @@ func (r *Registrator) ServiceStop(ctx context.Context, in *machineapi.ServiceSto
return reply, err
}
// ServiceRestart implements the machineapi.MachineServer interface and stops a
// ServiceRestart implements the machine.MachineServer interface and stops a
// service running on Talos.
func (r *Registrator) ServiceRestart(ctx context.Context, in *machineapi.ServiceRestartRequest) (reply *machineapi.ServiceRestartResponse, err error) {
if err = system.Services(r.config).APIRestart(ctx, in.Id); err != nil {
return &machineapi.ServiceRestartResponse{}, err
func (s *Server) ServiceRestart(ctx context.Context, in *machine.ServiceRestartRequest) (reply *machine.ServiceRestartResponse, err error) {
if err = system.Services(s.Controller.Runtime()).APIRestart(ctx, in.Id); err != nil {
return &machine.ServiceRestartResponse{}, err
}
reply = &machineapi.ServiceRestartResponse{
Messages: []*machineapi.ServiceRestart{
reply = &machine.ServiceRestartResponse{
Messages: []*machine.ServiceRestart{
{
Resp: fmt.Sprintf("Service %q restarted", in.Id),
},
@ -247,8 +254,8 @@ func (r *Registrator) ServiceRestart(ctx context.Context, in *machineapi.Service
return reply, err
}
// Copy implements the machineapi.MachineServer interface and copies data out of Talos node
func (r *Registrator) Copy(req *machineapi.CopyRequest, s machineapi.MachineService_CopyServer) error {
// Copy implements the machine.MachineServer interface and copies data out of Talos node
func (s *Server) Copy(req *machine.CopyRequest, obj machine.MachineService_CopyServer) error {
path := req.RootPath
path = filepath.Clean(path)
@ -260,7 +267,7 @@ func (r *Registrator) Copy(req *machineapi.CopyRequest, s machineapi.MachineServ
errCh := make(chan error, 1)
ctx, ctxCancel := context.WithCancel(s.Context())
ctx, ctxCancel := context.WithCancel(obj.Context())
defer ctxCancel()
go func() {
@ -273,7 +280,7 @@ func (r *Registrator) Copy(req *machineapi.CopyRequest, s machineapi.MachineServ
chunkCh := chunker.Read(ctx)
for data := range chunkCh {
err := s.SendMsg(&common.Data{Bytes: data})
err := obj.SendMsg(&common.Data{Bytes: data})
if err != nil {
ctxCancel()
}
@ -281,7 +288,7 @@ func (r *Registrator) Copy(req *machineapi.CopyRequest, s machineapi.MachineServ
archiveErr := <-errCh
if archiveErr != nil {
return s.SendMsg(&common.Data{
return obj.SendMsg(&common.Data{
Metadata: &common.Metadata{
Error: archiveErr.Error(),
},
@ -291,10 +298,10 @@ func (r *Registrator) Copy(req *machineapi.CopyRequest, s machineapi.MachineServ
return nil
}
// List implements the machineapi.MachineServer interface.
func (r *Registrator) List(req *machineapi.ListRequest, s machineapi.MachineService_ListServer) error {
// List implements the machine.MachineServer interface.
func (s *Server) List(req *machine.ListRequest, obj machine.MachineService_ListServer) error {
if req == nil {
req = new(machineapi.ListRequest)
req = new(machine.ListRequest)
}
if !strings.HasPrefix(req.Root, OSPathSeparator) {
@ -317,20 +324,20 @@ func (r *Registrator) List(req *machineapi.ListRequest, s machineapi.MachineServ
}
}
files, err := archiver.Walker(s.Context(), req.Root, archiver.WithMaxRecurseDepth(maxDepth))
files, err := archiver.Walker(obj.Context(), req.Root, archiver.WithMaxRecurseDepth(maxDepth))
if err != nil {
return err
}
for fi := range files {
if fi.Error != nil {
err = s.Send(&machineapi.FileInfo{
err = obj.Send(&machine.FileInfo{
Name: fi.FullPath,
RelativeName: fi.RelPath,
Error: fi.Error.Error(),
})
} else {
err = s.Send(&machineapi.FileInfo{
err = obj.Send(&machine.FileInfo{
Name: fi.FullPath,
RelativeName: fi.RelPath,
Size: fi.FileInfo.Size(),
@ -349,8 +356,8 @@ func (r *Registrator) List(req *machineapi.ListRequest, s machineapi.MachineServ
return nil
}
// Mounts implements the machineapi.OSDServer interface.
func (r *Registrator) Mounts(ctx context.Context, in *empty.Empty) (reply *machineapi.MountsResponse, err error) {
// Mounts implements the machine.OSDServer interface.
func (s *Server) Mounts(ctx context.Context, in *empty.Empty) (reply *machine.MountsResponse, err error) {
file, err := os.Open("/proc/mounts")
if err != nil {
return nil, err
@ -363,7 +370,7 @@ func (r *Registrator) Mounts(ctx context.Context, in *empty.Empty) (reply *machi
multiErr *multierror.Error
)
stats := []*machineapi.MountStat{}
stats := []*machine.MountStat{}
scanner := bufio.NewScanner(file)
for scanner.Scan() {
@ -394,7 +401,7 @@ func (r *Registrator) Mounts(ctx context.Context, in *empty.Empty) (reply *machi
totalSize := uint64(stat.Bsize) * stat.Blocks
totalAvail := uint64(stat.Bsize) * stat.Bavail
stat := &machineapi.MountStat{
stat := &machine.MountStat{
Filesystem: filesystem,
Size: totalSize,
Available: totalAvail,
@ -408,8 +415,8 @@ func (r *Registrator) Mounts(ctx context.Context, in *empty.Empty) (reply *machi
multiErr = multierror.Append(multiErr, err)
}
reply = &machineapi.MountsResponse{
Messages: []*machineapi.Mounts{
reply = &machine.MountsResponse{
Messages: []*machine.Mounts{
{
Stats: stats,
},
@ -419,19 +426,19 @@ func (r *Registrator) Mounts(ctx context.Context, in *empty.Empty) (reply *machi
return reply, multiErr.ErrorOrNil()
}
// Version implements the machineapi.MachineServer interface.
func (r *Registrator) Version(ctx context.Context, in *empty.Empty) (reply *machineapi.VersionResponse, err error) {
var platform *machineapi.PlatformInfo
// Version implements the machine.MachineServer interface.
func (s *Server) Version(ctx context.Context, in *empty.Empty) (reply *machine.VersionResponse, err error) {
var platform *machine.PlatformInfo
if r.platform != nil {
platform = &machineapi.PlatformInfo{
Name: r.platform.Name(),
Mode: r.platform.Mode().String(),
if s.Controller.Runtime().State().Platform() != nil {
platform = &machine.PlatformInfo{
Name: s.Controller.Runtime().State().Platform().Name(),
Mode: s.Controller.Runtime().State().Platform().Mode().String(),
}
}
return &machineapi.VersionResponse{
Messages: []*machineapi.Version{
return &machine.VersionResponse{
Messages: []*machine.Version{
{
Version: version.NewVersion(),
Platform: platform,
@ -441,10 +448,10 @@ func (r *Registrator) Version(ctx context.Context, in *empty.Empty) (reply *mach
}
// Kubeconfig implements the osapi.OSDServer interface.
func (r *Registrator) Kubeconfig(empty *empty.Empty, s machineapi.MachineService_KubeconfigServer) error {
var kubeconfigBuf bytes.Buffer
func (s *Server) Kubeconfig(empty *empty.Empty, obj machine.MachineService_KubeconfigServer) error {
var b bytes.Buffer
if err := kubeconfig.GenerateAdmin(r.config.Cluster(), &kubeconfigBuf); err != nil {
if err := kubeconfig.GenerateAdmin(s.Controller.Runtime().Config().Cluster(), &b); err != nil {
return err
}
@ -458,7 +465,7 @@ func (r *Registrator) Kubeconfig(empty *empty.Empty, s machineapi.MachineService
err := tarW.WriteHeader(&tar.Header{
Typeflag: tar.TypeReg,
Name: "kubeconfig",
Size: int64(kubeconfigBuf.Len()),
Size: int64(b.Len()),
ModTime: time.Now(),
Mode: 0600,
})
@ -466,7 +473,7 @@ func (r *Registrator) Kubeconfig(empty *empty.Empty, s machineapi.MachineService
return err
}
_, err = io.Copy(tarW, &kubeconfigBuf)
_, err = io.Copy(tarW, &b)
if err != nil {
return err
}
@ -475,7 +482,7 @@ func (r *Registrator) Kubeconfig(empty *empty.Empty, s machineapi.MachineService
return err
}
return s.Send(&common.Data{
return obj.Send(&common.Data{
Bytes: buf.Bytes(),
})
}
@ -483,7 +490,7 @@ func (r *Registrator) Kubeconfig(empty *empty.Empty, s machineapi.MachineService
// Logs provides a service or container logs can be requested and the contents of the
// log file are streamed in chunks.
// nolint: gocyclo
func (r *Registrator) Logs(req *machineapi.LogsRequest, l machineapi.MachineService_LogsServer) (err error) {
func (s *Server) Logs(req *machine.LogsRequest, l machine.MachineService_LogsServer) (err error) {
var chunk chunker.Chunker
switch {
@ -531,7 +538,7 @@ func (r *Registrator) Logs(req *machineapi.LogsRequest, l machineapi.MachineServ
return nil
}
func k8slogs(ctx context.Context, req *machineapi.LogsRequest) (chunker.Chunker, io.Closer, error) {
func k8slogs(ctx context.Context, req *machine.LogsRequest) (chunker.Chunker, io.Closer, error) {
inspector, err := getContainerInspector(ctx, req.Namespace, req.Driver)
if err != nil {
return nil, nil, err
@ -572,7 +579,7 @@ func getContainerInspector(ctx context.Context, namespace string, driver common.
}
// Read implements the read API.
func (r *Registrator) Read(in *machineapi.ReadRequest, srv machineapi.MachineService_ReadServer) (err error) {
func (s *Server) Read(in *machine.ReadRequest, srv machine.MachineService_ReadServer) (err error) {
stat, err := os.Stat(in.Path)
if err != nil {
return err
@ -606,7 +613,7 @@ func (r *Registrator) Read(in *machineapi.ReadRequest, srv machineapi.MachineSer
}
}
func pullAndValidateInstallerImage(ctx context.Context, config machinecfg.Registries, ref string) error {
func pullAndValidateInstallerImage(ctx context.Context, reg runtime.Registries, ref string) error {
// Pull down specified installer image early so we can bail if it doesn't exist in the upstream registry
containerdctx := namespaces.WithNamespace(ctx, constants.SystemContainerdNamespace)
@ -615,7 +622,7 @@ func pullAndValidateInstallerImage(ctx context.Context, config machinecfg.Regist
return err
}
img, err := image.Pull(containerdctx, config, client, ref)
img, err := image.Pull(containerdctx, reg, client, ref)
if err != nil {
return err
}

View File

@ -6,87 +6,35 @@ package main
import (
"errors"
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
"net/url"
"os"
"regexp"
"os/signal"
"syscall"
"time"
"golang.org/x/net/http/httpproxy"
"golang.org/x/sys/unix"
machineapi "github.com/talos-systems/talos/api/machine"
"github.com/talos-systems/talos/cmd/installer/pkg/bootloader/syslinux"
"github.com/talos-systems/talos/internal/app/machined/internal/sequencer"
"github.com/talos-systems/talos/internal/pkg/event"
"github.com/talos-systems/talos/internal/pkg/runtime"
"github.com/talos-systems/go-procfs/procfs"
v1alpha1server "github.com/talos-systems/talos/internal/app/machined/internal/server/v1alpha1"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
v1alpha1runtime "github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1"
"github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/bootloader/syslinux"
"github.com/talos-systems/talos/pkg/constants"
"github.com/talos-systems/talos/pkg/grpc/factory"
"github.com/talos-systems/talos/pkg/proc/reaper"
"github.com/talos-systems/talos/pkg/startup"
)
// EventBusObserver is used to subscribe to the event bus.
type EventBusObserver struct {
*event.Embeddable
}
func recovery() {
if r := recover(); r != nil {
log.Printf("recovered from: %+v\n", r)
if err := revert(); err != nil {
log.Printf("failed to revert upgrade: %v", err)
}
for i := 10; i >= 0; i-- {
log.Printf("rebooting in %d seconds\n", i)
time.Sleep(1 * time.Second)
}
if unix.Reboot(unix.LINUX_REBOOT_CMD_RESTART) == nil {
select {}
}
}
}
// See http://man7.org/linux/man-pages/man2/reboot.2.html.
func sync() {
syncdone := make(chan struct{})
go func() {
defer close(syncdone)
unix.Sync()
}()
log.Printf("waiting for sync...")
for i := 29; i >= 0; i-- {
select {
case <-syncdone:
log.Printf("sync done")
return
case <-time.After(time.Second):
}
if i != 0 {
log.Printf("waiting %d more seconds for sync to finish", i)
}
}
log.Printf("sync hasn't completed in time, aborting...")
}
func init() {
// Explicitly set the default http client transport
// to work around our fun proxy.Do once bug.
// This is the http.DefaultTransport with the Proxy
// func overridden so that the environment variables
// with be reread/initialized each time the http call
// is made.
// Explicitly set the default http client transport to work around proxy.Do
// once. This is the http.DefaultTransport with the Proxy func overridden so
// that the environment variables with be reread/initialized each time the
// http call is made.
http.DefaultClient.Transport = &http.Transport{
Proxy: func(req *http.Request) (*url.URL, error) {
return httpproxy.FromEnvironment().ProxyFunc()(req.URL)
@ -104,193 +52,112 @@ func init() {
}
}
// nolint: gocyclo
func revert() (err error) {
f, err := os.OpenFile(syslinux.SyslinuxLdlinux, os.O_RDWR, 0700)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return nil
func recovery() {
if r := recover(); r != nil {
var (
err error
ok bool
)
err, ok = r.(error)
if ok {
handle(err)
}
return err
}
}
// nolint: errcheck
defer f.Close()
adv, err := syslinux.NewADV(f)
func handle(err error) {
if err != nil {
return err
log.Print(err)
}
label, ok := adv.ReadTag(syslinux.AdvUpgrade)
if !ok {
return nil
if err := syslinux.Revert(); err != nil {
log.Printf("failed to revert upgrade: %v", err)
}
if label == "" {
adv.DeleteTag(syslinux.AdvUpgrade)
if p := procfs.ProcCmdline().Get(constants.KernelParamPanic).First(); p != nil {
if *p == "0" {
log.Printf("panic=0 kernel flag found, sleeping forever")
if _, err = f.Write(adv); err != nil {
return err
exitSignal := make(chan os.Signal, 1)
signal.Notify(exitSignal, syscall.SIGINT, syscall.SIGTERM)
<-exitSignal
}
return nil
}
log.Printf("reverting default boot to %q", label)
var b []byte
if b, err = ioutil.ReadFile(syslinux.SyslinuxConfig); err != nil {
return err
for i := 10; i >= 0; i-- {
log.Printf("rebooting in %d seconds\n", i)
time.Sleep(1 * time.Second)
}
re := regexp.MustCompile(`^DEFAULT\s(.*)`)
matches := re.FindSubmatch(b)
v1alpha1runtime.SyncNonVolatileStorageBuffers()
if len(matches) != 2 {
return fmt.Errorf("expected 2 matches, got %d", len(matches))
if unix.Reboot(unix.LINUX_REBOOT_CMD_RESTART) == nil {
// Wait forever.
select {}
}
b = re.ReplaceAll(b, []byte(fmt.Sprintf("DEFAULT %s", label)))
if err = ioutil.WriteFile(syslinux.SyslinuxConfig, b, 0600); err != nil {
return err
}
adv.DeleteTag(syslinux.AdvUpgrade)
if _, err = f.Write(adv); err != nil {
return err
}
return nil
}
// nolint: gocyclo
func main() {
var err error
// This is main entrypoint into machined execution, control is passed here
// from init after switch root.
//
// When machined terminates either on normal shutdown (reboot, poweroff), or
// due to panic, control goes through recovery() and reboot() functions
// below, which finalize node state - sync buffers, initiate poweroff or
// reboot. Also on shutdown, other deferred function are called, for example
// services are gracefully shutdown.
// On any return from init.main(), initiate host reboot or shutdown handle
// any panics in the main goroutine, and proceed to reboot() above
// Setup panic handler.
defer recovery()
// Subscribe to events.
init := EventBusObserver{&event.Embeddable{}}
defer close(init.Channel())
event.Bus().Register(init)
defer event.Bus().Unregister(init)
// Initialize process reaper.
// Initialize the process reaper.
reaper.Run()
defer reaper.Shutdown()
// Ensure rng is seeded.
if err = startup.RandSeed(); err != nil {
panic(err)
if err := startup.RandSeed(); err != nil {
handle(err)
}
// Set the PATH env var.
if err = os.Setenv("PATH", constants.PATH); err != nil {
panic(errors.New("error setting PATH"))
if err := os.Setenv("PATH", constants.PATH); err != nil {
handle(errors.New("error setting PATH"))
}
immediateReboot := false
// Initialize the controller without a config.
c, err := v1alpha1runtime.NewController(nil)
if err != nil {
handle(err)
}
// Initialize the machine.
if err = c.Run(runtime.SequenceInitialize, nil); err != nil {
handle(err)
}
// Start event listeners.
go func() {
if e := c.ListenForEvents(); e != nil {
log.Printf("WARNING: signals and ACPI events will be ignored: %+v", e)
}
}()
// Start the API server.
go func() {
server := &v1alpha1server.Server{
Controller: c,
}
e := factory.ListenAndServe(server, factory.Network("unix"), factory.SocketPath(constants.MachineSocketPath))
handle(e)
}()
// Perform an installation if required.
if err = c.Run(runtime.SequenceInstall, nil); err != nil {
handle(err)
}
// Boot the machine.
seq := sequencer.New(sequencer.V1Alpha1)
if err := seq.Boot(); err != nil {
if errors.Is(err, runtime.ErrReboot) {
immediateReboot = true
} else {
log.Println(err)
panic(fmt.Errorf("boot failed: %w", err))
}
if err = c.Run(runtime.SequenceBoot, nil); err != nil {
handle(err)
}
// Wait for an event.
flag := unix.LINUX_REBOOT_CMD_RESTART
runShutdownOnImmediateReboot := true
for !immediateReboot {
switch e := <-init.Channel(); e.Type {
case event.Shutdown:
flag = unix.LINUX_REBOOT_CMD_POWER_OFF
fallthrough
case event.Reboot:
immediateReboot = true
case event.Upgrade:
var (
req *machineapi.UpgradeRequest
ok bool
)
if req, ok = e.Data.(*machineapi.UpgradeRequest); !ok {
log.Println("cannot perform upgrade, unexpected data type")
continue
}
if err := seq.Upgrade(req); err != nil {
log.Println(err)
panic(fmt.Errorf("upgrade failed: %w", err))
}
immediateReboot = true
runShutdownOnImmediateReboot = false
case event.Reset:
var (
req *machineapi.ResetRequest
ok bool
)
if req, ok = e.Data.(*machineapi.ResetRequest); !ok {
log.Println("cannot perform reset, unexpected data type")
continue
}
if err := seq.Reset(req); err != nil {
log.Println(err)
panic(fmt.Errorf("reset failed: %w", err))
}
if !req.GetReboot() {
flag = unix.LINUX_REBOOT_CMD_POWER_OFF
}
immediateReboot = true
}
}
if runShutdownOnImmediateReboot {
if err := seq.Shutdown(); err != nil {
log.Println(err)
panic(fmt.Errorf("shutdown failed: %w", err))
}
}
sync()
if err := unix.Reboot(flag); err != nil {
log.Println(err)
panic(err)
}
// Prevent a kernel panic.
// Wait forever.
select {}
}

View File

@ -2,62 +2,105 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package machine
package runtime
import (
"crypto/tls"
"fmt"
"net/url"
"os"
"time"
stdx509 "crypto/x509"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/talos-systems/talos/pkg/blockdevice/probe"
"github.com/talos-systems/talos/pkg/client/config"
"github.com/talos-systems/talos/pkg/crypto/x509"
)
// Type represents a machine type.
type Type int
// Configurator defines the configuration interface.
type Configurator interface {
Version() string
Debug() bool
Persist() bool
Machine() MachineConfig
Cluster() ClusterConfig
Validate(Mode) error
String() (string, error)
Bytes() ([]byte, error)
}
// ConfiguratorBundle defines the configuration bundle interface.
type ConfiguratorBundle interface {
Init() Configurator
ControlPlane() Configurator
Join() Configurator
TalosConfig() *config.Config
}
// Machine defines the runtime parameters.
type Machine interface {
State() MachineState
Config() MachineConfig
}
// MachineState defines the machined state.
type MachineState interface {
Disk() *probe.ProbedBlockDevice
Close() error
Installed() bool
}
// MachineType represents a machine type.
type MachineType int
const (
// TypeInit represents an init node.
TypeInit Type = iota
// TypeControlPlane represents a control plane node.
TypeControlPlane
// TypeWorker represents a worker node.
TypeWorker
// MachineTypeInit represents a bootstrap node.
MachineTypeInit MachineType = iota
// MachineTypeControlPlane represents a control plane node.
MachineTypeControlPlane
// MachineTypeJoin represents a worker node.
MachineTypeJoin
)
const (
machineTypeInit = "init"
machineTypeControlPlane = "controlplane"
machineTypeJoin = "join"
)
// String returns the string representation of Type.
func (t Type) String() string {
return [...]string{"Init", "ControlPlane", "Join"}[t]
func (t MachineType) String() string {
return [...]string{machineTypeInit, machineTypeControlPlane, machineTypeJoin}[t]
}
// ParseType parses string constant as Type
func ParseType(t string) (Type, error) {
// ParseMachineType parses string constant as Type
func ParseMachineType(t string) (MachineType, error) {
switch t {
case "Init":
return TypeInit, nil
case "ControlPlane":
return TypeControlPlane, nil
case "Join":
return TypeWorker, nil
case machineTypeInit:
return MachineTypeInit, nil
case machineTypeControlPlane:
return MachineTypeControlPlane, nil
case machineTypeJoin:
return MachineTypeJoin, nil
default:
return 0, fmt.Errorf("unknown type %q", t)
return 0, fmt.Errorf("unknown machine type: %q", t)
}
}
// Machine defines the requirements for a config that pertains to machine
// MachineConfig defines the requirements for a config that pertains to machine
// related options.
type Machine interface {
type MachineConfig interface {
Install() Install
Security() Security
Network() Network
Network() MachineNetwork
Disks() []Disk
Time() Time
Env() Env
Files() ([]File, error)
Type() Type
Type() MachineType
Kubelet() Kubelet
Sysctls() map[string]string
Registries() Registries
@ -83,9 +126,9 @@ type Security interface {
SetCertSANs([]string)
}
// Network defines the requirements for a config that pertains to network
// MachineNetwork defines the requirements for a config that pertains to network
// related options.
type Network interface {
type MachineNetwork interface {
Hostname() string
SetHostname(string)
Resolvers() []string
@ -284,3 +327,96 @@ type Registries interface {
// ExtraFiles generates TOML config for containerd CRI plugin.
ExtraFiles() ([]File, error)
}
// ClusterState defines the cluster state.
type ClusterState interface{}
// ClusterConfig defines the requirements for a config that pertains to cluster
// related options.
type ClusterConfig interface {
Name() string
APIServer() APIServer
ControllerManager() ControllerManager
Scheduler() Scheduler
Endpoint() *url.URL
Token() Token
CertSANs() []string
SetCertSANs([]string)
CA() *x509.PEMEncodedCertificateAndKey
AESCBCEncryptionSecret() string
Config(MachineType) (string, error)
Etcd() Etcd
Network() ClusterNetwork
LocalAPIServerPort() int
PodCheckpointer() PodCheckpointer
CoreDNS() CoreDNS
ExtraManifestURLs() []string
ExtraManifestHeaderMap() map[string]string
AdminKubeconfig() AdminKubeconfig
}
// ClusterNetwork defines the requirements for a config that pertains to cluster
// network options.
type ClusterNetwork interface {
CNI() CNI
PodCIDR() string
ServiceCIDR() string
DNSDomain() string
}
// CNI defines the requirements for a config that pertains to Kubernetes
// cni.
type CNI interface {
Name() string
URLs() []string
}
// APIServer defines the requirements for a config that pertains to apiserver related
// options.
type APIServer interface {
ExtraArgs() map[string]string
}
// ControllerManager defines the requirements for a config that pertains to controller manager related
// options.
type ControllerManager interface {
ExtraArgs() map[string]string
}
// Scheduler defines the requirements for a config that pertains to scheduler related
// options.
type Scheduler interface {
ExtraArgs() map[string]string
}
// Etcd defines the requirements for a config that pertains to etcd related
// options.
type Etcd interface {
Image() string
CA() *x509.PEMEncodedCertificateAndKey
ExtraArgs() map[string]string
}
// Token defines the requirements for a config that pertains to Kubernetes
// bootstrap token.
type Token interface {
ID() string
Secret() string
}
// PodCheckpointer defines the requirements for a config that pertains to bootkube
// pod-checkpointer options.
type PodCheckpointer interface {
Image() string
}
// CoreDNS defines the requirements for a config that pertains to bootkube
// coredns options.
type CoreDNS interface {
Image() string
}
// AdminKubeconfig defines settings for admin kubeconfig.
type AdminKubeconfig interface {
CertLifetime() time.Duration
}

View File

@ -0,0 +1,94 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// nolint: dupl,scopelint
package runtime
import (
"reflect"
"testing"
)
func TestMachineType_String(t *testing.T) {
tests := []struct {
name string
t MachineType
want string
}{
{
name: "init",
t: MachineTypeInit,
want: "init",
},
{
name: "controlplane",
t: MachineTypeControlPlane,
want: "controlplane",
},
{
name: "join",
t: MachineTypeJoin,
want: "join",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.t.String(); got != tt.want {
t.Errorf("MachineType.String() = %v, want %v", got, tt.want)
}
})
}
}
func TestParseMachineType(t *testing.T) {
type args struct {
t string
}
tests := []struct {
name string
args args
want MachineType
wantErr bool
}{
{
name: "init",
args: args{"init"},
want: MachineTypeInit,
wantErr: false,
},
{
name: "controlplane",
args: args{"controlplane"},
want: MachineTypeControlPlane,
wantErr: false,
},
{
name: "join",
args: args{"join"},
want: MachineTypeJoin,
wantErr: false,
},
{
name: "invalid",
args: args{"invalid"},
want: 0,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := ParseMachineType(tt.args.t)
if (err != nil) != tt.wantErr {
t.Errorf("ParseMachineType() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("ParseMachineType() = %v, want %v", got, tt.want)
}
})
}
}

View File

@ -0,0 +1,29 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package runtime
import (
"context"
"log"
)
// TaskSetupFunc defines the function that a task will execute for a specific runtime
// mode.
type TaskSetupFunc func(seq Sequence, data interface{}) TaskExecutionFunc
// TaskExecutionFunc defines the function that a task will execute for a specific runtime
// mode.
type TaskExecutionFunc func(context.Context, *log.Logger, Runtime) error
// Phase represents a collection of tasks to be performed concurrently.
type Phase []TaskSetupFunc
// Controller represents the controller responsible for managing the execution
// of sequences.
type Controller interface {
Runtime() Runtime
Sequencer() Sequencer
Run(Sequence, interface{}) error
}

View File

@ -0,0 +1,680 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// nolint: scopelint,dupl
package runtime
// import (
// "fmt"
// "net"
// "testing"
// "github.com/talos-systems/go-procfs/procfs"
// "github.com/talos-systems/talos/api/machine"
// )
// type MockSuccessfulSequencer struct{}
// // Boot is a mock method that overrides the embedded sequencer's Boot method.
// func (s *MockSuccessfulSequencer) Boot() []Phase {
// return []Phase{
// &MockSuccessfulPhase{},
// }
// }
// // Initialize is a mock method that overrides the embedded sequencer's Initialize method.
// func (s *MockSuccessfulSequencer) Initialize() []Phase {
// return []Phase{
// &MockSuccessfulPhase{},
// }
// }
// // Shutdown is a mock method that overrides the embedded sequencer's Shutdown method.
// func (s *MockSuccessfulSequencer) Shutdown() []Phase {
// return []Phase{
// &MockSuccessfulPhase{},
// }
// }
// // Upgrade is a mock method that overrides the embedded sequencer's Upgrade method.
// func (s *MockSuccessfulSequencer) Upgrade(req *machine.UpgradeRequest) []Phase {
// return []Phase{
// &MockSuccessfulPhase{},
// }
// }
// // Reboot is a mock method that overrides the embedded sequencer's Reboot method.
// func (s *MockSuccessfulSequencer) Reboot() []Phase {
// return []Phase{
// &MockSuccessfulPhase{},
// }
// }
// // Reset is a mock method that overrides the embedded sequencer's Reset method.
// func (s *MockSuccessfulSequencer) Reset(req *machine.ResetRequest) []Phase {
// return []Phase{
// &MockSuccessfulPhase{},
// }
// }
// type MockUnsuccessfulSequencer struct{}
// // Boot is a mock method that overrides the embedded sequencer's Boot method.
// func (s *MockUnsuccessfulSequencer) Boot() []Phase {
// return []Phase{
// &MockUnsuccessfulPhase{},
// }
// }
// // Initialize is a mock method that overrides the embedded sequencer's Initialize method.
// func (s *MockUnsuccessfulSequencer) Initialize() []Phase {
// return []Phase{
// &MockUnsuccessfulPhase{},
// }
// }
// // Shutdown is a mock method that overrides the embedded sequencer's Shutdown method.
// func (s *MockUnsuccessfulSequencer) Shutdown() []Phase {
// return []Phase{
// &MockUnsuccessfulPhase{},
// }
// }
// // Upgrade is a mock method that overrides the embedded sequencer's Upgrade method.
// func (s *MockUnsuccessfulSequencer) Upgrade(req *machine.UpgradeRequest) []Phase {
// return []Phase{
// &MockUnsuccessfulPhase{},
// }
// }
// // Reboot is a mock method that overrides the embedded sequencer's Reboot method.
// func (s *MockUnsuccessfulSequencer) Reboot() []Phase {
// return []Phase{
// &MockUnsuccessfulPhase{},
// }
// }
// // Reset is a mock method that overrides the embedded sequencer's Reset method.
// func (s *MockUnsuccessfulSequencer) Reset(req *machine.ResetRequest) []Phase {
// return []Phase{
// &MockUnsuccessfulPhase{},
// }
// }
// type MockSuccessfulPhase struct{}
// func (*MockSuccessfulPhase) Tasks() []TaskSetupFunc {
// return []TaskSetupFunc{&MockSuccessfulTask{}}
// }
// type MockUnsuccessfulPhase struct{}
// func (*MockUnsuccessfulPhase) Tasks() []TaskSetupFunc {
// return []TaskSetupFunc{&MockUnsuccessfulTask{}}
// }
// type MockSuccessfulTask struct{}
// func (*MockSuccessfulTask) Func(Mode) TaskSetupFunc {
// return func(Runtime) error {
// return nil
// }
// }
// type MockUnsuccessfulTask struct{}
// func (*MockUnsuccessfulTask) Func(Mode) TaskSetupFunc {
// return func(Runtime) error { return fmt.Errorf("error") }
// }
// type MockPlatform struct{}
// func (*MockPlatform) Name() string {
// return "mock"
// }
// func (*MockPlatform) Configuration() ([]byte, error) {
// return nil, nil
// }
// func (*MockPlatform) ExternalIPs() ([]net.IP, error) {
// return nil, nil
// }
// func (*MockPlatform) Hostname() ([]byte, error) {
// return nil, nil
// }
// func (*MockPlatform) Mode() Mode {
// return Metal
// }
// func (*MockPlatform) KernelArgs() procfs.Parameters {
// return procfs.Parameters{}
// }
// type MockConfigurator struct{}
// func (*MockConfigurator) Version() string {
// return ""
// }
// func (*MockConfigurator) Debug() bool {
// return false
// }
// func (*MockConfigurator) Persist() bool {
// return false
// }
// func (*MockConfigurator) Machine() Machine {
// return nil
// }
// func (*MockConfigurator) Cluster() Cluster {
// return nil
// }
// func (*MockConfigurator) Validate(Mode) error {
// return nil
// }
// func (*MockConfigurator) String() (string, error) {
// return "", nil
// }
// func (*MockConfigurator) Bytes() ([]byte, error) {
// return nil, nil
// }
// type MockRuntime struct{}
// func (*MockRuntime) Platform() Platform {
// return &MockPlatform{}
// }
// func (*MockRuntime) Config() Configurator {
// return &MockConfigurator{}
// }
// func (*MockRuntime) Sequence() Sequence {
// return Noop
// }
// func TestController_Run(t *testing.T) {
// type fields struct {
// Sequencer Sequencer
// Runtime Runtime
// semaphore int32
// }
// type args struct {
// seq Sequence
// data interface{}
// }
// tests := []struct {
// name string
// fields fields
// args args
// wantErr bool
// }{
// {
// name: "boot",
// fields: fields{
// Sequencer: &MockSuccessfulSequencer{},
// Runtime: &MockRuntime{},
// semaphore: 0,
// },
// args: args{
// seq: Boot,
// data: nil,
// },
// wantErr: false,
// },
// {
// name: "initialize",
// fields: fields{
// Sequencer: &MockSuccessfulSequencer{},
// Runtime: &MockRuntime{},
// semaphore: 0,
// },
// args: args{
// seq: Initialize,
// data: nil,
// },
// wantErr: false,
// },
// {
// name: "shutdown",
// fields: fields{
// Sequencer: &MockSuccessfulSequencer{},
// Runtime: &MockRuntime{},
// semaphore: 0,
// },
// args: args{
// seq: Shutdown,
// data: nil,
// },
// wantErr: false,
// },
// {
// name: "upgrade with valid data",
// fields: fields{
// Sequencer: &MockSuccessfulSequencer{},
// Runtime: &MockRuntime{},
// semaphore: 0,
// },
// args: args{
// seq: Upgrade,
// data: &machine.UpgradeRequest{},
// },
// wantErr: false,
// },
// {
// name: "upgrade with invalid data",
// fields: fields{
// Sequencer: &MockSuccessfulSequencer{},
// Runtime: &MockRuntime{},
// semaphore: 0,
// },
// args: args{
// seq: Upgrade,
// data: nil,
// },
// wantErr: true,
// },
// {
// name: "upgrade with lock",
// fields: fields{
// Sequencer: &MockSuccessfulSequencer{},
// Runtime: &MockRuntime{},
// semaphore: 1,
// },
// args: args{
// seq: Upgrade,
// data: &machine.UpgradeRequest{},
// },
// wantErr: true,
// },
// {
// name: "reset with valid data",
// fields: fields{
// Sequencer: &MockSuccessfulSequencer{},
// Runtime: &MockRuntime{},
// semaphore: 0,
// },
// args: args{
// seq: Reset,
// data: &machine.ResetRequest{},
// },
// wantErr: false,
// },
// {
// name: "reset with invalid data",
// fields: fields{
// Sequencer: &MockSuccessfulSequencer{},
// Runtime: &MockRuntime{},
// semaphore: 0,
// },
// args: args{
// seq: Reset,
// data: nil,
// },
// wantErr: true,
// },
// {
// name: "unsuccessful phase",
// fields: fields{
// Sequencer: &MockUnsuccessfulSequencer{},
// Runtime: &MockRuntime{},
// semaphore: 0,
// },
// args: args{
// seq: Boot,
// data: nil,
// },
// wantErr: true,
// },
// {
// name: "undefined runtime",
// fields: fields{
// Sequencer: &MockSuccessfulSequencer{},
// Runtime: nil,
// semaphore: 0,
// },
// args: args{
// seq: Boot,
// data: nil,
// },
// wantErr: true,
// },
// }
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// c := &Controller{
// Sequencer: tt.fields.Sequencer,
// Runtime: tt.fields.Runtime,
// semaphore: tt.fields.semaphore,
// }
// t.Logf("c.Sequencer: %v", c.Sequencer)
// if err := c.Run(tt.args.seq, tt.args.data); (err != nil) != tt.wantErr {
// t.Errorf("Controller.Run() error = %v, wantErr %v", err, tt.wantErr)
// }
// })
// }
// }
// func TestController_runPhase(t *testing.T) {
// type fields struct {
// Sequencer Sequencer
// Runtime Runtime
// semaphore int32
// }
// type args struct {
// phase Phase
// }
// tests := []struct {
// name string
// fields fields
// args args
// wantErr bool
// }{
// {
// name: "successful phase",
// fields: fields{
// Sequencer: &MockSuccessfulSequencer{},
// Runtime: &MockRuntime{},
// semaphore: 0,
// },
// args: args{
// phase: &MockSuccessfulPhase{},
// },
// wantErr: false,
// },
// {
// name: "unsuccessful phase",
// fields: fields{
// Sequencer: &MockSuccessfulSequencer{},
// Runtime: &MockRuntime{},
// semaphore: 0,
// },
// args: args{
// phase: &MockUnsuccessfulPhase{},
// },
// wantErr: true,
// },
// }
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// c := &Controller{
// Sequencer: tt.fields.Sequencer,
// Runtime: tt.fields.Runtime,
// semaphore: tt.fields.semaphore,
// }
// if err := c.runPhase(tt.args.phase); (err != nil) != tt.wantErr {
// t.Errorf("Controller.runPhase() error = %v, wantErr %v", err, tt.wantErr)
// }
// })
// }
// }
// func TestController_runTask(t *testing.T) {
// type fields struct {
// Sequencer Sequencer
// Runtime Runtime
// semaphore int32
// }
// type args struct {
// t TaskSetupFunc
// }
// tests := []struct {
// name string
// fields fields
// args args
// wantErr bool
// }{
// {
// name: "successful task",
// fields: fields{
// Sequencer: &MockSuccessfulSequencer{},
// Runtime: &MockRuntime{},
// semaphore: 0,
// },
// args: args{
// t: &MockSuccessfulTask{},
// },
// wantErr: false,
// },
// {
// name: "unsuccessful task",
// fields: fields{
// Sequencer: &MockSuccessfulSequencer{},
// Runtime: &MockRuntime{},
// semaphore: 0,
// },
// args: args{
// t: &MockUnsuccessfulTask{},
// },
// wantErr: true,
// },
// }
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// c := &Controller{
// Sequencer: tt.fields.Sequencer,
// Runtime: tt.fields.Runtime,
// semaphore: tt.fields.semaphore,
// }
// if err := c.runTask(tt.args.t); (err != nil) != tt.wantErr {
// t.Errorf("Controller.runTask() error = %v, wantErr %v", err, tt.wantErr)
// }
// })
// }
// }
// func TestController_TryLock(t *testing.T) {
// type fields struct {
// Sequencer Sequencer
// Runtime Runtime
// semaphore int32
// }
// tests := []struct {
// name string
// fields fields
// want bool
// }{
// {
// name: "is locked",
// fields: fields{
// Sequencer: &MockSuccessfulSequencer{},
// semaphore: 0,
// },
// want: false,
// },
// {
// name: "is unlocked",
// fields: fields{
// Sequencer: &MockSuccessfulSequencer{},
// semaphore: 1,
// },
// want: true,
// },
// }
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// c := &Controller{
// Sequencer: tt.fields.Sequencer,
// Runtime: tt.fields.Runtime,
// semaphore: tt.fields.semaphore,
// }
// if got := c.TryLock(); got != tt.want {
// t.Errorf("Controller.TryLock() = %v, want %v", got, tt.want)
// }
// })
// }
// }
// func TestController_Unlock(t *testing.T) {
// type fields struct {
// Sequencer Sequencer
// Runtime Runtime
// semaphore int32
// }
// tests := []struct {
// name string
// fields fields
// want bool
// }{
// {
// name: "did not unlock",
// fields: fields{
// semaphore: 0,
// },
// want: false,
// },
// {
// name: "did unlock",
// fields: fields{
// semaphore: 1,
// },
// want: true,
// },
// }
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// c := &Controller{
// Sequencer: tt.fields.Sequencer,
// Runtime: tt.fields.Runtime,
// semaphore: tt.fields.semaphore,
// }
// if got := c.Unlock(); got != tt.want {
// t.Errorf("Controller.Unlock() = %v, want %v", got, tt.want)
// }
// })
// }
// }
// import (
// "errors"
// "os"
// "testing"
// "github.com/stretchr/testify/suite"
// "github.com/talos-systems/talos/internal/app/machined/pkg/runtime"
// "github.com/talos-systems/talos/internal/app/machined/pkg/runtime/v1alpha1/phase"
// )
// type PhaseSuite struct {
// suite.Suite
// platformExists bool
// platformValue string
// }
// type regularTask struct {
// errCh <-chan error
// }
// func (t *regularTask) TaskFunc(runtime.Mode) TaskFunc {
// return func(runtime.Runtime) error {
// return <-t.errCh
// }
// }
// type nilTask struct{}
// func (t *nilTask) TaskFunc(runtime.Mode) TaskFunc {
// return nil
// }
// type panicTask struct{}
// func (t *panicTask) TaskFunc(runtime.Mode) TaskFunc {
// return func(runtime.Runtime) error {
// panic("in task")
// }
// }
// func (suite *PhaseSuite) SetupSuite() {
// suite.platformValue, suite.platformExists = os.LookupEnv("PLATFORM")
// suite.Require().NoError(os.Setenv("PLATFORM", "container"))
// }
// func (suite *PhaseSuite) TearDownSuite() {
// if !suite.platformExists {
// suite.Require().NoError(os.Unsetenv("PLATFORM"))
// } else {
// suite.Require().NoError(os.Setenv("PLATFORM", suite.platformValue))
// }
// }
// func (suite *PhaseSuite) TestRunSuccess() {
// r, err := phase.NewRunner(nil, runtime.Noop)
// suite.Require().NoError(err)
// taskErr := make(chan error)
// r.Add(phase.NewPhase("empty"))
// r.Add(phase.NewPhase("phase1", &regularTask{errCh: taskErr}, &regularTask{errCh: taskErr}))
// r.Add(phase.NewPhase("phase2", &regularTask{errCh: taskErr}, &nilTask{}))
// errCh := make(chan error)
// go func() {
// errCh <- r.Run()
// }()
// taskErr <- nil
// taskErr <- nil
// select {
// case <-errCh:
// suite.Require().Fail("should be still running")
// default:
// }
// taskErr <- nil
// suite.Require().NoError(<-errCh)
// }
// func (suite *PhaseSuite) TestRunFailures() {
// r, err := phase.NewRunner(nil, runtime.Noop)
// suite.Require().NoError(err)
// taskErr := make(chan error, 1)
// r.Add(phase.NewPhase("empty"))
// r.Add(phase.NewPhase("failphase", &panicTask{}, &regularTask{errCh: taskErr}, &nilTask{}))
// r.Add(phase.NewPhase("neverreached",
// &regularTask{}, // should never be reached
// ))
// taskErr <- errors.New("test error")
// err = r.Run()
// suite.Require().Error(err)
// suite.Assert().Contains(err.Error(), "2 errors occurred")
// suite.Assert().Contains(err.Error(), "test error")
// suite.Assert().Contains(err.Error(), "panic recovered: in task")
// }
// func TestPhaseSuite(t *testing.T) {
// suite.Run(t, new(PhaseSuite))
// }

View File

@ -2,13 +2,6 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package cni_test
import "testing"
func TestEmpty(t *testing.T) {
// added for accurate coverage estimation
//
// please remove it once any unit-test is added
// for this package
}
// Package runtime defines interfaces for accessing runtime specific settings,
// and state.
package runtime

View File

@ -0,0 +1,23 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package runtime
import "errors"
var (
// ErrLocked indicates that the sequencer is currently locked, and processing
// another sequence.
ErrLocked = errors.New("locked")
// ErrReboot indicates that a task is requesting a reboot.
ErrReboot = errors.New("reboot")
// ErrInvalidSequenceData indicates that the sequencer got data the wrong
// data type for a sequence.
ErrInvalidSequenceData = errors.New("invalid sequence data")
// ErrUndefinedRuntime indicates that the sequencer's runtime is not defined.
ErrUndefinedRuntime = errors.New("undefined runtime")
)

View File

@ -0,0 +1,48 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package runtime
import (
"fmt"
)
// Mode is a runtime mode.
type Mode int
const (
// ModeCloud is the cloud runtime mode.
ModeCloud Mode = iota
// ModeContainer is the container runtime mode.
ModeContainer
// ModeMetal is the metal runtime mode.
ModeMetal
)
const (
cloud = "cloud"
container = "container"
metal = "metal"
)
// String returns the string representation of a Mode.
func (m Mode) String() string {
return [...]string{cloud, container, metal}[m]
}
// ParseMode returns a `Mode` that matches the specified string.
func ParseMode(s string) (mod Mode, err error) {
switch s {
case cloud:
mod = ModeCloud
case container:
mod = ModeContainer
case metal:
mod = ModeMetal
default:
return mod, fmt.Errorf("unknown runtime mode: %q", s)
}
return mod, nil
}

View File

@ -0,0 +1,94 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// nolint: dupl,scopelint
package runtime
import (
"reflect"
"testing"
)
func TestMode_String(t *testing.T) {
tests := []struct {
name string
m Mode
want string
}{
{
name: "cloud",
m: ModeCloud,
want: "cloud",
},
{
name: "container",
m: ModeContainer,
want: "container",
},
{
name: "metal",
m: ModeMetal,
want: "metal",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.m.String(); got != tt.want {
t.Errorf("Mode.String() = %v, want %v", got, tt.want)
}
})
}
}
func TestParseMode(t *testing.T) {
type args struct {
s string
}
tests := []struct {
name string
args args
wantM Mode
wantErr bool
}{
{
name: "cloud",
args: args{"cloud"},
wantM: ModeCloud,
wantErr: false,
},
{
name: "container",
args: args{"container"},
wantM: ModeContainer,
wantErr: false,
},
{
name: "metal",
args: args{"metal"},
wantM: ModeMetal,
wantErr: false,
},
{
name: "invalid",
args: args{"invalid"},
wantM: 0,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotM, err := ParseMode(tt.args.s)
if (err != nil) != tt.wantErr {
t.Errorf("ParseMode() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(gotM, tt.wantM) {
t.Errorf("ParseMode() = %v, want %v", gotM, tt.wantM)
}
})
}
}

View File

@ -10,7 +10,7 @@ import (
"github.com/talos-systems/go-procfs/procfs"
)
// Platform is an interface describing a platform.
// Platform defines the requirements for a platform.
type Platform interface {
Name() string
Configuration() ([]byte, error)

View File

@ -2,13 +2,11 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package api_test
package runtime
import "testing"
func TestEmpty(t *testing.T) {
// added for accurate coverage estimation
//
// please remove it once any unit-test is added
// for this package
// Runtime defines the runtime parameters.
type Runtime interface {
Config() Configurator
SetConfig([]byte) error
State() State
}

View File

@ -0,0 +1,87 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package runtime
import (
"fmt"
"github.com/talos-systems/talos/api/machine"
)
// Sequence represents a sequence type.
type Sequence int
const (
// SequenceBoot is the boot sequence.
SequenceBoot Sequence = iota
// SequenceInitialize is the initialize sequence.
SequenceInitialize
// SequenceInstall is the install sequence.
SequenceInstall
// SequenceShutdown is the shutdown sequence.
SequenceShutdown
// SequenceUpgrade is the upgrade sequence.
SequenceUpgrade
// SequenceReset is the reset sequence.
SequenceReset
// SequenceReboot is the reboot sequence.
SequenceReboot
// SequenceNoop is the noop sequence.
SequenceNoop
)
const (
boot = "boot"
initialize = "initialize"
install = "install"
shutdown = "shutdown"
upgrade = "upgrade"
reset = "reset"
reboot = "reboot"
noop = "noop"
)
// String returns the string representation of a `Sequence`.
func (s Sequence) String() string {
return [...]string{boot, initialize, install, shutdown, upgrade, reset, reboot, noop}[s]
}
// ParseSequence returns a `Sequence` that matches the specified string.
func ParseSequence(s string) (seq Sequence, err error) {
switch s {
case boot:
seq = SequenceBoot
case initialize:
seq = SequenceInitialize
case install:
seq = SequenceInstall
case shutdown:
seq = SequenceShutdown
case upgrade:
seq = SequenceUpgrade
case reset:
seq = SequenceReset
case reboot:
seq = SequenceReboot
case noop:
seq = SequenceNoop
default:
return seq, fmt.Errorf("unknown runtime sequence: %q", s)
}
return seq, nil
}
// Sequencer describes the set of sequences required for the lifecycle
// management of the operating system.
type Sequencer interface {
Boot(Runtime) []Phase
Initialize(Runtime) []Phase
Install(Runtime) []Phase
Reboot(Runtime) []Phase
Reset(Runtime, *machine.ResetRequest) []Phase
Shutdown(Runtime) []Phase
Upgrade(Runtime, *machine.UpgradeRequest) []Phase
}

View File

@ -0,0 +1,124 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// nolint: scopelint
package runtime
import "testing"
func TestSequence_String(t *testing.T) {
tests := []struct {
name string
s Sequence
want string
}{
{
name: "boot",
s: SequenceBoot,
want: "boot",
},
{
name: "initialize",
s: SequenceInitialize,
want: "initialize",
},
{
name: "shutdown",
s: SequenceShutdown,
want: "shutdown",
},
{
name: "upgrade",
s: SequenceUpgrade,
want: "upgrade",
},
{
name: "reboot",
s: SequenceReboot,
want: "reboot",
},
{
name: "reset",
s: SequenceReset,
want: "reset",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.s.String(); got != tt.want {
t.Errorf("Sequence.String() = %v, want %v", got, tt.want)
}
})
}
}
func TestParseSequence(t *testing.T) {
type args struct {
s string
}
tests := []struct {
name string
args args
wantSeq Sequence
wantErr bool
}{
{
name: "boot",
args: args{"boot"},
wantSeq: SequenceBoot,
wantErr: false,
},
{
name: "initialize",
args: args{"initialize"},
wantSeq: SequenceInitialize,
wantErr: false,
},
{
name: "shutdown",
args: args{"shutdown"},
wantSeq: SequenceShutdown,
wantErr: false,
},
{
name: "upgrade",
args: args{"upgrade"},
wantSeq: SequenceUpgrade,
wantErr: false,
},
{
name: "reboot",
args: args{"reboot"},
wantSeq: SequenceReboot,
wantErr: false,
},
{
name: "reset",
args: args{"reset"},
wantSeq: SequenceReset,
wantErr: false,
},
{
name: "invalid",
args: args{"invalid"},
wantSeq: 0,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotSeq, err := ParseSequence(tt.args.s)
if (err != nil) != tt.wantErr {
t.Errorf("ParseSequence() error = %v, wantErr %v", err, tt.wantErr)
return
}
if gotSeq != tt.wantSeq {
t.Errorf("ParseSequence() = %v, want %v", gotSeq, tt.wantSeq)
}
})
}
}

View File

@ -4,7 +4,9 @@
package runtime
import "errors"
// ErrReboot is raised to initiate early reboot sequence via panic.
var ErrReboot = errors.New("reboot")
// State defines the state.
type State interface {
Platform() Platform
Machine() MachineState
Cluster() ClusterState
}

View File

@ -14,52 +14,21 @@ import (
"github.com/hashicorp/go-multierror"
"github.com/mdlayher/genetlink"
"github.com/mdlayher/netlink"
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/pkg/event"
"github.com/talos-systems/talos/internal/pkg/runtime"
)
const (
// PowerButtonEvent is the ACPI event name associated with the power off
// button.
PowerButtonEvent = "button/power"
)
// Handler represents the ACPI handler task.
type Handler struct{}
// NewHandlerTask initializes and returns a ACPI handler task.
func NewHandlerTask() phase.Task {
return &Handler{}
}
// TaskFunc returns the runtime function.
func (task *Handler) TaskFunc(mode runtime.Mode) phase.TaskFunc {
switch mode {
case runtime.Container:
return nil
default:
return task.standard
}
}
func (task *Handler) standard(r runtime.Runtime) (err error) {
if err := listenForPowerButton(); err != nil {
log.Printf("WARNING: power off events will be ignored: %+v", err)
}
return nil
}
const (
// See https://github.com/torvalds/linux/blob/master/drivers/acpi/event.c
acpiGenlFamilyName = "acpi_event"
acpiGenlMcastGroupName = "acpi_mc_group"
)
// StartACPIListener starts listening for ACPI netlink events.
//
//nolint: gocyclo
func listenForPowerButton() (err error) {
func StartACPIListener() (err error) {
// Get the acpi_event family.
conn, err := genetlink.Dial(nil)
if err != nil {
@ -87,37 +56,30 @@ func listenForPowerButton() (err error) {
return err
}
go func() {
// nolint: errcheck
defer conn.Close()
// nolint: errcheck
defer conn.Close()
for {
msgs, _, err := conn.Receive()
if err != nil {
log.Printf("error reading from ACPI channel: %s", err)
return
}
if len(msgs) > 0 {
ok, err := parse(msgs, PowerButtonEvent)
if err != nil {
log.Printf("failed to parse netlink message: %v", err)
continue
}
if !ok {
continue
}
log.Printf("shutdown via ACPI received")
event.Bus().Notify(event.Event{Type: event.Shutdown})
return
}
for {
msgs, _, err := conn.Receive()
if err != nil {
return fmt.Errorf("error reading from ACPI channel: %w", err)
}
}()
return nil
if len(msgs) > 0 {
ok, err := parse(msgs, PowerButtonEvent)
if err != nil {
log.Printf("failed to parse netlink message: %v", err)
continue
}
if !ok {
continue
}
return nil
}
}
}
func parse(msgs []genetlink.Message, event string) (bool, error) {

Some files were not shown because too many files have changed in this diff Show More