🎉 Initial version

This commit is contained in:
Franck Nijhof 2017-10-14 21:42:24 +02:00
parent b93f24d1ca
commit 1021fab708
No known key found for this signature in database
GPG key ID: D62583BA8AB11CA3
14 changed files with 686 additions and 0 deletions

8
.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
.vagrant/*
addons/*
backup/*
config/*
share/*
ssl/*
*.log
!.gitkeep

13
CHANGELOG.md Normal file
View file

@ -0,0 +1,13 @@
# Changelog Community Hass.io Add-ons: Vagrant
All notable changes to this repository will be documented in this file.
The format is based on [Keep a Changelog][keep-a-changelog]
and this project adheres to [Semantic Versioning][semantic-versioning].
## Unreleased
There are currently no unreleased changes.
[keep-a-changelog]: http://keepachangelog.com/en/1.0.0/
[semantic-versioning]: http://semver.org/spec/v2.0.0.html

281
README.md Normal file
View file

@ -0,0 +1,281 @@
# Community Hass.io Add-ons: Vagrant
![Project Stage][project-stage-shield]
![Maintenance][maintenance-shield]
![Awesome][awesome-shield]
[![License][license-shield]](LICENSE.md)
[![Code Climate][codeclimate-shield]][codeclimate]
[![GitHub Release][releases-shield]][releases]
![GitHub Downloads][downloads-shield]
This is a Vagrant box containing [Home Assistant][home-assistant]
based on Hass.io.
## About
This Vagrant virtual machine allows you to test and play with Hass.io and
Home Assistant, and is a great environment for add-on developers. A simple
`vagrant up` command would give you a fully installed Hass.io system,
in a couple of minutes.
![Home Assistant](images/homeassistant.png)
This setup comes preloaded with [netdata][] and [Portainer][portainer] to
provide you, even more, insight to what is happing under the hood.
### Portainer
Portainer is a lightweight Docker management UI which allows you to easily
manage your Docker/Hass.io host.
It allows add-on developers to look at the logs of their add-on, or even
get a console into their running add-on to allow for easy debugging issues.
![Portainer](images/portainer.png)
### netdata
netdata allow you to monitor your Docker containers (of which Hass.io consists).
Simple. Effective. Awesome!
Unparalleled insights, in real-time, of everything happening on your systems,
applications and add-ons with stunning, interactive web dashboards and
powerful performance and health alarms.
This gives add-on developers detailed information about the performance and
resource usage of their add-ons.
![netdata](images/netdata.png)
## System requirements
This setup does not require a lot. Sure it does cost some CPU & memory, but
to be honest, Google Chrome eats more memory these days.
This setup is tested on MacOS but should work fine on Linux as well. Windows
might work, but is not tested (please let us know!).
When following the installation instructions of the tools in the following
chapter, please be sure to check the system requirements of each of those
tools.
## Getting started
Before launching your Hass.io environment, you must install
[VirtualBox][virtualbox] 5.1 or higher, as well as [Vagrant][vagrant] 1.9.0 or
higher. These software packages provide easy-to-use visual installers for
all popular operating systems and are open source.
Once [VirtualBox][virtualbox] and [Vagrant][vagrant] have been installed, you
install `hassio-vagrant` by simply cloning this repository. Consider cloning
the repository into a folder within your "home" directory.
```bash
# Goto your home directory
cd ~
# Clone this repository into a folder called `hassio`
git clone https://github.com/hassio-addons/hassio-vagrant.git hassio
```
You should check out a tagged version of `hassio-vagrant` since the `master`
branch may not always be stable. You can find the latest stable version on the
[GitHub Release Page][releases]:
```bash
# Change the directory to `hassio`
cd hassio
# Checkout the desired release
git checkout v0.0.1
````
Once you have cloned the `hassio-vagrant` repository, you can use the following
command to start Hass.io:
```bash
vagrant up hassio
```
After 10 minutes or so, the process would finish and the following messages
will appear on your screen:
```txt
==> hassio: [INFO] Start services
==> hassio: =====================================================================
==> hassio: Community Hass.io Add-ons: Vagrant
==> hassio:
==> hassio: Hass.io is installed & started! It may take a couple of minutes
==> hassio: before it is actually responding/available.
==> hassio:
==> hassio: Home Assitant is running on the following links:
==> hassio: - http://172.28.128.11:8123
==> hassio: - http://192.168.1.2:8123
==> hassio:
==> hassio: Portainer is running on the following links:
==> hassio: - http://172.28.128.11:9000
==> hassio: - http://192.168.1.2:9000
==> hassio:
==> hassio: Netdata is providing awesome stats on these links:
==> hassio: - http://172.28.128.11:19999
==> hassio: - http://192.168.1.2:19999
==> hassio: =====================================================================
==> hassio:
==> hassio: Machine 'hassio' has a post `vagrant up` message. This is a message
==> hassio: from the creator of the Vagrantfile, and not from Vagrant itself:
==> hassio:
==> hassio: Hass.io starting... wait a couple of minutes!
```
:tada: Congratulations! Happy testing/developing :smile:
Note: _The links and IP addresses are examples, yours may differ and change
each time you run this virtual machine_
## Managing the Virtual machine
If you followed the above procedure, you have got Hass.io up and running.
But there may be a time where you need to shut it down, start up again or
maybe start over again.
Shutting down the virtual machine:
```bash
vagrant halt hassio
```
Starting/Resuming the virtual machine again:
```bash
vagrant up hassio
```
Destroying/Deleting the virtual machine:
```bash
vagrant destroy hassio
```
After you've destroyed your Hass.io virtual machine, you can use the
start command to create a fresh one.
Note: _Please, be aware! Destroying the machine would make you lose your
configuration of Home Assistant!_
You can also use SSH into the virtual machine, giving you direct access
to the Docker host:
```bash
vagrant ssh hassio
```
## Shared folder
After starting the Hass.io virtual machine, some folders on your harddrive
will be made available. These are shared folders with your Hass.io virtual
machine. As files within these folders are changed, they will be kept in
sync between your local machine and the Hass.io virtual environment.
The following folders are provided within the location where you have cloned
this repository to:
- `addons` - May contain local add-on (e.g. for development).
- `backup` - May contain snapshots made with Hass.io.
- `config` - Contains the Home Assistant configuration.
- `share` - Cross add-on shared folder.
- `ssl` - May contain SSL certificate files.
Note: _When destroying the Hass.io virtual machine, the contents of the
`config` folder WILL BE DELETED. All other folders are left untouched._
## Changelog
This repository keeps a [change log](CHANGELOG.md) and adhere to
[Semantic Versioning][semver]. The format of the log is based
on [Keep a Changelog][keepchangelog].
## Support
Got questions?
You have several options to get them answered:
- The Home Assistant [Community Forums][forums], we have a
[dedicated topic][forums] on that forum regarding this repository.
- The Home Assistant [Discord Chat Server][discord] for general Home Assistant
discussions and questions.
- Join the [Reddit subreddit][reddit] in [/r/homeassistant][reddit]
You could also [open an issue here][issue] GitHub.
## Contributing
This is an active open-source project. We are always open to people who want to
use the code or contribute to it.
We've set up a separate document for our [contribution guidelines](CONTRIBUTING.md).
Thank you for being involved! :heart_eyes:
## Authors & contributors
The original setup of this repository is by [Franck Nijhof][frenck].
For a full list of all authors and contributors,
check [the contributor's page][contributors].
## We've got some Hass.io add-ons for you
Want some more functionality to your Hass.io Home Assistant instance?
We have created multiple add-ons for Hass.io. For a full list, check out
our [GitHub Repository][repository].
## License
MIT License
Copyright (c) 2017 Franck Nijhof
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.
[awesome-shield]: https://img.shields.io/badge/awesome%3F-yes-brightgreen.svg
[codeclimate-shield]: https://img.shields.io/codeclimate/github/hassio-addons/hassio-vagrant.svg
[codeclimate]: https://codeclimate.com/github/hassio-addons/hassio-vagrant
[contributors]: https://github.com/hassio-addons/hassio-vagrant/graphs/contributors
[discord]: https://discord.gg/c5DvZ4e
[downloads-shield]: https://img.shields.io/github/downloads/hassio-addons/hassio-vagrant/total.svg
[forums]: https://community.home-assistant.io/t/repository-community-hass-io-add-ons/24705?u=frenck
[frenck]: https://github.com/frenck
[home-assistant]: https://home-assistant.io/
[issue]: https://github.com/hassio-addons/hassio-vagrant/issues
[keepchangelog]: http://keepachangelog.com/en/1.0.0/
[license-shield]: https://img.shields.io/github/license/hassio-addons/hassio-vagrant.svg
[maintenance-shield]: https://img.shields.io/maintenance/yes/2017.svg
[netdata]: https://my-netdata.io
[portainer]: https://portainer.io
[project-stage-shield]: https://img.shields.io/badge/Project%20Stage-Experimental-yellow.svg
[reddit]: https://reddit.com/r/homeassistant
[releases-shield]: https://img.shields.io/github/release/hassio-addons/hassio-vagrant.svg
[releases]: https://github.com/hassio-addons/hassio-vagrant/releases
[repository]: https://github.com/hassio-addons/repository
[semver]: http://semver.org/spec/v2.0.0.html
[vagrant]: https://www.vagrantup.com/
[virtualbox]: https://www.virtualbox.org/

194
Vagrantfile vendored Normal file
View file

@ -0,0 +1,194 @@
# ==============================================================================
#
# Community Hass.io Add-ons: Vagrant
#
# ==============================================================================
# MIT License
#
# Copyright (c) 2017 Franck Nijhof
#
# 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.
# ==============================================================================
require 'English'
require 'fileutils'
require 'vagrant'
require 'yaml'
require 'pp'
VAGRANT_API_VERSION = '2'.freeze
::Vagrant.require_version '>= 1.9.0'
module HassioCommunityAddons
# Manages the Vagrant configuration
# @author Franck Nijhof <frenck@addons.community>
class Vagrant
# Class constructor
def initialize
@config = YAML.load_file(
File.join(File.dirname(__FILE__), 'configuration.yml')
)
end
# Simple CLI Yes / No question
#
# @param [String] message Question to ask
# @param [Boolean] default True, to default to yes, false to default to no
# @return [Boolean] True if answered yes, false if answered no
def confirm(message, default)
print "#{message} [#{(default ? 'Y/n' : 'y/N')}]: "
result = $stdin.gets.chomp.strip.downcase
return default if result.empty?
return true if %w(y yes).include? result
return false if %w(n no).include? result
print "\nInvalid input. Try again...\n"
confirm(message, default)
end
# Checks/install required vagrant-triggers plugin
def require_triggers_plugin
return if ::Vagrant.has_plugin?('vagrant-triggers')
print "A required vagrant plugin is missing: vagrant-triggers\n"
confirm 'Shall I go ahead an install it?', true unless raise \
::Vagrant::Errors::VagrantError.new, 'Required plugin missing.'
system 'vagrant plugin install vagrant-triggers' unless raise \
::Vagrant::Errors::VagrantError.new, 'Installation of plugin failed.'
print "Restarting Vagrant to re-load plugin changes...\n"
system 'vagrant ' + ARGV.join(' ')
exit! $CHILD_STATUS.exitstatus
end
# Configures generic Vagrant options
#
# @param [Vagrant::Config::V2::Root] config Vagrant root config
def vagrant_config(config)
config.vm.box = @config['box']
config.vm.post_up_message = @config['post_up_message']
end
# Defines a Vagrant virtual machine
#
# @param [Vagrant::Config::V2::Root] config Vagrant root config
# @param [String] name Name of the machine to define
def machine(config, name)
config.vm.define name do |machine|
machine_config machine
machine_provider_virtualbox machine
machine_provider_vmware machine
machine_shares machine
machine_provision machine
machine_cleanup_on_destroy machine
end
end
# Configures a VM's generic options
#
# @param [Vagrant::Config::V2::Root] machine Vagrant VM root config
def machine_config(machine)
machine.vm.hostname = @config['hostname']
machine.vm.network 'public_network', type: 'dhcp'
machine.vm.network 'private_network', type: 'dhcp'
end
# Configures the Virtualbox provider
#
# @param [Vagrant::Config::V2::Root] machine Vagrant VM root config
def machine_provider_virtualbox(machine)
machine.vm.provider :virtualbox do |vbox|
vbox.name = @config['hostname']
vbox.cpus = @config['cpus']
vbox.customize ['modifyvm', :id, '--memory', @config['memory']]
vbox.customize ['modifyvm', :id, '--nictype1', 'virtio']
vbox.customize ['modifyvm', :id, '--nictype2', 'virtio']
vbox.customize ['modifyvm', :id, '--nictype3', 'virtio']
vbox.customize ['modifyvm', :id, '--natdnshostresolver1', 'on']
vbox.customize ['modifyvm', :id, '--natdnsproxy1', 'on']
end
end
# Configures the VMware provider
#
# @param [Vagrant::Config::V2::Root] machine Vagrant VM root config
def machine_provider_vmware(machine)
%w(vmware_fusion vmware_workstation).each do |vmware|
machine.vm.provider vmware do |vmw|
vmw.vmx['displayName'] = @config['hostname']
vmw.vmx['memsize'] = @config['memory']
vmw.vmx['numvcpus'] = @config['cpus']
end
end
end
# Configures a VM's shares
#
# @param [Vagrant::Config::V2::Root] machine Vagrant VM root config
def machine_shares(machine)
@config['shares'].each do |src, dst|
machine.vm.synced_folder src, dst, create: true, type: share_type
end
end
# Determines the type of filesharing. SMB for windows, else NFS.
def share_type
RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/ ? 'smb' : 'nfs'
end
# Configures a VM's provisioning
#
# @param [Vagrant::Config::V2::Root] machine Vagrant VM root config
def machine_provision(machine)
machine.vm.provision 'fix-no-tty', type: 'shell' do |shell|
shell.path = 'provision.sh'
end
end
# Defines a VM cleanup task when destroying the VM
#
# @param [Vagrant::Config::V2::Root] machine Vagrant VM root config
def machine_cleanup_on_destroy(machine)
root_directory = File.dirname(__FILE__)
machine.trigger.after :destroy do
FileUtils.rm_rf(
Dir.glob(File.join(root_directory, 'config/**'), File::FNM_DOTMATCH)
.reject { |i| i =~ %r{(\/.|\/\.\.|\.gitkeep)$} }
)
end
end
# Run this thing!
def run
require_triggers_plugin
::Vagrant.configure(VAGRANT_API_VERSION) do |config|
vagrant_config(config)
machine(config, 'hassio')
end
end
end
end
# Create a instance
hassio = HassioCommunityAddons::Vagrant.new
# Go!
hassio.run

1
addons/.gitkeep Normal file
View file

@ -0,0 +1 @@
Without requirements or design, programming is the art of adding bugs to an empty text file. (Louis Srygley)

1
backup/.gitkeep Normal file
View file

@ -0,0 +1 @@
Without requirements or design, programming is the art of adding bugs to an empty text file. (Louis Srygley)

1
config/.gitkeep Normal file
View file

@ -0,0 +1 @@
Without requirements or design, programming is the art of adding bugs to an empty text file. (Louis Srygley)

12
configuration.yml Normal file
View file

@ -0,0 +1,12 @@
---
memory: 2048
cpus: 2
hostname: hassio
post_up_message: Hass.io starting... wait a couple of minutes!
box: ubuntu/xenial64
shares:
addons: /usr/share/hassio/addons/local
backup: /usr/share/hassio/backup
config: /usr/share/hassio/homeassistant
share: /usr/share/hassio/share
ssl: /usr/share/hassio/ssl

BIN
images/homeassistant.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
images/netdata.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

BIN
images/portainer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

173
provision.sh Normal file
View file

@ -0,0 +1,173 @@
#!/usr/bin/env bash
# ==============================================================================
#
# Community Hass.io Add-ons: Vagrant
#
# Provisions a Vagrant guest with Hass.io
#
# ==============================================================================
set -o errexit # Exit script when a command exits with non-zero status
set -o errtrace # Exit on error inside any functions or sub-shells
set -o nounset # Exit script on use of an undefined variable
set -o pipefail # Return exit status of the last command in the pipe that failed
# ==============================================================================
# GLOBALS
# ==============================================================================
readonly EX_OK=0
readonly HASSIO_INSTALLER="https://raw.githubusercontent.com/home-assistant/hassio-build/master/install/hassio_install"
readonly DOCKER_DOWNLOAD="https://download.docker.com/linux"
readonly NETDATA_INSTALLER="https://my-netdata.io/kickstart-static64.sh"
readonly APT_REQUIREMENTS=(
apt-transport-https
ca-certificates
curl
software-properties-common
socat
jq
)
# ==============================================================================
# SCRIPT LOGIC
# ==============================================================================
# ------------------------------------------------------------------------------
# Installs all required software packages and tools
#
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
install_requirements() {
apt-get update
apt-get install -y "${APT_REQUIREMENTS[@]}"
}
# ------------------------------------------------------------------------------
# Installs the Docker engine
#
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
install_docker() {
local os
local lsb_release
os=$(. /etc/os-release; echo "${ID}")
lsb_release=$(lsb_release -cs)
curl -fsSL "${DOCKER_DOWNLOAD}/${os}/gpg" | sudo apt-key add -
add-apt-repository \
"deb [arch=amd64] ${DOCKER_DOWNLOAD}/${os} ${lsb_release} stable"
apt-get update
apt-get install -y docker-ce
usermod -aG docker ubuntu
}
# ------------------------------------------------------------------------------
# Installs and starts netdata
#
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
install_netdata() {
curl -s "${NETDATA_INSTALLER}" > /tmp/kickstart-netdata.sh
bash /tmp/kickstart-netdata.sh --dont-wait
rm /tmp/kickstart-netdata.sh
}
# ------------------------------------------------------------------------------
# Installs and starts Portainer
#
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
install_portainer() {
mkdir -p /usr/share/portainer
docker pull portainer/portainer:latest
docker create \
--name=portainer \
--restart=always \
-v /usr/share/portainer:/data \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 9000:9000 \
portainer/portainer \
-H unix:///var/run/docker.sock \
--no-auth
docker start portainer
}
# ------------------------------------------------------------------------------
# Installs and starts Hass.io
#
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
install_hassio() {
curl -sL "${HASSIO_INSTALLER}" | bash -s
}
# ------------------------------------------------------------------------------
# Shows a message on how to connect to Home Assistant, including the
# dynamic IP the guest was given.
#
# Arguments:
# None
# Returns:
# None
# ------------------------------------------------------------------------------
show_post_up_message() {
local ip_public
local ip_private
ip_public=$(ip -f inet -o addr show enp0s8 | cut -d\ -f 7 | cut -d/ -f 1)
ip_private=$(ip -f inet -o addr show enp0s9 | cut -d\ -f 7 | cut -d/ -f 1)
echo '====================================================================='
echo ' Community Hass.io Add-ons: Vagrant'
echo ''
echo ' Hass.io is installed & started! It may take a couple of minutes'
echo ' before it is actually responding/available.'
echo ''
echo ' Home Assitant is running on the following links:'
echo " - http://${ip_private}:8123"
echo " - http://${ip_public}:8123"
echo ''
echo ' Portainer is running on the following links:'
echo " - http://${ip_private}:9000"
echo " - http://${ip_public}:9000"
echo ''
echo ' Netdata is providing awesome stats on these links:'
echo " - http://${ip_private}:19999"
echo " - http://${ip_public}:19999"
echo '====================================================================='
}
# ==============================================================================
# RUN LOGIC
# ------------------------------------------------------------------------------
main() {
install_requirements
install_docker
install_netdata
install_portainer
install_hassio
show_post_up_message
exit "${EX_OK}"
}
main "$@"

1
share/.gitkeep Normal file
View file

@ -0,0 +1 @@
Without requirements or design, programming is the art of adding bugs to an empty text file. (Louis Srygley)

1
ssl/.gitkeep Normal file
View file

@ -0,0 +1 @@
Without requirements or design, programming is the art of adding bugs to an empty text file. (Louis Srygley)