diff --git a/CHANGELOG.md b/CHANGELOG.md index adf0f42..9393de4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # CHANGELOG +## 2025-XX-XX - Tiny Cloud v3.2.0 + +* Initial support for `digitalocean` cloud provider + +* Alpine autoinstall - allow override disk and reboot and set swap (@ncopa) + + ## 2024-12-03 - Tiny Cloud v3.1.0 * Default to "/usr merge" friendly installation locations diff --git a/README.md b/README.md index c3c0b73..3ca948b 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ https://gitlab.alpinelinux.org/alpine/cloud/tiny-ec2-bootstrap), Tiny Cloud works with multiple cloud providers. Currently, the following are supported: * [AWS](https://aws.amazon.com) - Amazon Web Services * [Azure](https://azure.microsoft.com) - Microsoft Azure +* [DigitalOcean](https://digitalocean.com) - DigitalOcean * [GCP](https://cloud.google.com) - Google Cloud Platform * [Hetzner](https://www.hetzner.com) - Hetzner Cloud * [Incus](https://linuxcontainers.org/incus) - Incus Containers and Virtual Machines @@ -96,8 +97,8 @@ Tiny Cloud tries to autodetect (supported) clouds as of 3.1.0. The default value for `CLOUD` is `auto`. However, if you want to explicitly set a cloud provider, you can do so in the -conf file. Current valid values are `aws`, `azure`, `gcp`, `hetzner`, `incus`, -`nocloud`, `oci`, and `scaleway`. +conf file. Current valid values are `aws`, `azure`, `digitalocean`, `gcp`, +`hetzner`, `incus`, `nocloud`, `oci`, and `scaleway`. Alternatively, you can add `tinycloud=cloud=` (preferred) or `ds=` (cloud-init compatible) to the kernel `/proc/cmdline` (preferred) or diff --git a/TODO.md b/TODO.md index 781d248..2345a0c 100644 --- a/TODO.md +++ b/TODO.md @@ -13,7 +13,7 @@ ## FUTURE -* Support `vendor-data`? In theory this is a baseline, and and `user-data` +* Support `vendor-data`? In theory this is a baseline, and `user-data` is layered on top of that. * Support additional features of `#cloud-config` as needed @@ -21,7 +21,6 @@ * Support LVM partitioning and non-`ext[234]` filesystems? * Support other cloud providers... - * Digital Ocean * IBM * Openstack * ??? diff --git a/lib/tiny-cloud/cloud/digitalocean/autodetect b/lib/tiny-cloud/cloud/digitalocean/autodetect new file mode 100755 index 0000000..50721d3 --- /dev/null +++ b/lib/tiny-cloud/cloud/digitalocean/autodetect @@ -0,0 +1,5 @@ +#!/bin/sh +# vim:set filetype=sh: +# shellcheck shell=sh + +grep -qi digitalocean "$ROOT"/sys/class/dmi/id/modalias 2>/dev/null && echo "10 digitalocean" diff --git a/lib/tiny-cloud/cloud/digitalocean/imds b/lib/tiny-cloud/cloud/digitalocean/imds new file mode 100644 index 0000000..de29879 --- /dev/null +++ b/lib/tiny-cloud/cloud/digitalocean/imds @@ -0,0 +1,23 @@ +# DigitalOcean Instance MetaData Service variables and functions +# vim: set filetype=sh: +# shellcheck shell=sh + +IMDS_URI="metadata/v1" +IMDS_HOSTNAME="hostname" +IMDS_LOCAL_HOSTNAME="$IMDS_HOSTNAME" +IMDS_SSH_KEYS="public-keys" + +# TODO: flesh out networking +unset \ + IMDS_NICS \ + IMDS_MAC \ + IMDS_IPV4 \ + IMDS_IPV6 \ + IMDS_IPV4_NET \ + IMDS_IPV6_NET \ + IMDS_IPV4_PREFIX \ + IMDS_IPV6_PREFIX + +_imds_header() { echo; } + +_imds_ssh_keys() { _imds "$IMDS_SSH_KEYS"; } diff --git a/lib/tiny-cloud/cloud/hetzner/imds copy b/lib/tiny-cloud/cloud/hetzner/imds copy deleted file mode 100644 index f7b877d..0000000 --- a/lib/tiny-cloud/cloud/hetzner/imds copy +++ /dev/null @@ -1,18 +0,0 @@ -# AWS Instance MetaData Service variables and functions -# vim:set filetype=sh: -# shellcheck shell=sh - -IMDS_HEADER="X-aws-ec2-metadata-token" -IMDS_TOKEN_TTL_HEADER="X-aws-ec2-metadata-token-ttl-seconds" -: "${IMDS_TOKEN_TTL:=5}" -IMDS_URI="latest" - -_imds_token() { - printf "PUT /latest/api/token HTTP/1.0\r\n%s: %s\r\n\r\n" \ - "$IMDS_TOKEN_TTL_HEADER" "$IMDS_TOKEN_TTL" \ - | nc -w 1 "$IMDS_ENDPOINT" 80 | tail -n 1 -} - -_imds_header() { - echo "$IMDS_HEADER: $(_imds_token)" -} diff --git a/lib/tiny-cloud/cloud/scaleway/imds copy b/lib/tiny-cloud/cloud/scaleway/imds copy deleted file mode 100644 index f7b877d..0000000 --- a/lib/tiny-cloud/cloud/scaleway/imds copy +++ /dev/null @@ -1,18 +0,0 @@ -# AWS Instance MetaData Service variables and functions -# vim:set filetype=sh: -# shellcheck shell=sh - -IMDS_HEADER="X-aws-ec2-metadata-token" -IMDS_TOKEN_TTL_HEADER="X-aws-ec2-metadata-token-ttl-seconds" -: "${IMDS_TOKEN_TTL:=5}" -IMDS_URI="latest" - -_imds_token() { - printf "PUT /latest/api/token HTTP/1.0\r\n%s: %s\r\n\r\n" \ - "$IMDS_TOKEN_TTL_HEADER" "$IMDS_TOKEN_TTL" \ - | nc -w 1 "$IMDS_ENDPOINT" 80 | tail -n 1 -} - -_imds_header() { - echo "$IMDS_HEADER: $(_imds_token)" -} diff --git a/tests/imds.test b/tests/imds.test index e7a90b6..a4cfd56 100755 --- a/tests/imds.test +++ b/tests/imds.test @@ -5,7 +5,7 @@ . $(atf_get_srcdir)/test_env.sh export PREFIX="$srcdir" -PROVIDERS="aws azure gcp hetzner incus oci nocloud scaleway" +PROVIDERS="aws azure digitalocean gcp hetzner incus oci nocloud scaleway" init_tests \ imds_help \ @@ -13,6 +13,7 @@ init_tests \ \ imds_hostname_aws \ imds_hostname_azure \ + imds_hostname_digitalocean \ imds_hostname_gcp \ imds_hostname_hetzner \ imds_hostname_incus \ @@ -22,6 +23,7 @@ init_tests \ \ imds_local_hostname_aws \ imds_local_hostname_azure \ + imds_local_hostname_digitalocean \ imds_local_hostname_gcp \ imds_local_hostname_hetzner \ imds_local_hostname_incus \ @@ -31,6 +33,7 @@ init_tests \ \ imds_ssh_keys_aws \ imds_ssh_keys_azure \ + imds_ssh_keys_digitalocean \ imds_ssh_keys_gcp \ imds_ssh_keys_hetzner \ imds_ssh_keys_incus \ @@ -58,7 +61,7 @@ imds_space_body() { check_hostname() { fake_metadata "$1" <<-EOF - # nocloud, alpine, aws, hetzner + # aws, digitalocean, hetzner, nocloud hostname: myhostname # azure compute: @@ -71,6 +74,7 @@ check_hostname() { } imds_hostname_aws_body() { check_hostname aws; } imds_hostname_azure_body() { check_hostname azure; } +imds_hostname_digitalocean_body() { check_hostname digitalocean; } imds_hostname_gcp_body() { check_hostname gcp; } imds_hostname_hetzner_body() { check_hostname hetzner; } imds_hostname_incus_body() { @@ -91,9 +95,9 @@ EOF check_local_hostname() { fake_metadata "$1" <<-EOF - # nocloud, alpine, aws, incus + # nocloud, aws, incus local-hostname: myhostname - # hetzner + # digitalocean, hetzner hostname: myhostname # azure compute: @@ -106,6 +110,7 @@ check_local_hostname() { } imds_local_hostname_aws_body() { check_local_hostname aws; } imds_local_hostname_azure_body() { check_local_hostname azure; } +imds_local_hostname_digitalocean_body() { check_local_hostname digitalocean; } imds_local_hostname_gcp_body() { check_local_hostname gcp; } imds_local_hostname_hetzner_body() { check_local_hostname hetzner; } imds_local_hostname_incus_body() { check_local_hostname incus; } @@ -144,6 +149,14 @@ check_ssh_keys() { } imds_ssh_keys_aws_body() { check_ssh_keys aws; } imds_ssh_keys_azure_body() { check_ssh_keys azure; } +imds_ssh_keys_digitalocean_body() { + local key="ssh-ed25519 keydata" + fake_metadata "digitalocean" <<-EOF + # digitalocean + public-keys: $key + EOF + CLOUD="digitalocean" atf_check -o match:"$key" imds @ssh-keys +} imds_ssh_keys_gcp_body() { check_ssh_keys gcp; } imds_ssh_keys_hetzner_body() { local key="ssh-ed25519 keydata" diff --git a/tests/init.test b/tests/init.test index b88e8ef..bbff1e0 100755 --- a/tests/init.test +++ b/tests/init.test @@ -27,6 +27,7 @@ init_tests \ autodetect_aws_nitro \ autodetect_aws_xen \ autodetect_azure \ + autodetect_digitalocean \ autodetect_gcp \ autodetect_hetzner \ autodetect_incus \ @@ -37,7 +38,7 @@ init_tests \ autodetect_scaleway \ autodetect_unknown -PROVIDERS="aws azure gcp nocloud oci scaleway hetzner" +PROVIDERS="aws azure digitalocean gcp hetzner nocloud oci scaleway" expand_root_body() { mkdir proc @@ -276,6 +277,16 @@ autodetect_azure_body() { sh -c ". \"$lib\"; echo \$CLOUD" } +autodetect_digitalocean_body() { + mkdir -p sys/class/dmi/id + cat > sys/class/dmi/id/modalias <<-EOT + dmi:bvnDigitalOcean:bvrReleasev4.1:bd03/08/2024:br4.1:svn:pnVirtualMachine:pvrReleasev4.1:rvn:rnVirtualMachine:rvrReleasev4.1:cvn:ct3:cvrReleasev4.1:skuNone: + EOT + atf_check \ + -o match:"digitalocean" \ + sh -c ". \"$lib\"; echo \$CLOUD" +} + autodetect_gcp_body() { mkdir -p sys/class/dmi/id cat > sys/class/dmi/id/modalias <<-EOT diff --git a/tests/test_env.sh b/tests/test_env.sh index c3e8935..d807959 100644 --- a/tests/test_env.sh +++ b/tests/test_env.sh @@ -74,6 +74,11 @@ fake_metadata_azure() { export WGET_STRIP_PREFIX="/metadata/instance" } +fake_metadata_digitalocean() { + cat > "169.254.169.254.yaml" + export WGET_STRIP_PREFIX="/metadata/v1" +} + fake_metadata_gcp() { cat > "169.254.169.254.yaml" export WGET_STRIP_PREFIX="/computeMetadata/v1" @@ -111,6 +116,7 @@ fake_metadata() { alpine|nocloud) fake_metadata_nocloud;; aws) fake_metadata_aws;; azure) fake_metadata_azure;; + digitalocean) fake_metadata_digitalocean;; gcp) fake_metadata_gcp;; hetzner) fake_metadata_hetzner;; incus) fake_metadata_incus;; diff --git a/tests/tiny-cloud.test b/tests/tiny-cloud.test index 2639c36..6ec74fc 100755 --- a/tests/tiny-cloud.test +++ b/tests/tiny-cloud.test @@ -6,7 +6,7 @@ export PREFIX="$srcdir" export MOCK=echo -PROVIDERS="alpine aws azure gcp incus hetzner nocloud oci scaleway" +PROVIDERS="alpine aws azure digitalocean gcp incus hetzner nocloud oci scaleway" init_tests \ tiny_cloud_help \