refactor: add more runtime modes

In order to DRY up all installation methods and mount methods, this PR
introduces a few more runtime modes. The modes are then used to
determine the strategy for creating and or mounting the paritions.

Signed-off-by: Andrew Rynhard <andrew@andrewrynhard.com>
This commit is contained in:
Andrew Rynhard 2019-08-11 21:38:24 +00:00
parent 794c7231f5
commit 0af1eba159
42 changed files with 539 additions and 482 deletions

View File

@ -744,10 +744,10 @@ steps:
depends_on:
- installer
- name: image-gce
- name: image-gcp
image: autonomy/build-container:latest
commands:
- make image-gce
- make image-gcp
environment:
BINDIR: /usr/local/bin
BUILDKIT_HOST: ${BUILDKIT_HOST=tcp://buildkitd.ci.svc:1234}
@ -784,10 +784,10 @@ steps:
depends_on:
- image-azure
- name: push-image-gce
- name: push-image-gcp
image: autonomy/build-container:latest
commands:
- make push-image-gce
- make push-image-gcp
environment:
AZURE_SVC_ACCT:
from_secret: azure_svc_acct
@ -805,7 +805,7 @@ steps:
- name: tmp
path: /tmp
depends_on:
- image-gce
- image-gcp
- name: e2e-integration-azure
image: autonomy/build-container:latest
@ -826,14 +826,14 @@ steps:
- capi
- push-image-azure
- name: e2e-integration-gce
- name: e2e-integration-gcp
image: autonomy/build-container:latest
commands:
- make e2e-integration
environment:
BINDIR: /usr/local/bin
BUILDKIT_HOST: ${BUILDKIT_HOST=tcp://buildkitd.ci.svc:1234}
PLATFORM: gce
PLATFORM: gcp
volumes:
- name: dockersock
path: /var/run
@ -843,7 +843,7 @@ steps:
path: /tmp
depends_on:
- capi
- push-image-gce
- push-image-gcp
services:
- name: docker
@ -1253,10 +1253,10 @@ steps:
depends_on:
- installer
- name: image-gce
- name: image-gcp
image: autonomy/build-container:latest
commands:
- make image-gce
- make image-gcp
environment:
BINDIR: /usr/local/bin
BUILDKIT_HOST: ${BUILDKIT_HOST=tcp://buildkitd.ci.svc:1234}
@ -1293,10 +1293,10 @@ steps:
depends_on:
- image-azure
- name: push-image-gce
- name: push-image-gcp
image: autonomy/build-container:latest
commands:
- make push-image-gce
- make push-image-gcp
environment:
AZURE_SVC_ACCT:
from_secret: azure_svc_acct
@ -1314,7 +1314,7 @@ steps:
- name: tmp
path: /tmp
depends_on:
- image-gce
- image-gcp
- name: conformance-azure
image: autonomy/build-container:latest
@ -1336,7 +1336,7 @@ steps:
- capi
- push-image-azure
- name: conformance-gce
- name: conformance-gcp
image: autonomy/build-container:latest
commands:
- make e2e-integration
@ -1344,7 +1344,7 @@ steps:
BINDIR: /usr/local/bin
BUILDKIT_HOST: ${BUILDKIT_HOST=tcp://buildkitd.ci.svc:1234}
CONFORMANCE: run
PLATFORM: gce
PLATFORM: gcp
volumes:
- name: dockersock
path: /var/run
@ -1354,7 +1354,7 @@ steps:
path: /tmp
depends_on:
- capi
- push-image-gce
- push-image-gcp
services:
- name: docker
@ -1764,10 +1764,10 @@ steps:
depends_on:
- installer
- name: image-gce
- name: image-gcp
image: autonomy/build-container:latest
commands:
- make image-gce
- make image-gcp
environment:
BINDIR: /usr/local/bin
BUILDKIT_HOST: ${BUILDKIT_HOST=tcp://buildkitd.ci.svc:1234}
@ -1804,10 +1804,10 @@ steps:
depends_on:
- image-azure
- name: push-image-gce
- name: push-image-gcp
image: autonomy/build-container:latest
commands:
- make push-image-gce
- make push-image-gcp
environment:
AZURE_SVC_ACCT:
from_secret: azure_svc_acct
@ -1825,7 +1825,7 @@ steps:
- name: tmp
path: /tmp
depends_on:
- image-gce
- image-gcp
- name: conformance-azure
image: autonomy/build-container:latest
@ -1847,7 +1847,7 @@ steps:
- capi
- push-image-azure
- name: conformance-gce
- name: conformance-gcp
image: autonomy/build-container:latest
commands:
- make e2e-integration
@ -1855,7 +1855,7 @@ steps:
BINDIR: /usr/local/bin
BUILDKIT_HOST: ${BUILDKIT_HOST=tcp://buildkitd.ci.svc:1234}
CONFORMANCE: run
PLATFORM: gce
PLATFORM: gcp
volumes:
- name: dockersock
path: /var/run
@ -1865,7 +1865,7 @@ steps:
path: /tmp
depends_on:
- capi
- push-image-gce
- push-image-gcp
services:
- name: docker
@ -2269,10 +2269,10 @@ steps:
depends_on:
- installer
- name: image-gce
- name: image-gcp
image: autonomy/build-container:latest
commands:
- make image-gce
- make image-gcp
environment:
BINDIR: /usr/local/bin
BUILDKIT_HOST: ${BUILDKIT_HOST=tcp://buildkitd.ci.svc:1234}
@ -2346,7 +2346,7 @@ steps:
depends_on:
- kernel
- iso
- image-gce
- image-gcp
- image-azure
- image-aws
- push

View File

@ -190,22 +190,21 @@ image-azure:
push-image-azure:
@TAG=$(TAG) ./hack/test/azure-setup.sh
.PHONY: image-gce
image-gce:
.PHONY: image-gcp
image-gcp:
@docker run --rm -v /dev:/dev -v $(PWD)/build:/out \
--privileged $(DOCKER_ARGS) \
autonomy/installer:$(TAG) \
install \
-n disk \
-r \
-p googlecloud \
-p gcp \
-u none
@tar -C $(PWD)/build -czf $(PWD)/build/gce.tar.gz disk.raw
@rm -rf $(PWD)/build/disk.raw
@tar -C $(PWD)/build -czf $(PWD)/build/gcp.tar.gz disk.raw
.PHONY: push-image-gce
push-image-gce:
@TAG=$(TAG) ./hack/test/gce-setup.sh
.PHONY: push-image-gcp
push-image-gcp:
@TAG=$(TAG) ./hack/test/gcp-setup.sh
.PHONY: image-test
image-test:

View File

@ -17,7 +17,7 @@ docker run \
--privileged \
--volume /dev:/dev \
talos-systems/talos:latest image -b /dev/sdb -f \
-p bare-metal -u http://${IP}:8080/master.yaml
-p metal -u http://${IP}:8080/master.yaml
```
{{% note %}}`http://${IP}:8080/master.yaml` should be reachable by the VM and contain a valid master configuration file.{{% /note %}}
@ -51,7 +51,7 @@ docker run \
--privileged \
--volume /dev:/dev \
talos-systems/talos:latest image -b /dev/sdc -f \
-p bare-metal -u http://${IP}:8080/worker.yaml
-p metal -u http://${IP}:8080/worker.yaml
```
{{% note %}}`http://${IP}:8080/worker.yaml` should be reachable by the VM and contain a valid worker configuration file.{{% /note %}}

View File

@ -31,7 +31,7 @@ An iPXE server such as [coreos/Matchbox](https://github.com/poseidon/matchbox) i
The following is the list of related kernel commandline parameters:
- `talos.userdata` (required) the HTTP(S) URL at which the machine data can be found
- `talos.platform` (required) should be 'bare-metal' for bare-metal installs
- `talos.platform` (required) should be 'metal' for bare-metal installs
Talos also enforces some minimum requirements from the KSPP (kernel self-protection project):

View File

@ -36,7 +36,7 @@ kernel = "/var/lib/xen/talos/vmlinuz"
ramdisk = "/var/lib/xen/talos/initramfs.xz"
disk = [ 'phy:/dev/sdb,xvda,w', ]
vif = [ 'mac=52:54:00:A8:4C:E1,bridge=xenbr0,model=e1000', ]
extra = "consoleblank=0 console=hvc0 console=tty0 console=ttyS0,9600 talos.platform=bare-metal talos.userdata=http://${IP}:8080/master.yaml"
extra = "consoleblank=0 console=hvc0 console=tty0 console=ttyS0,9600 talos.platform=metal talos.userdata=http://${IP}:8080/master.yaml"
```
{{% note %}}`http://${IP}:8080/master.yaml` should be reachable by the VM and contain a valid master configuration file.{{% /note %}}
@ -76,7 +76,7 @@ kernel = "/var/lib/xen/talos/vmlinuz"
ramdisk = "/var/lib/xen/talos/initramfs.xz"
disk = [ 'phy:/dev/sdc,xvda,w', ]
vif = [ 'mac=52:54:00:B9:5D:F2,bridge=xenbr0,model=e1000', ]
extra = "consoleblank=0 console=hvc0 console=tty0 console=ttyS0,9600 talos.platform=bare-metal talos.userdata=http://${IP}:8080/worker.yaml"
extra = "consoleblank=0 console=hvc0 console=tty0 console=ttyS0,9600 talos.platform=metal talos.userdata=http://${IP}:8080/worker.yaml"
```
{{% note %}}`http://${IP}:8080/worker.yaml` should be reachable by the VM and contain a valid worker configuration file.{{% /note %}}

View File

@ -229,26 +229,27 @@ local default_pipeline = Pipeline("default", default_steps) + default_trigger;
local creds_env_vars = {
AZURE_SVC_ACCT: {from_secret: "azure_svc_acct"},
// TODO(andrewrynhard): Rename this to the GCP convention.
GCE_SVC_ACCT: {from_secret: "gce_svc_acct"},
PACKET_AUTH_TOKEN: {from_secret: "packet_auth_token"},
};
local image_azure = Step("image-azure", depends_on=[installer]);
local image_gce = Step("image-gce", depends_on=[installer]);
local image_gcp = Step("image-gcp", depends_on=[installer]);
local capi = Step("capi", depends_on=[basic_integration], environment=creds_env_vars);
local push_image_azure = Step("push-image-azure", depends_on=[image_azure], environment=creds_env_vars);
local push_image_gce = Step("push-image-gce", depends_on=[image_gce], environment=creds_env_vars);
local push_image_gcp = Step("push-image-gcp", depends_on=[image_gcp], environment=creds_env_vars);
local e2e_integration_azure = Step("e2e-integration-azure", "e2e-integration", depends_on=[capi, push_image_azure], environment={PLATFORM: "azure"});
local e2e_integration_gce = Step("e2e-integration-gce", "e2e-integration", depends_on=[capi, push_image_gce], environment={PLATFORM: "gce"});
local e2e_integration_gcp = Step("e2e-integration-gcp", "e2e-integration", depends_on=[capi, push_image_gcp], environment={PLATFORM: "gcp"});
local e2e_steps = default_steps + [
capi,
image_azure,
image_gce,
image_gcp,
push_image_azure,
push_image_gce,
push_image_gcp,
e2e_integration_azure,
e2e_integration_gce,
e2e_integration_gcp,
];
local e2e_trigger = {
@ -264,16 +265,16 @@ local e2e_pipeline = Pipeline("e2e", e2e_steps) + e2e_trigger;
// Conformance pipeline.
local conformance_azure = Step("conformance-azure", "e2e-integration", depends_on=[capi, push_image_azure], environment={PLATFORM: "azure", CONFORMANCE: "run"});
local conformance_gce = Step("conformance-gce", "e2e-integration", depends_on=[capi, push_image_gce], environment={PLATFORM: "gce", CONFORMANCE: "run"});
local conformance_gcp = Step("conformance-gcp", "e2e-integration", depends_on=[capi, push_image_gcp], environment={PLATFORM: "gcp", CONFORMANCE: "run"});
local conformance_steps = default_steps + [
capi,
image_azure,
image_gce,
image_gcp,
push_image_azure,
push_image_gce,
push_image_gcp,
conformance_azure,
conformance_gce,
conformance_gcp,
];
local conformance_trigger = {
@ -330,13 +331,13 @@ local release ={
when: {
event: ["tag"],
},
depends_on: [kernel.name, iso.name, image_gce.name, image_azure.name, image_aws.name, push.name]
depends_on: [kernel.name, iso.name, image_gcp.name, image_azure.name, image_aws.name, push.name]
};
local release_steps = default_steps + [
kernel,
image_azure,
image_gce,
image_gcp,
image_aws,
iso,
release,

View File

@ -68,7 +68,7 @@ function usage() {
TALOS_RAW="/out/talos.raw"
TALOS_ISO="/out/talos.iso"
TALOS_VMDK="/out/talos.vmdk"
TALOS_PLATFORM="bare-metal"
TALOS_PLATFORM="metal"
TALOS_USERDATA="none"
WITH_BOOTLOADER="true"
EXTRA_ARGS=""

View File

@ -10,9 +10,9 @@ tar -xf /tmp/google-cloud-sdk.tar.gz -C /tmp
/tmp/google-cloud-sdk/install.sh --disable-installation-options --quiet
/tmp/google-cloud-sdk/bin/gcloud auth activate-service-account --key-file /tmp/svc-acct.json
## Push talos-gce to storage bucket
/tmp/google-cloud-sdk/bin/gsutil cp ./build/gce.tar.gz gs://talos-e2e/gce-${TAG}.tar.gz
## Push talos-gcp to storage bucket
/tmp/google-cloud-sdk/bin/gsutil cp ./build/gcp.tar.gz gs://talos-e2e/gcp-${TAG}.tar.gz
## Create image from talos-gce
## Create image from talos-gcp
/tmp/google-cloud-sdk/bin/gcloud --quiet --project talos-testbed compute images delete talos-e2e-${TAG} || true ##Ignore error if image doesn't exist
/tmp/google-cloud-sdk/bin/gcloud --quiet --project talos-testbed compute images create talos-e2e-${TAG} --source-uri gs://talos-e2e/gce-${TAG}.tar.gz
/tmp/google-cloud-sdk/bin/gcloud --quiet --project talos-testbed compute images create talos-e2e-${TAG} --source-uri gs://talos-e2e/gcp-${TAG}.tar.gz

View File

@ -2,7 +2,7 @@ apiVersion: cluster.k8s.io/v1alpha1
kind: Cluster
metadata:
annotations: null
name: talos-e2e-{{TAG}}-gce
name: talos-e2e-{{TAG}}-gcp
spec:
clusterNetwork:
pods:
@ -28,9 +28,9 @@ apiVersion: cluster.k8s.io/v1alpha1
kind: Machine
metadata:
labels:
cluster.k8s.io/cluster-name: talos-e2e-{{TAG}}-gce
cluster.k8s.io/cluster-name: talos-e2e-{{TAG}}-gcp
set: master
name: talos-e2e-{{TAG}}-gce-master-0
name: talos-e2e-{{TAG}}-gcp-master-0
spec:
providerSpec:
value:
@ -51,9 +51,9 @@ apiVersion: cluster.k8s.io/v1alpha1
kind: Machine
metadata:
labels:
cluster.k8s.io/cluster-name: talos-e2e-{{TAG}}-gce
cluster.k8s.io/cluster-name: talos-e2e-{{TAG}}-gcp
set: master
name: talos-e2e-{{TAG}}-gce-master-1
name: talos-e2e-{{TAG}}-gcp-master-1
spec:
providerSpec:
value:
@ -74,9 +74,9 @@ apiVersion: cluster.k8s.io/v1alpha1
kind: Machine
metadata:
labels:
cluster.k8s.io/cluster-name: talos-e2e-{{TAG}}-gce
cluster.k8s.io/cluster-name: talos-e2e-{{TAG}}-gcp
set: master
name: talos-e2e-{{TAG}}-gce-master-2
name: talos-e2e-{{TAG}}-gcp-master-2
spec:
providerSpec:
value:
@ -97,19 +97,19 @@ apiVersion: cluster.k8s.io/v1alpha1
kind: MachineDeployment
metadata:
labels:
cluster.k8s.io/cluster-name: talos-e2e-{{TAG}}-gce
cluster.k8s.io/cluster-name: talos-e2e-{{TAG}}-gcp
set: worker
name: talos-e2e-{{TAG}}-gce-workers
name: talos-e2e-{{TAG}}-gcp-workers
spec:
replicas: 3
selector:
matchLabels:
cluster.k8s.io/cluster-name: talos-e2e-{{TAG}}-gce
cluster.k8s.io/cluster-name: talos-e2e-{{TAG}}-gcp
set: worker
template:
metadata:
labels:
cluster.k8s.io/cluster-name: talos-e2e-{{TAG}}-gce
cluster.k8s.io/cluster-name: talos-e2e-{{TAG}}-gcp
set: worker
spec:
providerSpec:

View File

@ -29,10 +29,10 @@ func NewHandlerTask() phase.Task {
// RuntimeFunc returns the runtime function.
func (task *Handler) RuntimeFunc(mode runtime.Mode) phase.RuntimeFunc {
switch mode {
case runtime.Standard:
return task.standard
default:
case runtime.Container:
return nil
default:
return task.standard
}
}

View File

@ -26,10 +26,10 @@ func NewUserDefinedNetworkTask() phase.Task {
// RuntimeFunc returns the runtime function.
func (task *UserDefinedNetwork) RuntimeFunc(mode runtime.Mode) phase.RuntimeFunc {
switch mode {
case runtime.Standard:
return task.runtime
default:
case runtime.Container:
return nil
default:
return task.runtime
}
}

View File

@ -12,7 +12,6 @@ import (
"github.com/hashicorp/go-multierror"
"github.com/pkg/errors"
"github.com/talos-systems/talos/internal/app/machined/internal/platform"
"github.com/talos-systems/talos/internal/app/machined/internal/platform/container"
"github.com/talos-systems/talos/internal/app/machined/internal/runtime"
"github.com/talos-systems/talos/internal/pkg/kmsg"
"github.com/talos-systems/talos/pkg/userdata"
@ -33,11 +32,11 @@ func NewRunner(data *userdata.UserData) (*Runner, error) {
return nil, err
}
mode := runtime.Standard
switch platform.(type) {
case *container.Container:
mode = runtime.Container
default:
mode := platform.Mode()
switch mode {
case runtime.Metal:
fallthrough
case runtime.Cloud:
// Setup logging to /dev/kmsg.
if _, err = kmsg.Setup("[talos]"); err != nil {
return nil, errors.Errorf("failed to setup logging to /dev/kmsg: %v", err)

View File

@ -8,6 +8,7 @@ import (
"github.com/talos-systems/talos/internal/app/machined/internal/phase"
"github.com/talos-systems/talos/internal/app/machined/internal/platform"
"github.com/talos-systems/talos/internal/app/machined/internal/runtime"
"github.com/talos-systems/talos/internal/app/machined/internal/runtime/initializer"
"github.com/talos-systems/talos/pkg/userdata"
)
@ -25,9 +26,29 @@ func (task *Platform) RuntimeFunc(mode runtime.Mode) phase.RuntimeFunc {
}
func (task *Platform) runtime(platform platform.Platform, data *userdata.UserData) (err error) {
if err = platform.Initialize(data); err != nil {
i, err := initializer.New(platform.Mode())
if err != nil {
return err
}
if err = i.Initialize(platform, data); err != nil {
return err
}
if data.Networking == nil {
data.Networking = &userdata.Networking{}
}
if data.Networking.OS == nil {
data.Networking.OS = &userdata.OSNet{}
}
b, err := platform.Hostname()
if err != nil {
return err
}
if b != nil {
data.Networking.OS.Hostname = string(b)
}
return nil
}

View File

@ -26,10 +26,10 @@ func NewCheckInstallTask() phase.Task {
// RuntimeFunc returns the runtime function.
func (task *CheckInstall) RuntimeFunc(mode runtime.Mode) phase.RuntimeFunc {
switch mode {
case runtime.Standard:
return task.standard
default:
case runtime.Container:
return nil
default:
return task.standard
}
}

View File

@ -25,10 +25,10 @@ func NewMountBPFFSTask() phase.Task {
// RuntimeFunc returns the runtime function.
func (task *MountBPFFS) RuntimeFunc(mode runtime.Mode) phase.RuntimeFunc {
switch mode {
case runtime.Standard:
return task.runtime
default:
case runtime.Container:
return nil
default:
return task.runtime
}
}

View File

@ -41,10 +41,10 @@ func NewMountCgroupsTask() phase.Task {
// RuntimeFunc returns the runtime function.
func (task *MountCgroups) RuntimeFunc(mode runtime.Mode) phase.RuntimeFunc {
switch mode {
case runtime.Standard:
return task.runtime
default:
case runtime.Container:
return nil
default:
return task.runtime
}
}

View File

@ -36,12 +36,10 @@ func NewMountOverlayTask() phase.Task {
// RuntimeFunc returns the runtime function.
func (task *MountOverlay) RuntimeFunc(mode runtime.Mode) phase.RuntimeFunc {
switch mode {
case runtime.Standard:
return task.standard
case runtime.Container:
return task.container
default:
return nil
return task.standard
}
}

View File

@ -27,10 +27,10 @@ func NewMountSubDevicesTask() phase.Task {
// RuntimeFunc returns the runtime function.
func (task *MountSubDevices) RuntimeFunc(mode runtime.Mode) phase.RuntimeFunc {
switch mode {
case runtime.Standard:
return task.runtime
default:
case runtime.Container:
return nil
default:
return task.runtime
}
}

View File

@ -23,10 +23,10 @@ func NewNetworkConfigurationTask() phase.Task {
// RuntimeFunc returns the runtime function.
func (task *NetworkConfiguration) RuntimeFunc(mode runtime.Mode) phase.RuntimeFunc {
switch mode {
case runtime.Standard:
return task.runtime
default:
case runtime.Container:
return nil
default:
return task.runtime
}
}

View File

@ -23,10 +23,10 @@ func NewSecurityTask() phase.Task {
// RuntimeFunc returns the runtime function.
func (task *Security) RuntimeFunc(mode runtime.Mode) phase.RuntimeFunc {
switch mode {
case runtime.Standard:
return task.runtime
default:
case runtime.Container:
return nil
default:
return task.runtime
}
}

View File

@ -25,12 +25,10 @@ func NewUserDataTask() phase.Task {
// RuntimeFunc returns the runtime function.
func (task *UserData) RuntimeFunc(mode runtime.Mode) phase.RuntimeFunc {
switch mode {
case runtime.Standard:
return task.standard
case runtime.Container:
return task.container
default:
return nil
return task.standard
}
}

View File

@ -13,9 +13,7 @@ import (
"net/http"
"github.com/fullsailor/pkcs7"
"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/app/machined/internal/runtime"
"github.com/talos-systems/talos/pkg/userdata"
)
@ -123,40 +121,13 @@ func (a *AWS) UserData() (*userdata.UserData, error) {
return userdata.Download(AWSUserDataEndpoint)
}
// Initialize implements the platform.Platform interface and handles additional system setup.
// nolint: dupl
func (a *AWS) Initialize(data *userdata.UserData) (err error) {
var mountpoints *mount.Points
mountpoints, err = owned.MountPointsFromLabels()
if err != nil {
return err
}
m := manager.NewManager(mountpoints)
if err = m.MountAll(); err != nil {
return err
}
hostnameBytes, err := hostname()
if err != nil {
return err
}
// Stub out networking
if data.Networking == nil {
data.Networking = &userdata.Networking{}
}
if data.Networking.OS == nil {
data.Networking.OS = &userdata.OSNet{}
}
data.Networking.OS.Hostname = string(hostnameBytes)
return err
// Mode implements the platform.Platform interface.
func (a *AWS) Mode() runtime.Mode {
return runtime.Cloud
}
func hostname() (hostname []byte, err error) {
// Hostname gets the hostname from the AWS metadata endpoint.
func (a *AWS) Hostname() (hostname []byte, err error) {
resp, err := http.Get(AWSHostnameEndpoint)
if err != nil {
return

View File

@ -9,9 +9,7 @@ import (
"io/ioutil"
"net/http"
"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/app/machined/internal/runtime"
"github.com/talos-systems/talos/pkg/userdata"
)
@ -44,39 +42,13 @@ func (a *Azure) UserData() (*userdata.UserData, error) {
return userdata.Download(AzureUserDataEndpoint, userdata.WithHeaders(map[string]string{"Metadata": "true"}), userdata.WithFormat("base64"))
}
// Initialize implements the platform.Platform interface and handles additional system setup.
// nolint: dupl
func (a *Azure) Initialize(data *userdata.UserData) (err error) {
var mountpoints *mount.Points
mountpoints, err = owned.MountPointsFromLabels()
if err != nil {
return err
}
m := manager.NewManager(mountpoints)
if err = m.MountAll(); err != nil {
return err
}
hostnameBytes, err := hostname()
if err != nil {
return err
}
// Stub out networking
if data.Networking == nil {
data.Networking = &userdata.Networking{}
}
if data.Networking.OS == nil {
data.Networking.OS = &userdata.OSNet{}
}
data.Networking.OS.Hostname = string(hostnameBytes)
return err
// Mode implements the platform.Platform interface.
func (a *Azure) Mode() runtime.Mode {
return runtime.Cloud
}
func hostname() (hostname []byte, err error) {
// Hostname gets the hostname from the Azure metadata endpoint.
func (a *Azure) Hostname() (hostname []byte, err error) {
var req *http.Request
var resp *http.Response

View File

@ -1,122 +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 baremetal
import (
"io/ioutil"
"os"
"path"
"path/filepath"
"github.com/pkg/errors"
"github.com/talos-systems/talos/internal/pkg/installer"
"github.com/talos-systems/talos/internal/pkg/kernel"
"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/pkg/blockdevice/probe"
"github.com/talos-systems/talos/pkg/constants"
"github.com/talos-systems/talos/pkg/userdata"
"golang.org/x/sys/unix"
yaml "gopkg.in/yaml.v2"
)
const (
mnt = "/mnt"
)
// BareMetal is a discoverer for non-cloud environments.
type BareMetal struct{}
// Name implements the platform.Platform interface.
func (b *BareMetal) Name() string {
return "Bare Metal"
}
// UserData implements the platform.Platform interface.
func (b *BareMetal) UserData() (data *userdata.UserData, err error) {
var option *string
if option = kernel.ProcCmdline().Get(constants.KernelParamUserData).First(); option == nil {
return data, errors.Errorf("no user data option was found")
}
if *option == constants.UserDataCIData {
var dev *probe.ProbedBlockDevice
dev, err = probe.GetDevWithFileSystemLabel(constants.UserDataCIData)
if err != nil {
return data, errors.Errorf("failed to find %s iso: %v", constants.UserDataCIData, err)
}
if err = os.Mkdir(mnt, 0700); err != nil {
return data, errors.Errorf("failed to mkdir: %v", err)
}
if err = unix.Mount(dev.Path, mnt, dev.SuperBlock.Type(), unix.MS_RDONLY, ""); err != nil {
return data, errors.Errorf("failed to mount iso: %v", err)
}
var dataBytes []byte
dataBytes, err = ioutil.ReadFile(path.Join(mnt, "user-data"))
if err != nil {
return data, errors.Errorf("read user data: %s", err.Error())
}
if err = unix.Unmount(mnt, 0); err != nil {
return data, errors.Errorf("failed to unmount: %v", err)
}
if err = yaml.Unmarshal(dataBytes, &data); err != nil {
return data, errors.Errorf("unmarshal user data: %s", err.Error())
}
return data, nil
}
return userdata.Download(*option)
}
// Initialize provides the functionality to install talos by downloading the
// required artifacts and writing them to a target device.
// nolint: dupl
func (b *BareMetal) Initialize(data *userdata.UserData) (err error) {
var endpoint *string
if endpoint = kernel.ProcCmdline().Get(constants.KernelParamUserData).First(); endpoint == nil {
return errors.Errorf("failed to find %s in kernel parameters", constants.KernelParamUserData)
}
cmdline := kernel.NewDefaultCmdline()
cmdline.Append("initrd", filepath.Join("/", "default", "initramfs.xz"))
cmdline.Append(constants.KernelParamPlatform, "bare-metal")
cmdline.Append(constants.KernelParamUserData, *endpoint)
if err = cmdline.AppendAll(data.Install.ExtraKernelArgs); err != nil {
return err
}
// Attempt to discover a previous installation
// An err case should only happen if no partitions
// with matching labels were found
var mountpoints *mount.Points
mountpoints, err = owned.MountPointsFromLabels()
if err != nil {
// No previous installation was found, attempt an install
var i *installer.Installer
i, err = installer.NewInstaller(cmdline, data)
if err != nil {
return err
}
if err = i.Install(); err != nil {
return errors.Wrap(err, "failed to install")
}
mountpoints, err = owned.MountPointsFromLabels()
if err != nil {
return err
}
}
m := manager.NewManager(mountpoints)
if err = m.MountAll(); err != nil {
return err
}
return nil
}

View File

@ -9,6 +9,7 @@ import (
"os"
"github.com/pkg/errors"
"github.com/talos-systems/talos/internal/app/machined/internal/runtime"
"github.com/talos-systems/talos/pkg/userdata"
"gopkg.in/yaml.v2"
@ -40,7 +41,12 @@ func (c *Container) UserData() (data *userdata.UserData, err error) {
return data, nil
}
// Initialize implements the platform.Platform interface.
func (c *Container) Initialize(data *userdata.UserData) error {
return nil
// Mode implements the platform.Platform interface.
func (c *Container) Mode() runtime.Mode {
return runtime.Container
}
// Hostname implements the platform.Platform interface.
func (c *Container) Hostname() (hostname []byte, err error) {
return nil, nil
}

View File

@ -0,0 +1,38 @@
/* 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 gcp
import (
"github.com/talos-systems/talos/internal/app/machined/internal/runtime"
"github.com/talos-systems/talos/pkg/userdata"
)
const (
// GCUserDataEndpoint is the local metadata endpoint inside of DO
GCUserDataEndpoint = "http://metadata.google.internal/computeMetadata/v1/instance/attributes/user-data"
)
// GCP is the concrete type that implements the platform.Platform interface.
type GCP struct{}
// Name implements the platform.Platform interface.
func (gc *GCP) Name() string {
return "GCP"
}
// UserData implements the platform.Platform interface.
func (gc *GCP) UserData() (data *userdata.UserData, err error) {
return userdata.Download(GCUserDataEndpoint, userdata.WithHeaders(map[string]string{"Metadata-Flavor": "Google"}))
}
// Mode implements the platform.Platform interface.
func (gc *GCP) Mode() runtime.Mode {
return runtime.Cloud
}
// Hostname implements the platform.Platform interface.
func (gc *GCP) Hostname() (hostname []byte, err error) {
return nil, 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 baremetal_test
package gcp_test
import "testing"

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 googlecloud
import (
"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/pkg/userdata"
)
const (
// GCUserDataEndpoint is the local metadata endpoint inside of DO
GCUserDataEndpoint = "http://metadata.google.internal/computeMetadata/v1/instance/attributes/user-data"
)
// GoogleCloud is the concrete type that implements the platform.Platform interface.
type GoogleCloud struct{}
// Name implements the platform.Platform interface.
func (gc *GoogleCloud) Name() string {
return "GoogleCloud"
}
// UserData implements the platform.Platform interface.
func (gc *GoogleCloud) UserData() (data *userdata.UserData, err error) {
return userdata.Download(GCUserDataEndpoint, userdata.WithHeaders(map[string]string{"Metadata-Flavor": "Google"}))
}
// Initialize implements the platform.Platform interface and handles additional system setup.
func (gc *GoogleCloud) Initialize(data *userdata.UserData) (err error) {
var mountpoints *mount.Points
mountpoints, err = owned.MountPointsFromLabels()
if err != nil {
return err
}
m := manager.NewManager(mountpoints)
return m.MountAll()
}

View File

@ -5,20 +5,9 @@
package iso
import (
"bufio"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/pkg/errors"
"github.com/talos-systems/talos/internal/pkg/installer"
"github.com/talos-systems/talos/internal/pkg/kernel"
"github.com/talos-systems/talos/pkg/blockdevice/probe"
"github.com/talos-systems/talos/pkg/constants"
"github.com/talos-systems/talos/internal/app/machined/internal/runtime"
"github.com/talos-systems/talos/pkg/crypto/x509"
"github.com/talos-systems/talos/pkg/userdata"
"golang.org/x/sys/unix"
)
// ISO is a platform for installing Talos via an ISO image.
@ -61,51 +50,12 @@ func (i *ISO) UserData() (data *userdata.UserData, err error) {
return data, nil
}
// Initialize implements the platform.Platform interface.
func (i *ISO) Initialize(data *userdata.UserData) (err error) {
var dev *probe.ProbedBlockDevice
dev, err = probe.GetDevWithFileSystemLabel(constants.ISOFilesystemLabel)
if err != nil {
return errors.Errorf("failed to find %s iso: %v", constants.ISOFilesystemLabel, err)
}
if err = unix.Mount(dev.Path, "/tmp", dev.SuperBlock.Type(), unix.MS_RDONLY, ""); err != nil {
return err
}
for _, f := range []string{"/tmp/usr/install/vmlinuz", "/tmp/usr/install/initramfs.xz"} {
var source []byte
source, err = ioutil.ReadFile(f)
if err != nil {
return err
}
if err = ioutil.WriteFile("/"+filepath.Base(f), source, 0644); err != nil {
return err
}
}
reader := bufio.NewReader(os.Stdin)
fmt.Print("Talos configuration URL: ")
endpoint, err := reader.ReadString('\n')
if err != nil {
return err
}
cmdline := kernel.NewDefaultCmdline()
cmdline.Append("initrd", filepath.Join("/", "default", "initramfs.xz"))
cmdline.Append(constants.KernelParamPlatform, "bare-metal")
cmdline.Append(constants.KernelParamUserData, endpoint)
inst, err := installer.NewInstaller(cmdline, data)
if err != nil {
return err
}
if err = inst.Install(); err != nil {
return errors.Wrap(err, "failed to install")
}
// nolint: errcheck
unix.Reboot(int(unix.LINUX_REBOOT_CMD_RESTART))
return nil
// Mode implements the platform.Platform interface.
func (i *ISO) Mode() runtime.Mode {
return runtime.Interactive
}
// Hostname implements the platform.Platform interface.
func (i *ISO) Hostname() (hostname []byte, err error) {
return nil, nil
}

View File

@ -0,0 +1,81 @@
/* 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 metal
import (
"io/ioutil"
"os"
"path"
"github.com/pkg/errors"
"github.com/talos-systems/talos/internal/app/machined/internal/runtime"
"github.com/talos-systems/talos/internal/pkg/kernel"
"github.com/talos-systems/talos/pkg/blockdevice/probe"
"github.com/talos-systems/talos/pkg/constants"
"github.com/talos-systems/talos/pkg/userdata"
"golang.org/x/sys/unix"
yaml "gopkg.in/yaml.v2"
)
const (
mnt = "/mnt"
)
// Metal is a discoverer for non-cloud environments.
type Metal struct{}
// Name implements the platform.Platform interface.
func (b *Metal) Name() string {
return "Bare Metal"
}
// UserData implements the platform.Platform interface.
func (b *Metal) UserData() (data *userdata.UserData, err error) {
var option *string
if option = kernel.ProcCmdline().Get(constants.KernelParamUserData).First(); option == nil {
return data, errors.Errorf("no user data option was found")
}
if *option == constants.UserDataCIData {
var dev *probe.ProbedBlockDevice
dev, err = probe.GetDevWithFileSystemLabel(constants.UserDataCIData)
if err != nil {
return data, errors.Errorf("failed to find %s iso: %v", constants.UserDataCIData, err)
}
if err = os.Mkdir(mnt, 0700); err != nil {
return data, errors.Errorf("failed to mkdir: %v", err)
}
if err = unix.Mount(dev.Path, mnt, dev.SuperBlock.Type(), unix.MS_RDONLY, ""); err != nil {
return data, errors.Errorf("failed to mount iso: %v", err)
}
var dataBytes []byte
dataBytes, err = ioutil.ReadFile(path.Join(mnt, "user-data"))
if err != nil {
return data, errors.Errorf("read user data: %s", err.Error())
}
if err = unix.Unmount(mnt, 0); err != nil {
return data, errors.Errorf("failed to unmount: %v", err)
}
if err = yaml.Unmarshal(dataBytes, &data); err != nil {
return data, errors.Errorf("unmarshal user data: %s", err.Error())
}
return data, nil
}
return userdata.Download(*option)
}
// Mode implements the platform.Platform interface.
func (b *Metal) Mode() runtime.Mode {
return runtime.Metal
}
// Hostname implements the platform.Platform interface.
func (b *Metal) Hostname() (hostname []byte, err error) {
return nil, 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 googlecloud_test
package metal_test
import "testing"

View File

@ -5,15 +5,7 @@
package packet
import (
"path/filepath"
"github.com/pkg/errors"
"github.com/talos-systems/talos/internal/pkg/installer"
"github.com/talos-systems/talos/internal/pkg/kernel"
"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/pkg/constants"
"github.com/talos-systems/talos/internal/app/machined/internal/runtime"
"github.com/talos-systems/talos/pkg/userdata"
)
@ -35,49 +27,12 @@ func (p *Packet) UserData() (data *userdata.UserData, err error) {
return userdata.Download(PacketUserDataEndpoint)
}
// Initialize implements the platform.Platform interface.
// nolint: dupl
func (p *Packet) Initialize(data *userdata.UserData) (err error) {
var endpoint *string
if endpoint = kernel.ProcCmdline().Get(constants.KernelParamUserData).First(); endpoint == nil {
return errors.Errorf("failed to find %s in kernel parameters", constants.KernelParamUserData)
}
cmdline := kernel.NewDefaultCmdline()
cmdline.Append("initrd", filepath.Join("/", "default", "initramfs.xz"))
cmdline.Append(constants.KernelParamPlatform, "packet")
cmdline.Append(constants.KernelParamUserData, *endpoint)
if err = cmdline.AppendAll(data.Install.ExtraKernelArgs); err != nil {
return err
}
// Attempt to discover a previous installation
// An err case should only happen if no partitions
// with matching labels were found
var mountpoints *mount.Points
mountpoints, err = owned.MountPointsFromLabels()
if err != nil {
// No previous installation was found, attempt an install
var i *installer.Installer
i, err = installer.NewInstaller(cmdline, data)
if err != nil {
return err
}
if err = i.Install(); err != nil {
return errors.Wrap(err, "failed to install")
}
mountpoints, err = owned.MountPointsFromLabels()
if err != nil {
return err
}
}
m := manager.NewManager(mountpoints)
if err = m.MountAll(); err != nil {
return err
}
return nil
// Mode implements the platform.Platform interface.
func (p *Packet) Mode() runtime.Mode {
return runtime.Metal
}
// Hostname implements the platform.Platform interface.
func (p *Packet) Hostname() (hostname []byte, err error) {
return nil, nil
}

View File

@ -10,12 +10,13 @@ import (
"github.com/pkg/errors"
"github.com/talos-systems/talos/internal/app/machined/internal/platform/aws"
"github.com/talos-systems/talos/internal/app/machined/internal/platform/azure"
"github.com/talos-systems/talos/internal/app/machined/internal/platform/baremetal"
"github.com/talos-systems/talos/internal/app/machined/internal/platform/container"
"github.com/talos-systems/talos/internal/app/machined/internal/platform/googlecloud"
"github.com/talos-systems/talos/internal/app/machined/internal/platform/gcp"
"github.com/talos-systems/talos/internal/app/machined/internal/platform/iso"
"github.com/talos-systems/talos/internal/app/machined/internal/platform/metal"
"github.com/talos-systems/talos/internal/app/machined/internal/platform/packet"
"github.com/talos-systems/talos/internal/app/machined/internal/platform/vmware"
"github.com/talos-systems/talos/internal/app/machined/internal/runtime"
"github.com/talos-systems/talos/internal/pkg/kernel"
"github.com/talos-systems/talos/pkg/constants"
"github.com/talos-systems/talos/pkg/userdata"
@ -25,7 +26,8 @@ import (
type Platform interface {
Name() string
UserData() (*userdata.UserData, error)
Initialize(*userdata.UserData) error
Mode() runtime.Mode
Hostname() ([]byte, error)
}
// NewPlatform is a helper func for discovering the current platform.
@ -50,12 +52,12 @@ func NewPlatform() (p Platform, err error) {
p = &aws.AWS{}
case "azure":
p = &azure.Azure{}
case "bare-metal":
p = &baremetal.BareMetal{}
case "metal":
p = &metal.Metal{}
case "container":
p = &container.Container{}
case "googlecloud":
p = &googlecloud.GoogleCloud{}
case "gcp":
p = &gcp.GCP{}
case "iso":
p = &iso.ISO{}
case "packet":

View File

@ -8,10 +8,8 @@ import (
"encoding/base64"
"fmt"
"github.com/talos-systems/talos/internal/app/machined/internal/runtime"
"github.com/talos-systems/talos/internal/pkg/kernel"
"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/pkg/constants"
"github.com/talos-systems/talos/pkg/userdata"
"github.com/vmware/vmw-guestinfo/rpcvmx"
@ -68,15 +66,12 @@ func (vmw *VMware) UserData() (data *userdata.UserData, err error) {
return data, nil
}
// Initialize implements the platform.Platform interface and handles additional system setup.
func (vmw *VMware) Initialize(data *userdata.UserData) (err error) {
var mountpoints *mount.Points
mountpoints, err = owned.MountPointsFromLabels()
if err != nil {
return err
}
m := manager.NewManager(mountpoints)
return m.MountAll()
// Mode implements the platform.Platform interface.
func (vmw *VMware) Mode() runtime.Mode {
return runtime.Cloud
}
// Hostname implements the platform.Platform interface.
func (vmw *VMware) Hostname() (hostname []byte, err error) {
return nil, nil
}

View File

@ -0,0 +1,32 @@
/* 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 cloud
import (
"github.com/talos-systems/talos/internal/app/machined/internal/platform"
"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/pkg/userdata"
)
// Cloud is an initializer that mounts an existing installation.
type Cloud struct{}
// Initialize implements the Initializer interface.
func (c *Cloud) Initialize(platform platform.Platform, data *userdata.UserData) (err error) {
var mountpoints *mount.Points
mountpoints, err = owned.MountPointsFromLabels()
if err != nil {
return err
}
m := manager.NewManager(mountpoints)
if err = m.MountAll(); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,18 @@
/* 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 container
import (
"github.com/talos-systems/talos/internal/app/machined/internal/platform"
"github.com/talos-systems/talos/pkg/userdata"
)
// Container is an initializer that is a noop.
type Container struct{}
// Initialize implements the Initializer interface.
func (c *Container) Initialize(platform platform.Platform, data *userdata.UserData) (err error) {
return nil
}

View File

@ -0,0 +1,38 @@
/* 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 initializer
import (
"github.com/talos-systems/talos/internal/app/machined/internal/platform"
"github.com/talos-systems/talos/internal/app/machined/internal/runtime"
"github.com/talos-systems/talos/internal/app/machined/internal/runtime/initializer/cloud"
"github.com/talos-systems/talos/internal/app/machined/internal/runtime/initializer/container"
"github.com/talos-systems/talos/internal/app/machined/internal/runtime/initializer/interactive"
"github.com/talos-systems/talos/internal/app/machined/internal/runtime/initializer/metal"
"github.com/talos-systems/talos/pkg/userdata"
)
// Initializer defines a process for initializing the system based on the
// environment it is in.
type Initializer interface {
Initialize(platform.Platform, *userdata.UserData) error
}
// New initializes and returns and Initializer based on the runtime mode.
func New(mode runtime.Mode) (Initializer, error) {
switch mode {
case runtime.Interactive:
return &interactive.Interactive{}, nil
case runtime.Metal:
return &metal.Metal{}, nil
case runtime.Cloud:
return &cloud.Cloud{}, nil
case runtime.Container:
return &container.Container{}, nil
default:
}
return nil, nil
}

View File

@ -0,0 +1,74 @@
/* 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 interactive
import (
"bufio"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/pkg/errors"
"github.com/talos-systems/talos/internal/app/machined/internal/platform"
"github.com/talos-systems/talos/internal/pkg/installer"
"github.com/talos-systems/talos/internal/pkg/kernel"
"github.com/talos-systems/talos/pkg/blockdevice/probe"
"github.com/talos-systems/talos/pkg/constants"
"github.com/talos-systems/talos/pkg/userdata"
"golang.org/x/sys/unix"
)
// Interactive is an initializer that performs an installation by prompting the
// user.
type Interactive struct{}
// Initialize implements the Initializer interface.
func (i *Interactive) Initialize(platform platform.Platform, data *userdata.UserData) (err error) {
var dev *probe.ProbedBlockDevice
dev, err = probe.GetDevWithFileSystemLabel(constants.ISOFilesystemLabel)
if err != nil {
return errors.Errorf("failed to find %s iso: %v", constants.ISOFilesystemLabel, err)
}
if err = unix.Mount(dev.Path, "/tmp", dev.SuperBlock.Type(), unix.MS_RDONLY, ""); err != nil {
return err
}
for _, f := range []string{"/tmp/usr/install/vmlinuz", "/tmp/usr/install/initramfs.xz"} {
var source []byte
source, err = ioutil.ReadFile(f)
if err != nil {
return err
}
if err = ioutil.WriteFile("/"+filepath.Base(f), source, 0644); err != nil {
return err
}
}
reader := bufio.NewReader(os.Stdin)
fmt.Print("Talos configuration URL: ")
endpoint, err := reader.ReadString('\n')
if err != nil {
return err
}
cmdline := kernel.NewDefaultCmdline()
cmdline.Append("initrd", filepath.Join("/", "default", "initramfs.xz"))
cmdline.Append(constants.KernelParamPlatform, strings.ToLower(platform.Name()))
cmdline.Append(constants.KernelParamUserData, endpoint)
var inst *installer.Installer
inst, err = installer.NewInstaller(cmdline, data)
if err != nil {
return err
}
if err = inst.Install(); err != nil {
return errors.Wrap(err, "failed to install")
}
return unix.Reboot(int(unix.LINUX_REBOOT_CMD_RESTART))
}

View File

@ -0,0 +1,70 @@
/* 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 metal
import (
"path/filepath"
"strings"
"github.com/pkg/errors"
"github.com/talos-systems/talos/internal/app/machined/internal/platform"
"github.com/talos-systems/talos/internal/pkg/installer"
"github.com/talos-systems/talos/internal/pkg/kernel"
"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/pkg/constants"
"github.com/talos-systems/talos/pkg/userdata"
)
// Metal represents an initializer that performs a full installation to a
// disk.
type Metal struct{}
// Initialize implements the Initializer interface.
func (b *Metal) Initialize(platform platform.Platform, data *userdata.UserData) (err error) {
var endpoint *string
if endpoint = kernel.ProcCmdline().Get(constants.KernelParamUserData).First(); endpoint == nil {
return errors.Errorf("failed to find %s in kernel parameters", constants.KernelParamUserData)
}
cmdline := kernel.NewDefaultCmdline()
cmdline.Append("initrd", filepath.Join("/", "default", "initramfs.xz"))
cmdline.Append(constants.KernelParamPlatform, strings.ToLower(platform.Name()))
cmdline.Append(constants.KernelParamUserData, *endpoint)
if err = cmdline.AppendAll(data.Install.ExtraKernelArgs); err != nil {
return err
}
// Attempt to discover a previous installation
// An err case should only happen if no partitions
// with matching labels were found
var mountpoints *mount.Points
mountpoints, err = owned.MountPointsFromLabels()
if err != nil {
// No previous installation was found, attempt an install
var i *installer.Installer
i, err = installer.NewInstaller(cmdline, data)
if err != nil {
return err
}
if err = i.Install(); err != nil {
return errors.Wrap(err, "failed to install")
}
mountpoints, err = owned.MountPointsFromLabels()
if err != nil {
return err
}
}
m := manager.NewManager(mountpoints)
if err = m.MountAll(); err != nil {
return err
}
return nil
}

View File

@ -8,13 +8,17 @@ package runtime
type Mode int
const (
// Standard represents a runtime mode.
Standard Mode = iota
// Cloud represents a runtime mode.
Cloud Mode = iota
// Container represents a runtime mode.
Container
// Interactive represents a runtime mode.
Interactive
// Metal represents a runtime mode.
Metal
)
// String returns the string representation of a Mode.
func (m Mode) String() string {
return [...]string{"Standard", "Container"}[m]
return [...]string{"Cloud", "Container", "Interactive", "Metal"}[m]
}

View File

@ -32,7 +32,7 @@ func NewDefaultCmdline() *Cmdline {
// device will be used when you open /dev/console.
// AWS: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UserProvidedKernels.html
// VMWare: https://kb.vmware.com/s/article/2009269
// GCE: https://cloud.google.com/compute/docs/instances/interacting-with-serial-console
// GCP: https://cloud.google.com/compute/docs/instances/interacting-with-serial-console
// Azure: https://docs.microsoft.com/en-us/azure/virtual-machines/linux/create-upload-generic#general-linux-system-requirements
cmdline.Append("console", "tty0")
cmdline.Append("console", "tty1")