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:
parent
794c7231f5
commit
0af1eba159
54
.drone.yml
54
.drone.yml
@ -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
|
||||
|
15
Makefile
15
Makefile
@ -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:
|
||||
|
@ -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 %}}
|
||||
|
@ -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):
|
||||
|
@ -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 %}}
|
||||
|
@ -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,
|
||||
|
@ -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=""
|
||||
|
@ -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
|
@ -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:
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
||||
|
38
internal/app/machined/internal/platform/gcp/gcp.go
Normal file
38
internal/app/machined/internal/platform/gcp/gcp.go
Normal 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
|
||||
}
|
@ -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"
|
||||
|
@ -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()
|
||||
}
|
@ -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
|
||||
}
|
||||
|
81
internal/app/machined/internal/platform/metal/metal.go
Normal file
81
internal/app/machined/internal/platform/metal/metal.go
Normal 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
|
||||
}
|
@ -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"
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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":
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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))
|
||||
}
|
@ -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
|
||||
}
|
@ -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]
|
||||
}
|
||||
|
@ -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")
|
||||
|
Loading…
x
Reference in New Issue
Block a user