├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── Vagrantfile ├── build.sh ├── components ├── common.mk ├── common │ ├── exec.go │ ├── gatekeeper │ │ └── gatekeeper.proto │ ├── util.go │ └── widgets │ │ ├── button.go │ │ ├── dialog.go │ │ ├── editable_list.go │ │ ├── focusable_set.go │ │ ├── focusable_set_test.go │ │ ├── helper.go │ │ ├── helper_test.go │ │ ├── menu.go │ │ ├── par.go │ │ ├── screen.go │ │ ├── textbox.go │ │ ├── validation.go │ │ └── vertical_layout.go ├── diag │ ├── diag.mk │ ├── installerdiag.sh │ ├── operosdiag.sh │ └── operosdiagauth.go ├── installer │ ├── cmd │ │ └── installer.go │ ├── installer.mk │ └── pkg │ │ ├── context.go │ │ ├── crypto.go │ │ ├── hardware.go │ │ ├── hardware_test.go │ │ ├── network │ │ ├── configurator.go │ │ ├── helper.go │ │ ├── helper_test.go │ │ └── interfaces.go │ │ ├── screens │ │ ├── disk.go │ │ ├── eula.go │ │ ├── hwprobe.go │ │ ├── install.go │ │ ├── intro.go │ │ ├── network.go │ │ ├── org.go │ │ ├── passwd.go │ │ └── storage.go │ │ └── util.go ├── prospector │ ├── .gitignore │ ├── README.md │ ├── blkdevice.go │ ├── blkdevice_test.go │ ├── cmd │ │ ├── prospector.go │ │ └── showdevicetree_test.go │ ├── devicetree.go │ ├── devicetree_test.go │ ├── prospector.mk │ ├── report.go │ ├── tst │ │ ├── README.md │ │ ├── collisionprobability │ │ │ └── TestNewDeviceTreeForCollisionProbabilitySerialsOnly.xml │ │ ├── compatability │ │ │ ├── test_01.xml │ │ │ ├── test_02.xml │ │ │ ├── test_03.xml │ │ │ └── test_04.xml │ │ ├── compatability_large_set │ │ │ ├── 0.0.0.0.out │ │ │ ├── 10.75.10.100.out │ │ │ ├── 10.75.10.101.out │ │ │ ├── 10.75.10.102.out │ │ │ ├── 10.75.10.103.out │ │ │ ├── 10.75.10.105.out │ │ │ ├── 10.75.10.107.out │ │ │ ├── 10.75.10.108.out │ │ │ ├── 10.75.10.109.out │ │ │ ├── 10.75.10.110.out │ │ │ ├── 10.75.10.111.out │ │ │ ├── 10.75.10.113.out │ │ │ ├── 10.75.10.114.out │ │ │ ├── 10.75.10.115.out │ │ │ ├── 10.75.10.116.out │ │ │ ├── 10.75.10.117.out │ │ │ ├── 10.75.10.119.out │ │ │ ├── 10.75.10.121.out │ │ │ ├── 10.75.10.122.out │ │ │ ├── 10.75.10.123.out │ │ │ ├── 10.75.10.124.out │ │ │ ├── 10.75.10.125.out │ │ │ ├── 10.75.10.127.out │ │ │ ├── 10.75.10.44.out │ │ │ ├── 10.75.10.45.out │ │ │ ├── 10.75.10.46.out │ │ │ ├── 10.75.10.47.out │ │ │ ├── 10.75.10.48.out │ │ │ ├── 10.75.10.49.out │ │ │ ├── 10.75.10.50.out │ │ │ ├── 10.75.10.51.out │ │ │ ├── 10.75.10.52.out │ │ │ ├── 10.75.10.53.out │ │ │ ├── 10.75.10.54.out │ │ │ ├── 10.75.10.55.out │ │ │ ├── 10.75.10.56.out │ │ │ ├── 10.75.10.57.out │ │ │ ├── 10.75.10.58.out │ │ │ ├── 10.75.10.59.out │ │ │ ├── 10.75.10.60.out │ │ │ ├── 10.75.10.61.out │ │ │ ├── 10.75.10.62.out │ │ │ ├── 10.75.10.63.out │ │ │ ├── 10.75.10.64.out │ │ │ ├── 10.75.10.65.out │ │ │ ├── 10.75.10.67.out │ │ │ ├── 10.75.10.69.out │ │ │ ├── 10.75.10.70.out │ │ │ ├── 10.75.10.71.out │ │ │ ├── 10.75.10.72.out │ │ │ ├── 10.75.10.73.out │ │ │ ├── 10.75.10.74.out │ │ │ ├── 10.75.10.76.out │ │ │ ├── 10.75.10.77.out │ │ │ ├── 10.75.10.78.out │ │ │ ├── 10.75.10.79.out │ │ │ ├── 10.75.10.80.out │ │ │ ├── 10.75.10.81.out │ │ │ ├── 10.75.10.82.out │ │ │ ├── 10.75.10.83.out │ │ │ ├── 10.75.10.84.out │ │ │ ├── 10.75.10.85.out │ │ │ ├── 10.75.10.86.out │ │ │ ├── 10.75.10.87.out │ │ │ ├── 10.75.10.88.out │ │ │ ├── 10.75.10.89.out │ │ │ ├── 10.75.10.90.out │ │ │ ├── 10.75.10.91.out │ │ │ ├── 10.75.10.92.out │ │ │ ├── 10.75.10.94.out │ │ │ ├── 10.75.10.95.out │ │ │ ├── 10.75.10.96.out │ │ │ ├── 10.75.10.97.out │ │ │ ├── 10.75.10.98.out │ │ │ ├── 10.75.10.99.out │ │ │ ├── 10.75.11.2.out │ │ │ ├── 10.75.11.3.out │ │ │ ├── 10.75.11.4.out │ │ │ ├── 10.75.11.6.out │ │ │ ├── 10.75.11.7.out │ │ │ ├── 10.75.12.1.out │ │ │ ├── 10.75.12.13.out │ │ │ ├── 10.75.12.2.out │ │ │ ├── 10.75.12.3.out │ │ │ ├── 127.0.0.1.out │ │ │ └── ::1.out │ │ ├── json │ │ │ └── laptop.json │ │ ├── lsblk │ │ │ ├── test1.json │ │ │ ├── test2.json │ │ │ ├── test3.json │ │ │ ├── test4.json │ │ │ ├── test5.json │ │ │ ├── test6.json │ │ │ ├── test7.json │ │ │ └── test8.json │ │ ├── report_teamster │ │ │ ├── report.json │ │ │ └── report_lower_case_n.json │ │ └── vbox │ │ │ ├── controller.xml │ │ │ ├── controller_different_nic.xml │ │ │ ├── node1.xml │ │ │ ├── node2.xml │ │ │ ├── real_hw.xml │ │ │ └── real_hw_new_nic.xml │ ├── uuid.go │ └── uuid_test.go ├── statustty │ ├── cmd │ │ └── main.go │ ├── pkg │ │ ├── hostname.go │ │ ├── kube.go │ │ ├── net.go │ │ ├── net_test.go │ │ └── systemd.go │ └── statustty.mk ├── teamster │ ├── .gitignore │ ├── cmd │ │ └── main.go │ ├── pkg │ │ ├── cluster │ │ │ └── cluster.go │ │ ├── identity │ │ │ ├── client.go │ │ │ └── worker.go │ │ ├── tarball │ │ │ └── tarball.go │ │ └── teamster │ │ │ ├── api.go │ │ │ ├── api_test.go │ │ │ └── teamster.proto │ └── teamster.mk └── waterfront │ ├── .gitignore │ ├── client │ ├── .babelrc │ ├── .eslintrc │ ├── package.json │ ├── src │ │ ├── app │ │ │ ├── App.jsx │ │ │ ├── Chrome.jsx │ │ │ └── LoginScreen.jsx │ │ ├── components │ │ │ ├── RefreshIndicator.jsx │ │ │ ├── UserCard.jsx │ │ │ ├── chart │ │ │ │ ├── Bar.jsx │ │ │ │ ├── Gauge.jsx │ │ │ │ ├── Line.jsx │ │ │ │ ├── SingleStat.jsx │ │ │ │ ├── colors.js │ │ │ │ ├── format.js │ │ │ │ ├── timeseriesQueriableChart.jsx │ │ │ │ └── withQueries.js │ │ │ └── withLoader.jsx │ │ ├── index.html │ │ ├── index.js │ │ ├── service │ │ │ ├── LocalNetworkInterface.js │ │ │ ├── apiclient.js │ │ │ └── schema.js │ │ ├── static │ │ │ ├── fonts │ │ │ │ ├── MaterialIcons-Regular.eot │ │ │ │ ├── MaterialIcons-Regular.ttf │ │ │ │ ├── MaterialIcons-Regular.woff │ │ │ │ └── MaterialIcons-Regular.woff2 │ │ │ ├── kube-logo.svg │ │ │ ├── login-top.png │ │ │ ├── logo.png │ │ │ ├── main.css │ │ │ └── operos-logo.svg │ │ └── views │ │ │ ├── about │ │ │ ├── AboutView.jsx │ │ │ └── index.js │ │ │ ├── access │ │ │ ├── AccessManagementView.jsx │ │ │ ├── CredentialsCard.jsx │ │ │ ├── RootPasswordCard.jsx │ │ │ └── index.js │ │ │ ├── cluster │ │ │ ├── ClusterOverviewView.jsx │ │ │ └── index.js │ │ │ ├── metrics │ │ │ ├── MetricsView.jsx │ │ │ └── index.js │ │ │ └── nodes │ │ │ ├── NodeListView.jsx │ │ │ ├── NodeView.jsx │ │ │ └── index.js │ ├── webpack.common.js │ ├── webpack.dev.js │ ├── webpack.prod.js │ └── yarn.lock │ ├── containers │ ├── build │ │ └── Dockerfile │ └── ship │ │ └── Dockerfile │ ├── server │ ├── Makefile │ ├── cmd │ │ └── main.go │ └── pkg │ │ ├── kube │ │ └── kube.go │ │ ├── teamster │ │ └── client.go │ │ └── waterfront │ │ ├── api.go │ │ ├── auth.go │ │ ├── clientcert.go │ │ └── waterfront.proto │ └── waterfront.mk ├── glide.lock ├── glide.yaml ├── iso ├── _cpiohooks │ ├── hooks │ │ ├── operosiso │ │ ├── operosiso_pxe_common │ │ └── operosiso_pxe_http │ └── install │ │ ├── operosiso │ │ ├── operosiso_pxe_common │ │ └── operosiso_pxe_http ├── _isolinux │ └── isolinux.cfg ├── base │ ├── build-layer.sh │ └── packages ├── controller │ ├── airootfs │ │ ├── etc │ │ │ ├── hosts │ │ │ ├── sysctl.d │ │ │ │ └── printk.conf │ │ │ ├── systemd │ │ │ │ ├── scripts │ │ │ │ │ ├── ceph-mon-init │ │ │ │ │ ├── load-images │ │ │ │ │ ├── nat │ │ │ │ │ ├── operos-cfg-populate │ │ │ │ │ ├── start-addons │ │ │ │ │ └── statustty │ │ │ │ └── system │ │ │ │ │ ├── dhcpd4@.service │ │ │ │ │ ├── load-images.service │ │ │ │ │ ├── nat.service │ │ │ │ │ ├── operos-ceph-mon-init.service │ │ │ │ │ ├── operos-cfg-populate.service │ │ │ │ │ ├── operos-cfg-store.service │ │ │ │ │ ├── operos-image.service │ │ │ │ │ ├── start-addons.service │ │ │ │ │ ├── statustty.service │ │ │ │ │ ├── teamster.service │ │ │ │ │ └── tftpd.service.d │ │ │ │ │ └── 10-require-network.conf │ │ │ └── tftpd.mapfile │ │ └── root │ │ │ └── customize_airootfs.sh │ ├── build-layer.sh │ ├── packages │ └── syslinux │ │ ├── splash.png │ │ └── syslinux.cfg ├── installer │ ├── 300-devbuild.sh │ ├── airootfs │ │ ├── etc │ │ │ ├── fstab │ │ │ ├── hostname │ │ │ ├── locale.conf │ │ │ ├── machine-id │ │ │ ├── pacman.conf │ │ │ ├── sysctl.d │ │ │ │ └── printk.conf │ │ │ └── systemd │ │ │ │ └── system │ │ │ │ ├── etc-pacman.d-gnupg.mount │ │ │ │ ├── getty@tty1.service.d │ │ │ │ └── autologin.conf │ │ │ │ └── pacman-init.service │ │ └── root │ │ │ ├── .zlogin │ │ │ ├── autoinstall.sh │ │ │ ├── cleanup.sh │ │ │ ├── customize_airootfs.sh │ │ │ ├── efiboot │ │ │ └── loader │ │ │ │ ├── entries │ │ │ │ └── operos.conf │ │ │ │ └── loader.conf │ │ │ ├── install.sh │ │ │ ├── install │ │ │ ├── 010-partition.sh │ │ │ ├── 020-system.sh │ │ │ ├── 030-fstab.sh │ │ │ ├── 040-hostname.sh │ │ │ ├── 050-time.sh │ │ │ ├── 070-bootloader.sh │ │ │ ├── 080-network.sh │ │ │ ├── 100-etcd.sh │ │ │ ├── 102-configure.sh │ │ │ ├── 104-worker-boot.sh │ │ │ ├── 105-calico.sh │ │ │ ├── 110-kubelet.sh │ │ │ ├── 130-sshd.sh │ │ │ ├── 140-issue.sh │ │ │ ├── 150-settings.sh │ │ │ ├── 180-root-passwd.sh │ │ │ ├── 900-cleanup.sh │ │ │ └── _common │ │ │ └── manifests │ │ │ ├── addons │ │ │ ├── 10-calico-sa.yml │ │ │ ├── 11-calico-crd.yml │ │ │ ├── 12-calico-ds.yml │ │ │ ├── 20-kubedns-sa.yml │ │ │ ├── 21-kubedns-depl.yml │ │ │ ├── 22-kubedns-svc.yml │ │ │ ├── 30-kube-dashboard-sa.yml │ │ │ ├── 31-kube-dashboard-depl.yml │ │ │ ├── 32-kube-dashboard-svc.yml │ │ │ ├── 40-waterfront-sa.yml │ │ │ ├── 41-waterfront-ds.yml │ │ │ ├── 52-node-exporter-daemonset.yml │ │ │ ├── 53-prometheus-config.yml │ │ │ ├── 54-prometheus-deployment.yml │ │ │ ├── 55-prometheus-service.yml │ │ │ └── 60-rbd-provisioner.yml │ │ │ └── kubelet │ │ │ ├── kube-apiserver.yml │ │ │ ├── kube-controller-manager.yml │ │ │ └── kube-scheduler.yml │ ├── build-layer.sh │ ├── efiboot │ │ └── loader │ │ │ ├── entries │ │ │ ├── archiso-x86_64-cd.conf │ │ │ ├── archiso-x86_64-usb.conf │ │ │ ├── uefi-shell-v1-x86_64.conf │ │ │ └── uefi-shell-v2-x86_64.conf │ │ │ └── loader.conf │ ├── mkinitcpio.conf │ ├── packages │ └── syslinux │ │ ├── operos_head.cfg │ │ ├── operos_pxe.cfg │ │ ├── operos_sys.cfg │ │ ├── operos_tail.cfg │ │ ├── splash.png │ │ └── syslinux.cfg ├── node │ ├── airootfs │ │ ├── etc │ │ │ └── docker │ │ │ │ └── daemon.json │ │ └── root │ │ │ └── customize_airootfs.sh │ ├── build-layer.sh │ └── packages ├── pacman.conf └── worker │ ├── airootfs │ ├── etc │ │ ├── hosts │ │ ├── issue │ │ ├── sysctl.d │ │ │ └── printk.conf │ │ ├── systemd │ │ │ ├── scripts │ │ │ │ ├── apply-settings.sh │ │ │ │ ├── make-partitions.sh │ │ │ │ └── pull-images.sh │ │ │ └── system │ │ │ │ ├── apply-settings.service │ │ │ │ ├── chronyd.service.d │ │ │ │ └── 10-settings.conf │ │ │ │ ├── docker.service.d │ │ │ │ └── 10-partitions.conf │ │ │ │ ├── etc-pacman.d-gnupg.mount │ │ │ │ ├── kubelet.service.d │ │ │ │ └── 10-partitions.conf │ │ │ │ ├── make-partitions.service │ │ │ │ ├── operos-statustty.service │ │ │ │ ├── pacman-init.service │ │ │ │ ├── pull-images.service │ │ │ │ └── statustty.service │ │ └── udev │ │ │ └── rules.d │ │ │ └── 81-dhcpcd.rules │ ├── root │ │ └── customize_airootfs.sh │ └── usr │ │ └── lib │ │ └── os-release │ ├── build-layer.sh │ ├── mkinitcpio.conf │ ├── packages │ └── syslinux │ ├── operos_head.cfg │ ├── operos_pxe.cfg │ ├── operos_sys.cfg │ ├── operos_tail.cfg │ ├── splash.png │ └── syslinux.cfg ├── kubectl ├── operos-version ├── update-imgs.sh ├── update-pkgs.sh ├── vagrant-build.sh └── versions /.gitignore: -------------------------------------------------------------------------------- 1 | .vagrant/ 2 | .vscode/ 3 | .testvms/ 4 | .buildnum 5 | out/ 6 | work/ 7 | cache/ 8 | iso/base/airootfs/usr/bin/operosdiag 9 | iso/base/airootfs/usr/bin/operosdiagauth 10 | iso/node/airootfs/usr/bin/statustty 11 | iso/worker/airootfs/usr/bin/prospector 12 | iso/controller/airootfs/usr/bin/teamster 13 | iso/controller/airootfs/opt/docker-images/* 14 | iso/controller/airootfs/tftpboot 15 | iso/installer/airootfs/root/versions 16 | iso/installer/airootfs/root/installer 17 | iso/installer/airootfs/root/installerdiag.sh 18 | components/ipxe/ipxe/ 19 | vendor/ 20 | *.pb.go 21 | *.pb.gw.go 22 | keys/ 23 | -------------------------------------------------------------------------------- /components/common.mk: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Pax Automa Systems, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | %.pb.go: %.proto 16 | protoc \ 17 | -I$(dir $@) \ 18 | -I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ 19 | -I/usr/include \ 20 | --go_out=plugins=grpc:$(dir $@) \ 21 | $< 22 | 23 | %.pb.gw.go: %.proto 24 | protoc \ 25 | -I$(dir $@) \ 26 | -I/usr/include \ 27 | -I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ 28 | --grpc-gateway_out=logtostderr=true:$(dir $@) \ 29 | $< 30 | 31 | COMMON_FILES=$(find components/common -name "*.go") 32 | -------------------------------------------------------------------------------- /components/common/exec.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package common 18 | 19 | import ( 20 | "fmt" 21 | "io" 22 | "os/exec" 23 | 24 | "github.com/davecgh/go-spew/spew" 25 | log "github.com/sirupsen/logrus" 26 | ) 27 | 28 | type CmdExecutor struct { 29 | Name string 30 | SuccessMessage string 31 | FailMessage string 32 | OnFinish func(success bool) 33 | 34 | cmd *exec.Cmd 35 | } 36 | 37 | func NewCmdExecutor(cmd *exec.Cmd) *CmdExecutor { 38 | return &CmdExecutor{ 39 | cmd: cmd, 40 | } 41 | } 42 | 43 | func (ce *CmdExecutor) Start(w io.Writer) error { 44 | ce.cmd.Stdout = w 45 | ce.cmd.Stderr = w 46 | 47 | log.Debugf("Starting process %s with env", ce.cmd.Path, spew.Sdump(ce.cmd.Env)) 48 | err := ce.cmd.Start() 49 | 50 | if err != nil { 51 | log.Debugf("Failed to start process: %s", err.Error()) 52 | return err 53 | } 54 | 55 | go func() { 56 | err := ce.cmd.Wait() 57 | success := true 58 | 59 | if ioerr, ok := err.(*exec.ExitError); ok { 60 | success = ioerr.Success() 61 | } else if err != nil { 62 | panic(err) 63 | } 64 | 65 | if success { 66 | fmt.Fprintln(w, ce.SuccessMessage) 67 | } else { 68 | fmt.Fprintln(w, ce.FailMessage) 69 | } 70 | 71 | if ce.OnFinish != nil { 72 | ce.OnFinish(success) 73 | } 74 | }() 75 | 76 | return nil 77 | } 78 | -------------------------------------------------------------------------------- /components/common/gatekeeper/gatekeeper.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Pax Automa Systems, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package gatekeeper; 18 | 19 | message AuthorizeDiagUploadReq { 20 | string install_id = 1; 21 | } 22 | 23 | message AuthorizeDiagUploadResp { 24 | string policy = 1; 25 | string signature = 2; 26 | string url = 3; 27 | string date = 4; 28 | string credential =5; 29 | } 30 | 31 | service Gatekeeper { 32 | rpc AuthorizeDiagUpload (AuthorizeDiagUploadReq) returns (AuthorizeDiagUploadResp); 33 | } 34 | -------------------------------------------------------------------------------- /components/common/util.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package common 18 | 19 | import ( 20 | "runtime/debug" 21 | 22 | "github.com/sirupsen/logrus" 23 | ) 24 | 25 | func LogPanic() { 26 | if r := recover(); r != nil { 27 | logrus.Fatalf("%s: %s", r, debug.Stack()) 28 | } 29 | } 30 | 31 | func ArrayContains(haystack []string, needle string) bool { 32 | for _, item := range haystack { 33 | if item == needle { 34 | return true 35 | } 36 | } 37 | return false 38 | } 39 | -------------------------------------------------------------------------------- /components/common/widgets/button.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package widgets 18 | 19 | import ( 20 | "fmt" 21 | "image" 22 | 23 | "github.com/jroimartin/gocui" 24 | ) 25 | 26 | type Button struct { 27 | SimpleFocusable 28 | 29 | Label string 30 | Bounds image.Rectangle 31 | Handler func(string) error 32 | Visible bool 33 | } 34 | 35 | func NewButton(name string, label string, x int, y int, width int, height int) *Button { 36 | b := &Button{ 37 | SimpleFocusable: SimpleFocusable{Name: name}, 38 | Label: label, 39 | Bounds: image.Rect(x, y, x+width-1, y+height-1), 40 | Visible: true, 41 | } 42 | return b 43 | } 44 | 45 | func (b *Button) Layout(g *gocui.Gui) error { 46 | return b.Render(g, image.Point{0, 0}, nil) 47 | } 48 | 49 | func (b *Button) Render(g *gocui.Gui, container image.Point, fs *FocusableSet) error { 50 | b.SimpleFocusable.g = g 51 | 52 | absPos := b.Bounds.Add(container) 53 | 54 | v, err := g.SetView(b.Name, absPos.Min.X, absPos.Min.Y, absPos.Max.X, absPos.Max.Y) 55 | if err != nil { 56 | if err != gocui.ErrUnknownView { 57 | panic(err) 58 | } 59 | 60 | g.SetKeybinding(b.Name, gocui.KeyEnter, gocui.ModNone, func(g *gocui.Gui, v *gocui.View) error { 61 | if b.Handler != nil { 62 | return b.Handler(b.Name) 63 | } 64 | return nil 65 | }) 66 | 67 | if fs != nil { 68 | fs.Add(b) 69 | } 70 | } 71 | 72 | v.Clear() 73 | if b.Visible { 74 | v.Frame = true 75 | fmt.Fprintf(v, CenterInBox(b.Label, b.Bounds.Dx(), b.Bounds.Dy())) 76 | } else { 77 | v.Frame = false 78 | } 79 | 80 | return nil 81 | } 82 | 83 | func (b *Button) WantsFocus() bool { 84 | return b.Visible 85 | } 86 | 87 | func (b *Button) GetHeight() int { 88 | return b.Bounds.Dy() + 1 89 | } 90 | -------------------------------------------------------------------------------- /components/common/widgets/helper.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package widgets 18 | 19 | import ( 20 | "fmt" 21 | "strings" 22 | 23 | "github.com/jroimartin/gocui" 24 | ) 25 | 26 | func CenterString(str string, width int) string { 27 | lines := strings.Split(str, "\n") 28 | 29 | result := make([]string, len(lines)) 30 | for idx, line := range lines { 31 | if width <= len(line) { 32 | result[idx] = line 33 | continue 34 | } 35 | paddingLen := width - len(line) 36 | 37 | prefix := strings.Repeat(" ", paddingLen/2) 38 | postfix := strings.Repeat(" ", paddingLen/2+paddingLen%2) 39 | result[idx] += prefix + line + postfix 40 | } 41 | 42 | return strings.Join(result, "\n") 43 | } 44 | 45 | func CenterInBox(str string, width, height int) string { 46 | centeredText := CenterString(str, width) 47 | numLines := strings.Count(str, "\n") + 1 48 | 49 | if height <= numLines { 50 | return centeredText 51 | } 52 | 53 | numPadding := height - numLines 54 | padLine := strings.Repeat(" ", width) + "\n" 55 | paddingPre := strings.Repeat(padLine, numPadding/2) 56 | paddingPost := strings.Repeat(padLine, numPadding/2+numPadding%2) 57 | 58 | return paddingPre + centeredText + paddingPost 59 | } 60 | 61 | func ColorString(color gocui.Attribute, str string) string { 62 | return fmt.Sprintf("\033[%dm%s\033[0m", 30+color-1, str) 63 | } 64 | 65 | func ReverseString(str string) string { 66 | return fmt.Sprintf("\033[7m%s\033[0m", str) 67 | } 68 | 69 | func BoldString(color gocui.Attribute, str string) string { 70 | return fmt.Sprintf("\033[%d;1m%s\033[0m", 30+color-1, str) 71 | } 72 | -------------------------------------------------------------------------------- /components/common/widgets/helper_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package widgets 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/stretchr/testify/assert" 23 | ) 24 | 25 | func TestCenterString(t *testing.T) { 26 | assert.Equal(t, CenterString("foo", 9), " foo ") 27 | assert.Equal(t, CenterString("foo", 10), " foo ") 28 | assert.Equal(t, CenterString("foo", 3), "foo") 29 | assert.Equal(t, CenterString("foo", 1), "foo") 30 | } 31 | -------------------------------------------------------------------------------- /components/common/widgets/validation.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package widgets 18 | 19 | import ( 20 | "fmt" 21 | "net" 22 | "strconv" 23 | "strings" 24 | ) 25 | 26 | type ValidationError struct { 27 | Field string 28 | Message string 29 | Show bool 30 | } 31 | 32 | func NewValidationError(field string, message string) *ValidationError { 33 | return &ValidationError{field, message, true} 34 | } 35 | 36 | func (ve ValidationError) Error() string { 37 | return fmt.Sprintf("%s: %s", ve.Field, ve.Message) 38 | } 39 | 40 | func JoinValidationErrors(errors []error) string { 41 | errStrings := make([]string, 0) 42 | for _, err := range errors { 43 | if ve, ok := err.(*ValidationError); ok && ve.Show { 44 | errStrings = append(errStrings, err.Error()) 45 | } 46 | } 47 | 48 | return strings.Join(errStrings, "\n") 49 | } 50 | 51 | func ValidateNotEmpty(field string, value string) []error { 52 | value = strings.TrimSpace(value) 53 | 54 | if value == "" { 55 | return []error{ 56 | NewValidationError(field, "cannot be empty"), 57 | } 58 | } 59 | 60 | return []error{} 61 | } 62 | 63 | func ValidateIP(field string, value string) []error { 64 | if net.ParseIP(value) == nil { 65 | return []error{ 66 | NewValidationError(field, "not a valid IP"), 67 | } 68 | } 69 | return []error{} 70 | } 71 | 72 | func ValidateIPNet(field string, value string) []error { 73 | if _, _, err := net.ParseCIDR(value); err != nil { 74 | return []error{ 75 | NewValidationError(field, "not a valid CIDR string"), 76 | } 77 | } 78 | return []error{} 79 | } 80 | 81 | func ValidateIntMinMax(field string, value string, min int, max int) []error { 82 | intVal, err := strconv.Atoi(value) 83 | if err != nil { 84 | return []error{ 85 | NewValidationError(field, "is not a valid integer"), 86 | } 87 | } 88 | 89 | if intVal < min || intVal > max { 90 | return []error{ 91 | NewValidationError(field, fmt.Sprintf("must be between %d and %d", min, max)), 92 | } 93 | } 94 | return []error{} 95 | } 96 | -------------------------------------------------------------------------------- /components/common/widgets/vertical_layout.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package widgets 18 | 19 | import ( 20 | "image" 21 | 22 | "github.com/jroimartin/gocui" 23 | ) 24 | 25 | type VerticalLayout struct { 26 | Items []Renderable 27 | Padding int 28 | } 29 | 30 | func NewVerticalLayout() *VerticalLayout { 31 | return &VerticalLayout{Padding: 1} 32 | } 33 | 34 | func (vl *VerticalLayout) Render(g *gocui.Gui, container image.Point, fs *FocusableSet) error { 35 | pos := container 36 | for _, item := range vl.Items { 37 | if err := item.Render(g, pos, fs); err != nil { 38 | return err 39 | } 40 | pos.Y += item.GetHeight() + vl.Padding 41 | } 42 | 43 | return nil 44 | } 45 | 46 | func (vl *VerticalLayout) GetHeight() int { 47 | if len(vl.Items) < 1 { 48 | return 0 49 | } 50 | 51 | total := 0 52 | for _, item := range vl.Items { 53 | total += item.GetHeight() 54 | } 55 | 56 | total += vl.Padding * (len(vl.Items) - 1) 57 | return total 58 | } 59 | -------------------------------------------------------------------------------- /components/diag/diag.mk: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Pax Automa Systems, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | DIAG_FILES=$(shell find components/diag/ -type f) 16 | 17 | .PHONY: diag-novm 18 | diag-novm: iso/base/airootfs/usr/bin/operosdiagauth 19 | 20 | iso/base/airootfs/usr/bin/operosdiagauth: $(DIAG_FILES) $(COMMON_FILES) components/common/gatekeeper/gatekeeper.pb.go vendor 21 | mkdir -p $(dir $@) 22 | go build -v -o $@ ./components/diag/operosdiagauth.go 23 | cp components/diag/operosdiag.sh $(dir $@)/operosdiag 24 | cp components/diag/installerdiag.sh iso/installer/airootfs/root/installerdiag.sh 25 | 26 | clean: clean-diag 27 | 28 | clean-diag: 29 | rm -f iso/base/airootfs/usr/bin/operosdiagauth 30 | rm -f iso/base/airootfs/usr/bin/operosdiag 31 | rm -f iso/installer/airootfs/root/installerdiag.sh 32 | -------------------------------------------------------------------------------- /components/diag/installerdiag.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Pax Automa Systems, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | name=installer-diag-$(date +"%Y%m%d-%H%M%S") 18 | tmpdir=$(mktemp -d) 19 | workdir=$tmpdir/$name 20 | trap "rm -rf $tmpdir" EXIT 21 | 22 | mkdir -p $workdir 23 | 24 | echo "Collecting data" 25 | cp -r /root/logs $workdir/logs 26 | dmesg &> $workdir/dmesg 27 | systemctl &> $workdir/systemctl 28 | lshw -quiet -json &> $workdir/lshw 29 | ifconfig -a &> $workdir/ifconfig 30 | route -n &> $workdir/ifconfig 31 | netstat -an &> $workdir/netstat 32 | df -k &> $workdir/df 33 | ps -aux &> $workdir/ps 34 | journalctl -x &> $workdir/journal 35 | 36 | # Failure is no longer an option 37 | set -e 38 | 39 | echo "Creating tarball" 40 | cd $tmpdir 41 | tar -jcf /root/$name.tar.bz2 $name 42 | 43 | echo "Authorizing upload" 44 | curlcmd=`/usr/bin/operosdiagauth $@ /root/$name.tar.bz2` 45 | 46 | echo "Uploading" 47 | eval $curlcmd 48 | -------------------------------------------------------------------------------- /components/diag/operosdiag.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Pax Automa Systems, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | name=operos-diag-$(date +"%Y%m%d-%H%M%S")-$(hostname) 18 | tmpdir=$(mktemp -d) 19 | workdir=$tmpdir/$name 20 | trap "rm -rf $tmpdir" EXIT 21 | 22 | . /etc/paxautoma/settings 23 | 24 | collect() { 25 | set -x 26 | 27 | echo " > System information" >&3 28 | hostname &> $workdir/hostname 29 | dmesg &> $workdir/dmesg 30 | systemctl &> $workdir/systemctl 31 | lshw -quiet -json &> $workdir/lshw 32 | ifconfig -a &> $workdir/ifconfig 33 | route -n &> $workdir/ifconfig 34 | netstat -an &> $workdir/netstat 35 | df -k &> $workdir/df 36 | ps -aux &> $workdir/ps 37 | cp /etc/paxautoma/settings $workdir/paxautoma-settings 38 | 39 | echo " > System logs" >&3 40 | journalctl -x &> $workdir/journal 41 | 42 | echo " > Docker image and container list" >&3 43 | docker images &> $workdir/docker-images 44 | docker ps -a &> $workdir/docker-ps 45 | 46 | if [ -e /etc/kubernetes/worker-kubeconfig.yml ]; then 47 | collect_kube --kubeconfig=/etc/kubernetes/worker-kubeconfig.yml -s "https://${OPEROS_CONTROLLER_IP}:8443" 48 | else 49 | collect_kube 50 | fi 51 | } 52 | 53 | collect_kube() { 54 | kubeargs=$@ 55 | 56 | echo " > Kubernetes node and Operos pod information" >&3 57 | kubectl $kubeargs cluster-info dump --namespaces kube-system,operos --output-directory=$workdir/kube-cluster-info 58 | } 59 | 60 | # Descriptor 3 always goes to stdout even if 1 & 2 are being redirected 61 | exec 3>&1 62 | 63 | echo "Collecting data" 64 | mkdir -p $workdir 65 | 66 | # Run in subshell to avoid set -x bleeding out 67 | (collect &> $workdir/collection-log) 68 | 69 | # Failure no longer an option 70 | set -e 71 | 72 | echo "Creating tarball" 73 | cd $tmpdir 74 | tar -jcf /root/$name.tar.bz2 $name 75 | 76 | echo "Authorizing upload" 77 | curlcmd=`operosdiagauth $@ --install=$OPEROS_INSTALL_ID /root/$name.tar.bz2` 78 | 79 | echo "Uploading" 80 | eval $curlcmd 81 | -------------------------------------------------------------------------------- /components/installer/installer.mk: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Pax Automa Systems, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | INSTALLER_FILES=$(shell find components/installer/ -name "*.go") 16 | 17 | .PHONY: installer-novm 18 | installer-novm: iso/installer/airootfs/root/installer 19 | iso/installer/airootfs/root/installer: .buildnum vendor $(INSTALLER_FILES) $(COMMON_FILES) 20 | mkdir -p $(dir $@) 21 | go build \ 22 | -v -i \ 23 | -ldflags "-X main.operosVersion=$(ISO_VERSION)" \ 24 | -o $@ ./components/installer/cmd/installer.go 25 | 26 | clean: clean-installer 27 | 28 | clean-installer: 29 | rm -f iso/installer/airootfs/root/installer 30 | -------------------------------------------------------------------------------- /components/installer/pkg/hardware_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package installer 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/stretchr/testify/require" 23 | ) 24 | 25 | func TestStrSize(t *testing.T) { 26 | require.Equal(t, "1", StrSize(1)) 27 | require.Equal(t, "100", StrSize(100)) 28 | require.Equal(t, "1024", StrSize(1024)) 29 | require.Equal(t, "1K", StrSize(1025)) 30 | require.Equal(t, "1.2K", StrSize(1200)) 31 | require.Equal(t, "120K", StrSize(122880)) 32 | require.Equal(t, "1.2M", StrSize(1300000)) 33 | require.Equal(t, "1.2M", StrSize(1300001)) 34 | require.Equal(t, "775.7T", StrSize(852852852852852)) 35 | } 36 | -------------------------------------------------------------------------------- /components/installer/pkg/network/helper.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package network 18 | 19 | import ( 20 | "encoding/binary" 21 | "net" 22 | ) 23 | 24 | func IncrementIP(ip net.IP, delta int) net.IP { 25 | ipAsInt := int(binary.BigEndian.Uint32(ip)) 26 | if len(ip) == 16 { 27 | ipAsInt = int(binary.BigEndian.Uint32(ip[12:16])) 28 | } 29 | 30 | newIP := ipAsInt + delta 31 | 32 | result := make([]byte, 4) 33 | binary.BigEndian.PutUint32(result, uint32(newIP)) 34 | return result 35 | } 36 | -------------------------------------------------------------------------------- /components/installer/pkg/network/helper_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package network 18 | 19 | import ( 20 | "net" 21 | "testing" 22 | 23 | "github.com/stretchr/testify/require" 24 | ) 25 | 26 | func TestIncrementIP_IncrementByOneNoRollover_ReturnsCorrectResult(t *testing.T) { 27 | ip := net.ParseIP("1.1.1.1") 28 | require.Equal(t, "1.1.1.2", IncrementIP(ip, 1).String()) 29 | } 30 | func TestIncrementIP_IncrementByOneWithRollover_ReturnsCorrectResult(t *testing.T) { 31 | ip := net.ParseIP("1.1.1.255") 32 | require.Equal(t, "1.1.2.0", IncrementIP(ip, 1).String()) 33 | } 34 | 35 | func TestIncrementIP_IncrementByNumberNoRollover_ReturnsCorrectResult(t *testing.T) { 36 | ip := net.ParseIP("1.1.1.1") 37 | require.Equal(t, "1.1.1.28", IncrementIP(ip, 27).String()) 38 | } 39 | 40 | func TestIncrementIP_IncrementByNumberWithRollover_ReturnsCorrectResult(t *testing.T) { 41 | ip := net.ParseIP("1.1.1.1") 42 | require.Equal(t, "1.1.2.45", IncrementIP(ip, 300).String()) 43 | } 44 | 45 | func TestIncrementIP_IncrementByNumberWithMultiRollover_ReturnsCorrectResult(t *testing.T) { 46 | ip := net.ParseIP("1.1.1.1") 47 | require.Equal(t, "1.1.40.17", IncrementIP(ip, 10000).String()) 48 | } 49 | -------------------------------------------------------------------------------- /components/installer/pkg/screens/disk.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package screens 18 | 19 | import ( 20 | "github.com/jroimartin/gocui" 21 | "github.com/paxautoma/operos/components/common/widgets" 22 | installer "github.com/paxautoma/operos/components/installer/pkg" 23 | ) 24 | 25 | func DiskSelectionScreen(screenSet *widgets.ScreenSet, context interface{}) *widgets.Screen { 26 | ctx := context.(*installer.InstallerContext) 27 | 28 | screen := widgets.NewScreen() 29 | screen.Title = "Controller disk" 30 | screen.Message = ` 31 | Please select which disk should be used to install the controller software. 32 | Only disks with at least 50GB are shown. 33 | 34 | ` + 35 | widgets.BoldString(gocui.ColorWhite, "Warning: all data on this disk will be deleted!") 36 | 37 | items := make([]widgets.MenuItem, len(ctx.Disks)) 38 | selectedIdx := -1 39 | for idx, disk := range ctx.Disks { 40 | items[idx] = &widgets.SimpleMenuItem{ 41 | Text: disk.String(), 42 | Value: disk.Name, 43 | } 44 | if disk.Name == ctx.Responses.ControllerDisk { 45 | selectedIdx = idx 46 | } 47 | } 48 | 49 | menu := widgets.NewMenu("menu-disk", items, 80, 6) 50 | menu.OnSelectItem = func(item widgets.MenuItem) error { 51 | smi := item.(*widgets.SimpleMenuItem) 52 | ctx.Responses.ControllerDisk = "/dev/" + smi.Value 53 | return nil 54 | } 55 | if selectedIdx >= 0 { 56 | menu.SelectItem(selectedIdx) 57 | } 58 | 59 | screen.Content = menu 60 | 61 | screen.OnNext = func() error { 62 | screenSet.Forward(1) 63 | return nil 64 | } 65 | 66 | screen.OnPrev = func() error { 67 | screenSet.Back(1) 68 | return nil 69 | } 70 | 71 | return screen 72 | } 73 | -------------------------------------------------------------------------------- /components/installer/pkg/screens/intro.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package screens 18 | 19 | import ( 20 | "github.com/jroimartin/gocui" 21 | 22 | "github.com/paxautoma/operos/components/common/widgets" 23 | installer "github.com/paxautoma/operos/components/installer/pkg" 24 | ) 25 | 26 | func IntroScreen(screenSet *widgets.ScreenSet, context interface{}) *widgets.Screen { 27 | screen := widgets.NewScreen() 28 | screen.Title = "Welcome to the Pax Automa Operos Installer." 29 | screen.Message = "Please select one of the following options to get started:" 30 | screen.ShowPrev(false) 31 | screen.ShowNext(false) 32 | 33 | menu := widgets.NewMenu("menu-main", []widgets.MenuItem{ 34 | &widgets.SimpleMenuItem{"Install", "install"}, 35 | &widgets.SimpleMenuItem{"Exit to shell", "shell"}, 36 | &widgets.SimpleMenuItem{"Reboot", "reboot"}, 37 | }, 80, 5) 38 | menu.EnterToSelect = true 39 | 40 | menu.OnSelectItem = func(item widgets.MenuItem) error { 41 | smi := item.(*widgets.SimpleMenuItem) 42 | switch smi.Value { 43 | case "install": 44 | screenSet.Forward(1) 45 | case "reboot": 46 | return installer.Reboot() 47 | case "shell": 48 | return gocui.ErrQuit 49 | } 50 | 51 | return nil 52 | } 53 | 54 | screen.Content = menu 55 | return screen 56 | } 57 | -------------------------------------------------------------------------------- /components/installer/pkg/screens/passwd.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package screens 18 | 19 | import ( 20 | "image" 21 | 22 | "github.com/paxautoma/operos/components/common/widgets" 23 | installer "github.com/paxautoma/operos/components/installer/pkg" 24 | ) 25 | 26 | func PasswordScreen(screenSet *widgets.ScreenSet, context interface{}) *widgets.Screen { 27 | ctx := context.(*installer.InstallerContext) 28 | 29 | screen := widgets.NewScreen() 30 | screen.Title = "Root password" 31 | screen.Message = ` 32 | This password will be required to log into the UI and the console. Please type 33 | it twice to avoid mistakes. 34 | ` 35 | screen.ShowNext(false) 36 | 37 | pwdLabel1 := widgets.NewPar("pwd-1", "Password:") 38 | pwdLabel1.Bounds = image.Rect(0, 0, 20, 0) 39 | pwdTextBox1 := widgets.NewTextbox("pwd-txt-1", "", true, 80) 40 | pwdTextBox1.Mask = '*' 41 | 42 | pwdLabel2 := widgets.NewPar("pwd-2", "Confirm password:") 43 | pwdLabel2.Bounds = image.Rect(0, 0, 20, 0) 44 | pwdTextBox2 := widgets.NewTextbox("pwd-txt-2", "", true, 80) 45 | pwdTextBox2.Mask = '*' 46 | 47 | check := func(_ string) { 48 | if pwdTextBox1.Value == pwdTextBox2.Value && pwdTextBox1.Value != "" && pwdTextBox2.Value != "" { 49 | screen.ShowNext(true) 50 | } else { 51 | screen.ShowNext(false) 52 | } 53 | } 54 | 55 | pwdTextBox1.OnChange = check 56 | pwdTextBox2.OnChange = check 57 | pwdTextBox1.OnEnter = func(value string) { 58 | screen.FocusableSet.Next() 59 | } 60 | pwdTextBox2.OnEnter = func(value string) { 61 | screen.FocusableSet.Next() 62 | } 63 | 64 | screen.OnPrev = func() error { 65 | screenSet.Back(1) 66 | return nil 67 | } 68 | 69 | screen.OnNext = func() error { 70 | ctx.Responses.RootPassword = pwdTextBox1.Value 71 | screenSet.Forward(1) 72 | return nil 73 | } 74 | 75 | vl := widgets.NewVerticalLayout() 76 | vl.Items = []widgets.Renderable{pwdLabel1, pwdTextBox1, pwdLabel2, pwdTextBox2} 77 | screen.Content = vl 78 | 79 | return screen 80 | } 81 | -------------------------------------------------------------------------------- /components/installer/pkg/util.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package installer 18 | 19 | import ( 20 | "os/exec" 21 | 22 | "github.com/jroimartin/gocui" 23 | ) 24 | 25 | type userError interface { 26 | IsUserError() bool 27 | } 28 | 29 | type temporary interface { 30 | Temporary() bool 31 | } 32 | 33 | func IsUserError(err error) bool { 34 | if userErr, ok := err.(userError); ok { 35 | return userErr.IsUserError() 36 | } 37 | return false 38 | } 39 | 40 | func IsTemporaryError(err error) bool { 41 | if tempErr, ok := err.(temporary); ok { 42 | return tempErr.Temporary() 43 | } 44 | return false 45 | } 46 | 47 | func Reboot() error { 48 | cmd := exec.Command("/sbin/reboot") 49 | err := cmd.Run() 50 | if err != nil { 51 | panic(err) 52 | } 53 | return gocui.ErrQuit 54 | } 55 | -------------------------------------------------------------------------------- /components/prospector/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | tmp/* 3 | debug 4 | -------------------------------------------------------------------------------- /components/prospector/cmd/showdevicetree_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import "testing" 20 | 21 | func Test_main(t *testing.T) { 22 | tests := []struct { 23 | name string 24 | }{ 25 | {name: "Check if it runs"}, 26 | } 27 | for range tests { 28 | main() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /components/prospector/prospector.mk: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Pax Automa Systems, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | PROSPECTOR_FILES=$(shell find components/prospector/ -name "*.go") 16 | 17 | .PHONY: prospector-novm 18 | prospector-novm: iso/worker/airootfs/usr/bin/prospector 19 | 20 | iso/worker/airootfs/usr/bin/prospector: $(PROSPECTOR_FILES) vendor 21 | mkdir -p $(dir $@) 22 | go build -v -o $@ ./components/prospector/cmd/prospector.go 23 | 24 | clean: clean-prospector 25 | 26 | clean-prospector: 27 | rm -f iso/worker/airootfs/usr/bin/prospector 28 | -------------------------------------------------------------------------------- /components/prospector/report.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package prospector 18 | 19 | type Report struct { 20 | System *DeviceTree `json:"hardware"` 21 | Storage BlockDevices `json:"storage"` 22 | } 23 | -------------------------------------------------------------------------------- /components/prospector/tst/README.md: -------------------------------------------------------------------------------- 1 | Files used in unit,system and integration tests. Do NOT move, rename of change files. It might brakes the tests! -------------------------------------------------------------------------------- /components/prospector/tst/lsblk/test1.json: -------------------------------------------------------------------------------- 1 | { 2 | "blockdevices": [ 3 | {"mountpoint": null, "name": "sda", "kname": "sda", "model": "Samsung SSD 840 ", "serial": "SSDFSDFSADF01H", "size": "477G", "rota": "0", "type": "disk", 4 | "children": [ 5 | {"mountpoint": "/", "name": "sda1", "kname": "sda1", "model": null, "serial": null, "size": "461.2G", "rota": "0", "type": "part"}, 6 | {"mountpoint": null, "name": "sda2", "kname": "sda2", "model": null, "serial": null, "size": "1K", "rota": "0", "type": "part"}, 7 | {"mountpoint": "[SWAP]", "name": "sda5", "kname": "sda5", "model": null, "serial": null, "size": "15.7G", "rota": "0", "type": "part"} 8 | ] 9 | }, 10 | {"mountpoint": "/snap/hello-world/27", "name": "loop0", "kname": "loop0", "model": null, "serial": null, "size": "20K", "rota": "1", "type": "loop"}, 11 | {"mountpoint": "/snap/shotcut/9", "name": "loop1", "kname": "loop1", "model": null, "serial": null, "size": "820.9M", "rota": "1", "type": "loop"} 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /components/prospector/tst/lsblk/test3.json: -------------------------------------------------------------------------------- 1 | { 2 | "blockdevices": [ 3 | {"mountpoint": null, "name": "sda", "kname": "sda", "model": "iSCSI Storage ", "serial": "6a50asdasadc6bd9", "size": "40G", "rota": "1", "type": "disk", 4 | "children": [ 5 | {"mountpoint": "/boot", "name": "sda1", "kname": "sda1", "model": null, "serial": null, "size": "487M", "rota": "1", "type": "part"}, 6 | {"mountpoint": null, "name": "sda2", "kname": "sda2", "model": null, "serial": null, "size": "1K", "rota": "1", "type": "part"}, 7 | {"mountpoint": null, "name": "sda5", "kname": "sda5", "model": null, "serial": null, "size": "39.5G", "rota": "1", "type": "part", 8 | "children": [ 9 | {"mountpoint": "/", "name": "shell--vg-root", "kname": "dm-0", "model": null, "serial": null, "size": "39G", "rota": "1", "type": "lvm"}, 10 | {"mountpoint": "[SWAP]", "name": "shell--vg-swap_1", "kname": "dm-1", "model": null, "serial": null, "size": "508M", "rota": "1", "type": "lvm"} 11 | ] 12 | } 13 | ] 14 | }, 15 | {"mountpoint": null, "name": "sr0", "kname": "sr0", "model": "QEMU DVD-ROM ", "serial": "QM00001", "size": "655M", "rota": "1", "type": "rom"}, 16 | {"mountpoint": null, "name": "sr1", "kname": "sr1", "model": "QEMU DVD-ROM ", "serial": "QM00002", "size": "1024M", "rota": "1", "type": "rom"} 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /components/prospector/tst/lsblk/test4.json: -------------------------------------------------------------------------------- 1 | { 2 | "blockdevices": [ 3 | {"mountpoint": null, "name": "sda", "kname": "sda", "model": "ST3000DM001-1ER1", "serial": "ZDSFL8C", "size": "2.7T", "rota": "1", "type": "disk", 4 | "children": [ 5 | {"mountpoint": "/home/medialib/media", "name": "sda1", "kname": "sda1", "model": null, "serial": null, "size": "2.7T", "rota": "1", "type": "part"} 6 | ] 7 | }, 8 | {"mountpoint": null, "name": "sdb", "kname": "sdb", "model": "SAMSUNG SP1614C ", "serial": "S345345754190", "size": "149.1G", "rota": "1", "type": "disk", 9 | "children": [ 10 | {"mountpoint": null, "name": "sdb1", "kname": "sdb1", "model": null, "serial": null, "size": "78.1G", "rota": "1", "type": "part"}, 11 | {"mountpoint": null, "name": "sdb2", "kname": "sdb2", "model": null, "serial": null, "size": "70.9G", "rota": "1", "type": "part"} 12 | ] 13 | }, 14 | {"mountpoint": null, "name": "sdd", "kname": "sdd", "model": "ST3000DM001-1ER1", "serial": "Z4534577", "size": "2.7T", "rota": "1", "type": "disk", 15 | "children": [ 16 | {"mountpoint": "/home", "name": "sdd1", "kname": "sdd1", "model": null, "serial": null, "size": "2.7T", "rota": "1", "type": "part"} 17 | ] 18 | }, 19 | {"mountpoint": null, "name": "sde", "kname": "sde", "model": "KINGSTON SV300S3", "serial": "503453459347598A", "size": "223.6G", "rota": "0", "type": "disk", 20 | "children": [ 21 | {"mountpoint": "/", "name": "sde1", "kname": "sde1", "model": null, "serial": null, "size": "223.6G", "rota": "0", "type": "part"} 22 | ] 23 | }, 24 | {"mountpoint": null, "name": "sr0", "kname": "sr0", "model": "CDDVDW SH-S203B ", "serial": null, "size": "1024M", "rota": "1", "type": "rom"}, 25 | {"mountpoint": "/snap/core/3247", "name": "loop0", "kname": "loop0", "model": null, "serial": null, "size": "83.1M", "rota": "1", "type": "loop"}, 26 | {"mountpoint": "/snap/core/3017", "name": "loop1", "kname": "loop1", "model": null, "serial": null, "size": "83M", "rota": "1", "type": "loop"}, 27 | {"mountpoint": "/snap/core/2898", "name": "loop2", "kname": "loop2", "model": null, "serial": null, "size": "81.4M", "rota": "1", "type": "loop"} 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /components/prospector/tst/lsblk/test5.json: -------------------------------------------------------------------------------- 1 | { 2 | "blockdevices": [ 3 | {"mountpoint": null, "name": "xvda", "kname": "xvda", "model": null, "serial": null, "size": "30G", "rota": "0", "type": "disk", 4 | "children": [ 5 | {"mountpoint": "/", "name": "xvda1", "kname": "xvda1", "model": null, "serial": null, "size": "30G", "rota": "0", "type": "part"} 6 | ] 7 | }, 8 | {"mountpoint": null, "name": "xvdc", "kname": "xvdc", "model": null, "serial": null, "size": "50G", "rota": "0", "type": "disk"} 9 | ] 10 | } 11 | 12 | -------------------------------------------------------------------------------- /components/prospector/tst/lsblk/test6.json: -------------------------------------------------------------------------------- 1 | { 2 | "blockdevices": [ 3 | {"mountpoint": "/mnt/worker_image", "name": "loop0", "kname": "loop0", "model": null, "serial": null, "size": "565M", "rota": "1", "type": "loop"}, 4 | {"mountpoint": null, "name": "sda", "kname": "sda", "model": "VBOX HARDDISK ", "serial": "VB5234234234-de234234", "size": "38G", "rota": "1", "type": "disk", 5 | "children": [ 6 | {"mountpoint": null, "name": "sda1", "kname": "sda1", "model": null, "serial": null, "size": "1M", "rota": "1", "type": "part"}, 7 | {"mountpoint": "/efi", "name": "sda2", "kname": "sda2", "model": null, "serial": null, "size": "512M", "rota": "1", "type": "part"}, 8 | {"mountpoint": "/boot", "name": "sda3", "kname": "sda3", "model": null, "serial": null, "size": "1G", "rota": "1", "type": "part"}, 9 | {"mountpoint": "[SWAP]", "name": "sda4", "kname": "sda4", "model": null, "serial": null, "size": "4G", "rota": "1", "type": "part"}, 10 | {"mountpoint": null, "name": "sda5", "kname": "sda5", "model": null, "serial": null, "size": "8G", "rota": "1", "type": "part"}, 11 | {"mountpoint": "/", "name": "sda6", "kname": "sda6", "model": null, "serial": null, "size": "24.5G", "rota": "1", "type": "part"} 12 | ] 13 | }, 14 | {"mountpoint": null, "name": "sr0", "kname": "sr0", "model": "CD-ROM ", "serial": "VB2-01234234234", "size": "1024M", "rota": "1", "type": "rom"} 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /components/prospector/tst/lsblk/test7.json: -------------------------------------------------------------------------------- 1 | { 2 | "blockdevices": [ 3 | {"mountpoint": "/run/archiso/sfs/airootfs", "name": "loop0", "kname": "loop0", "model": null, "serial": null, "size": "503M", "rota": "1", "type": "loop"}, 4 | {"mountpoint": null, "name": "sda", "kname": "sda", "model": "VBOX HARDDISK ", "serial": "VB374223234234-82232349", "size": "40G", "rota": "1", "type": "disk", 5 | "children": [ 6 | {"mountpoint": "/storage/system", "name": "sda1", "kname": "sda1", "model": null, "serial": null, "size": "20G", "rota": "1", "type": "part"}, 7 | {"mountpoint": "/storage/data", "name": "sda2", "kname": "sda2", "model": null, "serial": null, "size": "20G", "rota": "1", "type": "part"} 8 | ] 9 | }, 10 | {"mountpoint": null, "name": "sr0", "kname": "sr0", "model": "CD-ROM ", "serial": "VB0-01f2342342342", "size": "1024M", "rota": "1", "type": "rom"} 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /components/prospector/tst/lsblk/test8.json: -------------------------------------------------------------------------------- 1 | { 2 | "blockdevices": [ 3 | {"mountpoint": "/run/archiso/sfs/airootfs", "name": "loop0", "kname": "loop0", "model": null, "serial": null, "size": "510.6M", "rota": "1", "type": "loop"}, 4 | {"mountpoint": null, "name": "sda", "kname": "sda", "model": "VBOX HARDDISK ", "serial": "VB602342342343464-33123123123", "size": "40G", "rota": "1", "type": "disk", 5 | "children": [ 6 | {"mountpoint": null, "name": "sda1", "kname": "sda1", "model": null, "serial": null, "size": "20G", "rota": "1", "type": "part"}, 7 | {"mountpoint": null, "name": "sda2", "kname": "sda2", "model": null, "serial": null, "size": "20G", "rota": "1", "type": "part"} 8 | ] 9 | }, 10 | {"mountpoint": "/run/archiso/bootmnt", "name": "sr0", "kname": "sr0", "model": "CD-ROM ", "serial": "VB0-01f031234234234", "size": "572M", "rota": "1", "type": "rom"} 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /components/statustty/pkg/hostname.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package statustty 18 | 19 | import ( 20 | "os" 21 | "time" 22 | 23 | log "github.com/sirupsen/logrus" 24 | ) 25 | 26 | func SubscribeHostname(closer <-chan struct{}) <-chan *string { 27 | ch := make(chan *string) 28 | 29 | go func() { 30 | ch <- GetHostname() 31 | ticker := time.NewTicker(3 * time.Second) 32 | 33 | for { 34 | select { 35 | case _, ok := <-closer: 36 | if !ok { 37 | break 38 | } 39 | case <-ticker.C: 40 | ch <- GetHostname() 41 | } 42 | } 43 | }() 44 | 45 | return ch 46 | } 47 | 48 | func GetHostname() *string { 49 | name, err := os.Hostname() 50 | if err != nil { 51 | log.Errorf("cannot get hostname: %v", err) 52 | return nil 53 | } 54 | return &name 55 | } 56 | -------------------------------------------------------------------------------- /components/statustty/pkg/kube.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package statustty 18 | 19 | import ( 20 | "net/http" 21 | "time" 22 | 23 | "github.com/paxautoma/operos/components/common" 24 | 25 | log "github.com/sirupsen/logrus" 26 | ) 27 | 28 | type KubeStatus struct { 29 | Reachable bool 30 | } 31 | 32 | func SubscribeKubeStatus(kubeURL string, closer <-chan struct{}) <-chan *KubeStatus { 33 | ch := make(chan *KubeStatus) 34 | 35 | if kubeURL != "" { 36 | go func() { 37 | defer common.LogPanic() 38 | 39 | ch <- GetKubeStatus(kubeURL) 40 | 41 | ticker := time.NewTicker(5 * time.Second) 42 | defer ticker.Stop() 43 | 44 | for { 45 | select { 46 | case _, ok := <-closer: 47 | if !ok { 48 | break 49 | } 50 | case <-ticker.C: 51 | ch <- GetKubeStatus(kubeURL) 52 | } 53 | 54 | } 55 | }() 56 | } 57 | 58 | return ch 59 | } 60 | 61 | func GetKubeStatus(kubeURL string) *KubeStatus { 62 | resp, err := http.Get(kubeURL) 63 | if err != nil { 64 | log.Debugf("could not reach kubernetes: %v", err) 65 | return &KubeStatus{Reachable: false} 66 | } 67 | defer resp.Body.Close() 68 | 69 | return &KubeStatus{Reachable: true} 70 | } 71 | -------------------------------------------------------------------------------- /components/statustty/pkg/net_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package statustty 18 | 19 | import ( 20 | "fmt" 21 | "net" 22 | "strings" 23 | "testing" 24 | 25 | "github.com/stretchr/testify/require" 26 | ) 27 | 28 | func TestGetBootIfaceFromCmdLine(t *testing.T) { 29 | errorTests := []struct { 30 | name string 31 | cmdline string 32 | errString string 33 | }{ 34 | { 35 | "NoArg_ReturnsError", 36 | "foo bar blah yahoo=hello foofoo=yes", 37 | "does not contain BOOT_IF", 38 | }, 39 | { 40 | "NoValue_ReturnsError", 41 | "foo bar blah yahoo=hello foofoo=yes BOOTIF=", 42 | "invalid format", 43 | }, 44 | { 45 | "ValueTooShort_ReturnsError", 46 | "foo bar blah yahoo=hello foofoo=yes BOOTIF=00-11-22-33-44-55", 47 | "invalid format", 48 | }, 49 | { 50 | "NotRealMac_ReturnsError", 51 | "foo bar blah yahoo=hello foofoo=yes BOOTIF=01-00-11-22-33-44-55", 52 | "not found", 53 | }, 54 | } 55 | 56 | for _, test := range errorTests { 57 | t.Run(test.name, func(t *testing.T) { 58 | _, err := GetBootIfaceFromCmdLine(test.cmdline) 59 | require.Error(t, err) 60 | require.Contains(t, err.Error(), test.errString) 61 | }) 62 | } 63 | 64 | ifaces, err := net.Interfaces() 65 | require.NoError(t, err) 66 | realMac := "01-" + strings.Replace(ifaces[1].HardwareAddr.String(), ":", "-", -1) 67 | realIfName := ifaces[1].Name 68 | 69 | goodTests := []struct { 70 | name string 71 | cmdline string 72 | }{ 73 | { 74 | "RealMac_ReturnsInterfaceName", 75 | fmt.Sprintf("foo bar blah yahoo=hello foofoo=yes BOOTIF=%s", realMac), 76 | }, 77 | } 78 | 79 | for _, test := range goodTests { 80 | t.Run(test.name, func(t *testing.T) { 81 | res, err := GetBootIfaceFromCmdLine(test.cmdline) 82 | require.NoError(t, err) 83 | require.Equal(t, res, realIfName) 84 | }) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /components/statustty/statustty.mk: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Pax Automa Systems, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | STATUSTTY_FILES=$(shell find components/statustty/ -name "*.go") 16 | 17 | .PHONY: statustty-novm 18 | statustty-novm: iso/node/airootfs/usr/bin/statustty 19 | iso/node/airootfs/usr/bin/statustty: .buildnum $(STATUSTTY_FILES) $(COMMON_FILES) vendor 20 | mkdir -p $(dir $@) 21 | go build \ 22 | -v -i \ 23 | -ldflags "-X main.operosVersion=$(ISO_VERSION)" \ 24 | -o $@ ./components/statustty/cmd/main.go 25 | 26 | clean: clean-statustty 27 | 28 | clean-statustty: 29 | rm -f iso/node/airootfs/usr/bin/statustty 30 | -------------------------------------------------------------------------------- /components/teamster/.gitignore: -------------------------------------------------------------------------------- 1 | build/* 2 | vendor/ 3 | *.pb.go 4 | -------------------------------------------------------------------------------- /components/teamster/pkg/tarball/tarball.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package tarball 18 | 19 | import ( 20 | "archive/tar" 21 | "bytes" 22 | "compress/gzip" 23 | "fmt" 24 | "log" 25 | "net/http" 26 | "strconv" 27 | 28 | "github.com/pkg/errors" 29 | ) 30 | 31 | type ManifestFile struct { 32 | Fstat tar.Header 33 | Content ManifestFileContent 34 | } 35 | 36 | type ManifestFileContent func(interface{}, *bytes.Buffer) error 37 | 38 | type Manifest []ManifestFile 39 | 40 | func CreateTarPkg(manifest Manifest, ctx interface{}) ([]byte, error) { 41 | buf := new(bytes.Buffer) 42 | gzwriter := gzip.NewWriter(buf) 43 | writer := tar.NewWriter(gzwriter) 44 | for _, file := range manifest { 45 | var data bytes.Buffer 46 | if err := file.Content(ctx, &data); err != nil { 47 | return nil, errors.Wrap(err, "cannot write manifest file") 48 | } 49 | cheader := file.Fstat 50 | cheader.Size = int64(data.Len()) 51 | if err := writer.WriteHeader(&cheader); err != nil { 52 | return nil, errors.Wrap(err, "cannot write header") 53 | } 54 | 55 | if _, err := writer.Write(data.Bytes()); err != nil { 56 | return nil, errors.Wrap(err, "cannot write data") 57 | } 58 | } 59 | 60 | if err := writer.Close(); err != nil { 61 | return nil, errors.Wrap(err, "cannot close writer") 62 | } 63 | 64 | if err := gzwriter.Close(); err != nil { 65 | return nil, errors.Wrap(err, "cannot close gzip") 66 | } 67 | 68 | return buf.Bytes(), nil 69 | } 70 | 71 | func SendTarball(manifest Manifest, ctx interface{}, w http.ResponseWriter, filename string) { 72 | pkgBytes, err := CreateTarPkg(manifest, ctx) 73 | if err != nil { 74 | log.Println(err) 75 | return 76 | } 77 | 78 | w.Header().Set("Content-Type", "application/octet-stream") 79 | w.Header().Set("Content-Length", strconv.Itoa(len(pkgBytes))) 80 | w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", filename)) 81 | w.WriteHeader(http.StatusOK) 82 | w.Write(pkgBytes) 83 | } 84 | -------------------------------------------------------------------------------- /components/teamster/pkg/teamster/teamster.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Pax Automa Systems, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | package teamster; 17 | 18 | message Empty {} 19 | 20 | message NodeSummary { 21 | string uuid = 1; 22 | } 23 | 24 | message ListNodesResponse { 25 | repeated NodeSummary nodes = 1; 26 | } 27 | 28 | message GetNodeHardwareRequest { 29 | string uuid = 1; 30 | } 31 | 32 | message GetNodeHardwareResponse { 33 | string hardware_info = 1; 34 | } 35 | 36 | message GetCACertExpiryResponse { 37 | int64 expiry_unix = 1; 38 | } 39 | 40 | message SetRootPasswordRequest { 41 | string password = 1; 42 | } 43 | 44 | service Teamster { 45 | rpc ListNodes (Empty) returns (ListNodesResponse); 46 | rpc GetNodeHardware (GetNodeHardwareRequest) returns (GetNodeHardwareResponse); 47 | rpc GetCACertExpiry (Empty) returns (GetCACertExpiryResponse); 48 | rpc SetRootPassword (SetRootPasswordRequest) returns (Empty); 49 | } 50 | -------------------------------------------------------------------------------- /components/teamster/teamster.mk: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Pax Automa Systems, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | TEAMSTER_FILES=$(shell find components/teamster/ -name "*.go") 16 | 17 | .PHONY: teamster-novm 18 | teamster-novm: iso/controller/airootfs/usr/bin/teamster 19 | 20 | iso/controller/airootfs/usr/bin/teamster: components/teamster/pkg/teamster/teamster.pb.go $(TEAMSTER_FILES) vendor 21 | mkdir -p $(dir $@) 22 | go build -v -o $@ ./components/teamster/cmd/main.go 23 | 24 | clean: clean-teamster 25 | 26 | clean-teamster: 27 | rm -f iso/controller/airootfs/usr/bin/teamster 28 | rm -f components/teamster/pkg/teamster/teamster.pb.go 29 | -------------------------------------------------------------------------------- /components/waterfront/.gitignore: -------------------------------------------------------------------------------- 1 | client/node_modules/ 2 | server/vendor/ 3 | dist/ 4 | *.pb.go 5 | -------------------------------------------------------------------------------- /components/waterfront/client/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "react", 5 | "stage-0" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /components/waterfront/client/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "plugins": [ 4 | "react" 5 | ], 6 | "parserOptions": { 7 | "ecmaVersion": 6, 8 | "sourceType": "module", 9 | "ecmaFeatures": { 10 | "jsx": true 11 | } 12 | }, 13 | "env": { 14 | "browser": true, 15 | "amd": true, 16 | "es6": true, 17 | "node": true, 18 | "mocha": true 19 | }, 20 | "extends": "eslint:recommended", 21 | "rules": { 22 | "comma-dangle": ["warn", "only-multiline"], 23 | "quotes": ["warn", "single"], 24 | "no-undef": "warn", 25 | "no-console": "warn", 26 | "no-unused-vars": ["warn", { 27 | "varsIgnorePattern": "^_.*", 28 | "argsIgnorePattern": "^_.*", 29 | "args": "all" 30 | }], 31 | "no-trailing-spaces": ["warn", { "skipBlankLines": true }], 32 | "react/jsx-uses-react": "warn", 33 | "react/jsx-uses-vars": "warn", 34 | "semi": ["error", "always"] 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /components/waterfront/client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pa-dashboard", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "serve": "webpack-dev-server --progress --config webpack.dev.js", 8 | "build": "webpack --config webpack.prod.js" 9 | }, 10 | "dependencies": { 11 | "chart.js": "^2.7.0", 12 | "classnames": "^2.2.5", 13 | "color": "^2.0.0", 14 | "graphql": "^0.11.3", 15 | "graphql-tools": "^1.2.2", 16 | "graphql-type-json": "^0.1.4", 17 | "human-format": "^0.8.0", 18 | "material-ui": "next", 19 | "moment": "^2.19.1", 20 | "prop-types": "^15.5.10", 21 | "query-string": "^5.0.0", 22 | "react": "^15.5.4", 23 | "react-apollo": "^1.4.15", 24 | "react-chartjs-2": "^2.6.4", 25 | "react-dom": "^15.5.4", 26 | "react-jss": "^6.1.1", 27 | "react-redux": "^5.0.5", 28 | "react-router-dom": "^4.1.1", 29 | "react-tap-event-plugin": "^2.0.1", 30 | "redux": "^3.6.0", 31 | "redux-logger": "^3.0.6", 32 | "redux-thunk": "^2.2.0", 33 | "reselect": "^3.0.1", 34 | "rest": "^2.0.0" 35 | }, 36 | "devDependencies": { 37 | "babel-cli": "^6.24.1", 38 | "babel-core": "^6.24.1", 39 | "babel-eslint": "^7.2.3", 40 | "babel-loader": "^7.0.0", 41 | "babel-preset-env": "^1.5.1", 42 | "babel-preset-es2015": "^6.24.1", 43 | "babel-preset-react": "^6.24.1", 44 | "babel-preset-stage-0": "^6.24.1", 45 | "eslint": "^3.19.0", 46 | "eslint-loader": "^1.7.1", 47 | "eslint-plugin-react": "^7.0.1", 48 | "uglifyjs-webpack-plugin": "^0.4.6", 49 | "webpack": "^2.6.1", 50 | "webpack-dev-server": "^2.4.5", 51 | "webpack-merge": "^4.1.0" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /components/waterfront/client/src/components/RefreshIndicator.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import React from 'react'; 18 | import {CircularProgress} from 'material-ui/Progress'; 19 | import {withStyles} from 'material-ui/styles'; 20 | 21 | const styles = { 22 | loading: { 23 | display: 'flex', 24 | alignItems: 'center', 25 | justifyContent: 'center', 26 | position: 'relative', 27 | width: props => props.width || '100%', 28 | height: props => props.height || 80 29 | } 30 | }; 31 | 32 | class RefreshIndicator extends React.Component { 33 | render() { 34 | const {classes, hide} = this.props; 35 | 36 | if (hide) { 37 | return null; 38 | } 39 | 40 | return ( 41 |
42 | 43 |
44 | ); 45 | } 46 | } 47 | 48 | export default withStyles(styles)(RefreshIndicator); 49 | -------------------------------------------------------------------------------- /components/waterfront/client/src/components/chart/Bar.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import {Bar} from 'react-chartjs-2'; 18 | 19 | import timeseriesQueriableChart from 'components/chart/timeseriesQueriableChart'; 20 | 21 | export default timeseriesQueriableChart(Bar, {}, {}); 22 | -------------------------------------------------------------------------------- /components/waterfront/client/src/components/chart/Line.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import {Line} from 'react-chartjs-2'; 18 | 19 | import timeseriesQueriableChart from 'components/chart/timeseriesQueriableChart'; 20 | 21 | const datasetDefaults = { 22 | pointHitRadius: 5, 23 | pointHoverRadius: 3, 24 | pointRadius: 0 25 | }; 26 | 27 | export default timeseriesQueriableChart(Line, {}, datasetDefaults); 28 | -------------------------------------------------------------------------------- /components/waterfront/client/src/components/chart/SingleStat.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import React from 'react'; 18 | import {withStyles} from 'material-ui/styles'; 19 | import classNames from 'classnames'; 20 | 21 | import formatLabel from 'components/chart/format'; 22 | import withQueries from 'components/chart/withQueries'; 23 | 24 | const styles = { 25 | title: { 26 | fontSize: 14, 27 | marginBottom: 18 28 | }, 29 | value: { 30 | fontSize: 30 31 | }, 32 | container: { 33 | textAlign: 'center', 34 | padding: 8, 35 | color: 'rgba(0, 0, 0, 0.6)' 36 | } 37 | }; 38 | 39 | class SingleStat extends React.Component { 40 | render() { 41 | const {title, data, classes, format, className} = this.props; 42 | 43 | return ( 44 |
45 |

{title}

46 |
{formatLabel(data.datasets[0].data, format)}
47 |
48 | ); 49 | } 50 | } 51 | 52 | export default withStyles(styles)(withQueries(false)(SingleStat)); 53 | -------------------------------------------------------------------------------- /components/waterfront/client/src/components/chart/colors.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // These are the colors that Grafana uses 18 | export const palette = [ 19 | '#7EB26D', '#EAB839', '#6ED0E0', '#EF843C', '#E24D42', '#1F78C1', '#BA43A9', '#705DA0', 20 | '#508642', '#CCA300', '#447EBC', '#C15C17', '#890F02', '#0A437C', '#6D1F62', '#584477', 21 | '#B7DBAB', '#F4D598', '#70DBED', '#F9BA8F', '#F29191', '#82B5D8', '#E5A8E2', '#AEA2E0', 22 | '#629E51', '#E5AC0E', '#64B0C8', '#E0752D', '#BF1B00', '#0A50A1', '#962D82', '#614D93', 23 | '#9AC48A', '#F2C96D', '#65C5DB', '#F9934E', '#EA6460', '#5195CE', '#D683CE', '#806EB7', 24 | '#3F6833', '#967302', '#2F575E', '#99440A', '#58140C', '#052B51', '#511749', '#3F2B5B', 25 | '#E0F9D7', '#FCEACA', '#CFFAFF', '#F9E2D2', '#FCE2DE', '#BADFF4', '#F9D9F9', '#DEDAF7' 26 | ]; 27 | 28 | export const levels = [ 29 | 'rgba(50, 172, 45, 0.97)', 30 | 'rgba(237, 129, 40, 0.89)', 31 | 'rgba(245, 54, 54, 0.9)' 32 | ]; 33 | 34 | export const noval = 'rgba(0, 0, 0, 0.1)'; 35 | -------------------------------------------------------------------------------- /components/waterfront/client/src/components/chart/format.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import humanFormat from 'human-format'; 18 | 19 | export default function formatLabel(number, format) { 20 | return (number < 0 ? '-' : '') + humanFormat(Math.abs(number), format); 21 | } 22 | -------------------------------------------------------------------------------- /components/waterfront/client/src/components/withLoader.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import React from 'react'; 18 | import Button from 'material-ui/Button'; 19 | 20 | import RefreshIndicator from 'components/RefreshIndicator'; 21 | 22 | const withLoader = (WrappedComponent) => { 23 | return class extends React.Component { 24 | render() { 25 | if (this.props.data.loading) { 26 | return ; 27 | } else if (this.props.data.error) { 28 | return ( 29 |
30 |

An error has occurred: {this.props.data.error.message}.

31 | 32 |
33 | ); 34 | } else { 35 | return ; 36 | } 37 | } 38 | }; 39 | }; 40 | 41 | export default withLoader; 42 | -------------------------------------------------------------------------------- /components/waterfront/client/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Pax Automa Dashboard 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /components/waterfront/client/src/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import React from 'react'; 18 | import ReactDOM from 'react-dom'; 19 | import {ApolloClient, ApolloProvider} from 'react-apollo'; 20 | import 'chart.js'; 21 | 22 | import LocalNetworkInterface from 'service/LocalNetworkInterface'; 23 | import schema from 'service/schema'; 24 | import ApiClient from 'service/apiclient'; 25 | import App from 'app/App'; 26 | 27 | // Needed for onTouchTap 28 | // http://stackoverflow.com/a/34015469/988941 29 | import injectTapEventPlugin from 'react-tap-event-plugin'; 30 | injectTapEventPlugin(); 31 | 32 | // Default chart options 33 | Chart.defaults.global.defaultFontFamily = 'Roboto'; 34 | 35 | const apiClient = new ApiClient(process.env.API_BASE_URL); 36 | const apolloClient = new ApolloClient({ 37 | networkInterface: new LocalNetworkInterface(schema, {apiClient}), 38 | dataIdFromObject: object => { 39 | if (object.__typename) { 40 | if (object.id !== undefined) { 41 | return `${object.__typename}:${object.id}`; 42 | } else { 43 | return `${object.__typename}:`; 44 | } 45 | } 46 | return null; 47 | } 48 | }); 49 | 50 | ReactDOM.render( 51 | 52 | 53 | , 54 | document.getElementById('app') 55 | ); 56 | -------------------------------------------------------------------------------- /components/waterfront/client/src/service/LocalNetworkInterface.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import {graphql} from 'graphql'; 18 | import {printAST} from 'apollo-client'; 19 | 20 | export default class LocalNetworkInterface { 21 | constructor(schema, context) { 22 | this.schema = schema; 23 | this.context = context; 24 | } 25 | 26 | query(request) { 27 | return graphql( 28 | this.schema, 29 | printAST(request.query), 30 | null, 31 | this.context, 32 | request.variables, 33 | request.operationName 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /components/waterfront/client/src/service/schema.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import {makeExecutableSchema} from 'graphql-tools'; 18 | import GraphQLJSON from 'graphql-type-json'; 19 | 20 | const typeDefs = ` 21 | scalar JSON 22 | 23 | enum NodeStatus { 24 | NOT_READY 25 | READY 26 | } 27 | 28 | type Node { 29 | id: String! 30 | status: NodeStatus! 31 | ip: String 32 | pod_cidr: String 33 | hardware_info: String 34 | } 35 | 36 | type ClusterInfo { 37 | settings: JSON 38 | } 39 | 40 | type User { 41 | username: String! 42 | loging_time: String! 43 | } 44 | 45 | type LoginInfo { 46 | logged_in: Boolean! 47 | user: User 48 | } 49 | 50 | type Query { 51 | nodes: [Node]! 52 | node(id: String!): Node 53 | cluster_info: ClusterInfo! 54 | login_info: LoginInfo! 55 | } 56 | 57 | type Mutation { 58 | login(username: String!, password: String!): LoginInfo! 59 | logout: LoginInfo! 60 | } 61 | 62 | schema { 63 | query: Query 64 | mutation: Mutation 65 | } 66 | `; 67 | 68 | const resolvers = { 69 | Query: { 70 | nodes: (_obj, _args, {apiClient}) => apiClient.getNodes(), 71 | node: (_obj, args, {apiClient}) => apiClient.getNode(args.id), 72 | cluster_info: (_obj, _args, {apiClient}) => apiClient.getClusterInfo(), 73 | login_info: (_obj, _args, {apiClient}) => apiClient.getLoginInfo() 74 | }, 75 | Node: { 76 | status: node => node.status || 'NOT_READY' 77 | }, 78 | Mutation: { 79 | login: (_obj, args, {apiClient}) => apiClient.login(args.username, args.password), 80 | logout: (_obj, args, {apiClient}) => apiClient.logout() 81 | }, 82 | JSON: GraphQLJSON 83 | }; 84 | 85 | export default makeExecutableSchema({typeDefs, resolvers}); 86 | -------------------------------------------------------------------------------- /components/waterfront/client/src/static/fonts/MaterialIcons-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaxAutoma/operos/2d1c5127eb5ce32c667c0f1a927457b41d7ae709/components/waterfront/client/src/static/fonts/MaterialIcons-Regular.eot -------------------------------------------------------------------------------- /components/waterfront/client/src/static/fonts/MaterialIcons-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaxAutoma/operos/2d1c5127eb5ce32c667c0f1a927457b41d7ae709/components/waterfront/client/src/static/fonts/MaterialIcons-Regular.ttf -------------------------------------------------------------------------------- /components/waterfront/client/src/static/fonts/MaterialIcons-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaxAutoma/operos/2d1c5127eb5ce32c667c0f1a927457b41d7ae709/components/waterfront/client/src/static/fonts/MaterialIcons-Regular.woff -------------------------------------------------------------------------------- /components/waterfront/client/src/static/fonts/MaterialIcons-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaxAutoma/operos/2d1c5127eb5ce32c667c0f1a927457b41d7ae709/components/waterfront/client/src/static/fonts/MaterialIcons-Regular.woff2 -------------------------------------------------------------------------------- /components/waterfront/client/src/static/login-top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaxAutoma/operos/2d1c5127eb5ce32c667c0f1a927457b41d7ae709/components/waterfront/client/src/static/login-top.png -------------------------------------------------------------------------------- /components/waterfront/client/src/static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaxAutoma/operos/2d1c5127eb5ce32c667c0f1a927457b41d7ae709/components/waterfront/client/src/static/logo.png -------------------------------------------------------------------------------- /components/waterfront/client/src/static/main.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Roboto:300,400,500'); 2 | 3 | @font-face { 4 | font-family: 'Material Icons'; 5 | font-style: normal; 6 | font-weight: 400; 7 | src: url(/static/fonts/MaterialIcons-Regular.eot); /* For IE6-8 */ 8 | src: local('Material Icons'), 9 | local('MaterialIcons-Regular'), 10 | url(/static/fonts/MaterialIcons-Regular.woff2) format('woff2'), 11 | url(/static/fonts/MaterialIcons-Regular.woff) format('woff'), 12 | url(/static/fonts/MaterialIcons-Regular.ttf) format('truetype'); 13 | } 14 | 15 | .material-icons { 16 | font-family: 'Material Icons'; 17 | font-weight: normal; 18 | font-style: normal; 19 | font-size: 24px; /* Preferred icon size */ 20 | display: inline-block; 21 | line-height: 1; 22 | text-transform: none; 23 | letter-spacing: normal; 24 | word-wrap: normal; 25 | white-space: nowrap; 26 | direction: ltr; 27 | 28 | /* Support for all WebKit browsers. */ 29 | -webkit-font-smoothing: antialiased; 30 | /* Support for Safari and Chrome. */ 31 | text-rendering: optimizeLegibility; 32 | 33 | /* Support for Firefox. */ 34 | -moz-osx-font-smoothing: grayscale; 35 | 36 | /* Support for IE. */ 37 | font-feature-settings: 'liga'; 38 | } 39 | 40 | a { 41 | text-decoration: none; 42 | } 43 | 44 | a:hover { 45 | text-decoration: underline; 46 | } 47 | 48 | html { 49 | font-family: 'Roboto', sans-serif; 50 | -webkit-font-smoothing: antialiased; 51 | } 52 | 53 | body, h1, h2, h3, h4, h5, h6 { 54 | margin: 0; 55 | } 56 | 57 | body { 58 | font-size: 14px; 59 | line-height: 24px; 60 | } 61 | /* 62 | .vizceral { 63 | height: 100%; 64 | width: 100%; 65 | } */ 66 | 67 | /*.vizceral { 68 | display: initial; 69 | text-align: left; 70 | width: 100%; 71 | background-color: rgb(35, 35, 35); 72 | } 73 | 74 | .vizceral canvas { 75 | height: 600px !important; 76 | } 77 | */ -------------------------------------------------------------------------------- /components/waterfront/client/src/views/about/AboutView.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import React from 'react'; 18 | import {graphql, gql} from 'react-apollo'; 19 | 20 | import Typography from 'material-ui/Typography'; 21 | import Table, { TableBody, TableCell, TableHead, TableRow } from 'material-ui/Table'; 22 | import {withStyles} from 'material-ui/styles'; 23 | 24 | const styles = { 25 | description: { 26 | margin: '8px 0 16px' 27 | } 28 | }; 29 | 30 | class AboutView extends React.Component { 31 | render() { 32 | const {data, classes} = this.props; 33 | 34 | if (data.loading) { 35 | return
Loading
; 36 | } 37 | 38 | return ( 39 |
40 | 41 | About Operos 42 | 43 | 44 | 45 | The following is a list of the settings that apply to this 46 | installation of Operos. 47 | 48 | 49 | 50 | 51 | 52 | Setting name 53 | Value 54 | 55 | 56 | 57 | { Object.keys(data.cluster_info.settings).map(k => ( 58 | 59 | {k} 60 | {data.cluster_info.settings[k]} 61 | 62 | ))} 63 | 64 |
65 |
66 | ); 67 | } 68 | } 69 | 70 | export default graphql(gql` 71 | query { 72 | cluster_info { 73 | settings 74 | } 75 | } 76 | `)(withStyles(styles)(AboutView)); 77 | -------------------------------------------------------------------------------- /components/waterfront/client/src/views/about/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import AboutView from 'views/about/AboutView'; 18 | 19 | export default { 20 | menuItem: { 21 | name: 'About', 22 | icon: 'help', 23 | link: '/about' 24 | }, 25 | views: [ 26 | { 27 | path: '/about', 28 | component: AboutView 29 | } 30 | ] 31 | }; 32 | -------------------------------------------------------------------------------- /components/waterfront/client/src/views/access/AccessManagementView.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import React from 'react'; 18 | import {withStyles} from 'material-ui/styles'; 19 | 20 | import CredentialsCard from 'views/access/CredentialsCard'; 21 | import RootPasswordCard from 'views/access/RootPasswordCard'; 22 | 23 | 24 | const styles = { 25 | container: { 26 | display: 'flex', 27 | flexDirection: 'column' 28 | }, 29 | card: { 30 | maxWidth: 800, 31 | marginBottom: 16 32 | } 33 | }; 34 | 35 | class AccessManagementView extends React.Component { 36 | render() { 37 | const {classes} = this.props; 38 | 39 | return ( 40 |
41 | 42 | 43 |
44 | ); 45 | } 46 | } 47 | 48 | export default withStyles(styles)(AccessManagementView); 49 | -------------------------------------------------------------------------------- /components/waterfront/client/src/views/access/CredentialsCard.jsx: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import React from 'react'; 18 | import Card, {CardContent, CardActions} from 'material-ui/Card'; 19 | import Typography from 'material-ui/Typography'; 20 | import Button from 'material-ui/Button'; 21 | import {withStyles} from 'material-ui/styles'; 22 | 23 | const styles = { 24 | }; 25 | 26 | class CredentialsCard extends React.Component { 27 | onDownloadCredentials() { 28 | window.open(`${process.env.API_BASE_URL}/clientcert`, '_blank'); 29 | } 30 | 31 | render() { 32 | const {classes, className} = this.props; 33 | 34 | return ( 35 | 36 | 37 | 38 | API and kubectl access 39 | 40 | 41 | Click the button below to generate and download TLS certificate credentials 42 | that can be used to control the Operos Kubernetes instance via 43 | the REST API or kubectl. 44 | 45 | 46 | 47 | 50 | 51 | 52 | ); 53 | } 54 | } 55 | 56 | export default withStyles(styles)(CredentialsCard); 57 | -------------------------------------------------------------------------------- /components/waterfront/client/src/views/access/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import AccessManagementView from 'views/access/AccessManagementView'; 18 | 19 | export default { 20 | menuItem: { 21 | name: 'Access', 22 | icon: 'lock', 23 | link: '/access' 24 | }, 25 | views: [ 26 | { 27 | path: '/access', 28 | component: AccessManagementView 29 | } 30 | ] 31 | }; 32 | -------------------------------------------------------------------------------- /components/waterfront/client/src/views/cluster/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import ClusterOverviewView from 'views/cluster/ClusterOverviewView'; 18 | 19 | export default { 20 | menuItem: { 21 | name: 'Cluster overview', 22 | icon: 'home', 23 | link: '/cluster' 24 | }, 25 | views: [ 26 | { 27 | path: '/cluster', 28 | component: ClusterOverviewView 29 | } 30 | ] 31 | }; 32 | -------------------------------------------------------------------------------- /components/waterfront/client/src/views/metrics/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import MetricsView from 'views/metrics/MetricsView'; 18 | 19 | export default { 20 | menuItem: { 21 | name: 'Metrics', 22 | icon: 'show_chart', 23 | link: '/metrics' 24 | }, 25 | views: [ 26 | { 27 | path: '/metrics', 28 | component: MetricsView 29 | } 30 | ] 31 | }; 32 | -------------------------------------------------------------------------------- /components/waterfront/client/src/views/nodes/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | import NodeListView from 'views/nodes/NodeListView'; 18 | import NodeView from 'views/nodes/NodeView'; 19 | 20 | export default { 21 | menuItem: { 22 | name: 'Nodes', 23 | icon: 'memory', 24 | link: '/nodes' 25 | }, 26 | views: [ 27 | { 28 | path: '/nodes/:nodeId', 29 | component: NodeView 30 | }, 31 | { 32 | path: '/nodes', 33 | component: NodeListView 34 | } 35 | ] 36 | }; 37 | -------------------------------------------------------------------------------- /components/waterfront/client/webpack.common.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | const webpack = require('webpack'); 18 | const path = require('path'); 19 | 20 | const srcDir = path.resolve(__dirname, 'src'); 21 | const distDir = path.resolve(__dirname, '..', 'dist/client'); 22 | 23 | module.exports = { 24 | srcDir, 25 | distDir, 26 | config: { 27 | entry: './src/index.js', 28 | output: { 29 | path: distDir, 30 | filename: 'app.js' 31 | }, 32 | module: { 33 | rules: [ 34 | { 35 | test: /\.jsx?$/, 36 | exclude: /(node_modules|bower_components)/, 37 | use: { 38 | loader: 'babel-loader' 39 | } 40 | } 41 | ] 42 | }, 43 | resolve: { 44 | modules: [srcDir, 'node_modules'], 45 | extensions: ['.js', '.jsx'] 46 | } 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /components/waterfront/client/webpack.dev.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | const webpack = require('webpack'); 18 | const merge = require('webpack-merge'); 19 | const common = require('./webpack.common.js'); 20 | 21 | module.exports = merge(common.config, { 22 | devtool: 'inline-source-map', 23 | devServer: { 24 | contentBase: common.srcDir, 25 | historyApiFallback: true, 26 | port: 10000 27 | }, 28 | plugins: [ 29 | new webpack.EnvironmentPlugin({ 30 | API_BASE_URL: 'http://localhost:2780/api/v1', 31 | KUBE_DASHBOARD_URL: '/kube-dashboard/' 32 | }) 33 | ] 34 | }); 35 | -------------------------------------------------------------------------------- /components/waterfront/client/webpack.prod.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | const merge = require('webpack-merge'); 18 | const webpack = require('webpack'); 19 | const common = require('./webpack.common.js'); 20 | const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); 21 | 22 | module.exports = merge(common.config, { 23 | devtool: 'source-map', 24 | plugins: [ 25 | new UglifyJSPlugin({ 26 | sourceMap: true 27 | }), 28 | new webpack.DefinePlugin({ 29 | 'process.env': { 30 | 'NODE_ENV': JSON.stringify('production') 31 | } 32 | }), 33 | new webpack.EnvironmentPlugin({ 34 | API_BASE_URL: '/api/v1', 35 | KUBE_DASHBOARD_URL: '/kube-dashboard/' 36 | }) 37 | ] 38 | }); 39 | -------------------------------------------------------------------------------- /components/waterfront/containers/build/Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Pax Automa Systems, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FROM paxautoma/golang-dev:latest 16 | 17 | RUN apk add --no-cache \ 18 | nodejs \ 19 | yarn \ 20 | protobuf \ 21 | protobuf-dev \ 22 | g++ \ 23 | linux-pam-dev 24 | 25 | # these have to be installed in the $GOPATH instead of vendor because they come 26 | # with command-line tools, which cannot be vendored 27 | RUN go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway && \ 28 | go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger && \ 29 | go get -u github.com/golang/protobuf/protoc-gen-go 30 | 31 | WORKDIR /go/src/github.com/paxautoma/operos 32 | 33 | -------------------------------------------------------------------------------- /components/waterfront/containers/ship/Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Pax Automa Systems, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FROM alpine:3.6 16 | 17 | RUN apk add --no-cache linux-pam 18 | RUN mkdir -p /opt/waterfront 19 | COPY dist/ /opt/waterfront/ 20 | 21 | RUN ln -sf /etc-host/shadow /etc/shadow && \ 22 | ln -sf /etc-host/passwd /etc/passwd && \ 23 | mkdir -p /etc/paxautoma && \ 24 | ln -sf /etc-host/paxautoma/settings /etc/paxautoma/settings 25 | 26 | EXPOSE 2780 2781 27 | WORKDIR /opt/waterfront 28 | 29 | # Waterfront needs to run as root and have the host's /etc mounted in at 30 | # /etc-host so that it can perform PAM authentication. 31 | # 32 | # See http://jenkins-ci.361315.n4.nabble.com/Using-UNIX-PAM-authentication-from-a-non-root-user-tp378559p378563.html 33 | 34 | CMD ["./waterfront"] 35 | -------------------------------------------------------------------------------- /components/waterfront/server/Makefile: -------------------------------------------------------------------------------- 1 | TEAMSTER_HTTP=192.168.33.10:2680 2 | TEAMSTER=192.168.33.10:2681 3 | KUBE=localhost:8001 4 | PROMETHEUS=localhost:9090 5 | 6 | # Assumes you have: 7 | # - a local Operos controller at 192.168.33.10 8 | # - running "kubectl kube-proxy", listening on localhost:8001 9 | # - running "kubectl port-forward 9090" 10 | # use KUBE, TEAMSTER, PROMETHEUS to override above 11 | .PHONY: dev 12 | dev: 13 | GRPC_GO_LOG_SEVERITY_LEVEL=info \ 14 | GRPC_GO_LOG_VERBOSITY_LEVEL=10 \ 15 | go run -v cmd/main.go \ 16 | --kubeconfig=../../operos/kubeconfig \ 17 | --kube-url="http://$(KUBE)" \ 18 | --teamster $(TEAMSTER) \ 19 | --teamster-http $(TEAMSTER_HTTP) \ 20 | --prometheus-url "http://$(PROMETHEUS)/api/v1" \ 21 | --clientdir "../client/src" \ 22 | --debug-addr 127.0.0.1:2782 23 | -------------------------------------------------------------------------------- /components/waterfront/server/pkg/kube/kube.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package kube 18 | 19 | import ( 20 | "github.com/pkg/errors" 21 | "k8s.io/client-go/kubernetes" 22 | "k8s.io/client-go/rest" 23 | "k8s.io/client-go/tools/clientcmd" 24 | ) 25 | 26 | func NewKubeClient(url, kubeConfig string) (*kubernetes.Clientset, error) { 27 | var ( 28 | err error 29 | config *rest.Config 30 | ) 31 | 32 | if kubeConfig == "" { 33 | config, err = rest.InClusterConfig() 34 | } else { 35 | config, err = clientcmd.BuildConfigFromFlags(url, kubeConfig) 36 | } 37 | if err != nil { 38 | return nil, errors.Wrap(err, "could not load kube config") 39 | } 40 | 41 | clientset, err := kubernetes.NewForConfig(config) 42 | if err != nil { 43 | return nil, errors.Wrap(err, "could not create kube clientset") 44 | } 45 | 46 | return clientset, nil 47 | } 48 | -------------------------------------------------------------------------------- /components/waterfront/server/pkg/teamster/client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package teamster 18 | 19 | import ( 20 | "github.com/pkg/errors" 21 | grpc "google.golang.org/grpc" 22 | 23 | teamster "github.com/paxautoma/operos/components/teamster/pkg/teamster" 24 | ) 25 | 26 | func NewTeamsterClientFromAddr(teamsterAddr string) (teamster.TeamsterClient, error) { 27 | conn, err := grpc.Dial(teamsterAddr, grpc.WithInsecure()) 28 | if err != nil { 29 | errors.Wrap(err, "could not dial teamster") 30 | } 31 | 32 | client := teamster.NewTeamsterClient(conn) 33 | return client, nil 34 | } 35 | -------------------------------------------------------------------------------- /components/waterfront/server/pkg/waterfront/clientcert.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package waterfront 18 | 19 | import ( 20 | "io" 21 | "log" 22 | "net/http" 23 | "net/url" 24 | "strings" 25 | ) 26 | 27 | func MakeGenClientCertHandler(teamsterAddr string) http.Handler { 28 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 29 | getURL := url.URL{ 30 | Scheme: "http", 31 | Host: teamsterAddr, 32 | Path: "/clientcert", 33 | } 34 | q := getURL.Query() 35 | q.Set("user", "admin") 36 | q.Add("group", "admin") 37 | q.Set("host", strings.SplitN(r.Host, ":", 2)[0]) 38 | 39 | getURL.RawQuery = q.Encode() 40 | 41 | resp, err := http.Get(getURL.String()) 42 | if err != nil { 43 | log.Printf("error while accessing Teamster: %v", err) 44 | return 45 | } 46 | defer resp.Body.Close() 47 | 48 | for name := range resp.Header { 49 | for _, value := range resp.Header[name] { 50 | w.Header().Set(name, value) 51 | } 52 | } 53 | w.WriteHeader(resp.StatusCode) 54 | 55 | _, err = io.Copy(w, resp.Body) 56 | if err != nil { 57 | log.Printf("error while forwarding Teamster response to client: %v", err) 58 | return 59 | } 60 | }) 61 | } 62 | -------------------------------------------------------------------------------- /components/waterfront/server/pkg/waterfront/waterfront.proto: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 Pax Automa Systems, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | syntax = "proto3"; 18 | package waterfront; 19 | 20 | import "google/api/annotations.proto"; 21 | 22 | message Empty {} 23 | 24 | enum NodeStatus { 25 | NOT_READY = 0; 26 | READY = 1; 27 | } 28 | 29 | message Node { 30 | string id = 1; 31 | NodeStatus status = 2; 32 | string ip = 3; 33 | string pod_cidr = 4; 34 | string hardware_info = 5; 35 | } 36 | 37 | message ListNodesResponse { 38 | repeated Node nodes = 1; 39 | } 40 | 41 | message GetNodeRequest { 42 | string id = 1; 43 | } 44 | 45 | message GetNodeResponse { 46 | Node node = 1; 47 | } 48 | 49 | message GetClusterInfoResponse { 50 | int64 license_expiry = 1; 51 | map settings = 2; 52 | } 53 | 54 | message SetRootPasswordRequest { 55 | string password = 1; 56 | } 57 | 58 | service Waterfront { 59 | rpc ListNodes (Empty) returns (ListNodesResponse) { 60 | option (google.api.http).get = "/v1/nodes"; 61 | } 62 | 63 | rpc GetNode (GetNodeRequest) returns (GetNodeResponse) { 64 | option (google.api.http).get = "/v1/nodes/{id}"; 65 | } 66 | 67 | rpc GetClusterInfo (Empty) returns (GetClusterInfoResponse) { 68 | option (google.api.http).get = "/v1/cluster_info"; 69 | } 70 | 71 | rpc SetRootPassword (SetRootPasswordRequest) returns (Empty) { 72 | option (google.api.http) = { 73 | post: "/v1/rootpass" 74 | body: "*" 75 | }; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /glide.yaml: -------------------------------------------------------------------------------- 1 | package: src.paxautoma.com/paxautoma/operos 2 | import: 3 | - package: k8s.io/client-go 4 | version: ^4.0.0 5 | subpackages: 6 | - kubernetes 7 | - pkg/api 8 | - pkg/api/v1 9 | - pkg/apis/extensions/v1beta1 10 | - tools/clientcmd 11 | - package: k8s.io/apimachinery 12 | subpackages: 13 | - pkg/api/errors 14 | - package: github.com/stretchr/testify 15 | version: ^1.1.4 16 | - package: github.com/sirupsen/logrus 17 | version: ^1.0.2 18 | - package: github.com/jroimartin/gocui 19 | version: master 20 | - package: github.com/pkg/errors 21 | version: ^0.8.0 22 | - package: github.com/rlisagor/dhcp4client 23 | version: fix-timeouts 24 | - package: github.com/cloudflare/cfssl 25 | version: ^1.2.0 26 | subpackages: 27 | - cli/genkey 28 | - config 29 | - csr 30 | - helpers 31 | - log 32 | - signer 33 | - signer/local 34 | - package: google.golang.org/grpc 35 | version: ^1.5.2 36 | - package: golang.org/x/net 37 | version: master 38 | - package: golang.org/x/text 39 | version: master 40 | - package: github.com/godbus/dbus 41 | version: ^4.1.0 42 | - package: github.com/coreos/go-systemd 43 | version: v17 44 | - package: github.com/wercker/journalhook 45 | - package: github.com/coreos/etcd 46 | version: ^3.2.7 47 | subpackages: 48 | - clientv3 49 | - package: github.com/gorilla/mux 50 | version: ^1.4.0 51 | - package: github.com/gorilla/handlers 52 | version: ^1.2.1 53 | - package: golang.org/x/crypto 54 | version: master 55 | - package: golang.org/x/sys 56 | version: master 57 | subpackages: 58 | - unix 59 | - package: github.com/tredoe/osutil/user/crypt 60 | - package: github.com/golang/protobuf 61 | version: master 62 | - package: github.com/google/uuid 63 | version: ^0.2.0 64 | - package: github.com/grpc-ecosystem/grpc-gateway 65 | version: ^1.2.2 66 | - package: google.golang.org/genproto 67 | - package: github.com/grpc-ecosystem/go-grpc-middleware 68 | - package: github.com/gorilla/sessions 69 | version: ^1.1.0 70 | - package: github.com/msteinert/pam 71 | -------------------------------------------------------------------------------- /iso/_cpiohooks/hooks/operosiso_pxe_http: -------------------------------------------------------------------------------- 1 | # vim: set ft=sh: 2 | 3 | run_hook() { 4 | if [[ -n "${ip}" && -n "${archiso_http_srv}" ]]; then 5 | archiso_http_srv=$(eval echo ${archiso_http_srv}) 6 | [[ -z "${archiso_http_spc}" ]] && archiso_http_spc="75%" 7 | 8 | mount_handler="archiso_pxe_http_mount_handler" 9 | fi 10 | } 11 | 12 | # Fetch a file with CURL 13 | # 14 | # $1 URL 15 | # $2 Destination directory inside httpspace/${archisobasedir} 16 | _curl_get() { 17 | local _url="${1}" 18 | local _dst="${2}" 19 | 20 | msg ":: Downloading '${_url}'" 21 | if ! curl -L -f -o "/run/archiso/httpspace/${archisobasedir}${_dst}/${_url##*/}" --create-dirs "${_url}"; then 22 | echo "ERROR: Downloading '${_url}'" 23 | echo " Falling back to interactive prompt" 24 | echo " You can try to fix the problem manually, log out when you are finished" 25 | launch_interactive_shell 26 | fi 27 | } 28 | 29 | archiso_pxe_http_mount_handler () { 30 | newroot="${1}" 31 | 32 | msg ":: Mounting /run/archiso/httpspace (tmpfs) filesystem, size='${archiso_http_spc}'" 33 | mkdir -p "/run/archiso/httpspace" 34 | mount -t tmpfs -o size="${archiso_http_spc}",mode=0755 httpspace "/run/archiso/httpspace" 35 | 36 | if [ -z "${archiso_layers}" ]; then 37 | echo "ERROR: Layers (archiso_layers) not specified on kernel commandline" 38 | echo " Falling back to interactive prompt" 39 | echo " You can try to fix the problem manually, log out when you are finished" 40 | launch_interactive_shell 41 | fi 42 | 43 | for layer in ${archiso_layers}; do 44 | _curl_get "${archiso_http_srv}${archisobasedir}/${arch}/airootfs-${layer}.sfs" "/${arch}" 45 | 46 | if [[ "${checksum}" == "y" ]]; then 47 | _curl_get "${archiso_http_srv}${archisobasedir}/${arch}/airootfs-${layer}.sha512" "/${arch}" 48 | fi 49 | if [[ "${verify}" == "y" ]]; then 50 | _curl_get "${archiso_http_srv}${archisobasedir}/${arch}/airootfs-${layer}.sfs.sig" "/${arch}" 51 | fi 52 | done 53 | 54 | mkdir -p "/run/archiso/bootmnt" 55 | mount -o bind /run/archiso/httpspace /run/archiso/bootmnt 56 | 57 | archiso_mount_handler ${newroot} 58 | } 59 | -------------------------------------------------------------------------------- /iso/_cpiohooks/install/operosiso: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | build() { 4 | add_module "cdrom" 5 | add_module "loop" 6 | add_module "dm-snapshot" 7 | add_module "overlay" 8 | 9 | add_runscript 10 | 11 | add_binary /usr/lib/udev/cdrom_id 12 | add_binary blockdev 13 | add_binary dmsetup 14 | add_binary losetup 15 | add_binary mountpoint 16 | add_binary truncate 17 | add_binary gpg 18 | add_binary grep 19 | 20 | add_file /usr/lib/udev/rules.d/60-cdrom_id.rules 21 | add_file /usr/lib/udev/rules.d/10-dm.rules 22 | add_file /usr/lib/udev/rules.d/95-dm-notify.rules 23 | add_file /usr/lib/initcpio/udev/11-dm-initramfs.rules /usr/lib/udev/rules.d/11-dm-initramfs.rules 24 | if [[ $ARCHISO_GNUPG_FD ]]; then 25 | mkdir -p "$BUILDROOT$dest"/gpg 26 | gpg --homedir "$BUILDROOT$dest"/gpg --import <&$ARCHISO_GNUPG_FD 27 | fi 28 | } 29 | 30 | # vim: set ft=sh ts=4 sw=4 et: 31 | -------------------------------------------------------------------------------- /iso/_cpiohooks/install/operosiso_pxe_common: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | build() { 4 | add_checked_modules -f "(irda|phy|wimax|wireless|ppp_|plip|pppoe)" "/drivers/net/" 5 | 6 | add_runscript 7 | 8 | add_binary /usr/lib/initcpio/ipconfig /bin/ipconfig 9 | 10 | # Add hosts support files+dns 11 | add_symlink /usr/lib/libnss_files.so.2 $(readlink /usr/lib/libnss_files.so.2) 12 | add_binary $(readlink -f /usr/lib/libnss_files.so.2) 13 | add_symlink /usr/lib/libnss_dns.so.2 $(readlink /usr/lib/libnss_dns.so.2) 14 | add_binary $(readlink -f /usr/lib/libnss_dns.so.2) 15 | 16 | add_dir /etc 17 | echo "hosts: files dns" > $BUILDROOT/etc/nsswitch.conf 18 | } 19 | 20 | help() { 21 | cat<&1 | grep '^Cache Dirs:' | sed 's/Cache Dirs:\s*//g')) 19 | sed -r "s|^#?\\s*CacheDir.+|CacheDir = $(echo -n ${_cache_dirs[@]})|g" ${script_path}/iso/pacman.conf > ${work_dir}/pacman.conf 20 | } 21 | 22 | # Base installation (airootfs) 23 | make_basefs() { 24 | mkarchiso ${verbose} -w "${work_dir}" -C "${work_dir}/pacman.conf" -D "${install_dir}" init 25 | } 26 | 27 | make_prepare_layer_base() { 28 | mkdir -p ${work_dir}/airootfs-base ${work_dir}/airootfs 29 | mount -o bind ${work_dir}/airootfs-base ${work_dir}/airootfs 30 | } 31 | 32 | run_once make_prepare_layer_base 33 | run_once make_pacman_conf 34 | run_once make_basefs 35 | run_once make_packages 36 | run_once make_customize_airootfs 37 | run_once make_squash_layer 38 | -------------------------------------------------------------------------------- /iso/base/packages: -------------------------------------------------------------------------------- 1 | haveged 2 | mkinitcpio-nfs-utils 3 | syslinux 4 | zsh 5 | efitools -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/hosts: -------------------------------------------------------------------------------- 1 | 127.0.0.1 localhost 2 | 127.0.1.1 controller 3 | -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/sysctl.d/printk.conf: -------------------------------------------------------------------------------- 1 | kernel.printk = 2 4 1 4 2 | -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/systemd/scripts/load-images: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Load images on the first boot. Disables itself after the first run. 17 | 18 | for img in $(find /opt/docker-images/ -name "*.tar.gz"); do 19 | gunzip -c $img | docker load 20 | done 21 | 22 | systemctl disable load-images.service 23 | -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/systemd/scripts/nat: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | iptables -t nat -A POSTROUTING -o ${CONTROLLER_PUBLIC_IF} -j MASQUERADE 17 | iptables -A FORWARD -i ${CONTROLLER_PUBLIC_IF} -o ${CONTROLLER_PRIVATE_IF} -m state --state RELATED,ESTABLISHED -j ACCEPT 18 | iptables -A FORWARD -i ${CONTROLLER_PRIVATE_IF} -o ${CONTROLLER_PUBLIC_IF} -j ACCEPT 19 | -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/systemd/scripts/operos-cfg-populate: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | export ETCDCTL_API=3 17 | 18 | etcd_cmd () { 19 | /usr/bin/etcdctl --endpoints=http://127.0.0.1:4279 "$@" 20 | } 21 | 22 | IS_CONFIGED=$(etcd_cmd get cluster/$OPEROS_INSTALL_ID/CLUSTER_BIRTH_DATE) 23 | if [ -z "$IS_CONFIGED" ] ; then 24 | IFS="" 25 | while read -r l; do 26 | var=${l/=*} 27 | val=${l/*=} 28 | etcd_cmd put "cluster/$OPEROS_INSTALL_ID/$var" "${val//\"}" 29 | done < <(cat /etc/paxautoma/settings | sed -e '/^$/d' -e '/^#/d') 30 | 31 | # ca.pem is the bundle of CA certs. If the controller is a self-signed root 32 | # CA then this bundle is equivalent to controller-ca.pem. However, if the 33 | # controller's CA cert is signed by a higher-level authority, then this 34 | # bundle will include the entire certificate chain. controller-ca.pem will 35 | # be only the controller CA cert itself. 36 | cat /etc/kubernetes/ssl/ca.pem | etcd_cmd put "cluster/$OPEROS_INSTALL_ID/secret-ca-bundle" 37 | cat /etc/kubernetes/ssl/controller-ca-key.pem | etcd_cmd put "cluster/$OPEROS_INSTALL_ID/secret-ca-key" 38 | cat /etc/kubernetes/ssl/controller-ca.pem | etcd_cmd put "cluster/$OPEROS_INSTALL_ID/secret-ca-cert" 39 | 40 | if [ -e /etc/paxautoma/testkey.pub ]; then 41 | cat /etc/paxautoma/testkey.pub | etcd_cmd put "cluster/$OPEROS_INSTALL_ID/authorized-keys/worker/test" 42 | fi 43 | cat /root/.ssh/id_rsa.pub | etcd_cmd put "cluster/$OPEROS_INSTALL_ID/authorized-keys/worker/controller" 44 | 45 | etcd_cmd put "cluster/$OPEROS_INSTALL_ID/CLUSTER_BIRTH_DATE" "$(env TZ=UTC date --rfc-3339=seconds)" 46 | fi 47 | -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/systemd/scripts/statustty: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | args=" 4 | --private-if ${CONTROLLER_PRIVATE_IF} 5 | --node-type Controller 6 | --kube-url http://localhost:8080 7 | " 8 | 9 | if [[ -n "${CONTROLLER_PUBLIC_IF}" ]]; then 10 | args="$args --public-if ${CONTROLLER_PUBLIC_IF}" 11 | fi 12 | 13 | echo Running agetty with $args 14 | exec /sbin/agetty --noclear -o "$args" -l /usr/bin/statustty -n tty1 $TERM 15 | -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/systemd/system/dhcpd4@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=IPv4 DHCP server on %I 3 | After=network.target network-online.target 4 | Wants=network-online.target 5 | 6 | [Service] 7 | Type=forking 8 | PIDFile=/run/dhcpd4.pid 9 | ExecStart=/usr/bin/dhcpd -4 -q -user dhcp -cf /etc/dhcpd.conf -pf /run/dhcpd4.pid %I 10 | ProtectSystem=full 11 | ProtectHome=on 12 | KillSignal=SIGINT 13 | RestartSec=2 14 | Restart=on-failure 15 | StartLimitInterval=12s 16 | 17 | [Install] 18 | WantedBy=multi-user.target 19 | -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/systemd/system/load-images.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Post-installation setup 3 | Requires=docker.service 4 | After=docker.service 5 | Before=kubelet.service 6 | 7 | [Service] 8 | Type=oneshot 9 | ExecStart=/etc/systemd/scripts/load-images 10 | RemainAfterExit=yes 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/systemd/system/nat.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=NAT 3 | Before=network-pre.target 4 | Wants=network-pre.target 5 | 6 | [Service] 7 | Type=oneshot 8 | EnvironmentFile=/etc/paxautoma/settings 9 | ExecStart=/etc/systemd/scripts/nat 10 | RemainAfterExit=yes 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/systemd/system/operos-ceph-mon-init.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Initialize Operos ceph mon 3 | Requires=operos-cfg-store.service 4 | After=operos-cfg-store.service 5 | After=network-online.target 6 | Wants=network-online.target 7 | Before=teamster.service 8 | 9 | [Service] 10 | EnvironmentFile=/etc/paxautoma/settings 11 | Type=oneshot 12 | ExecStart=/etc/systemd/scripts/ceph-mon-init 13 | 14 | [Install] 15 | WantedBy=multi-user.target 16 | -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/systemd/system/operos-cfg-populate.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Initialize Operos configuration 3 | Requires=operos-cfg-store.service 4 | After=operos-cfg-store.service 5 | Before=teamster.service 6 | 7 | [Service] 8 | EnvironmentFile=/etc/paxautoma/settings 9 | Type=oneshot 10 | ExecStart=/etc/systemd/scripts/operos-cfg-populate 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/systemd/system/operos-cfg-store.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Operos Cluster Configuration Store 3 | 4 | [Service] 5 | Type=notify 6 | Restart=always 7 | RestartSec=5s 8 | LimitNOFILE=40000 9 | TimeoutStartSec=0 10 | ExecStart=/usr/bin/etcd --name operos-cluster-cfg0 --data-dir /var/operos/cfg --initial-advertise-peer-urls https://127.0.0.1:4280 --listen-peer-urls http://127.0.0.1:4280 --advertise-client-urls http://127.0.0.1:4279 --listen-client-urls http://127.0.0.1:4279 --initial-cluster operos-cluster-cfg0=https://127.0.0.1:4280 --auto-compaction-retention 1 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/systemd/system/operos-image.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Operos Worker Image Server 3 | Requires=operos-cfg-store.service 4 | After=load-images.service 5 | 6 | [Service] 7 | TimeoutStartSec=0 8 | Restart=always 9 | RestartSec=5s 10 | EnvironmentFile=/etc/paxautoma/settings 11 | ExecStartPre=-/usr/bin/docker rm operos-image-server 12 | ExecStart=/usr/bin/docker run \ 13 | -p ${OPEROS_CONTROLLER_IP}:5080:80 \ 14 | --rm \ 15 | --name operos-image-server \ 16 | -v /etc/paxautoma/iso:/usr/share/nginx/html \ 17 | -v /boot:/usr/share/nginx/html/boot \ 18 | -v /run/archiso/bootmnt/operos-${OPEROS_VERSION}:/usr/share/nginx/html/operos \ 19 | -v /opt/docker-images:/usr/share/nginx/html/images \ 20 | nginx:${OPEROS_NGINX_VERSION} 21 | ExecStop=/usr/bin/docker stop operos-image-server 22 | KillMode=none 23 | 24 | [Install] 25 | WantedBy=multi-user.target 26 | -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/systemd/system/start-addons.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Kubernetes add-ons 3 | Requires=kubelet.service 4 | After=kubelet.service operos-ceph-mon-init.service 5 | 6 | [Service] 7 | Type=oneshot 8 | ExecStart=/etc/systemd/scripts/start-addons 9 | 10 | [Install] 11 | WantedBy=multi-user.target 12 | -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/systemd/system/statustty.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=TTY status display 3 | After=dbus.socket 4 | DefaultDependencies=no 5 | 6 | [Service] 7 | EnvironmentFile=/etc/paxautoma/settings 8 | ExecStart=/etc/systemd/scripts/statustty 9 | Type=simple 10 | Restart=always 11 | RestartSec=0 12 | UtmpIdentifier=tty1 13 | TTYPath=/dev/tty1 14 | TTYReset=yes 15 | TTYVHangup=yes 16 | TTYVTDisallocate=yes 17 | 18 | # Unset locale for the console getty since the console has problems 19 | # displaying some internationalized messages. 20 | Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION= 21 | 22 | [Install] 23 | WantedBy=multi-user.target 24 | -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/systemd/system/teamster.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Operos Node Management Daemon 3 | Requires=operos-cfg-store.service 4 | Wants=network-online.target 5 | After=network-online.target 6 | 7 | [Service] 8 | TimeoutStartSec=0 9 | Restart=always 10 | EnvironmentFile=/etc/paxautoma/settings 11 | ExecStart=/usr/bin/teamster \ 12 | -listen-addr ${OPEROS_CONTROLLER_IP}:2680 \ 13 | -listen-grpc ${OPEROS_CONTROLLER_IP}:2681 \ 14 | -install-id ${OPEROS_INSTALL_ID} \ 15 | -etcd-cluster 127.0.0.1:4279 \ 16 | -shadow-file /etc/shadow 17 | KillMode=none 18 | 19 | [Install] 20 | WantedBy=multi-user.target 21 | -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/systemd/system/tftpd.service.d/10-require-network.conf: -------------------------------------------------------------------------------- 1 | [Unit] 2 | After=network-online.target 3 | Wants=network-online.target 4 | -------------------------------------------------------------------------------- /iso/controller/airootfs/etc/tftpd.mapfile: -------------------------------------------------------------------------------- 1 | # 2 | # Rule file for the -m (remapping option) 3 | # 4 | # This file has three fields: operation, regex, remapping 5 | # 6 | # The operation is a combination of the following letters: 7 | # 8 | # r - rewrite the matched string with the remapping pattern 9 | # i - case-insensitive matching 10 | # g - repeat until no match (used with "r") 11 | # e - exit (with success) if we match this pattern, do not process 12 | # subsequent rules 13 | # s - start over from the first rule if we match this pattern 14 | # a - abort (refuse the request) if we match this rule 15 | # G - this rule applies to TFTP GET requests only 16 | # P - this rule applies to TFTP PUT requests only 17 | # 18 | # The regex is a regular expression in the style of egrep(1). 19 | # 20 | # The remapping is a pattern, all characters are verbatim except \ 21 | # \0 copies the full string that matched the regex 22 | # \1..\9 copies the 9 first (..) expressions in the regex 23 | # \\ is an escaped \ 24 | # See http://linux.die.net/man/8/tftpd for more info. 25 | # 26 | # "#" begins a comment, unless \-escaped 27 | # 28 | ri ^[a-z]: # Remove "drive letters" 29 | rg \\ / # Convert backslashes to slashes 30 | rg ([A-Z]) \L\1 # Convert uppercase to lowercase 31 | rg \# @ # Convert hash marks to @ signs 32 | rg /../ /..no../ # Convert /../ to /..no../ 33 | e ^ok/ # These are always ok 34 | r ^[^/] /\0 # Convert non-absolute files 35 | a \.pvt$ # Reject requests for private files 36 | -------------------------------------------------------------------------------- /iso/controller/airootfs/root/customize_airootfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -e 17 | 18 | # Permissions 19 | chmod 700 /root 20 | chown 0:0 /root 21 | 22 | # Networking 23 | systemctl enable systemd-networkd.service 24 | systemctl enable systemd-resolved.service 25 | 26 | # Images 27 | systemctl enable load-images.service 28 | 29 | # etcd 30 | mkdir -p /var/operos/cfg 31 | systemctl enable etcd.service 32 | systemctl enable operos-cfg-store.service 33 | systemctl enable operos-cfg-populate.service 34 | 35 | # Operos services 36 | systemctl enable teamster.service 37 | systemctl enable operos-image.service 38 | systemctl enable tftpd.service 39 | sed -i 's/#ShowStatus=.*/ShowStatus=no/' /etc/systemd/system.conf 40 | systemctl disable getty@tty1.service 41 | systemctl enable statustty.service 42 | 43 | # Addons to run inside Kubernetes 44 | systemctl enable start-addons.service 45 | 46 | # Ceph 47 | systemctl enable operos-ceph-mon-init.service 48 | -------------------------------------------------------------------------------- /iso/controller/build-layer.sh: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Pax Automa Systems, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | make_docker() { 16 | mkdir -p ${work_dir}/airootfs/opt/docker-images 17 | cp -af --no-preserve=ownership ${script_path}/cache/docker/* ${work_dir}/airootfs/opt/docker-images/ 18 | } 19 | 20 | run_once make_prepare_layer node base 21 | run_once make_packages 22 | run_once make_customize_airootfs 23 | run_once make_syslinux base node controller 24 | run_once make_docker 25 | run_once make_final_cleanup 26 | run_once make_squash_layer 27 | -------------------------------------------------------------------------------- /iso/controller/packages: -------------------------------------------------------------------------------- 1 | efibootmgr 2 | etcd 3 | grub 4 | ipmitool 5 | nmap 6 | tftp-hpa 7 | dhcp 8 | -------------------------------------------------------------------------------- /iso/controller/syslinux/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaxAutoma/operos/2d1c5127eb5ce32c667c0f1a927457b41d7ae709/iso/controller/syslinux/splash.png -------------------------------------------------------------------------------- /iso/controller/syslinux/syslinux.cfg: -------------------------------------------------------------------------------- 1 | SERIAL 0 38400 2 | UI syslinux-%ARCHISO_LAYER%/vesamenu.c32 3 | MENU TITLE Operos %ARCHISO_LAYER% 4 | MENU BACKGROUND syslinux-%ARCHISO_LAYER%/splash.png 5 | 6 | DEFAULT operos 7 | TIMEOUT 50 8 | 9 | MENU WIDTH 78 10 | MENU MARGIN 4 11 | MENU ROWS 7 12 | MENU VSHIFT 10 13 | MENU TABMSGROW 14 14 | MENU CMDLINEROW 14 15 | MENU HELPMSGROW 16 16 | MENU HELPMSGENDROW 29 17 | 18 | # Refer to http://syslinux.zytor.com/wiki/index.php/Doc/menu 19 | 20 | MENU COLOR border 30;44 #40ffffff #a0000000 std 21 | MENU COLOR title 1;36;44 #9033ccff #a0000000 std 22 | MENU COLOR sel 7;37;40 #e0ffffff #20ffffff all 23 | MENU COLOR unsel 37;44 #50ffffff #a0000000 std 24 | MENU COLOR help 37;40 #c0ffffff #a0000000 std 25 | MENU COLOR timeout_msg 37;40 #80ffffff #00000000 std 26 | MENU COLOR timeout 1;37;40 #c0ffffff #00000000 std 27 | MENU COLOR msg07 37;40 #90ffffff #a0000000 std 28 | MENU COLOR tabmsg 31;40 #30ffffff #00000000 std 29 | 30 | LABEL operos 31 | TEXT HELP 32 | Boot the Operos %ARCHISO_LAYER% v%OPEROS_VERSION%. 33 | ENDTEXT 34 | MENU LABEL Operos %ARCHISO_LAYER% v%OPEROS_VERSION% 35 | LINUX x86_64/vmlinuz 36 | INITRD intel_ucode.img,x86_64/archiso.img 37 | APPEND archisobasedir=%INSTALL_DIR%-%OPEROS_VERSION% archisodevice=%CONTROLLER_DISK%5 cow_device=%CONTROLLER_DISK%6 cow_directory=/ archiso_layers="%ARCHISO_LAYERS%" edd=off quiet 38 | 39 | # http://www.memtest.org/ 40 | LABEL memtest 41 | MENU LABEL Run Memtest86+ (RAM test) 42 | LINUX memtest 43 | 44 | # http://hdt-project.org/ 45 | LABEL hdt 46 | MENU LABEL Hardware Information (HDT) 47 | COM32 syslinux-%ARCHISO_LAYER%/hdt.c32 48 | APPEND modules_alias=syslinux-%ARCHISO_LAYER%/hdt/modalias.gz pciids=syslinux-%ARCHISO_LAYER%/hdt/pciids.gz 49 | 50 | LABEL reboot 51 | MENU LABEL Reboot 52 | COM32 syslinux-%ARCHISO_LAYER%/reboot.c32 53 | 54 | LABEL poweroff 55 | MENU LABEL Power Off 56 | COM32 syslinux-%ARCHISO_LAYER%/poweroff.c32 57 | -------------------------------------------------------------------------------- /iso/installer/300-devbuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | 3 | # Copyright 2018 Pax Automa Systems, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # This script installs the test SSH key on the controller 18 | 19 | # For the controller 20 | install -m 600 /root/testkey.pub /mnt/root/.ssh/authorized_keys 21 | # For teamster to give to the workers 22 | install -m 600 /root/testkey.pub /mnt/etc/paxautoma/testkey.pub 23 | 24 | sed -i 's/#\?\s*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config 25 | -------------------------------------------------------------------------------- /iso/installer/airootfs/etc/fstab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaxAutoma/operos/2d1c5127eb5ce32c667c0f1a927457b41d7ae709/iso/installer/airootfs/etc/fstab -------------------------------------------------------------------------------- /iso/installer/airootfs/etc/hostname: -------------------------------------------------------------------------------- 1 | archiso 2 | -------------------------------------------------------------------------------- /iso/installer/airootfs/etc/locale.conf: -------------------------------------------------------------------------------- 1 | LANG=en_US.UTF-8 2 | -------------------------------------------------------------------------------- /iso/installer/airootfs/etc/machine-id: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaxAutoma/operos/2d1c5127eb5ce32c667c0f1a927457b41d7ae709/iso/installer/airootfs/etc/machine-id -------------------------------------------------------------------------------- /iso/installer/airootfs/etc/pacman.conf: -------------------------------------------------------------------------------- 1 | [options] 2 | HoldPkg = pacman glibc 3 | Architecture = auto 4 | 5 | [core] 6 | Include = /etc/pacman.d/mirrorlist 7 | 8 | [extra] 9 | Include = /etc/pacman.d/mirrorlist 10 | 11 | [community] 12 | Include = /etc/pacman.d/mirrorlist 13 | 14 | [paxautoma] 15 | SigLevel = Optional TrustAll 16 | Server = http://arch-packages.paxautoma.com/ 17 | -------------------------------------------------------------------------------- /iso/installer/airootfs/etc/sysctl.d/printk.conf: -------------------------------------------------------------------------------- 1 | kernel.printk = 2 4 1 4 2 | -------------------------------------------------------------------------------- /iso/installer/airootfs/etc/systemd/system/etc-pacman.d-gnupg.mount: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Temporary /etc/pacman.d/gnupg directory 3 | 4 | [Mount] 5 | What=tmpfs 6 | Where=/etc/pacman.d/gnupg 7 | Type=tmpfs 8 | Options=mode=0755 9 | -------------------------------------------------------------------------------- /iso/installer/airootfs/etc/systemd/system/getty@tty1.service.d/autologin.conf: -------------------------------------------------------------------------------- 1 | [Service] 2 | ExecStart= 3 | ExecStart=-/sbin/agetty --autologin root --noclear %I 38400 linux 4 | -------------------------------------------------------------------------------- /iso/installer/airootfs/etc/systemd/system/pacman-init.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Initializes Pacman keyring 3 | Wants=haveged.service chronyd.service 4 | After=haveged.service chronyd.service 5 | Requires=etc-pacman.d-gnupg.mount 6 | After=etc-pacman.d-gnupg.mount 7 | 8 | [Service] 9 | Type=oneshot 10 | RemainAfterExit=yes 11 | ExecStart=/usr/bin/pacman-key --init 12 | ExecStart=/usr/bin/pacman-key --populate archlinux 13 | 14 | [Install] 15 | WantedBy=multi-user.target 16 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/.zlogin: -------------------------------------------------------------------------------- 1 | ~/installer 2 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | 3 | CONTROLLER_DISK=/dev/sda ./install/900-cleanup.sh 3>&1 4 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/customize_airootfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -e -u 17 | 18 | sed -i 's/#\(en_US\.UTF-8\)/\1/' /etc/locale.gen 19 | locale-gen 20 | 21 | ln -sf /usr/share/zoneinfo/UTC /etc/localtime 22 | 23 | usermod -s /usr/bin/zsh root 24 | cp -aT /etc/skel/ /root/ 25 | chmod 700 /root 26 | 27 | sed -i 's/#\(PermitRootLogin \).\+/\1yes/' /etc/ssh/sshd_config 28 | sed -i "s/#Server/Server/g" /etc/pacman.d/mirrorlist 29 | sed -i 's/#\(Storage=\)auto/\1volatile/' /etc/systemd/journald.conf 30 | 31 | sed -i 's/#\(HandleSuspendKey=\)suspend/\1ignore/' /etc/systemd/logind.conf 32 | sed -i 's/#\(HandleHibernateKey=\)hibernate/\1ignore/' /etc/systemd/logind.conf 33 | sed -i 's/#\(HandleLidSwitch=\)suspend/\1ignore/' /etc/systemd/logind.conf 34 | 35 | systemctl enable pacman-init.service 36 | systemctl enable systemd-resolved.service 37 | systemctl enable ntpdate.service 38 | systemctl set-default multi-user.target 39 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/efiboot/loader/entries/operos.conf: -------------------------------------------------------------------------------- 1 | title Operos controller (v%OPEROS_VERSION%) 2 | linux /EFI/operos-%OPEROS_VERSION%/vmlinuz.efi 3 | initrd /EFI/operos-%OPEROS_VERSION%/intel_ucode.img 4 | initrd /EFI/operos-%OPEROS_VERSION%/archiso.img 5 | options archisobasedir=operos-%OPEROS_VERSION% archisodevice=%CONTROLLER_DISK%5 cow_device=%CONTROLLER_DISK%6 cow_directory=/ archiso_layers="base node controller" edd=off quiet 6 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/efiboot/loader/loader.conf: -------------------------------------------------------------------------------- 1 | default operos-${OPEROS_VERSION} 2 | timeout 5 3 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | mkdir -p /root/logs 17 | 18 | for i in install/*.sh; do 19 | script=$(basename $i) 20 | logfile=/root/logs/${script%.sh}.log 21 | $i 3>&1 &>$logfile 22 | result=$? 23 | 24 | if [ $result -ne 0 ]; then 25 | echo "FAILED. Logs follow: ---->" 26 | cat $logfile 27 | exit $result 28 | fi 29 | done 30 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/install/010-partition.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -x 17 | 18 | echo \> Partitioning disk >&3 19 | 20 | . install/_common || exit 1 21 | 22 | # Disable LVM volumes to let go of disk devices 23 | vgchange -an 24 | 25 | # Clear out any existing partition tables 26 | sgdisk -Z $CONTROLLER_DISK 27 | ret=$? 28 | # sgdisk -Z returns 2 if the partition tables were broken even if it 29 | # successfully cleared them 30 | if [ $ret -ne 0 ] && [ $ret -ne 2 ]; then 31 | echo "Failed to clear partition tables" >&2 32 | exit 1 33 | fi 34 | 35 | set -e 36 | 37 | # Partition 38 | sgdisk -n 1:1M:+1M -t 1:ef02 -c 1:'BIOS Boot' \ 39 | -n 2:2M:+512M -t 2:ef00 -c 2:'EFI System' \ 40 | -n 3:514M:+1G -t 3:8300 -A 3:set:2 -c 3:'Boot' \ 41 | -n 4:1538M:+4G -t 4:8200 -c 4:'Swap' \ 42 | -n 5:5634M:+10G -t 5:8304 -c 5:'OS' \ 43 | $CONTROLLER_DISK 44 | ENDSECTOR=`sgdisk -E $CONTROLLER_DISK` 45 | sgdisk -n 6:15874M:$ENDSECTOR -t 6:8304 -c 6:'Root overlay' $CONTROLLER_DISK 46 | 47 | sleep 3 48 | 49 | partprobe -s $CONTROLLER_DISK 50 | 51 | # Make file systems 52 | yes | mkfs.fat -F32 $(partition_dev $CONTROLLER_DISK 2) 53 | yes | mkfs.ext4 -O \^64bit $(partition_dev $CONTROLLER_DISK 3) 54 | yes | mkswap $(partition_dev $CONTROLLER_DISK 4) 55 | yes | mkfs.ext4 $(partition_dev $CONTROLLER_DISK 5) 56 | yes | mkfs.ext4 $(partition_dev $CONTROLLER_DISK 6) 57 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/install/020-system.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | echo \> Copying system files >&3 17 | 18 | . install/_common 19 | 20 | # Mount 21 | mkdir -p /run/archiso/sfs/airootfs-node 22 | mount -o loop /run/archiso/bootmnt/operos/x86_64/airootfs-node.sfs /run/archiso/sfs/airootfs-node 23 | 24 | mkdir -p /run/archiso/sfs/airootfs-controller 25 | mount -o loop /run/archiso/bootmnt/operos/x86_64/airootfs-controller.sfs /run/archiso/sfs/airootfs-controller 26 | 27 | mkdir -p /run/archiso/cowspace/controller 28 | mount $(partition_dev $CONTROLLER_DISK 6) /run/archiso/cowspace/controller/ 29 | mkdir /run/archiso/cowspace/controller/{upperdir,workdir} 30 | 31 | mount -t overlay overlay \ 32 | -o lowerdir=/run/archiso/sfs/airootfs-controller:/run/archiso/sfs/airootfs-node:/run/archiso/sfs/airootfs-base,upperdir=/run/archiso/cowspace/controller/upperdir,workdir=/run/archiso/cowspace/controller/workdir \ 33 | /mnt 34 | 35 | mkdir -p /mnt/efi /mnt/boot /mnt/run/archiso/bootmnt 36 | mount $(partition_dev $CONTROLLER_DISK 2) /mnt/efi 37 | mount $(partition_dev $CONTROLLER_DISK 3) /mnt/boot 38 | 39 | # Kube recommends running without swap. We'll keep the partition around just in 40 | # case they decide to enable this later, but will not enable it in fstab for 41 | # now. 42 | #swapon $(partition_dev $CONTROLLER_DISK 4) 43 | 44 | mount $(partition_dev $CONTROLLER_DISK 5) /mnt/run/archiso/bootmnt 45 | 46 | # Copy files 47 | mkdir -p /mnt/run/archiso/bootmnt/operos-${OPEROS_VERSION}/ 48 | cp -af /run/archiso/bootmnt/operos/boot/* /mnt/boot/ 49 | cp -af /run/archiso/bootmnt/operos/x86_64 /mnt/run/archiso/bootmnt/operos-${OPEROS_VERSION}/ 50 | 51 | # Unmount the directory with the SquashFS images to prevent it from being added 52 | # to fstab later. It will be mounted by the cpio hooks (as archisodevice). 53 | umount /mnt/run/archiso/bootmnt 54 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/install/030-fstab.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | echo \> Setting up disk mount table >&3 17 | genfstab -U /mnt >> /mnt/etc/fstab 18 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/install/040-hostname.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | echo \> Setting hostname >&3 17 | echo "controller" > /mnt/etc/hostname 18 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/install/050-time.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | echo \> Setting up NTP >&3 17 | 18 | arch-chroot /mnt ln -sf /usr/share/zoneinfo/UTC /etc/localtime 19 | 20 | cat > /mnt/etc/chrony.conf < /mnt/etc/systemd/system/chronyd.service.d/10-wait-sync.conf < Installing bootloader >&3 17 | 18 | . install/_common 19 | 20 | disk_prefix=$(partition_prefix $CONTROLLER_DISK) 21 | 22 | install_bios() { 23 | # install MBR 24 | dd bs=440 conv=notrunc count=1 if=/usr/lib/syslinux/bios/gptmbr.bin of=${CONTROLLER_DISK} 25 | 26 | cat > /mnt/boot/syslinux.cfg < Configuring networking >&3 17 | 18 | if [ "$CONTROLLER_PUBLIC_IF_MODE" = "dhcp" ]; then 19 | cat > /mnt/etc/systemd/network/10-public.network < /mnt/etc/systemd/network/10-public.network < /mnt/etc/systemd/network/20-private.network <> /mnt/etc/systemd/network/20-private.network < Setting up the Operos configuration store >&3 17 | 18 | cat > /mnt/etc/conf.d/etcd < /mnt/etc/kubernetes/ssl/ca.pem 19 | echo "${INSTALLER_CONTROLLER_KEY}" > /mnt/etc/kubernetes/ssl/controller-ca-key.pem 20 | echo "${INSTALLER_CONTROLLER_CERT}" > /mnt/etc/kubernetes/ssl/controller-ca.pem 21 | echo "${INSTALLER_SERVER_KEY}" > /mnt/etc/kubernetes/ssl/apiserver-key.pem 22 | echo "${INSTALLER_SERVER_CERT}" > /mnt/etc/kubernetes/ssl/apiserver.pem 23 | 24 | mkdir -p /mnt/etc/paxautoma/tls 25 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/install/105-calico.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | echo \> Setting up container networking >&3 17 | 18 | mkdir -p /mnt/etc/cni/net.d 19 | cat > /mnt/etc/cni/net.d/10-calico.conflist < Setting up Kubernetes >&3 17 | 18 | install_manifests() { 19 | local src_path=$1 20 | local tgt_path=$2 21 | 22 | mkdir -p $src_path 23 | for manifest in $src_path/*; do 24 | envsubst < $manifest > $tgt_path/$(basename $manifest) 25 | done 26 | } 27 | 28 | mkdir -p /mnt/etc/kubernetes/{manifests,addons} 29 | install_manifests /root/manifests/kubelet /mnt/etc/kubernetes/manifests 30 | install_manifests /root/manifests/addons /mnt/etc/kubernetes/addons 31 | 32 | cat > /mnt/etc/kubernetes/config < /mnt/etc/kubernetes/kubelet < /mnt/etc/kubernetes/kubeconfig.yml < Setting up the SSH daemon >&3 17 | 18 | install -dm 700 /mnt/root/.ssh 19 | arch-chroot /mnt ssh-keygen -f /root/.ssh/id_rsa -N "" 20 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/install/140-issue.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | cat < /mnt/etc/issue 17 | Operos Controller (\l) 18 | 19 | EOF 20 | 21 | cat < /mnt/usr/lib/os-release 22 | NAME="Operos Controller" 23 | PRETTY_NAME="Operos Controller" 24 | VERSION="${OPEROS_VERSION}" 25 | ID=operos 26 | ID_LIKE=archlinux 27 | ANSI_COLOR="0;36" 28 | HOME_URL="https://www.paxautoma.com/" 29 | EOF 30 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/install/150-settings.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | echo \> Saving settings >&3 17 | 18 | mkdir -p /mnt/etc/paxautoma 19 | export | sed 's/declare -x //' | grep -E "^(OPEROS_|CONTROLLER_)" > /mnt/etc/paxautoma/settings 20 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/install/180-root-passwd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | echo "> Setting root password" >&3 17 | 18 | echo "root:$INSTALLER_ROOT_PASSWD" | arch-chroot /mnt chpasswd 19 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/install/900-cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | echo \> Cleaning up >&3 17 | 18 | mounts=" 19 | /mnt/efi 20 | /mnt/boot 21 | /mnt 22 | /run/archiso/cowspace/controller 23 | /run/archiso/sfs/airootfs-node 24 | /run/archiso/sfs/airootfs-controller 25 | " 26 | 27 | for m in $mounts; do 28 | if mountpoint -q $m; then 29 | umount $m 30 | fi 31 | done 32 | 33 | swapoff -a 34 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/install/_common: -------------------------------------------------------------------------------- 1 | partition_prefix() { 2 | local disk=$1 3 | if [[ $disk =~ .*[0-9]$ ]]; then 4 | echo ${disk}p 5 | else 6 | echo ${disk} 7 | fi 8 | } 9 | 10 | partition_dev() { 11 | local disk=$1 12 | local part_idx=$2 13 | echo $(partition_prefix $disk)${part_idx} 14 | } 15 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/manifests/addons/10-calico-sa.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: calico-node 5 | namespace: operos 6 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/manifests/addons/11-calico-crd.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1beta1 2 | description: Calico Global Felix Configuration 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: globalfelixconfigs.crd.projectcalico.org 6 | spec: 7 | scope: Cluster 8 | group: crd.projectcalico.org 9 | version: v1 10 | names: 11 | kind: GlobalFelixConfig 12 | plural: globalfelixconfigs 13 | singular: globalfelixconfig 14 | 15 | --- 16 | 17 | apiVersion: apiextensions.k8s.io/v1beta1 18 | description: Calico BGP Peers 19 | kind: CustomResourceDefinition 20 | metadata: 21 | name: bgppeers.crd.projectcalico.org 22 | spec: 23 | scope: Cluster 24 | group: crd.projectcalico.org 25 | version: v1 26 | names: 27 | kind: BGPPeer 28 | plural: bgppeers 29 | singular: bgppeer 30 | 31 | --- 32 | 33 | apiVersion: apiextensions.k8s.io/v1beta1 34 | description: Calico Global BGP Configuration 35 | kind: CustomResourceDefinition 36 | metadata: 37 | name: globalbgpconfigs.crd.projectcalico.org 38 | spec: 39 | scope: Cluster 40 | group: crd.projectcalico.org 41 | version: v1 42 | names: 43 | kind: GlobalBGPConfig 44 | plural: globalbgpconfigs 45 | singular: globalbgpconfig 46 | 47 | --- 48 | 49 | apiVersion: apiextensions.k8s.io/v1beta1 50 | description: Calico IP Pools 51 | kind: CustomResourceDefinition 52 | metadata: 53 | name: ippools.crd.projectcalico.org 54 | spec: 55 | scope: Cluster 56 | group: crd.projectcalico.org 57 | version: v1 58 | names: 59 | kind: IPPool 60 | plural: ippools 61 | singular: ippool 62 | 63 | --- 64 | 65 | apiVersion: apiextensions.k8s.io/v1beta1 66 | description: Calico Global Network Policies 67 | kind: CustomResourceDefinition 68 | metadata: 69 | name: globalnetworkpolicies.crd.projectcalico.org 70 | spec: 71 | scope: Cluster 72 | group: crd.projectcalico.org 73 | version: v1 74 | names: 75 | kind: GlobalNetworkPolicy 76 | plural: globalnetworkpolicies 77 | singular: globalnetworkpolicy 78 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/manifests/addons/20-kubedns-sa.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: kube-dns 5 | namespace: kube-system 6 | labels: 7 | kubernetes.io/cluster-service: "true" 8 | addonmanager.kubernetes.io/mode: Reconcile 9 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/manifests/addons/22-kubedns-svc.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2016 The Kubernetes Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # __MACHINE_GENERATED_WARNING__ 16 | 17 | apiVersion: v1 18 | kind: Service 19 | metadata: 20 | name: kube-dns 21 | namespace: kube-system 22 | labels: 23 | k8s-app: kube-dns 24 | kubernetes.io/cluster-service: "true" 25 | addonmanager.kubernetes.io/mode: Reconcile 26 | kubernetes.io/name: "KubeDNS" 27 | spec: 28 | selector: 29 | k8s-app: kube-dns 30 | clusterIP: ${OPEROS_DNS_SERVICE_IP} 31 | ports: 32 | - name: dns 33 | port: 53 34 | protocol: UDP 35 | - name: dns-tcp 36 | port: 53 37 | protocol: TCP 38 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/manifests/addons/30-kube-dashboard-sa.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | labels: 5 | app: kubernetes-dashboard 6 | name: kubernetes-dashboard 7 | namespace: kube-system 8 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/manifests/addons/31-kube-dashboard-depl.yml: -------------------------------------------------------------------------------- 1 | kind: Deployment 2 | apiVersion: apps/v1beta2 3 | metadata: 4 | labels: 5 | app: kubernetes-dashboard 6 | name: kubernetes-dashboard 7 | namespace: kube-system 8 | spec: 9 | replicas: 1 10 | revisionHistoryLimit: 10 11 | selector: 12 | matchLabels: 13 | app: kubernetes-dashboard 14 | template: 15 | metadata: 16 | labels: 17 | app: kubernetes-dashboard 18 | spec: 19 | affinity: 20 | nodeAffinity: 21 | requiredDuringSchedulingIgnoredDuringExecution: 22 | nodeSelectorTerms: 23 | - matchExpressions: 24 | - key: node-role.kubernetes.io/master 25 | operator: In 26 | values: 27 | - "true" 28 | tolerations: 29 | - key: node-role.kubernetes.io/master 30 | operator: "Exists" 31 | containers: 32 | - name: kubernetes-dashboard 33 | image: gcr.io/google_containers/kubernetes-dashboard-amd64:v${OPEROS_KUBE_DASHBOARD_VERSION} 34 | imagePullPolicy: Never 35 | ports: 36 | - containerPort: 9090 37 | protocol: TCP 38 | args: 39 | # Uncomment the following line to manually specify Kubernetes API server Host 40 | # If not specified, Dashboard will attempt to auto discover the API server and connect 41 | # to it. Uncomment only if the default does not work. 42 | # - --apiserver-host=http://my-address:port 43 | livenessProbe: 44 | httpGet: 45 | path: / 46 | port: 9090 47 | initialDelaySeconds: 30 48 | timeoutSeconds: 30 49 | serviceAccountName: kubernetes-dashboard 50 | # Comment the following tolerations if Dashboard must not be deployed on master 51 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/manifests/addons/32-kube-dashboard-svc.yml: -------------------------------------------------------------------------------- 1 | kind: Service 2 | apiVersion: v1 3 | metadata: 4 | labels: 5 | app: kubernetes-dashboard 6 | name: kubernetes-dashboard 7 | namespace: kube-system 8 | spec: 9 | type: NodePort 10 | ports: 11 | - port: 80 12 | targetPort: 9090 13 | selector: 14 | app: kubernetes-dashboard 15 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/manifests/addons/40-waterfront-sa.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Pax Automa Systems, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: v1 16 | kind: ServiceAccount 17 | metadata: 18 | name: operos-waterfront 19 | namespace: operos 20 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/manifests/addons/41-waterfront-ds.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Pax Automa Systems, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | apiVersion: extensions/v1beta1 16 | kind: DaemonSet 17 | metadata: 18 | name: operos-waterfront 19 | namespace: operos 20 | labels: 21 | app: operos-waterfront 22 | spec: 23 | revisionHistoryLimit: 5 24 | updateStrategy: 25 | type: RollingUpdate 26 | template: 27 | metadata: 28 | labels: 29 | app: operos-waterfront 30 | spec: 31 | affinity: 32 | nodeAffinity: 33 | requiredDuringSchedulingIgnoredDuringExecution: 34 | nodeSelectorTerms: 35 | - matchExpressions: 36 | - key: node-role.kubernetes.io/master 37 | operator: In 38 | values: 39 | - "true" 40 | tolerations: 41 | - key: node-role.kubernetes.io/master 42 | operator: "Exists" 43 | containers: 44 | - name: waterfront 45 | image: "waterfront:latest" 46 | imagePullPolicy: Never 47 | ports: 48 | - containerPort: 2780 49 | hostPort: 80 50 | protocol: TCP 51 | env: 52 | - name: SESSION_KEY 53 | valueFrom: 54 | secretKeyRef: 55 | name: waterfront-session-key 56 | key: session-key 57 | command: 58 | - ./waterfront 59 | - --teamster-http=${OPEROS_CONTROLLER_IP}:2680 60 | - --teamster=${OPEROS_CONTROLLER_IP}:2681 61 | - --session-key=$(SESSION_KEY) 62 | volumeMounts: 63 | - name: etc-host 64 | mountPath: /etc-host 65 | readOnly: true 66 | volumes: 67 | - name: etc-host 68 | hostPath: 69 | path: /etc 70 | serviceAccountName: operos-waterfront 71 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/manifests/addons/52-node-exporter-daemonset.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: DaemonSet 3 | metadata: 4 | name: node-exporter 5 | namespace: operos 6 | labels: 7 | name: node-exporter 8 | spec: 9 | template: 10 | metadata: 11 | labels: 12 | name: node-exporter 13 | spec: 14 | hostPID: true 15 | hostIPC: true 16 | hostNetwork: true 17 | tolerations: 18 | - key: node-role.kubernetes.io/master 19 | operator: Exists 20 | containers: 21 | - ports: 22 | - containerPort: 9100 23 | protocol: TCP 24 | resources: 25 | requests: 26 | cpu: 100m 27 | memory: 200Mi 28 | limits: 29 | cpu: 350m 30 | memory: 512Mi 31 | securityContext: 32 | privileged: true 33 | image: prom/node-exporter:${OPEROS_NODE_EXPORTER_VERSION} 34 | imagePullPolicy: Never 35 | livenessProbe: 36 | httpGet: 37 | path: /metrics 38 | port: 9100 39 | initialDelaySeconds: 30 40 | periodSeconds: 30 41 | timeoutSeconds: 3 42 | args: 43 | - --path.procfs 44 | - /host/proc 45 | - --path.sysfs 46 | - /host/sys 47 | - --collector.filesystem.ignored-mount-points 48 | - '"^/(sys|proc|dev|host|etc)($|/)"' 49 | name: node-exporter 50 | volumeMounts: 51 | - name: dev 52 | mountPath: /host/dev 53 | - name: proc 54 | mountPath: /host/proc 55 | - name: sys 56 | mountPath: /host/sys 57 | - name: rootfs 58 | mountPath: /rootfs 59 | volumes: 60 | - name: proc 61 | hostPath: 62 | path: /proc 63 | - name: dev 64 | hostPath: 65 | path: /dev 66 | - name: sys 67 | hostPath: 68 | path: /sys 69 | - name: rootfs 70 | hostPath: 71 | path: / 72 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/manifests/addons/54-prometheus-deployment.yml: -------------------------------------------------------------------------------- 1 | kind: Deployment 2 | apiVersion: apps/v1beta2 3 | metadata: 4 | labels: 5 | name: prometheus 6 | name: prometheus 7 | namespace: operos 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | name: prometheus 13 | strategy: 14 | rollingUpdate: 15 | maxSurge: 1 16 | maxUnavailable: 1 17 | type: RollingUpdate 18 | template: 19 | metadata: 20 | creationTimestamp: null 21 | labels: 22 | name: prometheus 23 | 24 | 25 | spec: 26 | affinity: 27 | nodeAffinity: 28 | requiredDuringSchedulingIgnoredDuringExecution: 29 | nodeSelectorTerms: 30 | - matchExpressions: 31 | - key: node-role.kubernetes.io/master 32 | operator: In 33 | values: 34 | - "true" 35 | schedulerName: default-scheduler 36 | tolerations: 37 | - key: node-role.kubernetes.io/master 38 | operator: Exists 39 | 40 | containers: 41 | - args: 42 | - --config.file=/etc/prometheus/prometheus.yml 43 | command: 44 | - /bin/prometheus 45 | image: quay.io/prometheus/prometheus:${OPEROS_PROMETHEUS_VERSION} 46 | imagePullPolicy: Never 47 | name: prometheus 48 | ports: 49 | - containerPort: 9090 50 | protocol: TCP 51 | livenessProbe: 52 | httpGet: 53 | path: / 54 | port: 9090 55 | initialDelaySeconds: 30 56 | periodSeconds: 30 57 | timeoutSeconds: 5 58 | resources: 59 | limits: 60 | cpu: 750m 61 | memory: 450Mi 62 | requests: 63 | cpu: 200m 64 | memory: 300Mi 65 | volumeMounts: 66 | - mountPath: /prometheus 67 | name: data 68 | - mountPath: /etc/prometheus 69 | name: config-volume 70 | restartPolicy: Always 71 | securityContext: {} 72 | terminationGracePeriodSeconds: 30 73 | volumes: 74 | - emptyDir: {} 75 | name: data 76 | - configMap: 77 | name: prometheus-config 78 | name: config-volume -------------------------------------------------------------------------------- /iso/installer/airootfs/root/manifests/addons/55-prometheus-service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: prometheus 5 | namespace: operos 6 | spec: 7 | ports: 8 | - port: 9090 9 | protocol: TCP 10 | targetPort: 9090 11 | selector: 12 | name: prometheus 13 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/manifests/addons/60-rbd-provisioner.yml: -------------------------------------------------------------------------------- 1 | kind: Deployment 2 | apiVersion: apps/v1beta2 3 | metadata: 4 | name: rbd-provisioner 5 | namespace: operos 6 | spec: 7 | replicas: 1 8 | selector: 9 | matchLabels: 10 | app: rbd-provisioner 11 | strategy: 12 | type: Recreate 13 | template: 14 | metadata: 15 | labels: 16 | app: rbd-provisioner 17 | spec: 18 | tolerations: 19 | - key: node-role.kubernetes.io/master 20 | operator: "Exists" 21 | affinity: 22 | nodeAffinity: 23 | requiredDuringSchedulingIgnoredDuringExecution: 24 | nodeSelectorTerms: 25 | - matchExpressions: 26 | - key: node-role.kubernetes.io/master 27 | operator: In 28 | values: 29 | - "true" 30 | containers: 31 | - name: rbd-provisioner 32 | image: "quay.io/external_storage/rbd-provisioner:latest" 33 | imagePullPolicy: Never 34 | env: 35 | - name: PROVISIONER_NAME 36 | value: ceph.com/rbd 37 | -------------------------------------------------------------------------------- /iso/installer/airootfs/root/manifests/kubelet/kube-apiserver.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: kube-apiserver 5 | namespace: kube-system 6 | spec: 7 | hostNetwork: true 8 | containers: 9 | - name: kube-apiserver 10 | image: gcr.io/google_containers/hyperkube:v${OPEROS_KUBERNETES_VERSION} 11 | imagePullPolicy: IfNotPresent 12 | command: 13 | - /hyperkube 14 | - apiserver 15 | - --bind-address=0.0.0.0 16 | - --etcd-servers=http://localhost:2379 17 | - --allow-privileged=true 18 | - --service-cluster-ip-range=${OPEROS_SERVICE_CIDR} 19 | - --insecure-port=${OPEROS_KUBE_API_INSECURE_PORT} 20 | - --secure-port=${OPEROS_KUBE_API_SECURE_PORT} 21 | - --advertise-address=${OPEROS_CONTROLLER_IP} 22 | - --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota 23 | - --tls-cert-file=/etc/kubernetes/ssl/apiserver.pem 24 | - --tls-private-key-file=/etc/kubernetes/ssl/apiserver-key.pem 25 | - --client-ca-file=/etc/kubernetes/ssl/ca.pem 26 | - --service-account-key-file=/etc/kubernetes/ssl/apiserver-key.pem 27 | - --runtime-config=extensions/v1beta1/networkpolicies=true 28 | - --kubelet-preferred-address-types=InternalIP,Hostname,ExternalIP 29 | livenessProbe: 30 | httpGet: 31 | host: 127.0.0.1 32 | port: 8080 33 | path: /healthz 34 | initialDelaySeconds: 15 35 | timeoutSeconds: 15 36 | ports: 37 | - containerPort: ${OPEROS_KUBE_API_INSECURE_PORT} 38 | hostPort: ${OPEROS_KUBE_API_INSECURE_PORT} 39 | name: https 40 | - containerPort: ${OPEROS_KUBE_API_SECURE_PORT} 41 | hostPort: ${OPEROS_KUBE_API_SECURE_PORT} 42 | name: local 43 | volumeMounts: 44 | - mountPath: /etc/kubernetes/ssl 45 | name: ssl-certs-kubernetes 46 | readOnly: true 47 | - mountPath: /etc/ssl/certs 48 | name: ssl-certs-host 49 | readOnly: true 50 | volumes: 51 | - hostPath: 52 | path: /etc/kubernetes/ssl 53 | name: ssl-certs-kubernetes 54 | - hostPath: 55 | path: /usr/share/ca-certificates 56 | name: ssl-certs-host -------------------------------------------------------------------------------- /iso/installer/airootfs/root/manifests/kubelet/kube-controller-manager.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: kube-controller-manager 5 | namespace: kube-system 6 | spec: 7 | containers: 8 | - name: kube-controller-manager 9 | image: gcr.io/google_containers/hyperkube:v${OPEROS_KUBERNETES_VERSION} 10 | imagePullPolicy: IfNotPresent 11 | command: 12 | - /hyperkube 13 | - controller-manager 14 | - --master=http://127.0.0.1:8080 15 | - --leader-elect=true 16 | - --service-account-private-key-file=/etc/kubernetes/ssl/apiserver-key.pem 17 | - --root-ca-file=/etc/kubernetes/ssl/ca.pem 18 | - --allocate-node-cidrs=true 19 | - --cluster-cidr=${OPEROS_POD_CIDR} 20 | resources: 21 | requests: 22 | cpu: 200m 23 | livenessProbe: 24 | httpGet: 25 | host: 127.0.0.1 26 | path: /healthz 27 | port: 10252 28 | initialDelaySeconds: 15 29 | timeoutSeconds: 15 30 | volumeMounts: 31 | - mountPath: /etc/kubernetes/ssl 32 | name: ssl-certs-kubernetes 33 | readOnly: true 34 | - mountPath: /etc/ssl/certs 35 | name: ssl-certs-host 36 | readOnly: true 37 | hostNetwork: true 38 | volumes: 39 | - hostPath: 40 | path: /etc/kubernetes/ssl 41 | name: ssl-certs-kubernetes 42 | - hostPath: 43 | path: /usr/share/ca-certificates 44 | name: ssl-certs-host -------------------------------------------------------------------------------- /iso/installer/airootfs/root/manifests/kubelet/kube-scheduler.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: kube-scheduler 5 | namespace: kube-system 6 | spec: 7 | hostNetwork: true 8 | containers: 9 | - name: kube-scheduler 10 | image: gcr.io/google_containers/hyperkube:v${OPEROS_KUBERNETES_VERSION} 11 | imagePullPolicy: IfNotPresent 12 | command: 13 | - /hyperkube 14 | - scheduler 15 | - --master=http://127.0.0.1:8080 16 | - --leader-elect=true 17 | resources: 18 | requests: 19 | cpu: 100m 20 | livenessProbe: 21 | httpGet: 22 | host: 127.0.0.1 23 | path: /healthz 24 | port: 10251 25 | initialDelaySeconds: 15 26 | timeoutSeconds: 15 27 | -------------------------------------------------------------------------------- /iso/installer/build-layer.sh: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Pax Automa Systems, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | make_devbuild() { 16 | cp ${script_path}/keys/testkey.pub ${work_dir}/airootfs/root/testkey.pub 17 | cp ${script_path}/iso/installer/300-devbuild.sh ${work_dir}/airootfs/root/install/300-devbuild.sh 18 | } 19 | 20 | make_prepare_iso_installer() { 21 | mkdir -p "${work_dir}/installer/iso/${install_dir}/${arch}" 22 | ln -f ${work_dir}/sfs/${install_dir}/${arch}/* ${work_dir}/installer/iso/${install_dir}/${arch}/ 23 | cp -af ${work_dir}/worker/iso/${install_dir}/boot/syslinux-worker/ ${work_dir}/installer/iso/${install_dir}/boot/ 24 | cp -af ${work_dir}/controller/iso/${install_dir}/boot/syslinux-controller/ ${work_dir}/installer/iso/${install_dir}/boot/ 25 | } 26 | 27 | run_once make_prepare_layer base 28 | run_once make_packages 29 | run_once make_customize_airootfs 30 | if [ -n "$devbuild" ]; then 31 | run_once make_devbuild 32 | fi 33 | run_once make_setup_mkinitcpio 34 | run_once make_boot 35 | run_once make_isolinux 36 | run_once make_syslinux base installer 37 | run_once make_efi base installer 38 | run_once make_efiboot base installer 39 | run_once make_final_cleanup 40 | run_once make_squash_layer 41 | run_once make_prepare_iso_installer 42 | run_once make_iso 43 | -------------------------------------------------------------------------------- /iso/installer/efiboot/loader/entries/archiso-x86_64-cd.conf: -------------------------------------------------------------------------------- 1 | title Operos %ARCHISO_LAYER% 2 | linux /EFI/archiso/vmlinuz.efi 3 | initrd /EFI/archiso/intel_ucode.img 4 | initrd /EFI/archiso/archiso.img 5 | options archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% archiso_layers="%ARCHISO_LAYERS%" edd=off quiet 6 | -------------------------------------------------------------------------------- /iso/installer/efiboot/loader/entries/archiso-x86_64-usb.conf: -------------------------------------------------------------------------------- 1 | title Operos %ARCHISO_LAYER% 2 | linux /%INSTALL_DIR%/boot/x86_64/vmlinuz 3 | initrd /%INSTALL_DIR%/boot/intel_ucode.img 4 | initrd /%INSTALL_DIR%/boot/x86_64/archiso.img 5 | options archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% archiso_layers="%ARCHISO_LAYERS%" edd=off quiet 6 | -------------------------------------------------------------------------------- /iso/installer/efiboot/loader/entries/uefi-shell-v1-x86_64.conf: -------------------------------------------------------------------------------- 1 | title UEFI Shell x86_64 v1 2 | efi /EFI/shellx64_v1.efi 3 | -------------------------------------------------------------------------------- /iso/installer/efiboot/loader/entries/uefi-shell-v2-x86_64.conf: -------------------------------------------------------------------------------- 1 | title UEFI Shell x86_64 v2 2 | efi /EFI/shellx64_v2.efi 3 | -------------------------------------------------------------------------------- /iso/installer/efiboot/loader/loader.conf: -------------------------------------------------------------------------------- 1 | timeout 3 2 | default archiso-x86_64 3 | -------------------------------------------------------------------------------- /iso/installer/mkinitcpio.conf: -------------------------------------------------------------------------------- 1 | HOOKS="base udev operosiso operosiso_pxe_common operosiso_pxe_http block filesystems keyboard" 2 | COMPRESSION="xz" 3 | -------------------------------------------------------------------------------- /iso/installer/packages: -------------------------------------------------------------------------------- 1 | arch-install-scripts 2 | b43-fwcutter 3 | btrfs-progs 4 | clonezilla 5 | crda 6 | darkhttpd 7 | ddrescue 8 | dhclient 9 | dialog 10 | dmraid 11 | dnsmasq 12 | dnsutils 13 | dosfstools 14 | elinks 15 | ethtool 16 | exfat-utils 17 | f2fs-tools 18 | fsarchiver 19 | gnu-netcat 20 | gpm 21 | gptfdisk 22 | grml-zsh-config 23 | grub 24 | hdparm 25 | intel-ucode 26 | ipw2100-fw 27 | ipw2200-fw 28 | irssi 29 | lftp 30 | linux-atm 31 | lsscsi 32 | mc 33 | memtest86+ 34 | mtools 35 | ndisc6 36 | nfs-utils 37 | nilfs-utils 38 | nmap 39 | ntfs-3g 40 | ntp 41 | openconnect 42 | openssh 43 | openvpn 44 | partclone 45 | parted 46 | partimage 47 | ppp 48 | pptpclient 49 | refind-efi 50 | rp-pppoe 51 | rsync 52 | sdparm 53 | sg3_utils 54 | smartmontools 55 | #speedtouch 56 | sudo 57 | tcpdump 58 | testdisk 59 | usb_modeswitch 60 | vim-minimal 61 | vpnc 62 | wget 63 | wireless_tools 64 | wpa_actiond 65 | wvdial 66 | xl2tpd 67 | #zd1211-firmware 68 | -------------------------------------------------------------------------------- /iso/installer/syslinux/operos_head.cfg: -------------------------------------------------------------------------------- 1 | SERIAL 0 38400 2 | UI syslinux-%ARCHISO_LAYER%/vesamenu.c32 3 | MENU TITLE Operos %ARCHISO_LAYER% 4 | MENU BACKGROUND syslinux-%ARCHISO_LAYER%/splash.png 5 | 6 | MENU WIDTH 78 7 | MENU MARGIN 4 8 | MENU ROWS 7 9 | MENU VSHIFT 10 10 | MENU TABMSGROW 14 11 | MENU CMDLINEROW 14 12 | MENU HELPMSGROW 16 13 | MENU HELPMSGENDROW 29 14 | 15 | # Refer to http://syslinux.zytor.com/wiki/index.php/Doc/menu 16 | 17 | MENU COLOR border 30;44 #40ffffff #a0000000 std 18 | MENU COLOR title 1;36;44 #9033ccff #a0000000 std 19 | MENU COLOR sel 7;37;40 #e0ffffff #20ffffff all 20 | MENU COLOR unsel 37;44 #50ffffff #a0000000 std 21 | MENU COLOR help 37;40 #c0ffffff #a0000000 std 22 | MENU COLOR timeout_msg 37;40 #80ffffff #00000000 std 23 | MENU COLOR timeout 1;37;40 #c0ffffff #00000000 std 24 | MENU COLOR msg07 37;40 #90ffffff #a0000000 std 25 | MENU COLOR tabmsg 31;40 #30ffffff #00000000 std 26 | -------------------------------------------------------------------------------- /iso/installer/syslinux/operos_pxe.cfg: -------------------------------------------------------------------------------- 1 | INCLUDE syslinux-%ARCHISO_LAYER%/operos_head.cfg 2 | 3 | LABEL operos_http 4 | TEXT HELP 5 | Boot the Operos %ARCHISO_LAYER% (Using HTTP). 6 | ENDTEXT 7 | MENU LABEL Operos %ARCHISO_LAYER% (HTTP) 8 | LINUX x86_64/vmlinuz 9 | INITRD intel_ucode.img,x86_64/archiso.img 10 | APPEND archisobasedir=%INSTALL_DIR% archiso_http_srv=http://${pxeserver}/ archiso_layers="%ARCHISO_LAYERS%" quiet edd=off 11 | SYSAPPEND 3 12 | 13 | INCLUDE syslinux-%ARCHISO_LAYER%/operos_tail.cfg 14 | -------------------------------------------------------------------------------- /iso/installer/syslinux/operos_sys.cfg: -------------------------------------------------------------------------------- 1 | INCLUDE syslinux-%ARCHISO_LAYER%/operos_head.cfg 2 | 3 | LABEL operos 4 | TEXT HELP 5 | Boot the Operos %ARCHISO_LAYER%. 6 | ENDTEXT 7 | MENU LABEL Operos %ARCHISO_LAYER% 8 | LINUX x86_64/vmlinuz 9 | INITRD intel_ucode.img,x86_64/archiso.img 10 | APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% archiso_layers="%ARCHISO_LAYERS%" quiet edd=off 11 | 12 | INCLUDE syslinux-%ARCHISO_LAYER%/operos_tail.cfg 13 | -------------------------------------------------------------------------------- /iso/installer/syslinux/operos_tail.cfg: -------------------------------------------------------------------------------- 1 | LABEL existing 2 | TEXT HELP 3 | Boot an existing operating system. 4 | Press TAB to edit the disk and partition number to boot. 5 | ENDTEXT 6 | MENU LABEL Boot existing OS 7 | COM32 syslinux-%ARCHISO_LAYER%/chain.c32 8 | APPEND hd0 0 9 | 10 | # http://www.memtest.org/ 11 | LABEL memtest 12 | MENU LABEL Run Memtest86+ (RAM test) 13 | LINUX memtest 14 | 15 | # http://hdt-project.org/ 16 | LABEL hdt 17 | MENU LABEL Hardware Information (HDT) 18 | COM32 syslinux-%ARCHISO_LAYER%/hdt.c32 19 | APPEND modules_alias=syslinux-%ARCHISO_LAYER%/hdt/modalias.gz pciids=syslinux-%ARCHISO_LAYER%/hdt/pciids.gz 20 | 21 | LABEL reboot 22 | MENU LABEL Reboot 23 | COM32 syslinux-%ARCHISO_LAYER%/reboot.c32 24 | 25 | LABEL poweroff 26 | MENU LABEL Power Off 27 | COM32 syslinux-%ARCHISO_LAYER%/poweroff.c32 28 | -------------------------------------------------------------------------------- /iso/installer/syslinux/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaxAutoma/operos/2d1c5127eb5ce32c667c0f1a927457b41d7ae709/iso/installer/syslinux/splash.png -------------------------------------------------------------------------------- /iso/installer/syslinux/syslinux.cfg: -------------------------------------------------------------------------------- 1 | DEFAULT select 2 | 3 | LABEL select 4 | COM32 syslinux-%ARCHISO_LAYER%/whichsys.c32 5 | APPEND -pxe- pxe -sys- sys -iso- sys 6 | 7 | LABEL pxe 8 | CONFIG syslinux-%ARCHISO_LAYER%/operos_pxe.cfg 9 | 10 | LABEL sys 11 | CONFIG syslinux-%ARCHISO_LAYER%/operos_sys.cfg 12 | -------------------------------------------------------------------------------- /iso/node/airootfs/etc/docker/daemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "log-driver": "json-file", 3 | "log-opts": { 4 | "max-size": "10m", 5 | "max-file": "3" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /iso/node/airootfs/root/customize_airootfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -e 17 | 18 | # Set locale 19 | sed -i 's/#\(en_US\.UTF-8\)/\1/' /etc/locale.gen 20 | locale-gen 21 | 22 | # Disable suspend and hibernate 23 | sed -i 's/#\(HandleSuspendKey=\)suspend/\1ignore/' /etc/systemd/logind.conf 24 | sed -i 's/#\(HandleHibernateKey=\)hibernate/\1ignore/' /etc/systemd/logind.conf 25 | sed -i 's/#\(HandleLidSwitch=\)suspend/\1ignore/' /etc/systemd/logind.conf 26 | 27 | # SSH 28 | sed -i 's/#\(PermitRootLogin \).\+/\1yes/' /etc/ssh/sshd_config 29 | systemctl enable sshd 30 | 31 | # Entropy 32 | systemctl enable haveged.service 33 | 34 | # Docker 35 | systemctl enable docker.service 36 | 37 | # Kubernetes 38 | systemctl enable kubelet.service 39 | systemctl enable kube-proxy.service 40 | 41 | # NTP 42 | systemctl enable chronyd.service 43 | 44 | systemctl set-default multi-user.target 45 | -------------------------------------------------------------------------------- /iso/node/build-layer.sh: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Pax Automa Systems, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | run_once make_prepare_layer base 16 | run_once make_packages 17 | run_once make_customize_airootfs 18 | run_once make_squash_layer 19 | -------------------------------------------------------------------------------- /iso/node/packages: -------------------------------------------------------------------------------- 1 | calico-cni 2 | calicoctl 3 | ceph 4 | chrony 5 | cni 6 | cni-plugins 7 | docker 8 | kubernetes 9 | net-tools 10 | gnu-netcat 11 | openssh 12 | socat 13 | tcpdump 14 | bc 15 | lshw 16 | gdisk 17 | -------------------------------------------------------------------------------- /iso/worker/airootfs/etc/hosts: -------------------------------------------------------------------------------- 1 | 127.0.0.1 localhost 2 | -------------------------------------------------------------------------------- /iso/worker/airootfs/etc/issue: -------------------------------------------------------------------------------- 1 | Operos Worker Node (\l) 2 | 3 | -------------------------------------------------------------------------------- /iso/worker/airootfs/etc/sysctl.d/printk.conf: -------------------------------------------------------------------------------- 1 | kernel.printk = 2 4 1 4 2 | -------------------------------------------------------------------------------- /iso/worker/airootfs/etc/systemd/scripts/pull-images.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | . /etc/paxautoma/settings 17 | 18 | load_images() { 19 | images=`curl --fail http://${OPEROS_CONTROLLER_IP}:5080/images/worker.txt` 20 | 21 | for img in $images; do 22 | curl --fail "http://${OPEROS_CONTROLLER_IP}:5080/images/$img" | docker load 23 | done 24 | } 25 | 26 | while true; do 27 | (set -e; load_images) 28 | [ $? -eq 0 ] && break 29 | sleep 10 30 | done 31 | 32 | systemctl disable pull-images.service 33 | -------------------------------------------------------------------------------- /iso/worker/airootfs/etc/systemd/system/apply-settings.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Apply worker settings 3 | After=network-online.target network.target 4 | Before=docker.service 5 | Before=kubelet.service 6 | Before=kube-proxy.service 7 | Before=make-partitions.service 8 | Before=var-lib-docker.mount 9 | Before=var-lib-kubelet.mount 10 | 11 | [Service] 12 | Type=oneshot 13 | RemainAfterExit=true 14 | ExecStart=/etc/systemd/scripts/apply-settings.sh 15 | 16 | [Install] 17 | WantedBy=multi-user.target 18 | RequiredBy=kubelet.service 19 | RequiredBy=kube-proxy.service 20 | RequiredBy=make-partitions.service 21 | RequiredBy=var-lib-docker.mount 22 | RequiredBy=var-lib-kubelet.mount 23 | -------------------------------------------------------------------------------- /iso/worker/airootfs/etc/systemd/system/chronyd.service.d/10-settings.conf: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Requires=apply-settings.service 3 | After=apply-settings.service 4 | 5 | [Service] 6 | ExecStartPre=/usr/bin/chronyd -q -u chrony 7 | TimeoutStartSec=infinity 8 | -------------------------------------------------------------------------------- /iso/worker/airootfs/etc/systemd/system/docker.service.d/10-partitions.conf: -------------------------------------------------------------------------------- 1 | [Unit] 2 | BindsTo=make-partitions.service 3 | After=make-partitions.service 4 | -------------------------------------------------------------------------------- /iso/worker/airootfs/etc/systemd/system/etc-pacman.d-gnupg.mount: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Temporary /etc/pacman.d/gnupg directory 3 | 4 | [Mount] 5 | What=tmpfs 6 | Where=/etc/pacman.d/gnupg 7 | Type=tmpfs 8 | Options=mode=0755 9 | -------------------------------------------------------------------------------- /iso/worker/airootfs/etc/systemd/system/kubelet.service.d/10-partitions.conf: -------------------------------------------------------------------------------- 1 | [Unit] 2 | BindsTo=make-partitions.service 3 | After=make-partitions.service 4 | After=chronyd.service 5 | -------------------------------------------------------------------------------- /iso/worker/airootfs/etc/systemd/system/make-partitions.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Worker partitions initialization 3 | 4 | [Service] 5 | Type=oneshot 6 | RemainAfterExit=yes 7 | ExecStart=/etc/systemd/scripts/make-partitions.sh start 8 | ExecStop=/etc/systemd/scripts/make-partitions.sh stop 9 | 10 | [Install] 11 | WantedBy=multi-user.target 12 | -------------------------------------------------------------------------------- /iso/worker/airootfs/etc/systemd/system/operos-statustty.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=TTY status display 3 | After=systemd-journald.service 4 | 5 | [Service] 6 | ExecStart=-/sbin/agetty --noclear -o "--boot-if --node-type Worker" -l /usr/bin/statustty -n tty1 $TERM 7 | Type=simple 8 | Restart=always 9 | RestartSec=0 10 | UtmpIdentifier=tty1 11 | TTYPath=/dev/tty1 12 | TTYReset=yes 13 | TTYVHangup=yes 14 | TTYVTDisallocate=yes 15 | KillMode=none 16 | 17 | # Unset locale for the console getty since the console has problems 18 | # displaying some internationalized messages. 19 | Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION= 20 | 21 | [Install] 22 | WantedBy=multi-user.target 23 | -------------------------------------------------------------------------------- /iso/worker/airootfs/etc/systemd/system/pacman-init.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Pacman keyring initialization 3 | Wants=haveged.service chronyd.service 4 | After=haveged.service chronyd.service 5 | Requires=etc-pacman.d-gnupg.mount 6 | After=etc-pacman.d-gnupg.mount 7 | 8 | [Service] 9 | Type=oneshot 10 | RemainAfterExit=yes 11 | ExecStart=/usr/bin/pacman-key --init 12 | ExecStart=/usr/bin/pacman-key --populate archlinux 13 | 14 | [Install] 15 | WantedBy=multi-user.target 16 | -------------------------------------------------------------------------------- /iso/worker/airootfs/etc/systemd/system/pull-images.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Download container images from controller 3 | After=docker.service apply-settings.service 4 | Before=kubelet.service 5 | 6 | [Service] 7 | Type=oneshot 8 | RemainAfterExit=true 9 | ExecStart=/etc/systemd/scripts/pull-images.sh 10 | 11 | [Install] 12 | WantedBy=multi-user.target 13 | -------------------------------------------------------------------------------- /iso/worker/airootfs/etc/systemd/system/statustty.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=TTY status display 3 | After=dbus.socket 4 | DefaultDependencies=no 5 | 6 | [Service] 7 | ExecStart=-/sbin/agetty --noclear -o "--boot-if --node-type Worker" -l /usr/bin/statustty -n tty1 $TERM 8 | Type=simple 9 | Restart=always 10 | RestartSec=0 11 | UtmpIdentifier=tty1 12 | TTYPath=/dev/tty1 13 | TTYReset=yes 14 | TTYVHangup=yes 15 | TTYVTDisallocate=yes 16 | 17 | # Unset locale for the console getty since the console has problems 18 | # displaying some internationalized messages. 19 | Environment=LANG= LANGUAGE= LC_CTYPE= LC_NUMERIC= LC_TIME= LC_COLLATE= LC_MONETARY= LC_MESSAGES= LC_PAPER= LC_NAME= LC_ADDRESS= LC_TELEPHONE= LC_MEASUREMENT= LC_IDENTIFICATION= 20 | 21 | [Install] 22 | WantedBy=multi-user.target 23 | -------------------------------------------------------------------------------- /iso/worker/airootfs/etc/udev/rules.d/81-dhcpcd.rules: -------------------------------------------------------------------------------- 1 | ACTION=="add", SUBSYSTEM=="net", ENV{INTERFACE}=="en*|eth*", ENV{SYSTEMD_WANTS}="dhcpcd@$name.service" 2 | -------------------------------------------------------------------------------- /iso/worker/airootfs/root/customize_airootfs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -e 17 | 18 | ln -sf /usr/share/zoneinfo/UTC /etc/localtime 19 | ln -s /dev/null /etc/systemd/network/99-default.link 20 | 21 | #usermod -s /usr/bin/zsh root 22 | #cp -aT /etc/skel/ /root/ 23 | chmod 700 /root 24 | chown 0:0 /root 25 | 26 | sed -i 's/#\(PermitRootLogin \).\+/\1yes/' /etc/ssh/sshd_config 27 | sed -i "s/#Server/Server/g" /etc/pacman.d/mirrorlist 28 | sed -i 's/#\(Storage=\)auto/\1volatile/' /etc/systemd/journald.conf 29 | 30 | # Networking 31 | systemctl enable systemd-resolved.service 32 | 33 | # Pacman 34 | systemctl enable pacman-init.service 35 | 36 | # Operos services 37 | sed -i 's/#ShowStatus=.*/ShowStatus=no/' /etc/systemd/system.conf 38 | systemctl disable getty@tty1.service 39 | systemctl enable statustty.service 40 | 41 | # Pax Automa worker setup 42 | systemctl enable make-partitions.service 43 | systemctl enable apply-settings.service 44 | systemctl enable pull-images.service 45 | -------------------------------------------------------------------------------- /iso/worker/airootfs/usr/lib/os-release: -------------------------------------------------------------------------------- 1 | NAME="Operos Worker" 2 | PRETTY_NAME="Operos Worker" 3 | ID=operos 4 | ID_LIKE=archlinux 5 | ANSI_COLOR="0;36" 6 | HOME_URL="https://www.paxautoma.com/" 7 | -------------------------------------------------------------------------------- /iso/worker/build-layer.sh: -------------------------------------------------------------------------------- 1 | # Copyright 2018 Pax Automa Systems, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | make_prepare_iso_worker() { 16 | mkdir -p "${work_dir}/worker/iso/${install_dir}/${arch}" 17 | ln -f ${work_dir}/sfs/${install_dir}/${arch}/airootfs-base.* ${work_dir}/worker/iso/${install_dir}/${arch}/ 18 | ln -f ${work_dir}/sfs/${install_dir}/${arch}/airootfs-node.* ${work_dir}/worker/iso/${install_dir}/${arch}/ 19 | ln -f ${work_dir}/sfs/${install_dir}/${arch}/airootfs-worker.* ${work_dir}/worker/iso/${install_dir}/${arch}/ 20 | } 21 | 22 | run_once make_prepare_layer node base 23 | run_once make_packages 24 | run_once make_customize_airootfs 25 | # run_once make_setup_mkinitcpio 26 | # run_once make_boot 27 | # run_once make_isolinux 28 | run_once make_syslinux base node worker 29 | # run_once make_final_cleanup 30 | run_once make_squash_layer 31 | # run_once make_prepare_iso_worker 32 | # run_once make_iso 33 | -------------------------------------------------------------------------------- /iso/worker/mkinitcpio.conf: -------------------------------------------------------------------------------- 1 | HOOKS="base udev operosiso operosiso_pxe_common operosiso_pxe_http block filesystems keyboard" 2 | COMPRESSION="xz" -------------------------------------------------------------------------------- /iso/worker/packages: -------------------------------------------------------------------------------- 1 | intel-ucode 2 | memtest86+ 3 | -------------------------------------------------------------------------------- /iso/worker/syslinux/operos_head.cfg: -------------------------------------------------------------------------------- 1 | SERIAL 0 38400 2 | UI syslinux-%ARCHISO_LAYER%/vesamenu.c32 3 | MENU TITLE Operos %ARCHISO_LAYER% 4 | MENU BACKGROUND syslinux-%ARCHISO_LAYER%/splash.png 5 | TIMEOUT 50 6 | 7 | MENU WIDTH 78 8 | MENU MARGIN 4 9 | MENU ROWS 7 10 | MENU VSHIFT 10 11 | MENU TABMSGROW 14 12 | MENU CMDLINEROW 14 13 | MENU HELPMSGROW 16 14 | MENU HELPMSGENDROW 29 15 | 16 | # Refer to http://syslinux.zytor.com/wiki/index.php/Doc/menu 17 | 18 | MENU COLOR border 30;44 #40ffffff #a0000000 std 19 | MENU COLOR title 1;36;44 #9033ccff #a0000000 std 20 | MENU COLOR sel 7;37;40 #e0ffffff #20ffffff all 21 | MENU COLOR unsel 37;44 #50ffffff #a0000000 std 22 | MENU COLOR help 37;40 #c0ffffff #a0000000 std 23 | MENU COLOR timeout_msg 37;40 #80ffffff #00000000 std 24 | MENU COLOR timeout 1;37;40 #c0ffffff #00000000 std 25 | MENU COLOR msg07 37;40 #90ffffff #a0000000 std 26 | MENU COLOR tabmsg 31;40 #30ffffff #00000000 std 27 | -------------------------------------------------------------------------------- /iso/worker/syslinux/operos_pxe.cfg: -------------------------------------------------------------------------------- 1 | INCLUDE syslinux-%ARCHISO_LAYER%/operos_head.cfg 2 | 3 | LABEL operos_http 4 | TEXT HELP 5 | Boot the Operos %ARCHISO_LAYER% v%OPEROS_VERSION% (Using HTTP). 6 | ENDTEXT 7 | MENU LABEL Operos %ARCHISO_LAYER% v%OPEROS_VERSION% (HTTP) 8 | LINUX x86_64/vmlinuz 9 | INITRD intel_ucode.img,x86_64/archiso.img 10 | APPEND archisobasedir=%INSTALL_DIR% archiso_http_srv=http://${pxeserver}:5080/ archiso_layers="%ARCHISO_LAYERS%" edd=off quiet 11 | SYSAPPEND 3 12 | 13 | INCLUDE syslinux-%ARCHISO_LAYER%/operos_tail.cfg 14 | -------------------------------------------------------------------------------- /iso/worker/syslinux/operos_sys.cfg: -------------------------------------------------------------------------------- 1 | INCLUDE syslinux-%ARCHISO_LAYER%/operos_head.cfg 2 | 3 | LABEL operos 4 | TEXT HELP 5 | Boot the Operos %ARCHISO_LAYER% v%OPEROS_VERSION%. 6 | ENDTEXT 7 | MENU LABEL Operos %ARCHISO_LAYER% v%OPEROS_VERSION% 8 | LINUX x86_64/vmlinuz 9 | INITRD intel_ucode.img,x86_64/archiso.img 10 | APPEND archisobasedir=%INSTALL_DIR% archisolabel=%ARCHISO_LABEL% archiso_layers="%ARCHISO_LAYERS%" edd=off quiet 11 | 12 | INCLUDE syslinux-%ARCHISO_LAYER%/operos_tail.cfg 13 | -------------------------------------------------------------------------------- /iso/worker/syslinux/operos_tail.cfg: -------------------------------------------------------------------------------- 1 | LABEL existing 2 | TEXT HELP 3 | Boot an existing operating system. 4 | Press TAB to edit the disk and partition number to boot. 5 | ENDTEXT 6 | MENU LABEL Boot existing OS 7 | COM32 syslinux-%ARCHISO_LAYER%/chain.c32 8 | APPEND hd0 0 9 | 10 | # http://www.memtest.org/ 11 | LABEL memtest 12 | MENU LABEL Run Memtest86+ (RAM test) 13 | LINUX memtest 14 | 15 | # http://hdt-project.org/ 16 | LABEL hdt 17 | MENU LABEL Hardware Information (HDT) 18 | COM32 syslinux-%ARCHISO_LAYER%/hdt.c32 19 | APPEND modules_alias=syslinux-%ARCHISO_LAYER%/hdt/modalias.gz pciids=syslinux-%ARCHISO_LAYER%/hdt/pciids.gz 20 | 21 | LABEL reboot 22 | MENU LABEL Reboot 23 | COM32 syslinux-%ARCHISO_LAYER%/reboot.c32 24 | 25 | LABEL poweroff 26 | MENU LABEL Power Off 27 | COM32 syslinux-%ARCHISO_LAYER%/poweroff.c32 28 | -------------------------------------------------------------------------------- /iso/worker/syslinux/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaxAutoma/operos/2d1c5127eb5ce32c667c0f1a927457b41d7ae709/iso/worker/syslinux/splash.png -------------------------------------------------------------------------------- /iso/worker/syslinux/syslinux.cfg: -------------------------------------------------------------------------------- 1 | DEFAULT select 2 | 3 | LABEL select 4 | COM32 syslinux-%ARCHISO_LAYER%/whichsys.c32 5 | APPEND -pxe- pxe -sys- sys -iso- sys 6 | 7 | LABEL pxe 8 | CONFIG syslinux-%ARCHISO_LAYER%/operos_pxe.cfg 9 | 10 | LABEL sys 11 | CONFIG syslinux-%ARCHISO_LAYER%/operos_sys.cfg 12 | -------------------------------------------------------------------------------- /kubectl: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Pax Automa Systems, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | CONTROLLER_IP=${CONTROLLER_IP:-192.168.33.10} 18 | 19 | get_credentials() { 20 | mkdir -p keys 21 | cd keys 22 | 23 | local url="http://${CONTROLLER_IP}/api/v1/clientcert" 24 | 25 | echo -n "Username: " 26 | read username 27 | echo -n "Password: " 28 | read -s password 29 | echo 30 | 31 | echo Downloading ${url} 32 | if ! curl --fail -L --user "${username//:/%3A}:${password//:/%3A}" ${url} | tar -xz; then 33 | echo Failed to download credentials >&2 34 | exit 1 35 | fi 36 | } 37 | 38 | if [ ! -d keys/operos-credentials ]; then 39 | echo "Credentials not found. Please log in to download from Operos controller." 40 | (get_credentials) 41 | fi 42 | 43 | kubectl --kubeconfig=keys/operos-credentials/kubeconfig $@ 44 | -------------------------------------------------------------------------------- /operos-version: -------------------------------------------------------------------------------- 1 | 0.2 2 | -------------------------------------------------------------------------------- /update-pkgs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Prepare an offline repo. This uses a dummy blank database in order to force 17 | # pacman to download all of the dependencies as well. We set the pacman 18 | # cachedir to the target dir to coerce it to place all the downloaded files 19 | # there. 20 | 21 | script_path=$(readlink -f ${0%/*}) 22 | repo_path=${script_path}/cache/pkg 23 | tmp_path=$(mktemp -d) 24 | trap "rm -rf $tmp_path" EXIT 25 | 26 | pacman \ 27 | --noconfirm \ 28 | --dbpath ${tmp_path} \ 29 | --cachedir ${repo_path} \ 30 | -Syuw \ 31 | base syslinux \ 32 | $(grep -h -v ^# ${script_path}/iso/*/packages | sort -u) 33 | 34 | # Create repo for installer. This cannot be called "local" because that seems 35 | # to be a reserved name. 36 | cd ${repo_path} 37 | repo-add -n -R paxautoma-local.db.tar.gz *.pkg.tar.* 38 | -------------------------------------------------------------------------------- /vagrant-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xe 2 | # Copyright 2018 Pax Automa Systems, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | rm -rf /opt/isobuild/out/* 17 | rsync -a --info=progress2 --delete --exclude out --exclude .git /home/vagrant/operos/. /opt/isobuild 18 | 19 | cd /opt/isobuild 20 | ./build.sh -v -N operos -D operos "$@" 21 | mkdir -p /home/vagrant/operos/out 22 | cp /opt/isobuild/out/* /home/vagrant/operos/out/ 23 | -------------------------------------------------------------------------------- /versions: -------------------------------------------------------------------------------- 1 | OPEROS_KUBERNETES_VERSION=1.8.9 2 | OPEROS_KUBE_DASHBOARD_VERSION=1.6.3 3 | OPEROS_KUBEDNS_VERSION=1.14.5 4 | OPEROS_CALICO_VERSION=2.6.8 5 | OPEROS_NGINX_VERSION=alpine 6 | OPEROS_PROMETHEUS_VERSION=v2.2.0 7 | OPEROS_NODE_EXPORTER_VERSION=v0.15.2 8 | OPEROS_RBD_PROVISIONER_VERSION=latest 9 | --------------------------------------------------------------------------------