1
0
mirror of https://gitlab.alpinelinux.org/alpine/cloud/tiny-cloud.git synced 2025-12-15 11:22:43 +03:00

Initial commit

This commit is contained in:
Mike Crute 2017-12-24 03:46:11 +00:00
commit 20513b6595
4 changed files with 146 additions and 0 deletions

19
LICENSE.txt Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2017 Michael Crute
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

5
Makefile Normal file
View File

@ -0,0 +1,5 @@
PREFIX?=/
.PHONY: install
install:
install -Dm 755 tiny-ec2-bootstrap $(PREFIX)/etc/init.d/tiny-ec2-bootstrap

56
README.md Normal file
View File

@ -0,0 +1,56 @@
# Tiny EC2 Bootstrapper
This is designed to do the minimal amount of work required to bootstrap an EC2
instance based on the local settings assigned at boot time as well as the
user's configured settings. This is in-concept similar to
[cloud-init](https://cloudinit.readthedocs.io/en/latest/) but trades features
and cloud platform support for small size and limited external dependencies.
## Requirements
The most important feature of this bootstrapper is the very limited set of
dependencies. In-fact this works with just busybox provided the wget applet is
built-in. The only required dependencies are:
- bash-like shell (e.g. bash, dash, ash)
- wget
## Supported Features and Environments
cloud-init has support for many different cloud providers. This project only
supports EC2, specifically the [EC2 metadata
service](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)
is a hard requirement of using this bootstrapper. All of the data for the
supported features below is sourced from the EC2 instance metadata service
which runs on every EC2 instance at IP 169.254.169.254.
cloud-init also has a very rich feature set with support for adding users,
installing packages, and many other things. This bootstrap does not support
those things. Instead it supports:
- setting system hostname
- install user's configured SSH keys to the alpine user's authorized_keys file
- run any script-like user data (must start with #!)
These steps only run once. After the initial bootstrap the bootstrapper script
is a no-op. To force the script to run again at boot time remove the file
`/var/lib/cloud/.bootstrap-complete` and reboot the instance.
## User Data
User data is provided at instance boot time and can be any arbitrary string of
data. The bootstrapper will consider any user data that begins with the ASCII
characters '#!' to be a script. It will write the entire contents of the user
data to `/var/lib/cloud/user-data.sh`, make the file executable, and execute
the file piping any output to `/var/log/cloud-bootstrap.log`.
The user data script can do anything it pleases with the instance. It will be
run as root and networking will be up. No other grantees about system state are
made at the point the script runs.
## Assumptions
- This was written for Alpine Linux and thus assumes that the login user is
called alpine. This could be configurable in the future but currently is not.
- The script is run by OpenRC

66
tiny-ec2-bootstrap Normal file
View File

@ -0,0 +1,66 @@
#!/sbin/openrc-run
# vim:set ft=bash:
description="Provides EC2 cloud bootstrap"
depend() {
need net
provide cloud-final
}
_get_metadata() {
local uri="$1"
wget -qO - "http://169.254.169.254/latest/$uri" 2>/dev/null
}
_update_hostname() {
local ec2_fqdn="$(_get_metadata meta-data/hostname)"
local short_hostname="${ec2_fqdn%%\.*}"
echo "$short_hostname" > /etc/hostname
hostname -F /etc/hostname
echo -e "127.0.1.1\t$ec2_fqdn $short_hostname" >> /etc/hosts
}
_set_ssh_keys() {
local user="$1"
local group="$(getent passwd $user | cut -d: -f4)"
local ssh_dir="$(getent passwd $user | cut -d: -f6)/.ssh"
local keys_file="$ssh_dir/authorized_keys"
if [ ! -d "$ssh_dir" ]; then
mkdir -p "$ssh_dir"
chmod 755 "$ssh_dir"
fi
[ -f "$keys_file" ] && rm "$keys_file"
touch "$keys_file"
chmod 600 "$keys_file"
chown -R $user:$group "$ssh_dir"
for key in "$(_get_metadata meta-data/public-keys/)"; do
echo $(_get_metadata "meta-data/public-keys/${key%=*}/openssh-key/") >> "$keys_file"
done
}
_run_userdata() {
user_data=$(_get_metadata user-data)
if echo $user_data | grep '^#!/' 2>&1 >/dev/null; then
echo "$user_data" > /var/lib/cloud/user-data.sh
chmod +x /var/lib/cloud/user-data.sh
/var/lib/cloud/user-data.sh > /var/log/cloud-bootstrap.log 2>&1
fi
}
start() {
# Don't bootstrap if the host has already been bootstrapped
[ -f "/var/lib/cloud/.bootstrap-complete" ] && return 0
[ -d "/var/lib/cloud" ] || mkdir -p /var/lib/cloud
ebegin "Setting ec2 hostname"; _update_hostname; eend $?
ebegin "Setting ec2 user ssh keys"; _set_ssh_keys "alpine"; eend $?
ebegin "Running ec2 user data script"; _run_userdata; eend $?
touch "/var/lib/cloud/.bootstrap-complete"
}