├── model ├── backend │ ├── .gitignore │ ├── test.proto │ ├── mock.go │ ├── bolt_test.go │ ├── timestamp_test.go │ ├── timestamp.go │ ├── proto_cluster.go │ ├── bolt.go │ └── types.go ├── base.go ├── model.pb_test.go └── connection_test.go ├── handlers ├── types_test.go ├── doc.go ├── none │ ├── none_test.go │ └── none.go └── vm │ ├── base.go │ ├── null │ └── null_test.go │ ├── qemu │ └── qemu_test.go │ ├── esxi │ └── esxi_test.go │ └── lxc │ └── lxc_test.go ├── pkg ├── conf │ ├── mesos-slave │ │ ├── attributes.lxc │ │ ├── attributes.null │ │ ├── attributes.qemu │ │ ├── attributes.esxi │ │ ├── resources.qemu │ │ └── resources.esxi │ ├── scripts │ │ ├── linux-bridge-down.sh.tmpl │ │ ├── ovs-down.sh.tmpl │ │ ├── linux-bridge-up.sh.tmpl │ │ └── ovs-up.sh.tmpl │ ├── scheduler.toml │ └── executor.toml └── rhel │ └── openvdc-scheduler.service ├── ci ├── citest │ ├── acceptance-test │ │ ├── multibox │ │ │ ├── 10.0.100.10-zookeeper │ │ │ │ ├── login.sh │ │ │ │ ├── guestroot │ │ │ │ │ ├── etc │ │ │ │ │ │ ├── hostname │ │ │ │ │ │ ├── sysconfig │ │ │ │ │ │ │ ├── network │ │ │ │ │ │ │ └── network-scripts │ │ │ │ │ │ │ │ └── ifcfg-eth0 │ │ │ │ │ │ ├── yum │ │ │ │ │ │ │ └── pluginconf.d │ │ │ │ │ │ │ │ └── fastestmirror.conf │ │ │ │ │ │ └── zookeeper │ │ │ │ │ │ │ └── conf │ │ │ │ │ │ │ └── zoo.cfg │ │ │ │ │ └── var │ │ │ │ │ │ └── lib │ │ │ │ │ │ └── zookeeper │ │ │ │ │ │ └── myid │ │ │ │ ├── vmspec.conf │ │ │ │ ├── destroy.sh │ │ │ │ ├── destroy_cache.sh │ │ │ │ └── build.sh │ │ │ ├── 10.0.100.11-mesos-master │ │ │ │ ├── login.sh │ │ │ │ ├── guestroot │ │ │ │ │ ├── etc │ │ │ │ │ │ ├── hostname │ │ │ │ │ │ ├── mesos │ │ │ │ │ │ │ ├── hostname_lookup │ │ │ │ │ │ │ └── zk │ │ │ │ │ │ ├── default │ │ │ │ │ │ │ ├── mesos │ │ │ │ │ │ │ └── mesos-master │ │ │ │ │ │ ├── sysconfig │ │ │ │ │ │ │ ├── network │ │ │ │ │ │ │ └── network-scripts │ │ │ │ │ │ │ │ └── ifcfg-eth0 │ │ │ │ │ │ ├── yum │ │ │ │ │ │ │ └── pluginconf.d │ │ │ │ │ │ │ │ └── fastestmirror.conf │ │ │ │ │ │ └── zookeeper │ │ │ │ │ │ │ └── conf │ │ │ │ │ │ │ └── zoo.cfg │ │ │ │ │ └── var │ │ │ │ │ │ └── lib │ │ │ │ │ │ └── zookeeper │ │ │ │ │ │ └── myid │ │ │ │ ├── destroy.sh │ │ │ │ ├── destroy_cache.sh │ │ │ │ ├── vmspec.conf │ │ │ │ └── build.sh │ │ │ ├── 10.0.100.12-vdc-scheduler │ │ │ │ ├── login.sh │ │ │ │ ├── guestroot │ │ │ │ │ ├── etc │ │ │ │ │ │ ├── hostname │ │ │ │ │ │ ├── sysconfig │ │ │ │ │ │ │ ├── network │ │ │ │ │ │ │ └── network-scripts │ │ │ │ │ │ │ │ └── ifcfg-eth0 │ │ │ │ │ │ ├── openvdc │ │ │ │ │ │ │ └── scheduler.toml │ │ │ │ │ │ ├── yum │ │ │ │ │ │ │ └── pluginconf.d │ │ │ │ │ │ │ │ └── fastestmirror.conf │ │ │ │ │ │ └── zookeeper │ │ │ │ │ │ │ └── conf │ │ │ │ │ │ │ └── zoo.cfg │ │ │ │ │ └── var │ │ │ │ │ │ └── lib │ │ │ │ │ │ └── zookeeper │ │ │ │ │ │ └── myid │ │ │ │ ├── destroy.sh │ │ │ │ ├── destroy_cache.sh │ │ │ │ ├── vmspec.conf │ │ │ │ └── build.sh │ │ │ ├── 10.0.100.14-vdc-executor-lxc │ │ │ │ ├── login.sh │ │ │ │ ├── guestroot │ │ │ │ │ └── etc │ │ │ │ │ │ ├── hostname │ │ │ │ │ │ ├── mesos-slave │ │ │ │ │ │ ├── switch_user │ │ │ │ │ │ └── attributes │ │ │ │ │ │ ├── mesos │ │ │ │ │ │ ├── hostname_lookup │ │ │ │ │ │ └── zk │ │ │ │ │ │ ├── default │ │ │ │ │ │ ├── mesos-slave │ │ │ │ │ │ └── mesos │ │ │ │ │ │ ├── sysconfig │ │ │ │ │ │ ├── network │ │ │ │ │ │ └── network-scripts │ │ │ │ │ │ │ ├── ifcfg-br0 │ │ │ │ │ │ │ ├── ifcfg-eth1 │ │ │ │ │ │ │ └── ifcfg-eth0 │ │ │ │ │ │ ├── yum │ │ │ │ │ │ └── pluginconf.d │ │ │ │ │ │ │ └── fastestmirror.conf │ │ │ │ │ │ └── openvdc │ │ │ │ │ │ └── executor.toml │ │ │ │ ├── destroy.sh │ │ │ │ ├── destroy_cache.sh │ │ │ │ ├── vmspec.conf │ │ │ │ └── build.sh │ │ │ ├── 10.0.100.13-vdc-executor-null │ │ │ │ ├── login.sh │ │ │ │ ├── guestroot │ │ │ │ │ └── etc │ │ │ │ │ │ ├── hostname │ │ │ │ │ │ ├── mesos-slave │ │ │ │ │ │ ├── switch_user │ │ │ │ │ │ └── attributes │ │ │ │ │ │ ├── mesos │ │ │ │ │ │ ├── hostname_lookup │ │ │ │ │ │ └── zk │ │ │ │ │ │ ├── default │ │ │ │ │ │ ├── mesos-slave │ │ │ │ │ │ └── mesos │ │ │ │ │ │ ├── sysconfig │ │ │ │ │ │ ├── network │ │ │ │ │ │ └── network-scripts │ │ │ │ │ │ │ └── ifcfg-eth0 │ │ │ │ │ │ ├── openvdc │ │ │ │ │ │ └── executor.toml │ │ │ │ │ │ └── yum │ │ │ │ │ │ └── pluginconf.d │ │ │ │ │ │ └── fastestmirror.conf │ │ │ │ ├── destroy.sh │ │ │ │ ├── destroy_cache.sh │ │ │ │ ├── vmspec.conf │ │ │ │ └── build.sh │ │ │ ├── 10.0.100.16-vdc-executor-qemu │ │ │ │ ├── login.sh │ │ │ │ ├── guestroot │ │ │ │ │ └── etc │ │ │ │ │ │ ├── hostname │ │ │ │ │ │ ├── mesos-slave │ │ │ │ │ │ ├── switch_user │ │ │ │ │ │ └── attributes │ │ │ │ │ │ ├── mesos │ │ │ │ │ │ ├── hostname_lookup │ │ │ │ │ │ └── zk │ │ │ │ │ │ ├── default │ │ │ │ │ │ ├── mesos-slave │ │ │ │ │ │ └── mesos │ │ │ │ │ │ ├── sysconfig │ │ │ │ │ │ ├── network │ │ │ │ │ │ └── network-scripts │ │ │ │ │ │ │ ├── ifcfg-br0 │ │ │ │ │ │ │ ├── ifcfg-eth1 │ │ │ │ │ │ │ └── ifcfg-eth0 │ │ │ │ │ │ ├── yum │ │ │ │ │ │ └── pluginconf.d │ │ │ │ │ │ │ └── fastestmirror.conf │ │ │ │ │ │ └── openvdc │ │ │ │ │ │ └── executor.toml │ │ │ │ ├── destroy.sh │ │ │ │ ├── destroy_cache.sh │ │ │ │ ├── vmspec.conf │ │ │ │ └── build.sh │ │ │ ├── ind-steps │ │ │ │ ├── step-box │ │ │ │ │ ├── post_boot.sh │ │ │ │ │ ├── pre_rsync.sh │ │ │ │ │ └── rsync.sh │ │ │ │ ├── step-ncat │ │ │ │ │ └── pre_boot.sh │ │ │ │ ├── step-zookeeper │ │ │ │ │ ├── common.source │ │ │ │ │ └── pre_boot.sh │ │ │ │ ├── step-bridge-utils │ │ │ │ │ └── pre_boot.sh │ │ │ │ ├── step-openvswitch │ │ │ │ │ ├── pre_boot.sh │ │ │ │ │ └── pre_rsync.sh │ │ │ │ ├── step-mesos-agent │ │ │ │ │ └── pre_boot.sh │ │ │ │ ├── step-mesos-master │ │ │ │ │ └── pre_boot.sh │ │ │ │ ├── step-qemu-kvm │ │ │ │ │ ├── pre_boot.sh │ │ │ │ │ └── post_boot.sh │ │ │ │ ├── step-disable-firewalld │ │ │ │ │ └── pre_rsync.sh │ │ │ │ ├── step-mesosphere-repo │ │ │ │ │ └── pre_rsync.sh │ │ │ │ ├── step-apache │ │ │ │ │ └── pre_boot.sh │ │ │ │ ├── step-cgroups │ │ │ │ │ └── post_boot.sh │ │ │ │ ├── step-hosts │ │ │ │ │ └── pre_boot.sh │ │ │ │ ├── step-epel │ │ │ │ │ └── pre_boot.sh │ │ │ │ ├── step-ssh │ │ │ │ │ ├── common.source │ │ │ │ │ ├── boot.sh │ │ │ │ │ └── pre_boot.sh │ │ │ │ └── step-vdc-images │ │ │ │ │ └── pre_rsync.sh │ │ │ ├── 10.0.100.15-vdc-executor-lxc-ovs │ │ │ │ ├── destroy.sh │ │ │ │ ├── guestroot │ │ │ │ │ └── etc │ │ │ │ │ │ ├── hostname │ │ │ │ │ │ ├── mesos │ │ │ │ │ │ ├── hostname_lookup │ │ │ │ │ │ └── zk │ │ │ │ │ │ ├── mesos-slave │ │ │ │ │ │ ├── switch_user │ │ │ │ │ │ └── attributes │ │ │ │ │ │ ├── sysconfig │ │ │ │ │ │ ├── network │ │ │ │ │ │ └── network-scripts │ │ │ │ │ │ │ ├── ifcfg-eth1 │ │ │ │ │ │ │ ├── ifcfg-eth0 │ │ │ │ │ │ │ └── ifcfg-br0 │ │ │ │ │ │ ├── yum │ │ │ │ │ │ └── pluginconf.d │ │ │ │ │ │ │ └── fastestmirror.conf │ │ │ │ │ │ └── openvdc │ │ │ │ │ │ └── executor.toml │ │ │ │ ├── login.sh │ │ │ │ ├── destroy_cache.sh │ │ │ │ ├── vmspec.conf │ │ │ │ └── build.sh │ │ │ ├── 10.0.100.17-vdc-executor-qemu-ovs │ │ │ │ ├── guestroot │ │ │ │ │ └── etc │ │ │ │ │ │ ├── hostname │ │ │ │ │ │ ├── mesos-slave │ │ │ │ │ │ ├── switch_user │ │ │ │ │ │ └── attributes │ │ │ │ │ │ ├── mesos │ │ │ │ │ │ ├── hostname_lookup │ │ │ │ │ │ └── zk │ │ │ │ │ │ ├── sysconfig │ │ │ │ │ │ ├── network │ │ │ │ │ │ └── network-scripts │ │ │ │ │ │ │ ├── ifcfg-eth1 │ │ │ │ │ │ │ ├── ifcfg-eth0 │ │ │ │ │ │ │ └── ifcfg-br0 │ │ │ │ │ │ ├── yum │ │ │ │ │ │ └── pluginconf.d │ │ │ │ │ │ │ └── fastestmirror.conf │ │ │ │ │ │ └── openvdc │ │ │ │ │ │ └── executor.toml │ │ │ │ ├── destroy.sh │ │ │ │ ├── login.sh │ │ │ │ ├── destroy_cache.sh │ │ │ │ ├── vmspec.conf │ │ │ │ └── build.sh │ │ │ ├── external_libraries │ │ │ │ ├── bashsteps │ │ │ │ │ ├── examples │ │ │ │ │ │ ├── new │ │ │ │ │ │ │ ├── simple-defaults-for-bashsteps.source │ │ │ │ │ │ │ ├── new-duped-substep.sh │ │ │ │ │ │ │ └── with-temporary-state.sh │ │ │ │ │ │ └── old │ │ │ │ │ │ │ ├── simple-defaults-for-bashsteps.source │ │ │ │ │ │ │ └── duped-substep.sh │ │ │ │ │ ├── ind-steps │ │ │ │ │ │ └── kvmsteps │ │ │ │ │ │ │ ├── vmdir-scripts │ │ │ │ │ │ │ ├── kvm-kill.sh │ │ │ │ │ │ │ ├── ssh-to-kvm.sh │ │ │ │ │ │ │ └── kvm-shutdown-via-ssh.sh │ │ │ │ │ │ │ └── monitor-process.sh │ │ │ │ │ └── README.md │ │ │ │ └── README.md │ │ │ ├── destroy_leaving_cache.sh │ │ │ ├── login.sh │ │ │ ├── destroy_with_cache.sh │ │ │ └── config.source │ │ ├── .dockerignore │ │ ├── tests │ │ │ ├── .gitignore │ │ │ ├── fixtures │ │ │ │ ├── lxc2.json │ │ │ │ ├── invalid1.json │ │ │ │ └── lxc.json │ │ │ ├── 01_cmd_in_path_test.go │ │ │ ├── cmd_log_test.go │ │ │ ├── README.md │ │ │ ├── vendor │ │ │ │ └── vendor.json │ │ │ ├── cmd_run_test.go │ │ │ ├── force_destroy_test.go │ │ │ ├── force_state_test.go │ │ │ ├── crash_recovery_test.go │ │ │ ├── cmd_console_test.go │ │ │ ├── local_image_test.go │ │ │ └── copy_local_file_to_instance_test.go │ │ ├── dot_openvdc-config.toml │ │ ├── illustrations │ │ │ └── README.md │ │ ├── Dockerfile │ │ └── build_and_run_in_docker.sh │ ├── rpmbuild │ │ ├── build-cache.list │ │ └── el7.Dockerfile │ ├── acceptance-test-esxi │ │ └── tests │ │ │ ├── fixtures │ │ │ └── esxi.json │ │ │ ├── 02_cmd_console_test.go │ │ │ └── 01_start_and_terminate_esxi_instance_test.go │ └── unit-tests │ │ ├── el7-unit-tests.Dockerfile │ │ └── unit-tests.sh ├── devbox │ ├── .gitignore │ ├── fastestmirror.conf │ ├── build.sh │ └── build.ps1 ├── appveyor │ └── install-zk.ps1 └── garbage_collection │ ├── garbage_collection_misc.sh │ ├── cache_cleanups │ └── cache_garbage_collection.sh │ ├── Jenkinsfile.garbage_collection │ ├── docker_cleanups │ └── docker_garbage_collection.sh │ └── repo_cleanups │ └── rpm_garbage_collection.sh ├── registry ├── doc.go ├── local_test.go ├── remote_test.go ├── schema.go ├── schema_test.go ├── types_test.go ├── local.go └── github_test.go ├── docs ├── diagrams │ └── crash-recovery.png ├── guide.md ├── resource_template.md ├── openvnet_integration.md └── computing_resources.md ├── templates ├── none.json ├── centos │ └── 7 │ │ ├── null.json │ │ ├── lxc.json │ │ ├── lxc2.json │ │ ├── esxi_ovf_tmpl.json │ │ ├── esxi.json │ │ ├── qemu.json │ │ ├── qemu_ga.json │ │ └── qemu_kvm.json └── ubuntu │ └── 16.04 │ └── lxc.json ├── .gitignore ├── deployment ├── docker │ └── yum.repo │ │ └── dev.repo └── packagebuild │ └── gen-dev-build-tag.sh ├── proto ├── executor.proto └── cluster.proto ├── hypervisor ├── base.go ├── qemu │ ├── qemu_image_test.go │ ├── qemu_machine_test.go │ ├── qemu_test.go │ ├── qemu_image.go │ ├── qemu_device_test.go │ └── qemu_cmd.go ├── esxi │ ├── esxi_machine.go │ └── esxi_test.go ├── null │ └── null_test.go └── types_test.go ├── cmd ├── openvdc-executor │ ├── init.go │ └── init_linux.go ├── openvdc │ ├── init.go │ ├── cmd │ │ ├── template.go │ │ ├── start.go │ │ ├── stop.go │ │ ├── list.go │ │ ├── reboot.go │ │ ├── destroy.go │ │ ├── log.go │ │ ├── show.go │ │ ├── force_state.go │ │ ├── template │ │ │ ├── validate.go │ │ │ └── show.go │ │ └── run.go │ └── main.go ├── openvdc-scheduler │ └── init.go ├── lxc-openvdc │ └── init_linux.go ├── version.go ├── qemu-ifdown │ └── main.go ├── qemu-ifup │ └── main.go └── formatter_test.go ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── terraform ├── openvdc │ ├── config.go │ ├── provider_test.go │ └── provider.go ├── main.go └── example.tf ├── .editorconfig ├── run_unit_tests.sh ├── internal └── unittest │ └── flags.go ├── README.md ├── schema ├── none.json ├── v1.json └── vm │ └── null.json ├── .idea └── libraries │ └── GOPATH__openvdc_.xml ├── api ├── server_test.go └── executor │ ├── server.go │ └── executor.pb.go └── appveyor.yml /model/backend/.gitignore: -------------------------------------------------------------------------------- 1 | my.db 2 | -------------------------------------------------------------------------------- /handlers/types_test.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | -------------------------------------------------------------------------------- /pkg/conf/mesos-slave/attributes.lxc: -------------------------------------------------------------------------------- 1 | hypervisor:lxc -------------------------------------------------------------------------------- /pkg/conf/mesos-slave/attributes.null: -------------------------------------------------------------------------------- 1 | hypervisor:null -------------------------------------------------------------------------------- /pkg/conf/mesos-slave/attributes.qemu: -------------------------------------------------------------------------------- 1 | hypervisor:qemu -------------------------------------------------------------------------------- /pkg/conf/mesos-slave/attributes.esxi: -------------------------------------------------------------------------------- 1 | hypervisor:esxi 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.10-zookeeper/login.sh: -------------------------------------------------------------------------------- 1 | ../login.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.11-mesos-master/login.sh: -------------------------------------------------------------------------------- 1 | ../login.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.12-vdc-scheduler/login.sh: -------------------------------------------------------------------------------- 1 | ../login.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.14-vdc-executor-lxc/login.sh: -------------------------------------------------------------------------------- 1 | ../login.sh -------------------------------------------------------------------------------- /ci/citest/rpmbuild/build-cache.list: -------------------------------------------------------------------------------- 1 | var/tmp/rpmbuild/SOURCES/openvnet/vnet/vendor -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.13-vdc-executor-null/login.sh: -------------------------------------------------------------------------------- 1 | ../login.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/login.sh: -------------------------------------------------------------------------------- 1 | ../login.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.10-zookeeper/guestroot/etc/hostname: -------------------------------------------------------------------------------- 1 | zookeeper 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.11-mesos-master/guestroot/etc/hostname: -------------------------------------------------------------------------------- 1 | mesos 2 | -------------------------------------------------------------------------------- /ci/devbox/.gitignore: -------------------------------------------------------------------------------- 1 | boxtemp/* 2 | packer 3 | packer.exe 4 | packer_cache/* 5 | output-* 6 | -------------------------------------------------------------------------------- /registry/doc.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | // Handle OpenVDC resource template registry. 4 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/.dockerignore: -------------------------------------------------------------------------------- 1 | tests 2 | illustrations 3 | build_and_run_in_docker.sh 4 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.10-zookeeper/guestroot/var/lib/zookeeper/myid: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.11-mesos-master/guestroot/var/lib/zookeeper/myid: -------------------------------------------------------------------------------- 1 | 2 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.12-vdc-scheduler/guestroot/etc/hostname: -------------------------------------------------------------------------------- 1 | scheduler 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.12-vdc-scheduler/guestroot/var/lib/zookeeper/myid: -------------------------------------------------------------------------------- 1 | 3 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.14-vdc-executor-lxc/guestroot/etc/hostname: -------------------------------------------------------------------------------- 1 | executor-lxc 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.11-mesos-master/destroy.sh: -------------------------------------------------------------------------------- 1 | ../10.0.100.10-zookeeper/destroy.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.11-mesos-master/guestroot/etc/mesos/hostname_lookup: -------------------------------------------------------------------------------- 1 | false 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.12-vdc-scheduler/destroy.sh: -------------------------------------------------------------------------------- 1 | ../10.0.100.10-zookeeper/destroy.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.13-vdc-executor-null/guestroot/etc/hostname: -------------------------------------------------------------------------------- 1 | executor-null 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/guestroot/etc/hostname: -------------------------------------------------------------------------------- 1 | executor-qemu 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-box/post_boot.sh: -------------------------------------------------------------------------------- 1 | run_ssh root@${IP_ADDR} "iptables -F" 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/tests/.gitignore: -------------------------------------------------------------------------------- 1 | vendor/*/ 2 | !vendor/vendor.json 3 | fixtures.bindata.go 4 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.13-vdc-executor-null/destroy.sh: -------------------------------------------------------------------------------- 1 | ../10.0.100.10-zookeeper/destroy.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.13-vdc-executor-null/guestroot/etc/mesos-slave/switch_user: -------------------------------------------------------------------------------- 1 | false 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.13-vdc-executor-null/guestroot/etc/mesos/hostname_lookup: -------------------------------------------------------------------------------- 1 | false 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.14-vdc-executor-lxc/destroy.sh: -------------------------------------------------------------------------------- 1 | ../10.0.100.10-zookeeper/destroy.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.14-vdc-executor-lxc/guestroot/etc/mesos-slave/switch_user: -------------------------------------------------------------------------------- 1 | false 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.14-vdc-executor-lxc/guestroot/etc/mesos/hostname_lookup: -------------------------------------------------------------------------------- 1 | false 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.15-vdc-executor-lxc-ovs/destroy.sh: -------------------------------------------------------------------------------- 1 | ../10.0.100.10-zookeeper/destroy.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.15-vdc-executor-lxc-ovs/guestroot/etc/hostname: -------------------------------------------------------------------------------- 1 | executor-lxc-ovs 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.15-vdc-executor-lxc-ovs/guestroot/etc/mesos/hostname_lookup: -------------------------------------------------------------------------------- 1 | false 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/destroy.sh: -------------------------------------------------------------------------------- 1 | ../10.0.100.10-zookeeper/destroy.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/guestroot/etc/mesos-slave/switch_user: -------------------------------------------------------------------------------- 1 | false 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/guestroot/etc/mesos/hostname_lookup: -------------------------------------------------------------------------------- 1 | false 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.17-vdc-executor-qemu-ovs/guestroot/etc/hostname: -------------------------------------------------------------------------------- 1 | executor-qemu-ovs 2 | -------------------------------------------------------------------------------- /docs/diagrams/crash-recovery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/axsh/openvdc/HEAD/docs/diagrams/crash-recovery.png -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.11-mesos-master/destroy_cache.sh: -------------------------------------------------------------------------------- 1 | ../10.0.100.10-zookeeper/destroy_cache.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.12-vdc-scheduler/destroy_cache.sh: -------------------------------------------------------------------------------- 1 | ../10.0.100.10-zookeeper/destroy_cache.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.15-vdc-executor-lxc-ovs/guestroot/etc/mesos-slave/switch_user: -------------------------------------------------------------------------------- 1 | false 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.15-vdc-executor-lxc-ovs/login.sh: -------------------------------------------------------------------------------- 1 | ../10.0.100.14-vdc-executor-lxc/login.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.17-vdc-executor-qemu-ovs/destroy.sh: -------------------------------------------------------------------------------- 1 | ../10.0.100.10-zookeeper/destroy.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.17-vdc-executor-qemu-ovs/guestroot/etc/mesos-slave/switch_user: -------------------------------------------------------------------------------- 1 | false 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.17-vdc-executor-qemu-ovs/guestroot/etc/mesos/hostname_lookup: -------------------------------------------------------------------------------- 1 | false 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.17-vdc-executor-qemu-ovs/login.sh: -------------------------------------------------------------------------------- 1 | ../10.0.100.14-vdc-executor-lxc/login.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-ncat/pre_boot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | install_yum_package "nc" 4 | -------------------------------------------------------------------------------- /templates/none.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Dummy Template", 3 | "template": { 4 | "type": "none" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.13-vdc-executor-null/destroy_cache.sh: -------------------------------------------------------------------------------- 1 | ../10.0.100.10-zookeeper/destroy_cache.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.14-vdc-executor-lxc/destroy_cache.sh: -------------------------------------------------------------------------------- 1 | ../10.0.100.10-zookeeper/destroy_cache.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.15-vdc-executor-lxc-ovs/guestroot/etc/mesos/zk: -------------------------------------------------------------------------------- 1 | zk://10.0.100.10:2181/mesos 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/destroy_cache.sh: -------------------------------------------------------------------------------- 1 | ../10.0.100.10-zookeeper/destroy_cache.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.17-vdc-executor-qemu-ovs/guestroot/etc/mesos/zk: -------------------------------------------------------------------------------- 1 | zk://10.0.100.10:2181/mesos 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-zookeeper/common.source: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | zk_host=${zk_host:-false} 3 | -------------------------------------------------------------------------------- /templates/centos/7/null.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "CentOS7", 3 | "template": { 4 | "type": "vm/null" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.15-vdc-executor-lxc-ovs/destroy_cache.sh: -------------------------------------------------------------------------------- 1 | ../10.0.100.10-zookeeper/destroy_cache.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.17-vdc-executor-qemu-ovs/destroy_cache.sh: -------------------------------------------------------------------------------- 1 | ../10.0.100.10-zookeeper/destroy_cache.sh -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.10-zookeeper/guestroot/etc/sysconfig/network: -------------------------------------------------------------------------------- 1 | NETWORKING=yes 2 | GATEWAY=10.0.100.1 3 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.11-mesos-master/guestroot/etc/default/mesos: -------------------------------------------------------------------------------- 1 | LOGS=/var/log/mesos 2 | ULIMIT="-n 8192" 3 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.11-mesos-master/guestroot/etc/sysconfig/network: -------------------------------------------------------------------------------- 1 | NETWORKING=yes 2 | GATEWAY=10.0.100.1 3 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.13-vdc-executor-null/guestroot/etc/default/mesos-slave: -------------------------------------------------------------------------------- 1 | MASTER=$(cat /etc/mesos/zk) 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.14-vdc-executor-lxc/guestroot/etc/default/mesos-slave: -------------------------------------------------------------------------------- 1 | MASTER=$(cat /etc/mesos/zk) 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/guestroot/etc/default/mesos-slave: -------------------------------------------------------------------------------- 1 | MASTER=$(cat /etc/mesos/zk) 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/dot_openvdc-config.toml: -------------------------------------------------------------------------------- 1 | [api] 2 | endpoint = "10.0.100.12:5000" 3 | [mesos] 4 | master = "10.0.100.11:5050" 5 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.12-vdc-scheduler/guestroot/etc/sysconfig/network: -------------------------------------------------------------------------------- 1 | NETWORKING=yes 2 | GATEWAY=10.0.100.1 3 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.13-vdc-executor-null/guestroot/etc/default/mesos: -------------------------------------------------------------------------------- 1 | LOGS=/var/log/mesos 2 | ULIMIT="-n 8192" 3 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.13-vdc-executor-null/guestroot/etc/sysconfig/network: -------------------------------------------------------------------------------- 1 | NETWORKING=yes 2 | GATEWAY=10.0.100.1 3 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.14-vdc-executor-lxc/guestroot/etc/default/mesos: -------------------------------------------------------------------------------- 1 | LOGS=/var/log/mesos 2 | ULIMIT="-n 8192" 3 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.14-vdc-executor-lxc/guestroot/etc/sysconfig/network: -------------------------------------------------------------------------------- 1 | NETWORKING=yes 2 | GATEWAY=10.0.100.1 3 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/guestroot/etc/default/mesos: -------------------------------------------------------------------------------- 1 | LOGS=/var/log/mesos 2 | ULIMIT="-n 8192" 3 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/guestroot/etc/sysconfig/network: -------------------------------------------------------------------------------- 1 | NETWORKING=yes 2 | GATEWAY=10.0.100.1 3 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-bridge-utils/pre_boot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | install_yum_package "bridge-utils" 4 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-openvswitch/pre_boot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | install_yum_package "openvswitch-2.4.1" 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # external packages folder 2 | vendor/*/ 3 | 4 | *.exe 5 | 6 | # macOS 7 | *.DS_Store 8 | # emacs 9 | *~ 10 | \#*\# 11 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.13-vdc-executor-null/guestroot/etc/mesos-slave/attributes: -------------------------------------------------------------------------------- 1 | hypervisor:null;openvdc-node-id:null1 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.15-vdc-executor-lxc-ovs/guestroot/etc/sysconfig/network: -------------------------------------------------------------------------------- 1 | NETWORKING=yes 2 | GATEWAY=10.0.100.1 3 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/guestroot/etc/mesos-slave/attributes: -------------------------------------------------------------------------------- 1 | hypervisor:qemu;node-groups:linuxbr 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.17-vdc-executor-qemu-ovs/guestroot/etc/mesos-slave/attributes: -------------------------------------------------------------------------------- 1 | hypervisor:qemu;node-groups:ovs 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.17-vdc-executor-qemu-ovs/guestroot/etc/sysconfig/network: -------------------------------------------------------------------------------- 1 | NETWORKING=yes 2 | GATEWAY=10.0.100.1 3 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.11-mesos-master/guestroot/etc/mesos/zk: -------------------------------------------------------------------------------- 1 | zk://10.0.100.10:2181,10.0.100.11:2181,10.0.100.12:2181/mesos 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.11-mesos-master/guestroot/etc/default/mesos-master: -------------------------------------------------------------------------------- 1 | PORT=5050 2 | ZK=$(cat /etc/mesos/zk) 3 | IP=10.0.100.11 -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.13-vdc-executor-null/guestroot/etc/mesos/zk: -------------------------------------------------------------------------------- 1 | zk://10.0.100.10:2181,10.0.100.11:2181,10.0.100.12:2181/mesos 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.14-vdc-executor-lxc/guestroot/etc/mesos/zk: -------------------------------------------------------------------------------- 1 | zk://10.0.100.10:2181,10.0.100.11:2181,10.0.100.12:2181/mesos 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/guestroot/etc/mesos/zk: -------------------------------------------------------------------------------- 1 | zk://10.0.100.10:2181,10.0.100.11:2181,10.0.100.12:2181/mesos 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/external_libraries/bashsteps/examples/new/simple-defaults-for-bashsteps.source: -------------------------------------------------------------------------------- 1 | ../../simple-defaults-for-bashsteps.source -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/external_libraries/bashsteps/examples/old/simple-defaults-for-bashsteps.source: -------------------------------------------------------------------------------- 1 | ../../simple-defaults-for-bashsteps.source -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.14-vdc-executor-lxc/guestroot/etc/mesos-slave/attributes: -------------------------------------------------------------------------------- 1 | hypervisor:lxc;openvdc-node-id:lxc1;node-groups:linuxbr 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.15-vdc-executor-lxc-ovs/guestroot/etc/mesos-slave/attributes: -------------------------------------------------------------------------------- 1 | hypervisor:lxc;openvdc-node-id:lxc2;node-groups:ovs 2 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-mesos-agent/pre_boot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | install_yum_package "mesos" 4 | disable_service "mesos-master" 5 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-mesos-master/pre_boot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | install_yum_package "mesos" 4 | disable_service "mesos-slave" 5 | -------------------------------------------------------------------------------- /deployment/docker/yum.repo/dev.repo: -------------------------------------------------------------------------------- 1 | [openvdc] 2 | name=OpenVDc Repo - devrepo 3 | baseurl=http://ci.openvdc.org/repos/$release_id/ 4 | enabled=1 5 | gpgcheck=0 6 | -------------------------------------------------------------------------------- /proto/executor.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package executor; 4 | 5 | option go_package = "github.com/axsh/openvdc/api/executor"; 6 | 7 | import "v1.proto"; 8 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-qemu-kvm/pre_boot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # install_yum_package "qemu-system-x86" 4 | install_yum_package "qemu-kvm" 5 | -------------------------------------------------------------------------------- /pkg/conf/mesos-slave/resources.qemu: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "cpus", 4 | "type": "SCALAR", 5 | "scalar": { 6 | "value": 20 7 | } 8 | } 9 | ] 10 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.15-vdc-executor-lxc-ovs/guestroot/etc/sysconfig/network-scripts/ifcfg-eth1: -------------------------------------------------------------------------------- 1 | DEVICE=eth1 2 | ONBOOT=yes 3 | TYPE=OVSPort 4 | OVS_BRIDGE=br0 5 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.17-vdc-executor-qemu-ovs/guestroot/etc/sysconfig/network-scripts/ifcfg-eth1: -------------------------------------------------------------------------------- 1 | DEVICE=eth1 2 | ONBOOT=yes 3 | TYPE=OVSPort 4 | OVS_BRIDGE=br0 5 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.14-vdc-executor-lxc/guestroot/etc/sysconfig/network-scripts/ifcfg-br0: -------------------------------------------------------------------------------- 1 | DEVICE=br0 2 | TYPE=Bridge 3 | BOOTPROTO=none 4 | ONBOOT=yes 5 | NM_CONTROLLED=no 6 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/guestroot/etc/sysconfig/network-scripts/ifcfg-br0: -------------------------------------------------------------------------------- 1 | DEVICE=br0 2 | TYPE=Bridge 3 | BOOTPROTO=none 4 | ONBOOT=yes 5 | NM_CONTROLLED=no 6 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.14-vdc-executor-lxc/guestroot/etc/sysconfig/network-scripts/ifcfg-eth1: -------------------------------------------------------------------------------- 1 | DEVICE="eth1" 2 | ONBOOT="yes" 3 | BRIDGE=br0 4 | NM_CONTROLLED=no 5 | BOOTPROTO=none 6 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/guestroot/etc/sysconfig/network-scripts/ifcfg-eth1: -------------------------------------------------------------------------------- 1 | DEVICE="eth1" 2 | ONBOOT="yes" 3 | BRIDGE=br0 4 | NM_CONTROLLED=no 5 | BOOTPROTO=none 6 | -------------------------------------------------------------------------------- /hypervisor/base.go: -------------------------------------------------------------------------------- 1 | package hypervisor 2 | 3 | import "github.com/Sirupsen/logrus" 4 | import "github.com/axsh/openvdc/model" 5 | 6 | type Base struct { 7 | Log *logrus.Entry 8 | Instance *model.Instance 9 | } 10 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.13-vdc-executor-null/guestroot/etc/openvdc/executor.toml: -------------------------------------------------------------------------------- 1 | [hypervisor] 2 | driver = "null" 3 | 4 | [zookeeper] 5 | endpoint = "zk://10.0.100.10:2181,10.0.100.11:2181,10.0.100.12:2181/openvdc" 6 | -------------------------------------------------------------------------------- /pkg/rhel/openvdc-scheduler.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=OpenVDC scheduler 3 | After=network.target 4 | 5 | [Service] 6 | ExecStart=/opt/axsh/openvdc/bin/openvdc-scheduler 7 | 8 | 9 | [Install] 10 | WantedBy=multi-user.target 11 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.10-zookeeper/guestroot/etc/sysconfig/network-scripts/ifcfg-eth0: -------------------------------------------------------------------------------- 1 | DEVICE=eth0 2 | ONBOOT=yes 3 | TYPE=Ethernet 4 | BOOTPROTO=static 5 | IPADDR=10.0.100.10 6 | NETMASK=255.255.255.0 7 | NETWORK=10.0.100.0 8 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.11-mesos-master/guestroot/etc/sysconfig/network-scripts/ifcfg-eth0: -------------------------------------------------------------------------------- 1 | DEVICE=eth0 2 | ONBOOT=yes 3 | TYPE=Ethernet 4 | BOOTPROTO=static 5 | IPADDR=10.0.100.11 6 | NETMASK=255.255.255.0 7 | NETWORK=10.0.100.0 8 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.12-vdc-scheduler/guestroot/etc/sysconfig/network-scripts/ifcfg-eth0: -------------------------------------------------------------------------------- 1 | DEVICE=eth0 2 | ONBOOT=yes 3 | TYPE=Ethernet 4 | BOOTPROTO=static 5 | IPADDR=10.0.100.12 6 | NETMASK=255.255.255.0 7 | NETWORK=10.0.100.0 8 | -------------------------------------------------------------------------------- /cmd/openvdc-executor/init.go: -------------------------------------------------------------------------------- 1 | // +build !linux 2 | 3 | package main 4 | 5 | import ( 6 | _ "github.com/axsh/openvdc/hypervisor/esxi" 7 | _ "github.com/axsh/openvdc/hypervisor/null" 8 | _ "github.com/axsh/openvdc/hypervisor/qemu" 9 | ) 10 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.13-vdc-executor-null/guestroot/etc/sysconfig/network-scripts/ifcfg-eth0: -------------------------------------------------------------------------------- 1 | DEVICE=eth0 2 | ONBOOT=yes 3 | TYPE=Ethernet 4 | BOOTPROTO=static 5 | IPADDR=10.0.100.13 6 | NETMASK=255.255.255.0 7 | NETWORK=10.0.100.0 8 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.14-vdc-executor-lxc/guestroot/etc/sysconfig/network-scripts/ifcfg-eth0: -------------------------------------------------------------------------------- 1 | DEVICE=eth0 2 | ONBOOT=yes 3 | TYPE=Ethernet 4 | BOOTPROTO=static 5 | IPADDR=10.0.100.14 6 | NETMASK=255.255.255.0 7 | NETWORK=10.0.100.0 8 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/guestroot/etc/sysconfig/network-scripts/ifcfg-eth0: -------------------------------------------------------------------------------- 1 | DEVICE=eth0 2 | ONBOOT=yes 3 | TYPE=Ethernet 4 | BOOTPROTO=static 5 | IPADDR=10.0.100.16 6 | NETMASK=255.255.255.0 7 | NETWORK=10.0.100.0 8 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.15-vdc-executor-lxc-ovs/guestroot/etc/sysconfig/network-scripts/ifcfg-eth0: -------------------------------------------------------------------------------- 1 | DEVICE=eth0 2 | ONBOOT=yes 3 | TYPE=Ethernet 4 | BOOTPROTO=static 5 | IPADDR=10.0.100.15 6 | NETWORK=10.0.100.0 7 | NETMASK=255.255.255.0 8 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.17-vdc-executor-qemu-ovs/guestroot/etc/sysconfig/network-scripts/ifcfg-eth0: -------------------------------------------------------------------------------- 1 | DEVICE=eth0 2 | ONBOOT=yes 3 | TYPE=Ethernet 4 | BOOTPROTO=static 5 | IPADDR=10.0.100.17 6 | NETWORK=10.0.100.0 7 | NETMASK=255.255.255.0 8 | -------------------------------------------------------------------------------- /templates/centos/7/lxc.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "CentOS7", 3 | "template": { 4 | "type": "vm/lxc", 5 | "lxc_template": { 6 | "download": { 7 | "distro": "centos", 8 | "release": "7" 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /templates/centos/7/lxc2.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "CentOS7", 3 | "template": { 4 | "type": "vm/lxc", 5 | "lxc_template": { 6 | "openvdc": { 7 | "distro": "centos", 8 | "release": "7" 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "EditorConfig.EditorConfig", 4 | "lukehoban.go", 5 | "zxh404.vscode-proto3", 6 | "1dot75cm.RPMSpec", 7 | "PeterJausovec.vscode-docker", 8 | "be5invis.toml" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /deployment/packagebuild/gen-dev-build-tag.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | # Show release tag for development build. "20160919093435gitb064bb7" 3 | timestamp=$(date --date="$(git show -s --format=%cd --date=iso HEAD)" +%Y%m%d%H%M%S) 4 | echo "${timestamp}git$(git rev-parse --short HEAD)" 5 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test-esxi/tests/fixtures/esxi.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "CentOS7", 3 | "template": { 4 | "type": "vm/esxi", 5 | "vcpu": 1, 6 | "memory_gb": 1, 7 | "diskspace": "10GB" 8 | }, 9 | "esxi_image": { 10 | "download_url": "", 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/tests/fixtures/lxc2.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "CentOS7", 3 | "template": { 4 | "type": "vm/lxc", 5 | "lxc_template": { 6 | "openvdc": { 7 | "distro": "centos", 8 | "release": "7" 9 | } 10 | } 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /terraform/openvdc/config.go: -------------------------------------------------------------------------------- 1 | // + build terraform 2 | 3 | package openvdc 4 | 5 | type config struct { 6 | apiEndpoint string 7 | } 8 | 9 | func (c *config) getApiEndpoint() string { 10 | if c.apiEndpoint != "" { 11 | return c.apiEndpoint 12 | } 13 | return "" 14 | } 15 | -------------------------------------------------------------------------------- /templates/centos/7/esxi_ovf_tmpl.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "CentOS7 OVF Template", 3 | "template": { 4 | "type": "vm/esxi", 5 | "vcpu": 1, 6 | "memory_gb": 1, 7 | "diskspace": "10GB", 8 | "esxi_image": { 9 | "name": "centos7base" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /templates/ubuntu/16.04/lxc.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Ubuntu 16.04.2 LTS (Xenial Xerus)", 3 | "template": { 4 | "type": "vm/lxc", 5 | "lxc_template": { 6 | "download": { 7 | "distro": "ubuntu", 8 | "release": "xenial" 9 | } 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/tests/fixtures/invalid1.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "CentOS7", 3 | "template": { 4 | "lxc_template": { 5 | "download_url": "https://images.linuxcontainers.org/1.0/images/d767cfe9a0df0b2213e28b39b61e8f79cb9b1e745eeed98c22bc5236f277309a/export" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /pkg/conf/mesos-slave/resources.esxi: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "cpus", 4 | "type": "SCALAR", 5 | "scalar": { 6 | "value": 20 7 | } 8 | }, 9 | { 10 | "name": "mem", 11 | "type": "SCALAR", 12 | "scalar": { 13 | "value": 20480 14 | } 15 | } 16 | ] 17 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.15-vdc-executor-lxc-ovs/guestroot/etc/sysconfig/network-scripts/ifcfg-br0: -------------------------------------------------------------------------------- 1 | DEVICE=br0 2 | DEVICETYPE=ovs 3 | TYPE=OVSBridge 4 | ONBOOT=yes 5 | BOOTPROTO=static 6 | HOTPLUG=no 7 | IPADDR=172.16.100.15 8 | NETWORK=172.16.100.0 9 | NETMASK=255.255.255.0 10 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.17-vdc-executor-qemu-ovs/guestroot/etc/sysconfig/network-scripts/ifcfg-br0: -------------------------------------------------------------------------------- 1 | DEVICE=br0 2 | DEVICETYPE=ovs 3 | TYPE=OVSBridge 4 | ONBOOT=yes 5 | BOOTPROTO=static 6 | HOTPLUG=no 7 | IPADDR=172.16.100.15 8 | NETWORK=172.16.100.0 9 | NETMASK=255.255.255.0 10 | -------------------------------------------------------------------------------- /templates/centos/7/esxi.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "CentOS7", 3 | "template": { 4 | "type": "vm/esxi", 5 | "vcpu": 1, 6 | "memory_gb": 1, 7 | "diskspace": "10GB", 8 | "esxi_image": { 9 | "datastore": "datastore2", 10 | "name": "CentOS7" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /terraform/main.go: -------------------------------------------------------------------------------- 1 | // +build terraform 2 | 3 | package main 4 | 5 | import ( 6 | "github.com/axsh/openvdc/terraform/openvdc" 7 | "github.com/hashicorp/terraform/plugin" 8 | ) 9 | 10 | func main() { 11 | plugin.Serve(&plugin.ServeOpts{ 12 | ProviderFunc: openvdc.Provider, 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /cmd/openvdc/init.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | _ "github.com/axsh/openvdc/handlers/none" 5 | _ "github.com/axsh/openvdc/handlers/vm/esxi" 6 | _ "github.com/axsh/openvdc/handlers/vm/lxc" 7 | _ "github.com/axsh/openvdc/handlers/vm/null" 8 | _ "github.com/axsh/openvdc/handlers/vm/qemu" 9 | ) 10 | -------------------------------------------------------------------------------- /templates/centos/7/qemu.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "CentOS7", 3 | "template": { 4 | "type": "vm/qemu", 5 | "vcpu": 1, 6 | "memory_gb": 1, 7 | "qemu_image": { 8 | "download_url": "https://ci.openvdc.org/img/centos7.qcow2", 9 | "format": "qcow2" 10 | } 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Launch", 6 | "type": "go", 7 | "request": "launch", 8 | "mode": "debug", 9 | "program": "${workspaceRoot}", 10 | "env": {}, 11 | "args": [] 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /pkg/conf/scripts/linux-bridge-down.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | # lxc.network.script.up/down does not capture stderr. 5 | exec 2>&1 6 | 7 | CONTAINER=$1 8 | SECTION=$2 # net 9 | ACTION=$3 # up/down 10 | IFTYPE=$4 # veth,macvlan,etc... 11 | IFNAME=$5 12 | 13 | ip link set dev "${IFNAME}" nomaster 14 | -------------------------------------------------------------------------------- /cmd/openvdc-scheduler/init.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | _ "github.com/axsh/openvdc/handlers/none" 5 | _ "github.com/axsh/openvdc/handlers/vm/esxi" 6 | _ "github.com/axsh/openvdc/handlers/vm/lxc" 7 | _ "github.com/axsh/openvdc/handlers/vm/null" 8 | _ "github.com/axsh/openvdc/handlers/vm/qemu" 9 | ) 10 | -------------------------------------------------------------------------------- /pkg/conf/scripts/ovs-down.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | # lxc.network.script.up/down does not capture stderr. 5 | exec 2>&1 6 | 7 | CONTAINER=$1 8 | SECTION=$2 # net 9 | ACTION=$3 # up/down 10 | IFTYPE=$4 # veth,macvlan,etc... 11 | IFNAME=$5 12 | 13 | ovs-vsctl del-port {{.BridgeName}} "${IFNAME}" 14 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/tests/fixtures/lxc.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "CentOS7", 3 | "template": { 4 | "type": "vm/lxc", 5 | "lxc_image": { 6 | "download_url": "https://images.linuxcontainers.org/1.0/images/d767cfe9a0df0b2213e28b39b61e8f79cb9b1e745eeed98c22bc5236f277309a/export" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /pkg/conf/scripts/linux-bridge-up.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | # lxc.network.script.up/down does not capture stderr. 5 | exec 2>&1 6 | 7 | CONTAINER=$1 8 | SECTION=$2 # net 9 | ACTION=$3 # up/down 10 | IFTYPE=$4 # veth,macvlan,etc... 11 | IFNAME=$5 12 | 13 | ip link set dev "${IFNAME}" master {{.BridgeName}} 14 | -------------------------------------------------------------------------------- /templates/centos/7/qemu_ga.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "CentOS7", 3 | "template": { 4 | "type": "vm/qemu", 5 | "vcpu": 1, 6 | "memory_gb": 1, 7 | "qemu_image": { 8 | "download_url": "https://ci.openvdc.org/img/centos7-qga.qcow2", 9 | "format": "qcow2" 10 | }, 11 | "use_kvm": true 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /templates/centos/7/qemu_kvm.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "CentOS7", 3 | "template": { 4 | "type": "vm/qemu", 5 | "vcpu": 1, 6 | "memory_gb": 1, 7 | "qemu_image": { 8 | "download_url": "https://ci.openvdc.org/img/centos7.qcow2", 9 | "format": "qcow2" 10 | }, 11 | "use_kvm": true 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | trim_trailing_whitespace = true 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 2 9 | 10 | [*.go] 11 | indent_style = tab 12 | 13 | [*.ps1] 14 | # https://github.com/PoshCode/PowerShellPracticeAndStyle 15 | end_of_line = crlf 16 | indent_size = 4 17 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.10-zookeeper/vmspec.conf: -------------------------------------------------------------------------------- 1 | vm_name="zookeeper" 2 | cpu_type=qemu64,+"${ACCEL_TYPE}" 3 | mem_size=1024 4 | cpu_num=1 5 | vnc_addr= 6 | vnc_port=12001 7 | serial=telnet:127.0.0.1:13001,server,nowait 8 | 9 | nics[0]="name=zk_m hwaddr=52:56:01:00:05:02 bridge=vdc_mngnt" 10 | 11 | IP_ADDR=10.0.100.10 12 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.11-mesos-master/vmspec.conf: -------------------------------------------------------------------------------- 1 | vm_name="mesos" 2 | cpu_type=qemu64,+"${ACCEL_TYPE}" 3 | mem_size=1024 4 | cpu_num=1 5 | vnc_addr= 6 | vnc_port=12000 7 | serial=telnet:127.0.0.1:13000,server,nowait 8 | 9 | nics[0]="name=mesos_m hwaddr=52:56:01:00:05:01 bridge=vdc_mngnt" 10 | 11 | IP_ADDR=10.0.100.11 12 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.12-vdc-scheduler/vmspec.conf: -------------------------------------------------------------------------------- 1 | vm_name="scheduler" 2 | cpu_type=qemu64,+"${ACCEL_TYPE}" 3 | mem_size=1024 4 | cpu_num=1 5 | vnc_addr= 6 | vnc_port=12002 7 | serial=telnet:127.0.0.1:13002,server,nowait 8 | 9 | nics[0]="name=sched_m hwaddr=52:56:01:00:05:03 bridge=vdc_mngnt" 10 | 11 | IP_ADDR=10.0.100.12 12 | -------------------------------------------------------------------------------- /terraform/openvdc/provider_test.go: -------------------------------------------------------------------------------- 1 | // +build terraform 2 | 3 | package openvdc 4 | 5 | import ( 6 | "testing" 7 | 8 | "github.com/hashicorp/terraform/helper/schema" 9 | ) 10 | 11 | func TestProvider(t *testing.T) { 12 | if err := Provider().(*schema.Provider).InternalValidate(); err != nil { 13 | t.Fatalf("err: %s", err) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.13-vdc-executor-null/vmspec.conf: -------------------------------------------------------------------------------- 1 | vm_name="executor-null" 2 | cpu_type=qemu64,+"${ACCEL_TYPE}" 3 | mem_size=1024 4 | cpu_num=1 5 | vnc_addr= 6 | vnc_port=12003 7 | serial=telnet:127.0.0.1:13003,server,nowait 8 | 9 | nics[0]="name=null_m hwaddr=52:56:01:00:05:04 bridge=vdc_mngnt" 10 | 11 | IP_ADDR=10.0.100.13 12 | -------------------------------------------------------------------------------- /model/backend/test.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "github.com/golang/protobuf/ptypes/timestamp/timestamp.proto"; 4 | 5 | package backend; 6 | 7 | //option go_package = "github.com/axsh/openvdc/model/backend"; 8 | 9 | message Timestamp { 10 | google.protobuf.Timestamp created_at = 1; 11 | google.protobuf.Timestamp updated_at = 2; 12 | } 13 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.12-vdc-scheduler/guestroot/etc/openvdc/scheduler.toml: -------------------------------------------------------------------------------- 1 | [mesos] 2 | master = "zk://10.0.100.10:2181,10.0.100.11:2181,10.0.100.12:2181/mesos" 3 | #listen = "0.0.0.0" 4 | 5 | [api] 6 | endpoint = "10.0.100.12:5000" 7 | 8 | [zookeeper] 9 | endpoint = "zk://10.0.100.10:2181,10.0.100.11:2181,10.0.100.12:2181/openvdc" 10 | -------------------------------------------------------------------------------- /hypervisor/qemu/qemu_image_test.go: -------------------------------------------------------------------------------- 1 | package qemu 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestNewImage(t *testing.T) { 10 | assert := assert.New(t) 11 | img := NewImage("path", "format") 12 | assert.NotNil(img) 13 | assert.Equal("format", img.Format) 14 | assert.Equal("path", img.Path) 15 | } 16 | -------------------------------------------------------------------------------- /pkg/conf/scheduler.toml: -------------------------------------------------------------------------------- 1 | [mesos] 2 | # master = "zk://localhost/mesos" 3 | # listen = "0.0.0.0" 4 | 5 | [zookeeper] 6 | # endpoint = "zk://localhost/openvdc" 7 | 8 | [api] 9 | # endpoint = "localhost:5000" 10 | 11 | [scheduler] 12 | # id = "scheduler_1" 13 | # name = "openvdc" 14 | # failover-timeout = 604800 #1 week 15 | # executor-path = "openvdc-executor" 16 | -------------------------------------------------------------------------------- /run_unit_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | VERSION="dev" 6 | SHA=$(git rev-parse --verify HEAD) 7 | BUILDDATE=$(date '+%Y/%m/%d %H:%M:%S %Z') 8 | GOVERSION=$(go version) 9 | LDFLAGS="-X 'main.version=${VERSION}' -X 'main.sha=${SHA}' -X 'main.builddate=${BUILDDATE}' -X 'main.goversion=${GOVERSION}'" 10 | 11 | go test $(go list ./... | grep -v /vendor/) 12 | -------------------------------------------------------------------------------- /ci/devbox/fastestmirror.conf: -------------------------------------------------------------------------------- 1 | [main] 2 | enabled=1 3 | verbose=0 4 | always_print_best_host = true 5 | socket_timeout=3 6 | # Relative paths are relative to the cachedir (and so works for users as well 7 | # as root). 8 | hostfilepath=timedhosts.txt 9 | maxhostfileage=10 10 | maxthreads=15 11 | #exclude=.gov, facebook 12 | #include_only=.nl,.de,.uk,.ie 13 | include_only=.jp 14 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.10-zookeeper/destroy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export ENV_ROOTDIR="$(cd "$(dirname $(readlink -f "$0"))/.." && pwd -P)" 4 | export NODE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 5 | 6 | . "${ENV_ROOTDIR}/config.source" 7 | . "${NODE_DIR}/vmspec.conf" 8 | . "${ENV_ROOTDIR}/ind-steps/step-box/common.source" 9 | 10 | destroy_vm 11 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.10-zookeeper/destroy_cache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export ENV_ROOTDIR="$(cd "$(dirname $(readlink -f "$0"))/.." && pwd -P)" 4 | export NODE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 5 | 6 | . "${ENV_ROOTDIR}/config.source" 7 | . "${NODE_DIR}/vmspec.conf" 8 | . "${ENV_ROOTDIR}/ind-steps/step-box/common.source" 9 | 10 | destroy_vm_cache 11 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-disable-firewalld/pre_rsync.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ( 4 | $starting_step "Disable firewalld" 5 | sudo chroot "${TMP_ROOT}" /bin/bash -c "systemctl is-enabled firewalld" 6 | [[ ! $? -eq 0 ]] 7 | $skip_step_if_already_done; set -xe 8 | sudo chroot "${TMP_ROOT}" /bin/bash -c "systemctl disable firewalld" 9 | ) ; prev_cmd_failed 10 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-mesosphere-repo/pre_rsync.sh: -------------------------------------------------------------------------------- 1 | 2 | ( 3 | $starting_step "Download mesosphere repo" 4 | [[ -f "${TMP_ROOT}/etc/yum.repos.d/mesosphere.repo" ]] 5 | $skip_step_if_already_done ; set -ex 6 | sudo chroot ${TMP_ROOT} /bin/bash -c "yum install -y http://repos.mesosphere.io/el/7/noarch/RPMS/mesosphere-el-repo-7-1.noarch.rpm" 7 | ) ; prev_cmd_failed 8 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-apache/pre_boot.sh: -------------------------------------------------------------------------------- 1 | ( 2 | $starting_step "Install Apache on ${vm_name}" 3 | sudo chroot ${TMP_ROOT} /bin/bash -c "rpm -q httpd" > /dev/null 4 | $skip_step_if_already_done; set -ex 5 | sudo chroot ${TMP_ROOT} /bin/bash -c "yum install httpd -y" 6 | sudo chroot ${TMP_ROOT} /bin/bash -c "mkdir -p /var/www/html/images" 7 | ) ; prev_cmd_failed 8 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-cgroups/post_boot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ( 4 | $starting_step "Setup cgroups" 5 | run_ssh root@${IP_ADDR} "mount | grep -q cgroup" 6 | $skip_step_if_already_done; set -xe 7 | run_ssh root@${IP_ADDR} <> /etc/fstab 10 | mount /cgroup 11 | EOS 12 | ) ; prev_cmd_failed 13 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.14-vdc-executor-lxc/vmspec.conf: -------------------------------------------------------------------------------- 1 | vm_name="executor-lxc" 2 | cpu_type=qemu64,+"${ACCEL_TYPE}" 3 | mem_size=1024 4 | cpu_num=1 5 | vnc_addr= 6 | vnc_port=12004 7 | serial=telnet:127.0.0.1:13004,server,nowait 8 | 9 | nics[0]="name=lxc_m hwaddr=52:56:01:00:05:05 bridge=vdc_mngnt" 10 | nics[1]="name=lxc_i hwaddr=52:56:01:00:06:05 bridge=vdc_insts" 11 | 12 | IP_ADDR=10.0.100.14 13 | -------------------------------------------------------------------------------- /cmd/lxc-openvdc/init_linux.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/Sirupsen/logrus" 5 | logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog" 6 | "log/syslog" 7 | ) 8 | 9 | func init() { 10 | hook, err := logrus_syslog.NewSyslogHook("", "", syslog.LOG_DEBUG, "lxc-openvdc") 11 | if err != nil { 12 | logrus.Fatal("Failed to initialize syslog hook: ", err) 13 | } 14 | logrus.AddHook(hook) 15 | } 16 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/vmspec.conf: -------------------------------------------------------------------------------- 1 | vm_name="executor-qemu" 2 | cpu_type=qemu64,+"${ACCEL_TYPE}" 3 | mem_size=4096 4 | cpu_num=3 5 | vnc_addr= 6 | vnc_port=12006 7 | serial=telnet:127.0.0.1:13006,server,nowait 8 | 9 | nics[0]="name=qemu_m hwaddr=52:56:01:00:05:07 bridge=vdc_mngnt" 10 | nics[1]="name=qemu_i hwaddr=52:56:01:00:06:07 bridge=vdc_insts" 11 | 12 | IP_ADDR=10.0.100.16 13 | -------------------------------------------------------------------------------- /internal/unittest/flags.go: -------------------------------------------------------------------------------- 1 | package unittest 2 | 3 | import "os" 4 | 5 | // Place global variables or flags only for unit test code. 6 | 7 | var TestZkServer = "127.0.0.1:2181" 8 | var GithubDefaultRef = "master" 9 | 10 | func init() { 11 | if v, exists := os.LookupEnv("ZK"); exists { 12 | TestZkServer = v 13 | } 14 | if v, exists := os.LookupEnv("GITHUB_DEFAULT_REF"); exists { 15 | GithubDefaultRef = v 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/tests/01_cmd_in_path_test.go: -------------------------------------------------------------------------------- 1 | // +build acceptance 2 | 3 | package tests 4 | 5 | import ( 6 | "strings" 7 | "testing" 8 | ) 9 | 10 | func TestOpenVDCCmdInPath(t *testing.T) { 11 | stdout, _ := RunCmdAndReportFail(t, "openvdc") 12 | 13 | if !strings.HasPrefix(stdout.String(), "Usage:") { 14 | t.Fatal("Running openvdc without arguments didn't print usage. Instead got: " + stdout.String()) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-zookeeper/pre_boot.sh: -------------------------------------------------------------------------------- 1 | ( 2 | $starting_step "Install zookeeper on ${vm_name}" 3 | sudo chroot ${TMP_ROOT} /bin/bash -c "rpm -q mesos-zookeeper" > /dev/null 4 | $skip_step_if_already_done; set -ex 5 | sudo chroot ${TMP_ROOT} /bin/bash -c "yum install -y mesosphere-zookeeper" 6 | $zk_host || sudo chroot ${TMP_ROOT} /bin/bash -c "systemctl disable zookeeper" 7 | ) ; prev_cmd_failed 8 | -------------------------------------------------------------------------------- /model/backend/mock.go: -------------------------------------------------------------------------------- 1 | package backend 2 | 3 | type MockClusterBackend struct{} 4 | 5 | func (m *MockClusterBackend) Connect(dest []string) error { 6 | return nil 7 | } 8 | func (m *MockClusterBackend) Close() error { 9 | return nil 10 | } 11 | func (m *MockClusterBackend) Register(key string, value []byte) error { 12 | return nil 13 | } 14 | func (m *MockClusterBackend) Find(key string) ([]byte, error) { 15 | return []byte{}, nil 16 | } 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # openvdc 2 | Extendable Tiny Datacenter Hypervisor on top of Mesos architecture. Wakame-vdc v2 Project. 3 | 4 | 5 | ## Build 6 | 7 | Ensure ``$GOPATH`` is set. ``$PATH`` needs to have ``$GOPATH/bin``. 8 | 9 | ``` 10 | go get -u github.com/axsh/openvdc 11 | cd $GOPATH/src/github.com/axsh/openvdc 12 | go run ./build.go 13 | ``` 14 | 15 | Build with compile ``proto/*.proto``. 16 | 17 | ``` 18 | go run ./build.go -with-gogen 19 | ``` 20 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.10-zookeeper/guestroot/etc/yum/pluginconf.d/fastestmirror.conf: -------------------------------------------------------------------------------- 1 | [main] 2 | enabled=1 3 | verbose=0 4 | always_print_best_host = true 5 | socket_timeout=3 6 | # Relative paths are relative to the cachedir (and so works for users as well 7 | # as root). 8 | hostfilepath=timedhosts.txt 9 | maxhostfileage=10 10 | maxthreads=15 11 | #exclude=.gov, facebook 12 | #include_only=.nl,.de,.uk,.ie 13 | include_only=.jp 14 | -------------------------------------------------------------------------------- /cmd/openvdc/cmd/template.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/axsh/openvdc/cmd/openvdc/cmd/template" 5 | "github.com/spf13/cobra" 6 | ) 7 | 8 | func init() { 9 | TemplateCmd.AddCommand(template.ValidateCmd) 10 | TemplateCmd.AddCommand(template.ShowCmd) 11 | } 12 | 13 | var TemplateCmd = &cobra.Command{ 14 | Use: "template", 15 | Short: "Operations for resource template", 16 | Long: "Operations for resource template", 17 | } 18 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.11-mesos-master/guestroot/etc/yum/pluginconf.d/fastestmirror.conf: -------------------------------------------------------------------------------- 1 | [main] 2 | enabled=1 3 | verbose=0 4 | always_print_best_host = true 5 | socket_timeout=3 6 | # Relative paths are relative to the cachedir (and so works for users as well 7 | # as root). 8 | hostfilepath=timedhosts.txt 9 | maxhostfileage=10 10 | maxthreads=15 11 | #exclude=.gov, facebook 12 | #include_only=.nl,.de,.uk,.ie 13 | include_only=.jp 14 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.12-vdc-scheduler/guestroot/etc/yum/pluginconf.d/fastestmirror.conf: -------------------------------------------------------------------------------- 1 | [main] 2 | enabled=1 3 | verbose=0 4 | always_print_best_host = true 5 | socket_timeout=3 6 | # Relative paths are relative to the cachedir (and so works for users as well 7 | # as root). 8 | hostfilepath=timedhosts.txt 9 | maxhostfileage=10 10 | maxthreads=15 11 | #exclude=.gov, facebook 12 | #include_only=.nl,.de,.uk,.ie 13 | include_only=.jp 14 | -------------------------------------------------------------------------------- /handlers/doc.go: -------------------------------------------------------------------------------- 1 | // Here is the place for the resource template handlers code. 2 | // Resource Handler is responsible for: 3 | // - Parse "template" section in the resource template .json 4 | // - Validate the "template" section. 5 | // - Merge the values from user interface (CLI/WebUI) which are allowed 6 | // to overwrite by user. 7 | // - Handle the real datacenter resource based on the parameters in the template. 8 | 9 | package handlers 10 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.13-vdc-executor-null/guestroot/etc/yum/pluginconf.d/fastestmirror.conf: -------------------------------------------------------------------------------- 1 | [main] 2 | enabled=1 3 | verbose=0 4 | always_print_best_host = true 5 | socket_timeout=3 6 | # Relative paths are relative to the cachedir (and so works for users as well 7 | # as root). 8 | hostfilepath=timedhosts.txt 9 | maxhostfileage=10 10 | maxthreads=15 11 | #exclude=.gov, facebook 12 | #include_only=.nl,.de,.uk,.ie 13 | include_only=.jp 14 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.14-vdc-executor-lxc/guestroot/etc/yum/pluginconf.d/fastestmirror.conf: -------------------------------------------------------------------------------- 1 | [main] 2 | enabled=1 3 | verbose=0 4 | always_print_best_host = true 5 | socket_timeout=3 6 | # Relative paths are relative to the cachedir (and so works for users as well 7 | # as root). 8 | hostfilepath=timedhosts.txt 9 | maxhostfileage=10 10 | maxthreads=15 11 | #exclude=.gov, facebook 12 | #include_only=.nl,.de,.uk,.ie 13 | include_only=.jp 14 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/guestroot/etc/yum/pluginconf.d/fastestmirror.conf: -------------------------------------------------------------------------------- 1 | [main] 2 | enabled=1 3 | verbose=0 4 | always_print_best_host = true 5 | socket_timeout=3 6 | # Relative paths are relative to the cachedir (and so works for users as well 7 | # as root). 8 | hostfilepath=timedhosts.txt 9 | maxhostfileage=10 10 | maxthreads=15 11 | #exclude=.gov, facebook 12 | #include_only=.nl,.de,.uk,.ie 13 | include_only=.jp 14 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.15-vdc-executor-lxc-ovs/guestroot/etc/yum/pluginconf.d/fastestmirror.conf: -------------------------------------------------------------------------------- 1 | [main] 2 | enabled=1 3 | verbose=0 4 | always_print_best_host = true 5 | socket_timeout=3 6 | # Relative paths are relative to the cachedir (and so works for users as well 7 | # as root). 8 | hostfilepath=timedhosts.txt 9 | maxhostfileage=10 10 | maxthreads=15 11 | #exclude=.gov, facebook 12 | #include_only=.nl,.de,.uk,.ie 13 | include_only=.jp 14 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.17-vdc-executor-qemu-ovs/guestroot/etc/yum/pluginconf.d/fastestmirror.conf: -------------------------------------------------------------------------------- 1 | [main] 2 | enabled=1 3 | verbose=0 4 | always_print_best_host = true 5 | socket_timeout=3 6 | # Relative paths are relative to the cachedir (and so works for users as well 7 | # as root). 8 | hostfilepath=timedhosts.txt 9 | maxhostfileage=10 10 | maxthreads=15 11 | #exclude=.gov, facebook 12 | #include_only=.nl,.de,.uk,.ie 13 | include_only=.jp 14 | -------------------------------------------------------------------------------- /handlers/none/none_test.go: -------------------------------------------------------------------------------- 1 | package none 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/axsh/openvdc/handlers" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestResourceName(t *testing.T) { 11 | assert := assert.New(t) 12 | assert.Equal("none", handlers.ResourceName(&NoneHandler{})) 13 | } 14 | 15 | func TestTypes(t *testing.T) { 16 | assert := assert.New(t) 17 | assert.Implements((*handlers.ResourceHandler)(nil), &NoneHandler{}) 18 | } 19 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.15-vdc-executor-lxc-ovs/vmspec.conf: -------------------------------------------------------------------------------- 1 | vm_name="executor-lxc-ovs" 2 | cpu_type=qemu64,+"${ACCEL_TYPE}" 3 | mem_size=1024 4 | cpu_num=1 5 | vnc_addr= 6 | vnc_port=12005 7 | serial=telnet:127.0.0.1:13005,server,nowait 8 | 9 | #TODO: Give better mac addresses 10 | nics[0]="name=lxcovs_m hwaddr=52:56:01:00:05:06 bridge=vdc_mngnt" 11 | nics[1]="name=lxcovs_i hwaddr=52:56:01:00:06:06 bridge=vdc_insts" 12 | 13 | IP_ADDR=10.0.100.15 14 | -------------------------------------------------------------------------------- /handlers/vm/base.go: -------------------------------------------------------------------------------- 1 | package vm 2 | 3 | type Base struct { 4 | } 5 | 6 | var SupportedAPICalls = []string{ 7 | "/api.Instance/Start", 8 | "/api.Instance/Run", 9 | "/api.Instance/Stop", 10 | "/api.Instance/Reboot", 11 | "/api.Instance/Console", 12 | "/api.Instance/Log", 13 | } 14 | 15 | func (*Base) IsSupportAPI(method string) bool { 16 | for _, m := range SupportedAPICalls { 17 | if m == method { 18 | return true 19 | } 20 | } 21 | return false 22 | } 23 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.17-vdc-executor-qemu-ovs/vmspec.conf: -------------------------------------------------------------------------------- 1 | vm_name="executor-qemu-ovs" 2 | cpu_type=qemu64,+"${ACCEL_TYPE}" 3 | mem_size=4096 4 | cpu_num=3 5 | vnc_addr= 6 | vnc_port=12007 7 | serial=telnet:127.0.0.1:13007,server,nowait 8 | 9 | #TODO: Give better mac addresses 10 | nics[0]="name=qemuovs_m hwaddr=52:56:01:00:05:08 bridge=vdc_mngnt" 11 | nics[1]="name=qemuovs_i hwaddr=52:56:01:00:06:08 bridge=vdc_insts" 12 | 13 | IP_ADDR=10.0.100.17 14 | -------------------------------------------------------------------------------- /ci/appveyor/install-zk.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = "Stop" 2 | 3 | Set-Location -Path $Args[0] 4 | 5 | Invoke-WebRequest -Uri http://www-us.apache.org/dist/zookeeper/zookeeper-3.4.9/zookeeper-3.4.9.tar.gz -OutFile zookeeper.tar.gz 6 | 7z -y e "zookeeper.tar.gz" 7 | 7z -y x "zookeeper.tar" 8 | Move-Item zookeeper-3.4.9\* . 9 | New-Item data -type directory 10 | Move-Item conf\zoo_sample.cfg conf\zoo.cfg 11 | "dataDir=C:\ZooKeeper\data" | Out-File conf\zoo.cfg -Encoding ASCII -Append 12 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/external_libraries/README.md: -------------------------------------------------------------------------------- 1 | All repositories in this directory were added with `git-subtree`. Take some time to familiarize yourself with `git-subtree` before making changes here. [This blog](http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/) is a good place to start. 2 | 3 | The repositories were subtreed from the following locations: 4 | 5 | * bashsteps: https://github.com/axsh/bashsteps 6 | * mount-partition: https://github.com/triggers/mount-partition 7 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.17-vdc-executor-qemu-ovs/guestroot/etc/openvdc/executor.toml: -------------------------------------------------------------------------------- 1 | [hypervisor] 2 | driver = "qemu" 3 | script-path = "/etc/openvdc/scripts/" 4 | 5 | [zookeeper] 6 | endpoint = "zk://10.0.100.10:2181,10.0.100.11:2181,10.0.100.12:2181/openvdc" 7 | 8 | [bridges] 9 | name = "br0" 10 | type = "ovs" 11 | 12 | [executor-api] 13 | # listen = "0.0.0.0:19372" 14 | advertise-ip = "10.0.100.17" 15 | 16 | [console] 17 | 18 | [console.ssh] 19 | # listen = "" 20 | advertise-ip = "10.0.100.17" 21 | -------------------------------------------------------------------------------- /schema/none.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "description": "OpenVDC Resource Template: none (For testing only)", 4 | "type": "object", 5 | "required": [ 6 | "type" 7 | ], 8 | "properties": { 9 | "_comment": { 10 | "type": "string" 11 | }, 12 | "type": { 13 | "enum": [ 14 | "none" 15 | ] 16 | }, 17 | "param1": { 18 | "type": "string" 19 | }, 20 | "param2": { 21 | "type": "string" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-hosts/pre_boot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ( 4 | $starting_step "Append entries to /etc/hosts" 5 | grep "10.0.100." ${TMP_ROOT}/etc/hosts > /dev/null 6 | $skip_step_if_already_done; set -xe 7 | cat <> /etc/hosts' 8 | 10.0.100.10 zookeeper 9 | 10.0.100.11 mesos 10 | 10.0.100.12 scheduler 11 | 10.0.100.13 executor-null 12 | 10.0.100.14 executor-lxc 13 | 10.0.100.15 executor-lxc-ovs 14 | EOF 15 | ) ; prev_cmd_failed 16 | -------------------------------------------------------------------------------- /.idea/libraries/GOPATH__openvdc_.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /handlers/vm/null/null_test.go: -------------------------------------------------------------------------------- 1 | package null 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/axsh/openvdc/handlers" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestResourceName(t *testing.T) { 11 | assert := assert.New(t) 12 | assert.Equal("vm/null", handlers.ResourceName(&NullHandler{})) 13 | } 14 | 15 | func TestTypes(t *testing.T) { 16 | assert := assert.New(t) 17 | assert.Implements((*handlers.ResourceHandler)(nil), &NullHandler{}) 18 | assert.Implements((*handlers.CLIHandler)(nil), &NullHandler{}) 19 | } 20 | -------------------------------------------------------------------------------- /terraform/example.tf: -------------------------------------------------------------------------------- 1 | provider "openvdc" { 2 | api_endpoint = "0.0.0.0:5000" 3 | } 4 | 5 | resource "openvdc_instance" "joske" { 6 | template = "centos/7/lxc" 7 | 8 | interfaces = [ 9 | { 10 | type = "veth" # default 11 | ipv4addr = "10.0.0.10" # optional 12 | macaddr = "10:54:ff:aa:00:04" # optional 13 | ipv4gateway = "10.0.0.1" 14 | }, 15 | { 16 | type = "veth" # default 17 | ipv4addr = "10.0.1.10" # optional 18 | macaddr = "10:54:ff:aa:00:05" # optional 19 | }, 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "search.exclude": { 3 | "vendor/**": true, 4 | "vendor/vendor.json": false 5 | }, 6 | "protoc": { 7 | "options": [ 8 | "--proto_path=${workspaceRoot}/proto", 9 | "--proto_path=${env.GOPATH}/src" 10 | ] 11 | }, 12 | "json.schemas": [ 13 | { 14 | "fileMatch": [ 15 | "/templates/**/*.json" 16 | ], 17 | "url": "./schema/v1.json" 18 | } 19 | ], 20 | // go formatter/lint called by vscode fails sources under ci/*. 21 | "go.buildTags": "acceptance" 22 | } 23 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/tests/cmd_log_test.go: -------------------------------------------------------------------------------- 1 | // +build acceptance 2 | 3 | package tests 4 | 5 | import ( 6 | "strings" 7 | "testing" 8 | "time" 9 | ) 10 | 11 | func TestOpenVDCLog(t *testing.T) { 12 | stdout, _ := RunCmdAndReportFail(t, "openvdc", "run", "centos/7/lxc") 13 | instance_id := strings.TrimSpace(stdout.String()) 14 | defer RunCmd("openvdc", "destroy", instance_id) 15 | 16 | WaitInstance(t, 5*time.Minute, instance_id, "RUNNING", []string{"QUEUED", "STARTING"}) 17 | RunCmdAndReportFail(t, "openvdc", "log", instance_id) 18 | } 19 | -------------------------------------------------------------------------------- /registry/local_test.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestNewLocalRegistry(t *testing.T) { 10 | assert := assert.New(t) 11 | reg := NewLocalRegistry() 12 | assert.Implements((*TemplateFinder)(nil), reg) 13 | } 14 | 15 | func TestLocalRegistryFind(t *testing.T) { 16 | assert := assert.New(t) 17 | reg := NewLocalRegistry() 18 | rt, err := reg.Find("../templates/centos/7/lxc.json") 19 | assert.NoError(err) 20 | assert.NotNil(rt) 21 | assert.Equal(rt.source, reg) 22 | } 23 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-epel/pre_boot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ( 4 | $starting_step "Install EPEL" 5 | sudo chroot "${TMP_ROOT}" /bin/bash -c \ 6 | "rpm -qa epel-release* | egrep -q epel-release" 7 | [[ $? -eq 0 ]] 8 | $skip_step_if_already_done; set -xe 9 | # epel-release.rpm from CentOS/extra contains deprecated index for mirror sites. 10 | sudo chroot "${TMP_ROOT}" /bin/bash -e <<'EOF' 11 | rpm -Uvh http://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-11.noarch.rpm 12 | EOF 13 | 14 | ) ; prev_cmd_failed 15 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.10-zookeeper/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export ENV_ROOTDIR="$(cd "$(dirname $(readlink -f "$0"))/.." && pwd -P)" 4 | export NODE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 5 | TMP_ROOT="${NODE_DIR}/tmp_root" 6 | 7 | . "${ENV_ROOTDIR}/config.source" 8 | . "${NODE_DIR}/vmspec.conf" 9 | . "${ENV_ROOTDIR}/ind-steps/common.source" 10 | 11 | zk_host=true 12 | 13 | IND_STEPS=( 14 | "box" 15 | "ssh" 16 | "hosts" 17 | "disable-firewalld" 18 | "mesosphere-repo" 19 | "zookeeper" 20 | ) 21 | 22 | build "${IND_STEPS[@]}" 23 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "showOutput": "silent", 4 | "tasks": [ 5 | { 6 | "taskName": "build", 7 | "problemMatcher": "$go", 8 | "isBuildCommand": true, 9 | "command": "go", 10 | "args": [ 11 | "run", 12 | "./build.go" 13 | ], 14 | "isShellCommand": false 15 | }, 16 | { 17 | "taskName": "gen", 18 | "command": "go", 19 | "args": [ 20 | "run", "./build.go", "-with-gogen" 21 | ], 22 | "problemMatcher": "$go", 23 | "isShellCommand": false 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/guestroot/etc/openvdc/executor.toml: -------------------------------------------------------------------------------- 1 | [hypervisor] 2 | driver = "qemu" 3 | script-path = "/etc/openvdc/scripts/" 4 | image-server-uri = "http://10.0.100.12/images" 5 | cache-path = "/var/cache/qemu/" 6 | 7 | [zookeeper] 8 | endpoint = "zk://10.0.100.10:2181,10.0.100.11:2181,10.0.100.12:2181/openvdc" 9 | 10 | [bridges] 11 | name = "br0" 12 | type = "linux" 13 | 14 | [executor-api] 15 | # listen = "0.0.0.0:19372" 16 | advertise-ip = "10.0.100.16" 17 | 18 | [console] 19 | 20 | [console.ssh] 21 | # listen = "" 22 | advertise-ip = "10.0.100.16" 23 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.11-mesos-master/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export ENV_ROOTDIR="$(cd "$(dirname $(readlink -f "$0"))/.." && pwd -P)" 4 | export NODE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 5 | TMP_ROOT="${NODE_DIR}/tmp_root" 6 | 7 | . "${ENV_ROOTDIR}/config.source" 8 | . "${NODE_DIR}/vmspec.conf" 9 | . "${ENV_ROOTDIR}/ind-steps/common.source" 10 | 11 | zk_host=true 12 | 13 | IND_STEPS=( 14 | "box" 15 | "ssh" 16 | "hosts" 17 | "disable-firewalld" 18 | "mesosphere-repo" 19 | "mesos-master" 20 | "zookeeper" 21 | ) 22 | 23 | build "${IND_STEPS[@]}" 24 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-ssh/common.source: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function add_user_key () { 4 | local user="${1}" 5 | 6 | rm -f ${NODE_DIR}/sshkey 7 | rm -f ${NODE_DIR}/sshkey.pub 8 | ssh-keygen -t rsa -b 2048 -N "" -f ${NODE_DIR}/sshkey 9 | chmod 600 ${NODE_DIR}/sshkey 10 | } 11 | 12 | function install_user_key () { 13 | local user="${1}" 14 | 15 | sudo chroot ${TMP_ROOT} /bin/bash -c "mkdir -p -m 600 /${user}/.ssh" 16 | sudo cp "${CACHE_DIR}/${BRANCH}/sshkey_${vm_name}.pub" "${TMP_ROOT}/${user}/.ssh/authorized_keys" 17 | } 18 | 19 | ci_user="${user:-root}" 20 | -------------------------------------------------------------------------------- /pkg/conf/scripts/ovs-up.sh.tmpl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | # lxc.network.script.up/down does not capture stderr. 5 | exec 2>&1 6 | 7 | CONTAINER=$1 8 | SECTION=$2 # net 9 | ACTION=$3 # up/down 10 | IFTYPE=$4 # veth,macvlan,etc... 11 | IFNAME=$5 12 | 13 | # When mesos-slave is stopped and restarted, all instances are momentarily stopped 14 | # without running the down.sh script causing defunct ports to remain on ovs. 15 | # Until a fix for that is found, we need to remove those on startup. 16 | ovs-vsctl --if-exists del-port {{.BridgeName}} "${IFNAME}" 17 | 18 | ovs-vsctl add-port {{.BridgeName}} "${IFNAME}" 19 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/tests/README.md: -------------------------------------------------------------------------------- 1 | 2 | Running acceptance/CI tests under ``ci/citest/acceptance-test/tests``: 3 | 4 | ``` 5 | cd ci/citest/acceptance-test/tests 6 | go test -tags=acceptance ./... 7 | ``` 8 | 9 | Writing acceptance/CI tests: 10 | 11 | - Each test file written in Go. And the file name ends with ``_test.go``. 12 | - Place ``// +build acceptance`` magic comment at the first line. 13 | 14 | Minimal code example: 15 | 16 | ```go 17 | // +build acceptance 18 | 19 | package tests 20 | 21 | import "testing" 22 | 23 | func TestScenario1(t *testing.T) { 24 | t.Log("TestScenario1") 25 | } 26 | ``` 27 | -------------------------------------------------------------------------------- /cmd/version.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/spf13/cobra" 7 | ) 8 | 9 | // Build time constant variables from -ldflags 10 | var ( 11 | Version string 12 | Sha string 13 | Builddate string 14 | Goversion string 15 | ) 16 | 17 | var VersionCmd = &cobra.Command{ 18 | Use: "version", 19 | Short: "Show version", 20 | Long: "Show version", 21 | Run: func(cmd *cobra.Command, args []string) { 22 | fmt.Printf("%s version %s (git: %s, build: %s, goversion: %s)\n", 23 | cmd.Root().CommandPath(), 24 | Version, 25 | Sha[:8], 26 | Builddate, 27 | Goversion, 28 | ) 29 | }, 30 | } 31 | -------------------------------------------------------------------------------- /ci/garbage_collection/garbage_collection_misc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | function remove_dir { 5 | dir_to_rm=$1 6 | 7 | ## "master" and "develop" dirs. should NEVER be removed 8 | short_name=${dir_to_rm%/} # Remove any trailing '/' 9 | short_name=${short_name##*/} # Remove everything up to and including the last '/' 10 | for no_rm in "master" "develop"; do 11 | if [[ "${short_name}" = "${no_rm}" ]]; then 12 | echo "Cannot remove \"${no_rm}\". Ignoring." 13 | return 0 14 | fi 15 | done 16 | 17 | echo "rm -rf ${dir_to_rm}" 18 | rm -rf ${dir_to_rm} 19 | 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/tests/vendor/vendor.json: -------------------------------------------------------------------------------- 1 | { 2 | "comment": "", 3 | "ignore": "test", 4 | "package": [ 5 | { 6 | "checksumSHA1": "k/Xh0p5L7+tBCXAL2dOCwUf9J3Y=", 7 | "path": "github.com/tidwall/gjson", 8 | "revision": "09d1c5c5bc64e094394dfe2150220d906c55ac37", 9 | "revisionTime": "2017-02-05T16:10:42Z" 10 | }, 11 | { 12 | "checksumSHA1": "qmePMXEDYGwkAfT9QvtMC58JN/E=", 13 | "path": "github.com/tidwall/match", 14 | "revision": "173748da739a410c5b0b813b956f89ff94730b4c", 15 | "revisionTime": "2016-08-30T17:39:30Z" 16 | } 17 | ], 18 | "rootPath": "github.com/axsh/openvdc/ci/citest/acceptance-test/tests" 19 | } 20 | -------------------------------------------------------------------------------- /cmd/openvdc-executor/init_linux.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log/syslog" 5 | 6 | "github.com/Sirupsen/logrus" 7 | logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog" 8 | 9 | _ "github.com/axsh/openvdc/hypervisor/esxi" 10 | _ "github.com/axsh/openvdc/hypervisor/lxc" 11 | _ "github.com/axsh/openvdc/hypervisor/null" 12 | _ "github.com/axsh/openvdc/hypervisor/qemu" 13 | ) 14 | 15 | func init() { 16 | // forward log messages to local syslog. 17 | hook, err := logrus_syslog.NewSyslogHook("", "", syslog.LOG_DEBUG, "vdc-executor") 18 | if err != nil { 19 | logrus.Fatal("Failed to initialize syslog hook: ", err) 20 | } 21 | logrus.AddHook(hook) 22 | } 23 | -------------------------------------------------------------------------------- /model/base.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/axsh/openvdc/model/backend" 7 | "golang.org/x/net/context" 8 | ) 9 | 10 | // TODO: move cluster.proto 11 | //go:generate protoc -I../proto -I${GOPATH}/src --go_out=${GOPATH}/src ../proto/model.proto ../proto/cluster.proto 12 | 13 | type base struct { 14 | ctx context.Context 15 | } 16 | 17 | func (i *base) connection() (backend.ProtoModelBackend, error) { 18 | bk := GetBackendCtx(i.ctx) 19 | if bk == nil { 20 | return nil, ErrBackendNotInContext 21 | } 22 | wrapper := backend.NewProtoWrapper(bk) 23 | wrapper.AddFilter(&backend.TimestampFilter{time.Now().UTC()}) 24 | return wrapper, nil 25 | } 26 | -------------------------------------------------------------------------------- /registry/remote_test.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/axsh/openvdc/internal/unittest" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestNewRemoteRegistry(t *testing.T) { 12 | assert := assert.New(t) 13 | reg := NewRemoteRegistry() 14 | assert.Implements((*TemplateFinder)(nil), reg) 15 | } 16 | 17 | func TestRemoteRegistryFind(t *testing.T) { 18 | assert := assert.New(t) 19 | reg := NewRemoteRegistry() 20 | rt, err := reg.Find(fmt.Sprintf("%s/%s/%s/templates/centos/7/lxc.json", 21 | githubRawURI, githubRepoSlug, unittest.GithubDefaultRef)) 22 | assert.NoError(err) 23 | assert.NotNil(rt) 24 | assert.Equal(rt.source, reg) 25 | } 26 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-openvswitch/pre_rsync.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | # Hard coding from the repo added in openvnets to-be centos7 5 | # ci environment. 6 | 7 | ( 8 | $starting_step "Download OpenVNet third party repo for openvswitch" 9 | [[ -f ${TMP_ROOT}/etc/yum.repos.d/openvnet-third-party.repo ]] 10 | $skip_step_if_already_done; set -xe 11 | sudo chroot ${TMP_ROOT} /bin/bash -c "cat > /etc/yum.repos.d/openvnet-third-party.repo <&2 7 | exit 1 8 | fi 9 | #box_url="${1:?ERROR: Require to set download .box URL}" 10 | box_url="https://atlas.hashicorp.com/bento/boxes/centos-7.3/versions/2.3.2/providers/virtualbox.box" 11 | box_tmp="${2:-boxtemp/7.3}" 12 | 13 | # ignore duplicating dir 14 | mkdir -p $box_tmp || : 15 | 16 | ( 17 | cd $box_tmp 18 | if [ -f './.etag' ]; then 19 | etag=$(cat ./.etag) 20 | fi 21 | curl --dump-header box.header ${etag:+-H "If-None-Match: ${etag}"} -L -o "t.box" "${box_url}" 22 | cat box.header | awk 'BEGIN {FS=": "}/^ETag/{print $2}' > .etag 23 | rm -f box.header 24 | tar -xzf t.box 25 | ) 26 | 27 | HOST_SWITCH=vboxnet0 packer build -force devbox-centos7.json 28 | -------------------------------------------------------------------------------- /ci/citest/rpmbuild/el7.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | WORKDIR /var/tmp 3 | ENTRYPOINT ["/sbin/init"] 4 | RUN yum install -y yum-utils 5 | # epel-release.rpm from CentOS/extra contains deprecated index for mirror sites. 6 | RUN yum install -y http://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-11.noarch.rpm 7 | RUN yum install -y git createrepo 8 | 9 | RUN curl -L https://storage.googleapis.com/golang/go1.8.linux-amd64.tar.gz | tar -C /usr/local -xzf - 10 | RUN yum install -y gcc 11 | ENV GOPATH=/var/tmp/go PATH=$PATH:/usr/local/go/bin:$GOPATH/bin 12 | RUN mkdir $GOPATH 13 | RUN go get -u github.com/kardianos/govendor 14 | RUN mkdir -p /var/tmp/go/src/github.com/axsh/openvdc 15 | RUN mkdir -p /var/tmp/rpmbuild/SOURCES 16 | RUN ln -s ${GOPATH}/src/github.com/axsh/openvdc /var/tmp/rpmbuild/SOURCES/openvdc 17 | ENV WORK_DIR=/var/tmp/rpmbuild 18 | -------------------------------------------------------------------------------- /hypervisor/esxi/esxi_machine.go: -------------------------------------------------------------------------------- 1 | package esxi 2 | 3 | import "github.com/axsh/openvdc/model" 4 | 5 | type Nic struct { 6 | NetworkId string 7 | IfName string 8 | Index string 9 | Ipv4Addr string 10 | MacAddr string 11 | Bridge string 12 | Ipv4Gateway string 13 | Type string 14 | } 15 | 16 | type baseImage struct { 17 | name string 18 | datastore string 19 | } 20 | 21 | type EsxiMachine struct { 22 | baseImage *baseImage 23 | SerialConsolePort int 24 | Nics []Nic 25 | } 26 | 27 | func newEsxiMachine(serialPort int, template *model.EsxiTemplate) *EsxiMachine { 28 | base := template.GetEsxiImage() 29 | return &EsxiMachine{ 30 | SerialConsolePort: serialPort, 31 | baseImage: &baseImage{ 32 | name: base.GetName(), 33 | datastore: base.GetDatastore(), 34 | }, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ci/citest/unit-tests/el7-unit-tests.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | WORKDIR /var/tmp 3 | ENTRYPOINT ["/sbin/init"] 4 | RUN yum install -y yum-utils 5 | # epel-release.rpm from CentOS/extra contains deprecated index for mirror sites. 6 | RUN yum install -y http://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-11.noarch.rpm 7 | 8 | RUN yum install -y git 9 | RUN curl -L https://storage.googleapis.com/golang/go1.9.linux-amd64.tar.gz | tar -C /usr/local -xzf - 10 | RUN yum install -y gcc 11 | ENV GOPATH=/var/tmp/go 12 | ENV PATH=$PATH:/usr/local/go/bin:$GOPATH/bin 13 | RUN mkdir $GOPATH 14 | 15 | RUN mkdir -p $GOPATH/src/github.com/axsh/openvdc 16 | RUN go get -u github.com/kardianos/govendor 17 | 18 | RUN yum install -y http://repos.mesosphere.io/el/7/noarch/RPMS/mesosphere-el-repo-7-1.noarch.rpm 19 | RUN yum install -y mesosphere-zookeeper 20 | RUN yum install -y lxc lxc-devel 21 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.13-vdc-executor-null/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export ENV_ROOTDIR="$(cd "$(dirname $(readlink -f "$0"))/.." && pwd -P)" 4 | export NODE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 5 | TMP_ROOT="${NODE_DIR}/tmp_root" 6 | 7 | . "${ENV_ROOTDIR}/config.source" 8 | . "${NODE_DIR}/vmspec.conf" 9 | . "${ENV_ROOTDIR}/ind-steps/common.source" 10 | 11 | IND_STEPS=( 12 | "box" 13 | "ssh" 14 | "hosts" 15 | "disable-firewalld" 16 | "epel" 17 | "mesosphere-repo" 18 | "mesos-agent" 19 | ) 20 | 21 | build "${IND_STEPS[@]}" 22 | 23 | # This is not part of the ind-steps because we don't want OpenVDC installed in 24 | # the cached images. We want a clean cache without OpenVDC so we can install a 25 | # different version to test every the CI runs. 26 | install_openvdc_yum_repo 27 | install_yum_package_over_ssh "openvdc-executor-null" 28 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/external_libraries/bashsteps/ind-steps/kvmsteps/vmdir-scripts/kvm-kill.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source "$(dirname $(readlink -f "$0"))/../simple-defaults-for-bashsteps.source" 4 | 5 | if [[ "$DATADIR" != /* ]]; then 6 | # Choose directory of symbolic link by default 7 | DATADIR="$LINKCODEDIR" 8 | fi 9 | 10 | kvm_is_running() 11 | { 12 | pid="$(cat "$DATADIR/runinfo/kvm.pid" 2>/dev/null)" && 13 | [ -d /proc/"$(< "$DATADIR/runinfo/kvm.pid")" ] 14 | } 15 | 16 | ( 17 | $starting_step "Killing KVM process" 18 | ! kvm_is_running 19 | $skip_step_if_already_done 20 | set -e 21 | thepid="$(cat "$DATADIR/runinfo/kvm.pid" 2>/dev/null)" 22 | marker="$(cat "$DATADIR/runinfo/kvm.marker" 2>/dev/null)" 23 | env="$(cat /proc/$thepid/environ 2>/dev/null)" && [[ "$env" == *${marker}* ]] 24 | kill -TERM "$thepid" 25 | ) ; prev_cmd_failed 26 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/destroy_leaving_cache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export ENV_ROOTDIR="$(cd "$(dirname $(readlink -f "$0"))" && pwd -P)" 4 | . "${ENV_ROOTDIR}/external_libraries/bashsteps/simple-defaults-for-bashsteps.source" 5 | . "${ENV_ROOTDIR}/ind-steps/common.source" 6 | 7 | . "${ENV_ROOTDIR}/config.source" 8 | 9 | scheduled_nodes=${NODES[@]} 10 | [[ -n "$1" ]] && scheduled_nodes="${@}" 11 | 12 | for node in ${scheduled_nodes[@]} ; do 13 | ${ENV_ROOTDIR}/${node}/destroy.sh 14 | done 15 | 16 | ( 17 | $starting_step "Destroy simulated global interface" 18 | ip link | grep -q "${GLOBAL_TAP}" 19 | [ "$?" != "0" ] 20 | $skip_step_if_already_done ; set -xe 21 | sudo ip link set "${GLOBAL_TAP}" down 22 | sudo ip link delete dev "${GLOBAL_TAP}" 23 | ) ; prev_cmd_failed 24 | 25 | destroy_bridge "vdc_mngnt" 26 | destroy_bridge "vdc_insts" 27 | stop_masquerade "${NETWORK}/${PREFIX}" 28 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.14-vdc-executor-lxc/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export ENV_ROOTDIR="$(cd "$(dirname $(readlink -f "$0"))/.." && pwd -P)" 4 | export NODE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 5 | TMP_ROOT="${NODE_DIR}/tmp_root" 6 | 7 | . "${ENV_ROOTDIR}/config.source" 8 | . "${NODE_DIR}/vmspec.conf" 9 | . "${ENV_ROOTDIR}/ind-steps/common.source" 10 | 11 | IND_STEPS=( 12 | "box" 13 | "ssh" 14 | "hosts" 15 | "disable-firewalld" 16 | "epel" 17 | "bridge-utils" 18 | "cgroups" 19 | "mesosphere-repo" 20 | "mesos-agent" 21 | ) 22 | 23 | build "${IND_STEPS[@]}" 24 | 25 | # This is not part of the ind-steps because we don't want OpenVDC installed in 26 | # the cached images. We want a clean cache without OpenVDC so we can install a 27 | # different version to test every the CI runs. 28 | install_openvdc_yum_repo 29 | install_yum_package_over_ssh "openvdc-executor-lxc" 30 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/tests/force_destroy_test.go: -------------------------------------------------------------------------------- 1 | // +build acceptance 2 | 3 | package tests 4 | 5 | import ( 6 | "strings" 7 | "testing" 8 | "time" 9 | ) 10 | 11 | func TestForceDestroy(t *testing.T) { 12 | stdout, _ := RunCmdAndReportFail(t, "openvdc", "run", "centos/7/lxc", `{"interfaces":[{"type":"veth"}], "node_groups":["linuxbr"]}`) 13 | instance_id := strings.TrimSpace(stdout.String()) 14 | 15 | WaitInstance(t, 5*time.Minute, instance_id, "RUNNING", []string{"QUEUED", "STARTING"}) 16 | 17 | //Simulate stuck state 18 | RunCmdAndReportFail(t, "openvdc", "force-state", instance_id, "starting") 19 | WaitInstance(t, 1*time.Minute, instance_id, "STARTING", nil) 20 | 21 | _, _ = RunCmdWithTimeoutAndReportFail(t, 10, 5, "openvdc", "destroy", "--force", instance_id) 22 | t.Log("Waiting for instance " + instance_id + " to become TERMINATED...") 23 | WaitInstance(t, 5*time.Minute, instance_id, "TERMINATED", nil) 24 | } 25 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.15-vdc-executor-lxc-ovs/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export ENV_ROOTDIR="$(cd "$(dirname $(readlink -f "$0"))/.." && pwd -P)" 4 | export NODE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 5 | TMP_ROOT="${NODE_DIR}/tmp_root" 6 | 7 | . "${ENV_ROOTDIR}/config.source" 8 | . "${NODE_DIR}/vmspec.conf" 9 | . "${ENV_ROOTDIR}/ind-steps/common.source" 10 | 11 | IND_STEPS=( 12 | "box" 13 | "ssh" 14 | "hosts" 15 | "disable-firewalld" 16 | "epel" 17 | "openvswitch" 18 | "cgroups" 19 | "mesosphere-repo" 20 | "mesos-agent" 21 | ) 22 | 23 | build "${IND_STEPS[@]}" 24 | 25 | # This is not part of the ind-steps because we don't want OpenVDC installed in 26 | # the cached images. We want a clean cache without OpenVDC so we can install a 27 | # different version to test every the CI runs. 28 | install_openvdc_yum_repo 29 | install_yum_package_over_ssh "openvdc-executor-lxc" 30 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/ind-steps/step-ssh/boot.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ( 4 | $starting_step "Import ssh key" 5 | # If we had built another branch before, its ssh key will still be in place. 6 | # That's why we always do this step even if there's a key already. 7 | false 8 | $skip_step_if_already_done 9 | cp ${CACHE_DIR}/${BRANCH}/sshkey_${vm_name} ${NODE_DIR}/sshkey 10 | chown ${USER}:${USER} ${NODE_DIR}/sshkey 11 | ) ; prev_cmd_failed 12 | 13 | ( 14 | $starting_step "Wait for ssh" 15 | [[ "$(nc ${IP_ADDR} 22 < /dev/null)" == *"SSH"* ]] 16 | $skip_step_if_already_done ; set -xe 17 | timeout=15 18 | while ! run_ssh root@${IP_ADDR} "uptime" > /dev/null ; do 19 | sleep 5 20 | tries=$(( tries + 1 )) 21 | [[ $tries -eq ${timeout} ]] && exit 1 22 | done 23 | : 24 | ) ; prev_cmd_failed 25 | 26 | [[ -f ${USER}/.ssh/known_hosts ]] && ssh-keygen -R ${IP_ADDR} 27 | -------------------------------------------------------------------------------- /schema/v1.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "https://raw.githubusercontent.com/axsh/openvdc/master/schema/v1.json#", 3 | "$schema": "http://json-schema.org/draft-04/schema#", 4 | "description": "OpenVDC Resource Template Schema", 5 | "type": "object", 6 | "required": [ 7 | "title", 8 | "template" 9 | ], 10 | "properties": { 11 | "_comment": { 12 | "type": "string" 13 | }, 14 | "title": { 15 | "type": "string" 16 | }, 17 | "description": { 18 | "type": "string" 19 | }, 20 | "template": { 21 | "type": "object", 22 | "oneOf": [ 23 | { 24 | "$ref": "./none.json#" 25 | }, 26 | { 27 | "$ref": "./vm/lxc.json#" 28 | }, 29 | { 30 | "$ref": "./vm/esxi.json#" 31 | }, 32 | { 33 | "$ref": "./vm/null.json#" 34 | }, 35 | { 36 | "$ref": "./vm/qemu.json#" 37 | } 38 | ] 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /hypervisor/qemu/qemu_machine_test.go: -------------------------------------------------------------------------------- 1 | // build +linux 2 | 3 | package qemu 4 | 5 | import ( 6 | "fmt" 7 | "testing" 8 | 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestNewMachine(t *testing.T) { 13 | assert := assert.New(t) 14 | machine := NewMachine(1, 512) 15 | assert.NotNil(machine) 16 | assert.Equal(1, machine.Cores) 17 | assert.Equal(uint64(512), machine.Memory) 18 | assert.NotNil(machine.Drives) 19 | } 20 | 21 | func TestAddNICs(t *testing.T) { 22 | assert := assert.New(t) 23 | machine := NewMachine(1, 512) 24 | machine.AddNICs([]Nic{Nic{IfName: "if0"}, Nic{IfName: "if1"}}) 25 | 26 | assert.Equal(len(machine.Nics), 2) 27 | for idx, nic := range machine.Nics { 28 | assert.Equal(fmt.Sprintf("if%d", idx), nic.IfName) 29 | } 30 | } 31 | 32 | func TestAddDevice(t *testing.T) { 33 | assert := assert.New(t) 34 | machine := NewMachine(1, 512) 35 | machine.AddDevice(NewDevice(DevType)) 36 | assert.Equal(len(machine.Devices), 1) 37 | } 38 | -------------------------------------------------------------------------------- /ci/garbage_collection/cache_cleanups/cache_garbage_collection.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | 5 | . ../garbage_collection_misc.sh 6 | . ../prune_branches.sh 7 | 8 | time_limit=14 ## Days. Set this to give the "deadline". All 9 | ## branches older than this will be removed. 10 | 11 | cache_location_dir=/data/openvdc-ci/branches 12 | 13 | 14 | ################################################################################### 15 | 16 | ## main() 17 | 18 | 19 | ## Remove all directories whose branch (on git) no longer exists 20 | ## or which has not beenm pushed to within $time_limit days. 21 | for directory in $(TIME_LIMIT=${time_limit} dirs_to_prune ${cache_location_dir}); do 22 | 23 | group_owner=$(stat -c %G ${cache_location_dir}/${directory}) 24 | if [[ "${group_owner}" = "root" ]]; then 25 | echo "${directory} is owned by root. Cannot remove!" 26 | else 27 | remove_dir ${cache_location_dir}/${directory} 28 | fi 29 | done 30 | -------------------------------------------------------------------------------- /hypervisor/null/null_test.go: -------------------------------------------------------------------------------- 1 | package null 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/axsh/openvdc/hypervisor" 7 | "github.com/axsh/openvdc/model" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestProviderRegistration(t *testing.T) { 12 | assert := assert.New(t) 13 | p, _ := hypervisor.FindProvider("null") 14 | assert.NotNil(p, "Check null provider is registered.") 15 | assert.Equal("null", p.Name()) 16 | assert.Implements((*hypervisor.HypervisorProvider)(nil), p) 17 | } 18 | 19 | func TestNullHypervisorProvider_CreateDriver(t *testing.T) { 20 | assert := assert.New(t) 21 | p, _ := hypervisor.FindProvider("null") 22 | 23 | d, err := p.CreateDriver(&model.Instance{Id: "i-xxxxx"}, &model.NullTemplate{}) 24 | assert.NoError(err) 25 | assert.Implements((*hypervisor.HypervisorDriver)(nil), d) 26 | _, err = p.CreateDriver(&model.Instance{Id: "i-xxxxx"}, nil) 27 | assert.Error(err, "NullHypvisorProvider.CreateDriver should fail if not with *model.NullTemplate") 28 | } 29 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/illustrations/README.md: -------------------------------------------------------------------------------- 1 | # Editing these 2 | 3 | These illustrations were made using [draw.io](http://draw.io/). They can be imported directly and all connections and other metadata should be in place. 4 | 5 | ### Before you commit 6 | 7 | * Export as .svg and set a borderwidth of 10. 8 | 9 | * Save the resulting .svg locally and run the following command on it. 10 | 11 | ``` 12 | xmllint --format /path/to/new.svg > /path/to/toyocho-tools/illustrations/new.svg 13 | ``` 14 | 15 | #### But why? 16 | 17 | * The border is because the line near the edge of the physical illustration will become very hard to see otherwise. 18 | 19 | * The `xmllint` command is used because draw.io saves .svg files' entire XML on one line. This is great for browsers but not great for github. This way git would create a new copy of the entire drawing for every tiny change. Not good for repo size. ;) `xmllint` makes the .svg file multi-line so git only needs to replace the lines that actually changed. 20 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.16-vdc-executor-qemu/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export ENV_ROOTDIR="$(cd "$(dirname $(readlink -f "$0"))/.." && pwd -P)" 4 | export NODE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 5 | TMP_ROOT="${NODE_DIR}/tmp_root" 6 | 7 | . "${ENV_ROOTDIR}/config.source" 8 | . "${NODE_DIR}/vmspec.conf" 9 | . "${ENV_ROOTDIR}/ind-steps/common.source" 10 | 11 | IND_STEPS=( 12 | "box" 13 | "ssh" 14 | "hosts" 15 | "disable-firewalld" 16 | "epel" 17 | "qemu-kvm" 18 | "ncat" 19 | "bridge-utils" 20 | "mesosphere-repo" 21 | "mesos-agent" 22 | "vdc-images" 23 | ) 24 | 25 | image_type=qemu 26 | 27 | build "${IND_STEPS[@]}" 28 | 29 | # This is not part of the ind-steps because we don't want OpenVDC installed in 30 | # the cached images. We want a clean cache without OpenVDC so we can install a 31 | # different version to test every the CI runs. 32 | install_openvdc_yum_repo 33 | install_yum_package_over_ssh "openvdc-executor-qemu" 34 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.17-vdc-executor-qemu-ovs/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export ENV_ROOTDIR="$(cd "$(dirname $(readlink -f "$0"))/.." && pwd -P)" 4 | export NODE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 5 | TMP_ROOT="${NODE_DIR}/tmp_root" 6 | 7 | . "${ENV_ROOTDIR}/config.source" 8 | . "${NODE_DIR}/vmspec.conf" 9 | . "${ENV_ROOTDIR}/ind-steps/common.source" 10 | 11 | IND_STEPS=( 12 | "box" 13 | "ssh" 14 | "hosts" 15 | "disable-firewalld" 16 | "epel" 17 | "openvswitch" 18 | "qemu-kvm" 19 | "ncat" 20 | "mesosphere-repo" 21 | "mesos-agent" 22 | "vdc-images" 23 | ) 24 | 25 | image_type=qemu 26 | 27 | build "${IND_STEPS[@]}" 28 | 29 | # This is not part of the ind-steps because we don't want OpenVDC installed in 30 | # the cached images. We want a clean cache without OpenVDC so we can install a 31 | # different version to test every the CI runs. 32 | install_openvdc_yum_repo 33 | install_yum_package_over_ssh "openvdc-executor-qemu" 34 | -------------------------------------------------------------------------------- /ci/devbox/build.ps1: -------------------------------------------------------------------------------- 1 | $ErrorActionPreference = "Stop" 2 | 3 | if(!(Get-Command -Name .\packer.exe )){ 4 | Write-Error "packer command not found. Please install from https://packer.io/" 5 | exit 1 6 | } 7 | 8 | if(!(Get-Command -Name 7z.exe )){ 9 | Write-Error "7z command not found. Please install from http://www.7-zip.org/" 10 | exit 1 11 | } 12 | 13 | $box_url="https://atlas.hashicorp.com/bento/boxes/centos-7.3/versions/2.3.2/providers/virtualbox.box" 14 | $box_tmp="boxtemp\7.3" 15 | 16 | if(!(Test-Path -Path $box_tmp)){ 17 | New-Item -ItemType directory -Path $box_tmp | Out-Null 18 | } 19 | 20 | if(!(Test-Path -Path "${box_tmp}\t.box")){ 21 | Write-Host "Downloading ${box_url} to ${box_tmp}\t.box" 22 | Invoke-WebRequest -Uri $box_url -OutFile "${box_tmp}\t.box" 23 | } 24 | 25 | pushd $box_tmp 26 | 7z -y e "t.box" 27 | 7z -y x "t" 28 | popd 29 | 30 | $env:HOST_SWITCH="VirtualBox Host-Only Ethernet Adapter" 31 | .\packer build -force devbox-centos7.json 32 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/login.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export ENV_ROOTDIR="$(cd "$(dirname $(readlink -f "$0"))" && pwd -P)" 4 | export NODE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 5 | 6 | node="${1}" 7 | protocol="${2:-ssh}" 8 | 9 | if [[ "${NODE_DIR}" == "${ENV_ROOTDIR}" ]] ; then 10 | [[ "${node}" == "" ]] && { 11 | echo "Error: missing node name" 12 | exit 1 13 | } 14 | PROTOCOL=${protocol} ${ENV_ROOTDIR}/${node}/login.sh 15 | else 16 | . "${NODE_DIR}/vmspec.conf" 17 | 18 | $(sudo kill -0 $(sudo cat "${NODE_DIR}/${vm_name}.pid" 2> /dev/null) 2> /dev/null) || { 19 | echo "Error: node not running" 20 | exit 1 21 | } 22 | 23 | [[ ${PROTOCOL} == "ssh" ]] && 24 | ssh ${SSH_OPTS:+$SSH_OPTS} -i ${NODE_DIR}/sshkey root@${IP_ADDR} 25 | [[ ${PROTOCOL} == "telnet" ]] && { 26 | telnet_host="${serial%%,*}" 27 | telnet_host=${telnet_host#*:} 28 | telnet "${telnet_host%:*}" "${telnet_host#*:}" 29 | } 30 | fi 31 | -------------------------------------------------------------------------------- /api/server_test.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "net" 5 | "testing" 6 | "time" 7 | 8 | "github.com/axsh/openvdc/internal/unittest" 9 | "github.com/axsh/openvdc/model" 10 | "github.com/axsh/openvdc/model/backend" 11 | "golang.org/x/net/context" 12 | ) 13 | 14 | func TestNewAPIServer(t *testing.T) { 15 | ze := &backend.ZkEndpoint{} 16 | ze.Set(unittest.TestZkServer) 17 | // TODO: Set mock SchedulerDriver 18 | s := NewAPIServer(ze, nil, model.WithMockClusterBackendCtx(context.Background())) 19 | if s == nil { 20 | t.Error("NewAPIServer() returned nil") 21 | } 22 | } 23 | 24 | func TestAPIServerRun(t *testing.T) { 25 | lis, err := net.Listen("tcp", "127.0.0.1:8765") 26 | if err != nil { 27 | t.Error(err) 28 | } 29 | ze := &backend.ZkEndpoint{} 30 | ze.Set(unittest.TestZkServer) 31 | // TODO: Set mock SchedulerDriver 32 | s := NewAPIServer(ze, nil, model.WithMockClusterBackendCtx(context.Background())) 33 | go func() { 34 | time.Sleep(2 * time.Second) 35 | s.Stop() 36 | }() 37 | s.Serve(lis) 38 | } 39 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/external_libraries/bashsteps/ind-steps/kvmsteps/vmdir-scripts/ssh-to-kvm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | reportfailed() 4 | { 5 | echo "Script failed...exiting. ($*)" 1>&2 6 | exit 255 7 | } 8 | 9 | export CODEDIR="$(cd "$(dirname "$0")" && pwd -P)" || reportfailed 10 | 11 | if [ "$DATADIR" = "" ]; then 12 | # Choose directory of symbolic link by default 13 | DATADIR="$CODEDIR" 14 | fi 15 | 16 | source "$DATADIR/datadir.conf" 17 | 18 | kvm_is_running() 19 | { 20 | pid="$(cat "$DATADIR/runinfo/kvm.pid" 2>/dev/null)" && 21 | [ -d /proc/"$(< "$DATADIR/runinfo/kvm.pid")" ] 22 | } 23 | 24 | kvm_is_running || reportfailed "KVM is not running" 25 | 26 | : ${SSHUSER:=$(cat "$DATADIR/sshuser" 2>/dev/null)} 27 | : ${SSHPORT:=$(cat "$DATADIR/runinfo/port.ssh" 2>/dev/null)} 28 | 29 | sshkeyfile="$DATADIR/sshkey" 30 | keyparams="-i $sshkeyfile" 31 | [ -f "$sshkeyfile" ] || keyparams="" 32 | 33 | : ${SSHUSER:?} ${SSHPORT:?} 34 | 35 | ssh "$SSHUSER"@127.0.0.1 -p "$SSHPORT" $keyparams "$@" 36 | -------------------------------------------------------------------------------- /cmd/openvdc/cmd/start.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | log "github.com/Sirupsen/logrus" 5 | "github.com/axsh/openvdc/api" 6 | "github.com/axsh/openvdc/cmd/openvdc/internal/util" 7 | "github.com/spf13/cobra" 8 | "golang.org/x/net/context" 9 | "google.golang.org/grpc" 10 | ) 11 | 12 | var startCmd = &cobra.Command{ 13 | Use: "start [Instance ID]", 14 | Short: "Start an instance", 15 | Long: `Start an instance in REGISTERED or STOPPED state to RUNNING.`, 16 | RunE: func(cmd *cobra.Command, args []string) error { 17 | if len(args) != 1 { 18 | log.Fatalf("Please provide an Instance ID.") 19 | } 20 | 21 | instanceID := args[0] 22 | 23 | req := &api.StartRequest{ 24 | InstanceId: instanceID, 25 | } 26 | return util.RemoteCall(func(conn *grpc.ClientConn) error { 27 | c := api.NewInstanceClient(conn) 28 | _, err := c.Start(context.Background(), req) 29 | if err != nil { 30 | log.WithError(err).Fatal("Disconnected abnormaly") 31 | return err 32 | } 33 | return err 34 | }) 35 | }} 36 | -------------------------------------------------------------------------------- /hypervisor/qemu/qemu_test.go: -------------------------------------------------------------------------------- 1 | // build +linux 2 | 3 | package qemu 4 | 5 | import ( 6 | "testing" 7 | 8 | "github.com/axsh/openvdc/hypervisor" 9 | "github.com/axsh/openvdc/model" 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func TestProviderRegistration(t *testing.T) { 14 | assert := assert.New(t) 15 | p, _ := hypervisor.FindProvider("qemu") 16 | assert.NotNil(p, "Check qemu provider is registered.") 17 | assert.Equal("qemu", p.Name()) 18 | assert.Implements((*hypervisor.HypervisorProvider)(nil), p) 19 | } 20 | 21 | func TestQEMUHypervisorProvider_CreateDriver(t *testing.T) { 22 | assert := assert.New(t) 23 | p, _ := hypervisor.FindProvider("qemu") 24 | 25 | d, err := p.CreateDriver(&model.Instance{Id: "i-xxxxx"}, &model.QemuTemplate{}) 26 | assert.NoError(err) 27 | assert.Implements((*hypervisor.HypervisorDriver)(nil), d) 28 | _, err = p.CreateDriver(&model.Instance{Id: "i-xxxxx"}, nil) 29 | assert.Error(err, "QEMUHypvisorProvider.CreateDriver should fail if not with *model.QEMUTemplate") 30 | } 31 | -------------------------------------------------------------------------------- /registry/schema.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | 7 | "github.com/xeipuuv/gojsonschema" 8 | ) 9 | 10 | type ErrInvalidTemplate struct { 11 | Errors []gojsonschema.ResultError 12 | } 13 | 14 | func (e *ErrInvalidTemplate) Error() string { 15 | return fmt.Sprintf("Detected %d errors", len(e.Errors)) 16 | } 17 | 18 | func (e *ErrInvalidTemplate) Dump(out io.Writer) { 19 | for _, r := range e.Errors { 20 | out.Write([]byte(r.Description() + ": " + r.Field() + "\n")) 21 | } 22 | } 23 | 24 | //go:generate go-bindata-assetfs -mode 420 -pkg registry -prefix ../ ../schema/... 25 | 26 | func ValidateTemplate(in []byte) error { 27 | schema, err := gojsonschema.NewSchema(gojsonschema.NewReferenceLoaderFileSystem("file://schema/v1.json", assetFS())) 28 | if err != nil { 29 | return err 30 | } 31 | r, err := schema.Validate(gojsonschema.NewBytesLoader(in)) 32 | if err != nil { 33 | return err 34 | } 35 | if !r.Valid() { 36 | return &ErrInvalidTemplate{Errors: r.Errors()} 37 | } 38 | return nil 39 | } 40 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/external_libraries/bashsteps/examples/old/duped-substep.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | reportfailed() 4 | { 5 | echo "Script failed...exiting. ($*)" 1>&2 6 | exit 255 7 | } 8 | 9 | export ORGCODEDIR="$(cd "$(dirname $(readlink -f "$0"))" && pwd -P)" || reportfailed 10 | 11 | DATADIR="$ORGCODEDIR" 12 | source "$ORGCODEDIR/simple-defaults-for-bashsteps.source" 13 | 14 | mfff() 15 | { 16 | ( 17 | $starting_checks "Make t-fff" 18 | cd "$DATADIR" 19 | [ -f t-fff ] 20 | $skip_rest_if_already_done; set -e 21 | date >t-fff 22 | ) ; $prev_cmd_failed 23 | } 24 | 25 | 26 | ( 27 | $starting_dependents "Make t-ddd" 28 | mfff 29 | $starting_checks 30 | cd "$DATADIR" 31 | [ -f t-ddd ] 32 | $skip_rest_if_already_done; set -e 33 | date >t-ddd 34 | ) ; $prev_cmd_failed 35 | 36 | ( 37 | $starting_dependents "Make t-eee" 38 | mfff 39 | $starting_checks 40 | cd "$DATADIR" 41 | [ -f t-eee ] 42 | $skip_rest_if_already_done; set -e 43 | date >t-eee 44 | ) ; $prev_cmd_failed 45 | -------------------------------------------------------------------------------- /cmd/openvdc/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "path/filepath" 8 | 9 | "github.com/axsh/openvdc/cmd/openvdc/cmd" 10 | "github.com/axsh/openvdc/cmd/openvdc/internal/util" 11 | ) 12 | 13 | const defaultTomlConfig = ` 14 | [api] 15 | # endpoint = "127.0.0.1:5000" 16 | ` 17 | 18 | func setupDefaultUserConfig(dir string) error { 19 | stat, err := os.Stat(dir) 20 | if err == nil { 21 | if stat.IsDir() { 22 | // nothing to do 23 | return nil 24 | } else { 25 | return fmt.Errorf("%s is not directory", dir) 26 | } 27 | } 28 | err = os.Mkdir(dir, 0755) 29 | if err != nil { 30 | return err 31 | } 32 | confPath := filepath.Join(dir, "config.toml") 33 | // Install default configuration file. 34 | return ioutil.WriteFile(confPath, []byte(defaultTomlConfig), 0644) 35 | } 36 | 37 | func main() { 38 | err := setupDefaultUserConfig(util.UserConfDir) 39 | if err != nil { 40 | fmt.Fprintf(os.Stderr, "Failed to setup %s: %v\n", util.UserConfDir, err) 41 | os.Exit(1) 42 | } 43 | cmd.Execute() 44 | } 45 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.12-vdc-scheduler/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export ENV_ROOTDIR="$(cd "$(dirname $(readlink -f "$0"))/.." && pwd -P)" 4 | export NODE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 5 | TMP_ROOT="${NODE_DIR}/tmp_root" 6 | 7 | . "${ENV_ROOTDIR}/config.source" 8 | . "${NODE_DIR}/vmspec.conf" 9 | . "${ENV_ROOTDIR}/ind-steps/common.source" 10 | 11 | scheduler=true 12 | zk_host=true 13 | 14 | IND_STEPS=( 15 | "box" 16 | "ssh" 17 | "hosts" 18 | "disable-firewalld" 19 | "apache" 20 | "mesosphere-repo" 21 | "zookeeper" 22 | "vdc-images" 23 | ) 24 | 25 | image_type=lxc 26 | 27 | build "${IND_STEPS[@]}" 28 | 29 | # This is not part of the ind-steps because we don't want OpenVDC installed in 30 | # the cached images. We want a clean cache without OpenVDC so we can install a 31 | # different version to test every the CI runs. 32 | install_openvdc_yum_repo 33 | install_yum_package_over_ssh "openvdc-scheduler" 34 | enable_service_over_ssh "openvdc-scheduler" 35 | enable_service_over_ssh "httpd" 36 | -------------------------------------------------------------------------------- /ci/garbage_collection/Jenkinsfile.garbage_collection: -------------------------------------------------------------------------------- 1 | #!groovy 2 | 3 | import org.jenkinsci.plugins.workflow.steps.FlowInterruptedException 4 | // http://stackoverflow.com/questions/37425064/how-to-use-environment-variables-in-a-groovy-function-using-a-jenkinsfile 5 | import groovy.transform.Field 6 | 7 | 8 | def runs=[:] 9 | 10 | runs[0]= { 11 | node("multibox") { 12 | checkout scm 13 | sh "git remote prune origin" 14 | sh "cd ci/garbage_collection/cache_cleanups/ ; ./cache_garbage_collection.sh" 15 | sh "cd ci/garbage_collection/docker_cleanups ; ./docker_garbage_collection.sh" 16 | } 17 | } 18 | 19 | runs[1]= { 20 | node("rpm_repo") { 21 | checkout scm 22 | sh "git remote prune origin" 23 | sh "cd ci/garbage_collection/repo_cleanups ; ./rpm_garbage_collection.sh" 24 | } 25 | } 26 | 27 | runs[2]= { 28 | node("master") { 29 | checkout scm 30 | sh "cd ci/garbage_collection/docker_cleanups ; ./docker_garbage_collection.sh" 31 | } 32 | } 33 | 34 | node() { 35 | stage "Checkout" 36 | } 37 | 38 | parallel runs 39 | -------------------------------------------------------------------------------- /cmd/openvdc/cmd/stop.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | log "github.com/Sirupsen/logrus" 5 | 6 | "github.com/axsh/openvdc/api" 7 | "github.com/axsh/openvdc/cmd/openvdc/internal/util" 8 | "github.com/spf13/cobra" 9 | "golang.org/x/net/context" 10 | "google.golang.org/grpc" 11 | ) 12 | 13 | var stopCmd = &cobra.Command{ 14 | Use: "stop [Instance ID]", 15 | Short: "Stop a running instance", 16 | Long: "Stop a running instance.", 17 | Example: "openvdc stop i-0000000001", 18 | RunE: func(cmd *cobra.Command, args []string) error { 19 | if len(args) != 1 { 20 | log.Fatalf("Please provide an instance ID.") 21 | } 22 | 23 | instanceID := args[0] 24 | 25 | req := &api.StopRequest{ 26 | InstanceId: instanceID, 27 | } 28 | 29 | return util.RemoteCall(func(conn *grpc.ClientConn) error { 30 | c := api.NewInstanceClient(conn) 31 | 32 | _, err := c.Stop(context.Background(), req) 33 | if err != nil { 34 | log.WithError(err).Fatal("Disconnected abnormally") 35 | return err 36 | } 37 | return err 38 | }) 39 | }, 40 | } 41 | -------------------------------------------------------------------------------- /model/connection_test.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/axsh/openvdc/internal/unittest" 7 | "github.com/axsh/openvdc/model/backend" 8 | "github.com/stretchr/testify/assert" 9 | "golang.org/x/net/context" 10 | ) 11 | 12 | func TestConnect(t *testing.T) { 13 | assert := assert.New(t) 14 | 15 | ze := &backend.ZkEndpoint{} 16 | if err := ze.Set(unittest.TestZkServer); err != nil { 17 | t.Fatal("Invalid zookeeper address:", unittest.TestZkServer) 18 | } 19 | ctx, err := Connect(context.Background(), ze) 20 | assert.NoError(err) 21 | assert.NotNil(ctx) 22 | err = Close(ctx) 23 | assert.NoError(err) 24 | } 25 | 26 | func TestClusterConnect(t *testing.T) { 27 | assert := assert.New(t) 28 | 29 | ze := &backend.ZkEndpoint{} 30 | if err := ze.Set(unittest.TestZkServer); err != nil { 31 | t.Fatal("Invalid zookeeper address:", unittest.TestZkServer) 32 | } 33 | ctx, err := ClusterConnect(context.Background(), ze) 34 | assert.NoError(err) 35 | assert.NotNil(ctx) 36 | err = ClusterClose(ctx) 37 | assert.NoError(err) 38 | } 39 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/external_libraries/bashsteps/README.md: -------------------------------------------------------------------------------- 1 | 2 | I'm just starting to write the documentation on this. 3 | 4 | Note that **bashsteps** is good for some types of scripts, not good 5 | for others. And there are a bunch of scripts in between for which it 6 | is experimental. If you are considering using bashsteps (or forced to 7 | use bashsteps), you should **discuss directly with me** about whether 8 | to use it and how to get the most out of it. 9 | 10 | An introduction that focuses on motivation is now at 11 | [./doc/intro-to-core.md](./doc/intro-to-core.md). It keeps the 12 | discussion to the parts of bashsteps that are stable. 13 | 14 | An example that exercises the core is at 15 | [./examples/new/with-temporary-state.sh](./examples/new/with-temporary-state.sh). 16 | Probably the next step in documentation is to annotate this example 17 | and show how to give a demo with it. 18 | 19 | Also there are comments in [./bashctrl.sh](./bashctrl.sh) and 20 | [./simple-defaults-for-bashsteps.source](./simple-defaults-for-bashsteps.source) 21 | that may give useful hints. 22 | -------------------------------------------------------------------------------- /cmd/openvdc/cmd/list.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | 6 | log "github.com/Sirupsen/logrus" 7 | "github.com/axsh/openvdc/api" 8 | "github.com/axsh/openvdc/cmd/openvdc/internal/util" 9 | "github.com/axsh/openvdc/model" 10 | "github.com/spf13/cobra" 11 | "golang.org/x/net/context" 12 | "google.golang.org/grpc" 13 | ) 14 | 15 | var listCmd = &cobra.Command{ 16 | Use: "list", 17 | Short: "List instances", 18 | Long: "List instances", 19 | RunE: func(cmd *cobra.Command, args []string) error { 20 | req := &api.InstanceListRequest{ 21 | Filter: &api.InstanceListRequest_Filter{ 22 | State: model.InstanceState_REGISTERED, 23 | }, 24 | } 25 | return util.RemoteCall(func(conn *grpc.ClientConn) error { 26 | c := api.NewInstanceClient(conn) 27 | res, err := c.List(context.Background(), req) 28 | if err != nil { 29 | log.WithError(err).Fatal("Disconnected abnormaly") 30 | return err 31 | } 32 | for i, item := range res.Items { 33 | fmt.Printf("%-5d %-20s %-15s\n", i, item.Id, item.State.String()) 34 | } 35 | return err 36 | }) 37 | }} 38 | -------------------------------------------------------------------------------- /registry/schema_test.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import ( 4 | "testing" 5 | 6 | "os" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | const validJSON1 = ` 12 | { 13 | "$schema": "https://raw.githubusercontent.com/axsh/openvdc/master/schema/v1.json#", 14 | "title": "CentOS7", 15 | "template": { 16 | "type": "vm/lxc", 17 | "lxc_image": { 18 | "download_url": "https://images.linuxcontainers.org/1.0/images/d767cfe9a0df0b2213e28b39b61e8f79cb9b1e745eeed98c22bc5236f277309a/export" 19 | } 20 | } 21 | }` 22 | const invalidJSON1 = ` 23 | { 24 | "$schema": "https://raw.githubusercontent.com/axsh/openvdc/master/schema/v1.json#", 25 | "title": "CentOS7", 26 | "template": { 27 | } 28 | }` 29 | 30 | func TestValidateTemplate(t *testing.T) { 31 | assert := assert.New(t) 32 | var err error 33 | 34 | err = ValidateTemplate([]byte(validJSON1)) 35 | assert.NoError(err) 36 | err = ValidateTemplate([]byte(invalidJSON1)) 37 | if err != nil { 38 | if err, ok := err.(*ErrInvalidTemplate); ok { 39 | err.Dump(os.Stderr) 40 | } 41 | } 42 | assert.Error(err) 43 | } 44 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/destroy_with_cache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export ENV_ROOTDIR="$(cd "$(dirname $(readlink -f "$0"))" && pwd -P)" 4 | . "${ENV_ROOTDIR}/ind-steps/common.source" 5 | . "${ENV_ROOTDIR}/config.source" 6 | 7 | require_branch_variable 8 | 9 | scheduled_nodes=${NODES[@]} 10 | [[ -n "$1" ]] && scheduled_nodes="${@}" 11 | 12 | for node in ${scheduled_nodes[@]} ; do 13 | ${ENV_ROOTDIR}/${node}/destroy.sh 14 | ${ENV_ROOTDIR}/${node}/destroy_cache.sh 15 | done 16 | 17 | ( 18 | $starting_step "Destroy simulated global interface" 19 | ip link | grep -q "${GLOBAL_TAP}" 20 | [ "$?" != "0" ] 21 | $skip_step_if_already_done ; set -xe 22 | sudo ip link set "${GLOBAL_TAP}" down 23 | sudo ip link delete dev "${GLOBAL_TAP}" 24 | ) ; prev_cmd_failed 25 | 26 | destroy_bridge "vdc_mngnt" 27 | destroy_bridge "vdc_insts" 28 | 29 | stop_masquerade "${NETWORK}/${PREFIX}" 30 | 31 | ( 32 | $starting_step "Remove cache directory" 33 | [[ ! -d "${CACHE_DIR}/${BRANCH}" ]] 34 | $skip_step_if_already_done; set -xe 35 | rmdir "${CACHE_DIR}/${BRANCH}" 36 | ) ; $prev_cmd_failed 37 | -------------------------------------------------------------------------------- /cmd/openvdc/cmd/reboot.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | 6 | log "github.com/Sirupsen/logrus" 7 | "github.com/axsh/openvdc/api" 8 | "github.com/axsh/openvdc/cmd/openvdc/internal/util" 9 | "github.com/spf13/cobra" 10 | "golang.org/x/net/context" 11 | "google.golang.org/grpc" 12 | ) 13 | 14 | var rebootCmd = &cobra.Command{ 15 | Use: "reboot [Instance ID]", 16 | Short: "Reboots an instance", 17 | Long: "Reboots an instance", 18 | Example: ` 19 | % openvdc reboot i-xxxxxxx 20 | `, 21 | RunE: func(cmd *cobra.Command, args []string) error { 22 | if len(args) != 1 { 23 | log.Fatalf("Please provide an Instance ID.") 24 | } 25 | 26 | instanceID := args[0] 27 | 28 | req := &api.RebootRequest{ 29 | InstanceId: instanceID, 30 | } 31 | return util.RemoteCall(func(conn *grpc.ClientConn) error { 32 | c := api.NewInstanceClient(conn) 33 | res, err := c.Reboot(context.Background(), req) 34 | if err != nil { 35 | log.WithError(err).Fatal("Disconnected abnormaly") 36 | return err 37 | } 38 | fmt.Println(res) 39 | return err 40 | }) 41 | }, 42 | } 43 | -------------------------------------------------------------------------------- /pkg/conf/executor.toml: -------------------------------------------------------------------------------- 1 | [hypervisor] 2 | # driver = "null" 3 | 4 | # ----- lxc ------ 5 | # script-path = "/etc/openvdc/scripts/" 6 | # image-server-uri = "http://127.0.0.1/images" 7 | # cache-path = "/var/cache/lxc/" 8 | 9 | # -----Vmware------ 10 | # esxi-user = "" 11 | # esxi-pass = "" 12 | # esxi-ip = "" 13 | # esxi-datacenter = "ha-datacenter" 14 | # esxi-insecure = true 15 | # esxi-host-sshkey = "" 16 | # esxi-host-name = "" 17 | # esxi-vm-user = "" 18 | # esxi-vm-pass = "" 19 | # esxi-vm-datastore = "" 20 | # esxi-inventory-folder = "" 21 | # esxi-vcenter = false 22 | 23 | [zookeeper] 24 | # endpoint = "zk://localhost/openvdc" 25 | 26 | [bridges] 27 | name = "br0" 28 | type = "linux" 29 | [bridges.linux] 30 | # up-script = "linux-bridge-up.sh.tmpl" 31 | # down-script = "linux-bridge-down.sh.tmpl" 32 | 33 | [bridges.ovs] 34 | # up-script = "ovs-up.sh.tmpl" 35 | # down-script = "ovs-down.sh.tmpl" 36 | 37 | [executor-api] 38 | # listen = "0.0.0.0:19372" 39 | # advertise-ip = "192.168.56.150" 40 | 41 | [console] 42 | 43 | [console.ssh] 44 | # listen = "" 45 | # advertise-ip = "192.168.56.150" 46 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | 3 | VOLUME /data 4 | 5 | RUN ["yum", "install", "-y", "epel-release"] 6 | RUN ["yum", "install", "-y", "rsync", "bridge-utils", "qemu-kvm", "qemu-system-x86", "parted", "sudo", "openssh-clients", "nmap-ncat"] 7 | 8 | RUN groupadd -r axsh && useradd -d /home/axsh -g axsh axsh && mkdir -p /home/axsh/.openvdc 9 | WORKDIR /home/axsh 10 | 11 | COPY ["multibox", "/multibox"] 12 | COPY ["run_tests.sh", "run_tests.sh"] 13 | COPY ["dot_openvdc-config.toml", "/home/axsh/.openvdc/config.toml"] 14 | RUN chown -R axsh /home/axsh/.openvdc 15 | 16 | ARG BRANCH 17 | ARG RELEASE_SUFFIX 18 | ARG REBUILD 19 | 20 | # Set the ARGs to ENV because otherwise they're not visible to the run_tests.sh script 21 | ENV BRANCH=${BRANCH:-master} RELEASE_SUFFIX=${RELEASE_SUFFIX:-current} REBUILD=${REBUILD:-false} 22 | 23 | LABEL "jp.axsh.vendor"="Axsh Co. LTD" \ 24 | "jp.axsh.project"="OpenVDC" \ 25 | "jp.axsh.task"="acceptance test" \ 26 | "jp.axsh.branch"="$BRANCH" \ 27 | "jp.axsh.release_suffix"="$RELEASE_SUFFIX" 28 | 29 | ENTRYPOINT ["./run_tests.sh", "RUN"] 30 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/external_libraries/bashsteps/examples/new/new-duped-substep.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | reportfailed() 4 | { 5 | echo "Script failed...exiting. ($*)" 1>&2 6 | exit 255 7 | } 8 | 9 | export ORGCODEDIR="$(cd "$(dirname $(readlink -f "$0"))" && pwd -P)" || reportfailed 10 | 11 | DATADIR="$ORGCODEDIR" 12 | source "$ORGCODEDIR/simple-defaults-for-bashsteps.source" 13 | 14 | mfff() 15 | { 16 | ( 17 | $starting_step "Make t-fff" 18 | cd "$DATADIR" 19 | [ -f t-fff ] 20 | $skip_step_if_already_done; set -e 21 | date >t-fff 22 | ) ; $prev_cmd_failed 23 | } 24 | 25 | 26 | ( 27 | $starting_group "group 1" 28 | mfff 29 | ( 30 | $starting_step "Make t-ddd" 31 | cd "$DATADIR" 32 | [ -f t-ddd ] 33 | $skip_step_if_already_done; set -e 34 | date >t-ddd 35 | ) ; $prev_cmd_failed 36 | ) ; $prev_cmd_failed 37 | 38 | ( 39 | $starting_group "group 2" 40 | mfff 41 | ( 42 | $starting_step "Make t-eee" 43 | cd "$DATADIR" 44 | [ -f t-eee ] 45 | $skip_step_if_already_done; set -e 46 | date >t-eee 47 | ) ; $prev_cmd_failed 48 | ) ; $prev_cmd_failed 49 | -------------------------------------------------------------------------------- /handlers/none/none.go: -------------------------------------------------------------------------------- 1 | package none 2 | 3 | import ( 4 | "encoding/json" 5 | "io" 6 | 7 | "github.com/axsh/openvdc/handlers" 8 | "github.com/axsh/openvdc/model" 9 | ) 10 | 11 | func init() { 12 | handlers.RegisterHandler(&NoneHandler{}) 13 | } 14 | 15 | type NoneHandler struct { 16 | } 17 | 18 | func (h *NoneHandler) ParseTemplate(in json.RawMessage) (model.ResourceTemplate, error) { 19 | tmpl := &model.NoneTemplate{} 20 | if err := json.Unmarshal(in, tmpl); err != nil { 21 | return nil, err 22 | } 23 | return tmpl, nil 24 | } 25 | 26 | func (h *NoneHandler) SetTemplateItem(t *model.Template, m model.ResourceTemplate) { 27 | t.Item = &model.Template_None{ 28 | None: m.(*model.NoneTemplate), 29 | } 30 | } 31 | 32 | func (h *NoneHandler) MergeArgs(dst model.ResourceTemplate, args []string) error { 33 | _, ok := dst.(*model.NoneTemplate) 34 | if !ok { 35 | return handlers.ErrMergeDstType(new(model.NoneTemplate), dst) 36 | } 37 | return nil 38 | } 39 | 40 | func (h *NoneHandler) Usage(out io.Writer) error { 41 | return nil 42 | } 43 | 44 | func (h *NoneHandler) IsSupportAPI(method string) bool { 45 | return false 46 | } 47 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test-esxi/tests/02_cmd_console_test.go: -------------------------------------------------------------------------------- 1 | // +build acceptance 2 | 3 | package tests 4 | 5 | import ( 6 | "strings" 7 | "testing" 8 | "time" 9 | 10 | tests "github.com/axsh/openvdc/ci/citest/acceptance-test/tests" 11 | ) 12 | 13 | func TestEsxiCmdConsole_ShowOption(t *testing.T) { 14 | stdout, _ := tests.RunCmdAndReportFail(t, "openvdc", "run", "centos/7/esxi") 15 | instance_id := strings.TrimSpace(stdout.String()) 16 | tests.WaitInstance(t, 10*time.Minute, instance_id, "RUNNING", []string{"QUEUED", "STARTING"}) 17 | 18 | tests.RunCmdAndReportFail(t, "openvdc", "console", instance_id, "--show") 19 | tests.RunCmdAndReportFail(t, "sh", "-c", strings.Join([]string{"openvdc", "console", instance_id, "ls"}, " ")) 20 | tests.RunCmdAndReportFail(t, "sh", "-c", strings.Join([]string{"openvdc", "console", instance_id, "--", "ls"}, " ")) 21 | tests.RunCmdAndExpectFail(t, "sh", "-c", strings.Join([]string{"openvdc", "console", instance_id, "--", "false"}, " ")) 22 | 23 | tests.RunCmdWithTimeoutAndReportFail(t, 10, 5, "openvdc", "destroy", instance_id) 24 | tests.WaitInstance(t, 10*time.Minute, instance_id, "TERMINATED", nil) 25 | } 26 | -------------------------------------------------------------------------------- /registry/types_test.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import ( 4 | "testing" 5 | 6 | "strings" 7 | 8 | "github.com/axsh/openvdc/model" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | const json1 = ` 13 | { 14 | "$schema": "https://raw.githubusercontent.com/axsh/openvdc/master/schema/v1.json#", 15 | "title": "CentOS7", 16 | "template": { 17 | "type": "vm/lxc", 18 | "lxc_image": { 19 | "download_url": "https://images.linuxcontainers.org/1.0/images/d767cfe9a0df0b2213e28b39b61e8f79cb9b1e745eeed98c22bc5236f277309a/export" 20 | } 21 | } 22 | }` 23 | 24 | func TestParseJSON(t *testing.T) { 25 | assert := assert.New(t) 26 | root, err := parseResourceTemplate(strings.NewReader(json1)) 27 | assert.NoError(err) 28 | assert.NotNil(root) 29 | assert.Equal("CentOS7", root.Title) 30 | assert.IsType(new(model.LxcTemplate), root.Template) 31 | lxc := root.Template.(*model.LxcTemplate) 32 | assert.IsType(new(model.LxcTemplate_Image), lxc.GetLxcImage()) 33 | assert.Equal("https://images.linuxcontainers.org/1.0/images/d767cfe9a0df0b2213e28b39b61e8f79cb9b1e745eeed98c22bc5236f277309a/export", 34 | lxc.GetLxcImage().GetDownloadUrl()) 35 | } 36 | -------------------------------------------------------------------------------- /hypervisor/qemu/qemu_image.go: -------------------------------------------------------------------------------- 1 | package qemu 2 | 3 | import ( 4 | "os" 5 | "os/exec" 6 | 7 | "github.com/pkg/errors" 8 | ) 9 | 10 | type Image struct { 11 | Path string 12 | Format string 13 | Size int 14 | baseImage string 15 | } 16 | 17 | type Drive struct { 18 | Image *Image 19 | If string 20 | } 21 | 22 | func NewImage(path string, format string) *Image { 23 | return &Image{ 24 | Format: format, 25 | Path: path, 26 | } 27 | } 28 | 29 | func (i *Image) SetBaseImage(baseImage string) error { 30 | // todo check for size ? 31 | if _, err := os.Stat(baseImage); err != nil { 32 | return errors.Errorf("File missing: %s", baseImage) 33 | } 34 | i.baseImage = baseImage 35 | return nil 36 | } 37 | 38 | func (i *Image) SetSize(size int) error { 39 | // todo check for base image ? 40 | i.Size = size 41 | return nil 42 | } 43 | 44 | func (i *Image) CreateImage() error { 45 | cmdLine := &cmdLine{args: make([]string, 0)} 46 | cmd := exec.Command("qemu-img", cmdLine.QemuImgCmd(i)...) 47 | if stdout, err := cmd.CombinedOutput(); err != nil { 48 | return errors.Errorf("%s failed with: %s", cmd.Args, stdout) 49 | } 50 | return nil 51 | } 52 | -------------------------------------------------------------------------------- /model/backend/timestamp.go: -------------------------------------------------------------------------------- 1 | package backend 2 | 3 | import ( 4 | "reflect" 5 | "time" 6 | 7 | "github.com/golang/protobuf/proto" 8 | "github.com/golang/protobuf/ptypes" 9 | "github.com/golang/protobuf/ptypes/timestamp" 10 | ) 11 | 12 | type TimestampFilter struct { 13 | Time time.Time 14 | } 15 | 16 | func (f *TimestampFilter) OnCreate(v proto.Message) error { 17 | createdAt, err := ptypes.TimestampProto(f.Time) 18 | if err != nil { 19 | return err 20 | } 21 | setTimestampField(v, "CreatedAt", createdAt) 22 | return nil 23 | } 24 | 25 | func (f *TimestampFilter) OnUpdate(v proto.Message) error { 26 | updatedAt, err := ptypes.TimestampProto(f.Time) 27 | if err != nil { 28 | return err 29 | } 30 | setTimestampField(v, "UpdatedAt", updatedAt) 31 | return nil 32 | } 33 | 34 | func setTimestampField(pb proto.Message, field string, tnow *timestamp.Timestamp) error { 35 | Filter(pb, field, func(v reflect.Value) { 36 | if !v.IsNil() { 37 | return 38 | } 39 | if !(v.Kind() == reflect.Ptr) { 40 | return 41 | } 42 | _, ok := v.Interface().(*timestamp.Timestamp) 43 | if ok { 44 | v.Set(reflect.ValueOf(tnow)) 45 | } 46 | }) 47 | return nil 48 | } 49 | -------------------------------------------------------------------------------- /schema/vm/null.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "description": "OpenVDC Resource Template: vm/null (For testing only)", 4 | "type": "object", 5 | "required": [ 6 | "type" 7 | ], 8 | "properties": { 9 | "_comment": { 10 | "type": "string" 11 | }, 12 | "type": { 13 | "enum": [ 14 | "vm/null" 15 | ] 16 | }, 17 | "min_vcpu": { 18 | "type": "integer", 19 | "default": 1 20 | }, 21 | "min_memory_gb": { 22 | "type": "integer", 23 | "default": 1 24 | }, 25 | "vcpu": { 26 | "type": "integer", 27 | "default": 1 28 | }, 29 | "memory_gb": { 30 | "type": "integer", 31 | "default": 1 32 | }, 33 | "node_groups": { 34 | "type": "array", 35 | "uniqueItems": true, 36 | "items": [ 37 | {"type": "string"} 38 | ] 39 | }, 40 | "crash_stage": { 41 | "type": "string", 42 | "enum": [ 43 | "none", 44 | "start", 45 | "stop", 46 | "create", 47 | "destroy", 48 | "reboot" 49 | ], 50 | "default": "none" 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/tests/force_state_test.go: -------------------------------------------------------------------------------- 1 | // +build acceptance 2 | 3 | package tests 4 | 5 | import ( 6 | "strings" 7 | "testing" 8 | "time" 9 | ) 10 | 11 | func TestForceState(t *testing.T) { 12 | stdout, _ := RunCmdAndReportFail(t, "openvdc", "run", "centos/7/lxc", `{"interfaces":[{"type":"veth"}], "node_groups":["linuxbr"]}`) 13 | instance_id := strings.TrimSpace(stdout.String()) 14 | 15 | WaitInstance(t, 5*time.Minute, instance_id, "RUNNING", []string{"QUEUED", "STARTING"}) 16 | 17 | RunCmdAndReportFail(t, "openvdc", "force-state", instance_id, "stopped") 18 | WaitInstance(t, 1*time.Minute, instance_id, "STOPPED", nil) 19 | 20 | RunCmdAndReportFail(t, "openvdc", "force-state", instance_id, "terminated") 21 | WaitInstance(t, 1*time.Minute, instance_id, "TERMINATED", nil) 22 | 23 | RunCmdAndReportFail(t, "openvdc", "force-state", instance_id, "running") 24 | WaitInstance(t, 1*time.Minute, instance_id, "RUNNING", nil) 25 | 26 | _, _ = RunCmdWithTimeoutAndReportFail(t, 10, 5, "openvdc", "destroy", instance_id) 27 | t.Log("Waiting for instance " + instance_id + " to become TERMINATED...") 28 | WaitInstance(t, 5*time.Minute, instance_id, "TERMINATED", nil) 29 | } 30 | -------------------------------------------------------------------------------- /handlers/vm/qemu/qemu_test.go: -------------------------------------------------------------------------------- 1 | package qemu 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "github.com/axsh/openvdc/handlers" 8 | "github.com/axsh/openvdc/model" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestResourceName(t *testing.T) { 13 | assert := assert.New(t) 14 | assert.Equal("vm/qemu", handlers.ResourceName(&QemuHandler{})) 15 | } 16 | 17 | func TestTypes(t *testing.T) { 18 | assert := assert.New(t) 19 | assert.Implements((*handlers.ResourceHandler)(nil), &QemuHandler{}) 20 | assert.Implements((*handlers.CLIHandler)(nil), &QemuHandler{}) 21 | } 22 | 23 | const jsonQemuImage = `{ 24 | "type": "vm/qemu", 25 | "qemu_image": { 26 | "download_url": "http://example.com/", 27 | "format": "raw" 28 | } 29 | }` 30 | 31 | func TestQemuHandler_ParseTemplate(t *testing.T) { 32 | assert := assert.New(t) 33 | h := &QemuHandler{} 34 | m, err := h.ParseTemplate(bytes.NewBufferString(jsonQemuImage).Bytes()) 35 | assert.NoError(err) 36 | assert.IsType((*model.QemuTemplate)(nil), m) 37 | modelqemu := m.(*model.QemuTemplate) 38 | assert.NotNil(modelqemu.GetQemuImage()) 39 | assert.Equal(modelqemu.GetQemuImage().GetDownloadUrl(), "http://example.com/") 40 | assert.Equal(modelqemu.GetQemuImage().GetFormat().String(), "RAW") 41 | } 42 | -------------------------------------------------------------------------------- /handlers/vm/esxi/esxi_test.go: -------------------------------------------------------------------------------- 1 | package esxi 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "github.com/axsh/openvdc/handlers" 8 | "github.com/axsh/openvdc/model" 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestResourceName(t *testing.T) { 13 | assert := assert.New(t) 14 | assert.Equal("vm/esxi", handlers.ResourceName(&EsxiHandler{})) 15 | } 16 | 17 | func TestTypes(t *testing.T) { 18 | assert := assert.New(t) 19 | assert.Implements((*handlers.ResourceHandler)(nil), &EsxiHandler{}) 20 | assert.Implements((*handlers.CLIHandler)(nil), &EsxiHandler{}) 21 | } 22 | 23 | const jsonEsxiImage = `{ 24 | "type": "vm/esxi", 25 | "esxi_image": { 26 | "name": "sample", 27 | "datastore": "datastore" 28 | } 29 | }` 30 | 31 | func TestEsxiHandler_ParseTemplate(t *testing.T) { 32 | assert := assert.New(t) 33 | h := &EsxiHandler{} 34 | m, err := h.ParseTemplate(bytes.NewBufferString(jsonEsxiImage).Bytes()) 35 | assert.NoError(err) 36 | assert.IsType((*model.EsxiTemplate)(nil), m) 37 | modelesxi := m.(*model.EsxiTemplate) 38 | assert.NotNil(modelesxi.GetEsxiImage()) 39 | 40 | assert.Equal(modelesxi.GetEsxiImage().GetName(), "sample") 41 | assert.Equal(modelesxi.GetEsxiImage().GetDatastore(), "datastore") 42 | } 43 | -------------------------------------------------------------------------------- /docs/resource_template.md: -------------------------------------------------------------------------------- 1 | # Resource Template 2 | 3 | The resource template is a definition of datacenter resource. 4 | 5 | Following is a LXC template as basic example: 6 | 7 | ```json 8 | % cat ./templates/centos/7/lxc.json 9 | { 10 | "title": "CentOS7", 11 | "template": { 12 | "type": "vm/lxc", 13 | "lxc_image": { 14 | "download_url": "https://images.linuxcontainers.org/1.0/images/d767cfe9a0df0b2213e28b39b61e8f79cb9b1e745eeed98c22bc5236f277309a/export" 15 | } 16 | } 17 | } 18 | ``` 19 | 20 | You can check the syntax. 21 | 22 | ```bash 23 | % openvdc template validate ./templates/centos/7/lxc.json 24 | ``` 25 | 26 | Show details about the template. 27 | 28 | ```bash 29 | % openvdc template show ./templates/centos/7/lxc.json 30 | lxc_image: < 31 | download_url: "https://images.linuxcontainers.org/1.0/images/d767cfe9a0df0b2213e28b39b61e8f79cb9b1e745eeed98c22bc5236f277309a/export" 32 | > 33 | ``` 34 | 35 | Overwrite some parameters. 36 | 37 | ```bash 38 | % openvdc template show ./templates/centos/7/lxc.json '{"interfaces":[{"macaddr":"11:11:11:11:11:11"}]}' 39 | lxc_image: < 40 | download_url: "https://images.linuxcontainers.org/1.0/images/d767cfe9a0df0b2213e28b39b61e8f79cb9b1e745eeed98c22bc5236f277309a/export" 41 | > 42 | interfaces: < 43 | macaddr: "11:11:11:11:11:11" 44 | > 45 | ``` 46 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/external_libraries/bashsteps/examples/new/with-temporary-state.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | reportfailed() 4 | { 5 | echo "Script failed...exiting. ($*)" 1>&2 6 | exit 255 7 | } 8 | 9 | export ORGCODEDIR="$(cd "$(dirname $(readlink -f "$0"))" && pwd -P)" || reportfailed 10 | 11 | DATADIR="$ORGCODEDIR" 12 | source "$ORGCODEDIR/simple-defaults-for-bashsteps.source" 13 | 14 | ( 15 | $starting_group "get hello world binary" 16 | [ -x "$DATADIR/hw" ] 17 | $skip_group_if_unnecessary 18 | ( 19 | $starting_step "output source" 20 | cd "$DATADIR" 21 | [ -f hw.c ] 22 | $skip_step_if_already_done; set -e 23 | cat >hw.c <<'EOF' 24 | #include 25 | int main() { printf("hw\n") ; } 26 | EOF 27 | ) ; $prev_cmd_failed 28 | 29 | ( 30 | $starting_step "compile source" 31 | cd "$DATADIR" 32 | [ -x hw ] 33 | $skip_step_if_already_done; set -e 34 | gcc -o hw hw.c 35 | ) ; $prev_cmd_failed 36 | 37 | ( 38 | $starting_step "remove source" 39 | cd "$DATADIR" 40 | [ -x hw.c ] 41 | $skip_step_if_already_done; set -e 42 | rm hw.c 43 | ) 44 | ) ; $prev_cmd_failed 45 | ( 46 | $starting_step "run binary" 47 | [ -f "$DATADIR/result" ] 48 | $skip_step_if_already_done; set -e 49 | "$DATADIR/hw" | tee "$DATADIR/result" 50 | ) ; $prev_cmd_failed 51 | -------------------------------------------------------------------------------- /hypervisor/esxi/esxi_test.go: -------------------------------------------------------------------------------- 1 | package esxi 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "testing" 7 | 8 | "github.com/axsh/openvdc/hypervisor" 9 | "github.com/axsh/openvdc/model" 10 | "github.com/stretchr/testify/assert" 11 | ) 12 | 13 | func TestProviderRegistration(t *testing.T) { 14 | assert := assert.New(t) 15 | p, _ := hypervisor.FindProvider("esxi") 16 | assert.NotNil(p, "Check if esxi provider is registered.") 17 | assert.Equal("esxi", p.Name()) 18 | assert.Implements((*hypervisor.HypervisorProvider)(nil), p) 19 | } 20 | 21 | func TestEsxiHypervisorProvider_CreateDriver(t *testing.T) { 22 | assert := assert.New(t) 23 | p, _ := hypervisor.FindProvider("esxi") 24 | 25 | d, err := p.CreateDriver(&model.Instance{Id: "i-xxxxx"}, &model.EsxiTemplate{}) 26 | assert.NoError(err) 27 | assert.Implements((*hypervisor.HypervisorDriver)(nil), d) 28 | _, err = p.CreateDriver(&model.Instance{Id: "i-xxxxx"}, nil) 29 | assert.Error(err, "ESXIHypvisorProvider.CreateDriver should fail if not with *model.EsxiTemplate") 30 | } 31 | 32 | func TestCaptureStdout(t *testing.T) { 33 | assert := assert.New(t) 34 | stdout, err := captureStdout(func() error { 35 | fmt.Fprint(os.Stdout, "sample output") 36 | return nil 37 | }) 38 | fmt.Println(stdout) 39 | assert.NoError(err) 40 | assert.Equal("sample output", string(stdout)) 41 | } 42 | -------------------------------------------------------------------------------- /cmd/openvdc/cmd/destroy.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | log "github.com/Sirupsen/logrus" 5 | "github.com/axsh/openvdc/cmd/openvdc/internal/util" 6 | 7 | "github.com/axsh/openvdc/api" 8 | "github.com/spf13/cobra" 9 | "golang.org/x/net/context" 10 | "google.golang.org/grpc" 11 | ) 12 | 13 | func init() { 14 | destroyCmd.Flags().Bool("force", false, "Force destroy instance, ignoring states") 15 | } 16 | 17 | var destroyCmd = &cobra.Command{ 18 | Use: "destroy [Instance ID] [flags]", 19 | Short: "Destroy an instance", 20 | Long: "Destroy an already existing instance.", 21 | RunE: func(cmd *cobra.Command, args []string) error { 22 | if len(args) < 1 { 23 | log.Fatal("Please provide an instance ID") 24 | } 25 | 26 | instanceID := args[0] 27 | 28 | force, err := cmd.Flags().GetBool("force") 29 | if err != nil { 30 | log.WithError(err).Fatal("Failed getting flag") 31 | } 32 | 33 | req := &api.DestroyRequest{ 34 | InstanceId: instanceID, 35 | Force: force, 36 | } 37 | 38 | return util.RemoteCall(func(conn *grpc.ClientConn) error { 39 | c := api.NewInstanceClient(conn) 40 | 41 | _, err := c.Destroy(context.Background(), req) 42 | if err != nil { 43 | log.WithError(err).Fatal("Disconnected abnormally") 44 | return err 45 | } 46 | 47 | return err 48 | }) 49 | }, 50 | } 51 | -------------------------------------------------------------------------------- /proto/cluster.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "github.com/golang/protobuf/ptypes/timestamp/timestamp.proto"; 4 | 5 | package model; 6 | 7 | option go_package = "github.com/axsh/openvdc/model"; 8 | 9 | message Console { 10 | enum Transport { 11 | SSH = 0; 12 | } 13 | Transport type = 1; 14 | string bind_addr = 2 [json_name="bind_addr"]; 15 | } 16 | 17 | message ExecutorNode { 18 | string id = 1; 19 | google.protobuf.Timestamp created_at = 2 [json_name="created_at"]; 20 | 21 | Console console = 3; 22 | string grpc_addr = 4 [json_name="grpc_addr"]; 23 | NodeState last_state = 5 [json_name="last_state"]; 24 | } 25 | 26 | message SchedulerNode { 27 | string id = 1; 28 | google.protobuf.Timestamp created_at = 2 [json_name="created_at"]; 29 | } 30 | 31 | message AgentNode { 32 | string agent_mesos_id = 1; 33 | string agent_id = 2; 34 | google.protobuf.Timestamp created_at = 3; 35 | } 36 | 37 | message CrashedNode { 38 | string uuid = 1; 39 | string agent_id = 2; 40 | string agent_mesos_id = 3; 41 | bool reconnected = 4; 42 | google.protobuf.Timestamp created_at = 5; 43 | google.protobuf.Timestamp reconnected_at = 6; 44 | } 45 | 46 | message NodeState { 47 | enum State { 48 | REGISTERED = 0; 49 | } 50 | State state = 1; 51 | google.protobuf.Timestamp created_at = 2 [json_name="created_at"]; 52 | } 53 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/config.source: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # The nodes to build. If any of these are replaced by a physical device, 3 | # comment it out here. 4 | NODES=( 5 | "10.0.100.10-zookeeper" 6 | "10.0.100.11-mesos-master" 7 | "10.0.100.12-vdc-scheduler" 8 | "10.0.100.13-vdc-executor-null" 9 | "10.0.100.14-vdc-executor-lxc" 10 | "10.0.100.15-vdc-executor-lxc-ovs" 11 | "10.0.100.16-vdc-executor-qemu" 12 | "10.0.100.17-vdc-executor-qemu-ovs" 13 | ) 14 | 15 | NETWORK="10.0.100.0" 16 | GATEWAY="10.0.100.1" 17 | PREFIX="24" 18 | BOXES=( 19 | "minimal-7.3.1611-x86_64.kvm.tar.gz" 20 | ) 21 | 22 | GW_INSTS="172.16.10.1" 23 | PREFIX_INSTS="24" 24 | 25 | GLOBAL_TAP="globaltap" 26 | GLOBAL_IP="10.16.90.199/24" 27 | GLOBAL_MAC="00:11:11:11:11:11" 28 | 29 | 30 | ZK_NODES=( 31 | "10.0.100.10" 32 | "10.0.100.11" 33 | "10.0.100.12" 34 | ) 35 | 36 | LXC_IMAGES=( 37 | "centos;7;amd64" 38 | ) 39 | 40 | QEMU_IMAGES=( 41 | "https://ci.openvdc.org/img/centos7.qcow2" 42 | ) 43 | 44 | # When a branch is built for the first time it will copy the cache from this branch 45 | # unless the REBUILD flag is set 46 | BASE_BRANCH="${BASE_BRANCH:-master}" 47 | 48 | BOXES_DIR="/data/openvdc-ci/boxes" 49 | CACHE_DIR="/data/openvdc-ci/branches" 50 | IMG_DIR="/data/openvdc-ci/images" 51 | 52 | # Used for hardare accelerated virtualization 53 | # intel: vmx, amd: svm 54 | ACCEL_TYPE="vmx" 55 | -------------------------------------------------------------------------------- /model/backend/proto_cluster.go: -------------------------------------------------------------------------------- 1 | package backend 2 | 3 | import ( 4 | "github.com/golang/protobuf/proto" 5 | "github.com/pkg/errors" 6 | ) 7 | 8 | // ProtoClusterBackend is the ClusterBackend interface wrapper 9 | // that accepts proto.Message instead of raw bytes. 10 | type ProtoClusterBackend interface { 11 | Backend() ClusterBackend 12 | Register(nodeID string, value proto.Message) error 13 | Find(nodeID string, value proto.Message) error 14 | Unregister(nodeID string) error 15 | } 16 | 17 | type ProtoClusterWrapper struct { 18 | backend ClusterBackend 19 | } 20 | 21 | func NewProtoClusterWrapper(bk ClusterBackend) ProtoClusterBackend { 22 | return &ProtoClusterWrapper{bk} 23 | } 24 | 25 | func (p *ProtoClusterWrapper) Backend() ClusterBackend { 26 | return p.backend 27 | } 28 | 29 | func (p *ProtoClusterWrapper) Register(key string, value proto.Message) error { 30 | buf, err := proto.Marshal(value) 31 | if err != nil { 32 | return errors.Wrapf(err, "Failed to marshall %T", value) 33 | } 34 | 35 | return p.backend.Register(key, buf) 36 | } 37 | 38 | func (p *ProtoClusterWrapper) Find(nodeID string, v proto.Message) error { 39 | buf, err := p.backend.Find(nodeID) 40 | if err != nil { 41 | return errors.Wrapf(err, "Find to %s", nodeID) 42 | } 43 | return proto.Unmarshal(buf, v) 44 | } 45 | 46 | func (p *ProtoClusterWrapper) Unregister(nodeID string) error { 47 | return p.backend.UnRegister(nodeID) 48 | } 49 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.10-zookeeper/guestroot/etc/zookeeper/conf/zoo.cfg: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. 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 | maxClientCnxns=50 17 | # The number of milliseconds of each tick 18 | tickTime=2000 19 | # The number of ticks that the initial 20 | # synchronization phase can take 21 | initLimit=10 22 | # The number of ticks that can pass between 23 | # sending a request and getting an acknowledgement 24 | syncLimit=5 25 | # the directory where the snapshot is stored. 26 | dataDir=/var/lib/zookeeper 27 | # the port at which the clients will connect 28 | clientPort=2181 29 | server.1=0.0.0.0:2888:3888 30 | server.2=10.0.100.11:2888:3888 31 | server.3=10.0.100.12:2888:3888 32 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.11-mesos-master/guestroot/etc/zookeeper/conf/zoo.cfg: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. 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 | maxClientCnxns=50 17 | # The number of milliseconds of each tick 18 | tickTime=2000 19 | # The number of ticks that the initial 20 | # synchronization phase can take 21 | initLimit=10 22 | # The number of ticks that can pass between 23 | # sending a request and getting an acknowledgement 24 | syncLimit=5 25 | # the directory where the snapshot is stored. 26 | dataDir=/var/lib/zookeeper 27 | # the port at which the clients will connect 28 | clientPort=2181 29 | server.1=10.0.100.10:2888:3888 30 | server.2=0.0.0.0:2888:3888 31 | server.3=10.0.100.12:2888:3888 32 | -------------------------------------------------------------------------------- /cmd/openvdc/cmd/log.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | 7 | log "github.com/Sirupsen/logrus" 8 | "github.com/axsh/openvdc/api" 9 | "github.com/axsh/openvdc/cmd/openvdc/internal/util" 10 | "github.com/spf13/cobra" 11 | "golang.org/x/net/context" 12 | "google.golang.org/grpc" 13 | ) 14 | 15 | var logCmd = &cobra.Command{ 16 | Use: "log [Instance ID]", 17 | Short: "Print logs of an instance", 18 | Long: "Print logs of an instance", 19 | Example: ` 20 | % openvdc log i-xxxxxxx 21 | `, 22 | RunE: func(cmd *cobra.Command, args []string) error { 23 | if len(args) != 1 { 24 | log.Fatalf("Please provide an Instance ID.") 25 | } 26 | instanceID := args[0] 27 | req := &api.InstanceLogRequest{ 28 | Target: &api.InstanceIDRequest{ 29 | Key: &api.InstanceIDRequest_ID{ 30 | ID: instanceID, 31 | }, 32 | }, 33 | } 34 | return util.RemoteCall(func(conn *grpc.ClientConn) error { 35 | c := api.NewInstanceClient(conn) 36 | stream, err := c.Log(context.Background(), req) 37 | if err != nil { 38 | log.WithError(err).Fatal("Disconnected abnormaly") 39 | return err 40 | } 41 | 42 | for { 43 | l, err := stream.Recv() 44 | if err != nil { 45 | if err == io.EOF { 46 | break 47 | } else { 48 | log.WithError(err).Fatal("Error streaming log") 49 | } 50 | } 51 | for _, l := range l.Line { 52 | fmt.Println(l) 53 | } 54 | } 55 | return nil 56 | }) 57 | }, 58 | } 59 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/10.0.100.12-vdc-scheduler/guestroot/etc/zookeeper/conf/zoo.cfg: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. 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 | maxClientCnxns=50 17 | # The number of milliseconds of each tick 18 | tickTime=2000 19 | # The number of ticks that the initial 20 | # synchronization phase can take 21 | initLimit=10 22 | # The number of ticks that can pass between 23 | # sending a request and getting an acknowledgement 24 | syncLimit=5 25 | # the directory where the snapshot is stored. 26 | dataDir=/var/lib/zookeeper 27 | # the port at which the clients will connect 28 | clientPort=2181 29 | server.1=10.0.100.10:2888:3888 30 | server.2=10.0.100.11:2888:3888 31 | server.3=0.0.0.0:2888:3888 32 | -------------------------------------------------------------------------------- /cmd/qemu-ifdown/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "os/exec" 6 | 7 | log "github.com/Sirupsen/logrus" 8 | "github.com/spf13/viper" 9 | ) 10 | 11 | var DefaultConfPath string 12 | 13 | func runCmd(cmd string, args []string) { 14 | c := exec.Command(cmd, args...) 15 | if err := c.Run(); err != nil { 16 | log.WithFields(log.Fields{ 17 | "cmd": cmd, 18 | "args": args, 19 | }).Fatal("Failed to execute command") 20 | } 21 | } 22 | 23 | func initConfig() error { 24 | viper.SetDefault("bridges.type", "linux") 25 | viper.SetDefault("bridges.name", "br0") 26 | viper.SetConfigFile(DefaultConfPath) 27 | viper.SetConfigType("toml") 28 | viper.AutomaticEnv() 29 | err := viper.ReadInConfig() 30 | if err != nil { 31 | if viper.ConfigFileUsed() == DefaultConfPath && os.IsNotExist(err) { 32 | // Ignore default conf file does not exist. 33 | return nil 34 | } 35 | return err 36 | } 37 | return nil 38 | } 39 | 40 | func main() { 41 | if err := initConfig(); err != nil { 42 | log.WithError(err).Fatalf("Failed to load config %s", viper.ConfigFileUsed()) 43 | } 44 | config := viper.GetViper() 45 | ifname := os.Args[1] 46 | 47 | switch config.GetString("bridges.type") { 48 | case "linux": 49 | runCmd("ip", []string{"link", "set", "dev", ifname, "nomaster"}) 50 | case "ovs": 51 | runCmd("ovs-vsctl", []string{"del-port", config.GetString("bridges.name"), ifname}) 52 | default: 53 | log.Fatalf("Unknown bridge type") 54 | } 55 | runCmd("ip", []string{"link", "set", ifname, "down"}) 56 | } 57 | -------------------------------------------------------------------------------- /ci/garbage_collection/docker_cleanups/docker_garbage_collection.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | . ../prune_branches.sh 6 | 7 | time_limit=${TIME_LIMIT:-14} ## Days. Set this to give the "deadline". 8 | ## All branches older than this a removed. 9 | 10 | function docker_image_date { 11 | image=${1?"No image passed to docker_image_date!"} 12 | 13 | creation_date=$(sudo docker inspect --format='{{.Created}}' --type=image ${image}) 14 | 15 | ## The date is in the format: yyyy-mm-ddThh:mm:ss.xxxx 16 | ## We want: yyyymmdd 17 | creation_date=${creation_date%T*} 18 | 19 | echo ${creation_date//-/} ## Remove the '-' between yyyy & mm, mm & dd 20 | } 21 | 22 | function remove_images { 23 | local repo_prefix="$1" 24 | 25 | cutoff_date=$(get_cutoff_date ${time_limit}) ## Images older than this are removed 26 | 27 | ## Remove all directories whose branch (on git) no longer exists 28 | ## or which has not beenm pushed to within $time_limit days. 29 | for docker_image in $(sudo docker images -q ${repo_prefix}* | sort -u); do 30 | image_date=$(docker_image_date ${docker_image}) 31 | 32 | if [[ "${image_date}" < "${cutoff_date}" ]]; then 33 | echo "docker rmi \"${docker_image}\"" 34 | sudo docker rmi "${docker_image}" 35 | fi 36 | 37 | done 38 | } 39 | 40 | #-------------------------------------------------------------------------# 41 | # main() 42 | 43 | remove_images "citest" 44 | remove_images "unit-tests.citest" 45 | remove_images "openvdc/acceptance-test" 46 | -------------------------------------------------------------------------------- /cmd/qemu-ifup/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "os/exec" 6 | 7 | log "github.com/Sirupsen/logrus" 8 | "github.com/spf13/viper" 9 | ) 10 | 11 | var DefaultConfPath string 12 | 13 | func runCmd(cmd string, args []string) { 14 | c := exec.Command(cmd, args...) 15 | if err := c.Run(); err != nil { 16 | log.WithFields(log.Fields{ 17 | "cmd": cmd, 18 | "args": args, 19 | }).Fatal("Failed to execute command") 20 | } 21 | } 22 | 23 | func initConfig() error { 24 | viper.SetDefault("bridges.type", "linux") 25 | viper.SetDefault("bridges.name", "br0") 26 | viper.SetConfigFile(DefaultConfPath) 27 | viper.SetConfigType("toml") 28 | viper.AutomaticEnv() 29 | err := viper.ReadInConfig() 30 | if err != nil { 31 | if viper.ConfigFileUsed() == DefaultConfPath && os.IsNotExist(err) { 32 | // Ignore default conf file does not exist. 33 | return nil 34 | } 35 | return err 36 | } 37 | return nil 38 | } 39 | 40 | func main() { 41 | if err := initConfig(); err != nil { 42 | log.WithError(err).Fatalf("Failed to load config %s", viper.ConfigFileUsed()) 43 | } 44 | config := viper.GetViper() 45 | ifname := os.Args[1] 46 | 47 | switch config.GetString("bridges.type") { 48 | case "linux": 49 | runCmd("ip", []string{"link", "set", "dev", ifname, "master", config.GetString("bridges.name")}) 50 | case "ovs": 51 | runCmd("ovs-vsctl", []string{"add-port", config.GetString("bridges.name"), ifname}) 52 | default: 53 | log.Fatalf("Unknown bridge type") 54 | } 55 | runCmd("ip", []string{"link", "set", ifname, "up"}) 56 | } 57 | -------------------------------------------------------------------------------- /api/executor/server.go: -------------------------------------------------------------------------------- 1 | package executor 2 | 3 | import ( 4 | "net" 5 | 6 | "github.com/axsh/openvdc/model" 7 | "github.com/axsh/openvdc/model/backend" 8 | "golang.org/x/net/context" 9 | "google.golang.org/grpc" 10 | ) 11 | 12 | //go:generate protoc -I../../proto -I${GOPATH}/src --go_out=plugins=grpc:${GOPATH}/src ../../proto/executor.proto 13 | 14 | type ExecutorAPIServer struct { 15 | server *grpc.Server 16 | listener net.Listener 17 | modelStoreAddr backend.ConnectionAddress 18 | } 19 | 20 | func NewExecutorAPIServer(modelAddr backend.ConnectionAddress, ctx context.Context) *ExecutorAPIServer { 21 | // Assert the ctx has "cluster.backend" key 22 | model.GetClusterBackendCtx(ctx) 23 | 24 | sopts := []grpc.ServerOption{ 25 | // Setup request middleware for the model.backend database connection. 26 | grpc.UnaryInterceptor(model.GrpcInterceptor(modelAddr, ctx)), 27 | grpc.StreamInterceptor(model.GrpcStreamInterceptor(modelAddr, ctx)), 28 | } 29 | s := &ExecutorAPIServer{ 30 | server: grpc.NewServer(sopts...), 31 | modelStoreAddr: modelAddr, 32 | } 33 | 34 | return s 35 | } 36 | 37 | func (s *ExecutorAPIServer) Serve(listen net.Listener) error { 38 | s.listener = listen 39 | return s.server.Serve(listen) 40 | } 41 | 42 | func (s *ExecutorAPIServer) Stop() { 43 | s.server.Stop() 44 | s.listener = nil 45 | } 46 | 47 | func (s *ExecutorAPIServer) GracefulStop() { 48 | s.server.GracefulStop() 49 | s.listener = nil 50 | } 51 | 52 | func (s *ExecutorAPIServer) Listener() net.Listener { 53 | return s.listener 54 | } 55 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/external_libraries/bashsteps/ind-steps/kvmsteps/vmdir-scripts/kvm-shutdown-via-ssh.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source "$(dirname $(readlink -f "$0"))/../simple-defaults-for-bashsteps.source" 4 | 5 | if [[ "$DATADIR" != /* ]]; then 6 | # Choose directory of symbolic link by default 7 | DATADIR="$LINKCODEDIR" 8 | fi 9 | 10 | kvm_is_running() 11 | { 12 | kvmpid="$(cat "$DATADIR/runinfo/kvm.pid" 2>/dev/null)" && 13 | [ -d /proc/"$(< "$DATADIR/runinfo/kvm.pid")" ] 14 | } 15 | 16 | ( 17 | $starting_step 'Send "sudo shutdown -h now" via ssh' 18 | false 19 | $skip_step_if_already_done ; set -e 20 | "$DATADIR/ssh-to-kvm.sh" sudo shutdown -h now 21 | ) ; prev_cmd_failed 22 | 23 | : ${WAITFORSHUTDOWN:=5 5 2 2 2 5 5 10 10 30 60} # set WAITFORSHUTDOWN to "0" to not wait 24 | ( 25 | $starting_step "Wait for KVM to exit" 26 | [ "$WAITFORSHUTDOWN" = "0" ] || ! kvm_is_running 27 | $skip_step_if_already_done 28 | WAITFORSHUTDOWN="${WAITFORSHUTDOWN/[^0-9 ]/}" # make sure its only a list of integers 29 | waitfor="5" 30 | while true; do 31 | kvm_is_running || break # sets $kvmpid 32 | # Note that the "${public_key}" 24 | ) ; prev_cmd_failed 25 | 26 | ( 27 | $starting_step "Install authorized ssh key for ${user} on ${vm_name}" 28 | sudo bash -c "[ -f ${TMP_ROOT}/${user}/.ssh/authorized_keys ]" 29 | $skip_step_if_already_done; set -ex 30 | install_user_key "${ci_user}" 31 | ) ; prev_cmd_failed 32 | 33 | # Quick hack for now. Should be changed in the seed image instead 34 | ( 35 | $starting_step "Disable DNS on sshd" 36 | grep -qw "UseDNS yes" "${TMP_ROOT}/etc/ssh/sshd_config" 37 | $skip_step_if_already_done; set -ex 38 | sudo sed -i 's/UseDNS yes/UseDNS no/g' "${TMP_ROOT}/etc/ssh/sshd_config" 39 | ) ; prev_cmd_failed 40 | -------------------------------------------------------------------------------- /cmd/formatter_test.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "regexp" 7 | "testing" 8 | 9 | "strings" 10 | 11 | "github.com/Sirupsen/logrus" 12 | "github.com/pkg/errors" 13 | ) 14 | 15 | func newLogger(w io.Writer) *logrus.Logger { 16 | log := logrus.New() 17 | log.Formatter = new(LogFormatter) 18 | log.Out = w 19 | return log 20 | } 21 | 22 | func TestLogFomatter(t *testing.T) { 23 | buf := new(bytes.Buffer) 24 | log := newLogger(buf) 25 | 26 | log.Info("test") 27 | ok, err := regexp.Match( 28 | "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} \\[INFO\\] github.com/axsh/openvdc/cmd/formatter_test.go:\\d+ test", 29 | buf.Bytes()) 30 | if err != nil { 31 | t.Error(err) 32 | } 33 | if !ok { 34 | t.Error("Does not match: ", buf.String()) 35 | } 36 | } 37 | 38 | func TestLogFomatter_StackTrace(t *testing.T) { 39 | buf := new(bytes.Buffer) 40 | log := newLogger(buf) 41 | 42 | err := errors.New("err1") 43 | err = errors.WithStack(err) 44 | 45 | log.WithError(err).Error("test") 46 | lines := strings.SplitN(buf.String(), "\n", 3) 47 | ok, err := regexp.MatchString( 48 | "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} \\[ERROR\\] github.com/axsh/openvdc/cmd/formatter_test.go:\\d+ test Error: err1", 49 | lines[0]) 50 | if err != nil { 51 | t.Error(err) 52 | } 53 | if !ok { 54 | t.Error("Does not match log line: ", lines[0]) 55 | } 56 | ok, err = regexp.MatchString( 57 | "^\\s*github\\.com/axsh/openvdc/cmd\\.TestLogFomatter_StackTrace", 58 | lines[2]) 59 | if err != nil { 60 | t.Error(err) 61 | } 62 | if !ok { 63 | t.Error("Does not match stack trace line: ", lines[1]) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /cmd/openvdc/cmd/show.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "os" 5 | "strings" 6 | 7 | log "github.com/Sirupsen/logrus" 8 | "github.com/axsh/openvdc/api" 9 | "github.com/axsh/openvdc/cmd/openvdc/internal/util" 10 | "github.com/golang/protobuf/jsonpb" 11 | "github.com/golang/protobuf/proto" 12 | "github.com/spf13/cobra" 13 | "golang.org/x/net/context" 14 | "google.golang.org/grpc" 15 | ) 16 | 17 | var showCmd = &cobra.Command{ 18 | Use: "show [Resource ID]", 19 | Short: "Show a resource", 20 | Long: `Show a resource.`, 21 | RunE: func(cmd *cobra.Command, args []string) error { 22 | if len(args) != 1 { 23 | log.Fatalf("Please provide a Resource ID.") 24 | } 25 | 26 | type showTargetCb func(conn *grpc.ClientConn) (proto.Message, error) 27 | var showTarget showTargetCb 28 | id := args[0] 29 | if strings.HasPrefix(id, "i-") { 30 | showTarget = func(conn *grpc.ClientConn) (proto.Message, error) { 31 | req := &api.InstanceIDRequest{ 32 | Key: &api.InstanceIDRequest_ID{ 33 | ID: id, 34 | }, 35 | } 36 | 37 | c := api.NewInstanceClient(conn) 38 | return c.Show(context.Background(), req) 39 | } 40 | } else { 41 | log.Fatal("Invalid ID syntax:", id) 42 | } 43 | 44 | return util.RemoteCall(func(conn *grpc.ClientConn) error { 45 | res, err := showTarget(conn) 46 | if err != nil { 47 | log.WithError(err).Fatal("Disconnected abnormaly") 48 | return err 49 | } 50 | if err := (&jsonpb.Marshaler{Indent: " "}).Marshal(os.Stdout, res); err != nil { 51 | log.WithError(err).Fatal("Faild to format to pretty JSON.") 52 | } 53 | return err 54 | }) 55 | }, 56 | } 57 | -------------------------------------------------------------------------------- /model/backend/bolt.go: -------------------------------------------------------------------------------- 1 | package backend 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/boltdb/bolt" 7 | ) 8 | 9 | type Bolt struct { 10 | db *bolt.DB 11 | basePath string 12 | } 13 | 14 | func NewBoltBackend() *Bolt { 15 | return &Bolt{ 16 | basePath: "/openvdc", 17 | } 18 | } 19 | 20 | type BoltDBPath string 21 | 22 | func (BoltDBPath) isConnectionAddress() {} 23 | 24 | func (b BoltDBPath) String() string { return string(b) } 25 | 26 | func (b *Bolt) Connect(dest ConnectionAddress) error { 27 | if b.db != nil { 28 | return ErrConnectionExists 29 | } 30 | path, ok := dest.(BoltDBPath) 31 | if !ok { 32 | return fmt.Errorf("Invalid connection address type: %T", dest) 33 | } 34 | db, err := bolt.Open(path.String(), 0644, nil) 35 | if err != nil { 36 | return err 37 | } 38 | b.db = db 39 | return nil 40 | } 41 | 42 | func (b *Bolt) Close() error { 43 | if b.db == nil { 44 | return ErrConnectionNotReady 45 | } 46 | defer func() { 47 | b.db = nil 48 | }() 49 | return b.db.Close() 50 | } 51 | 52 | func (b *Bolt) Create(key string, value []byte) error { 53 | return nil 54 | } 55 | 56 | func (b *Bolt) Update(key string, value []byte) error { 57 | return nil 58 | } 59 | 60 | func (b *Bolt) CreateWithID(key string, value []byte) (string, error) { 61 | return "", nil 62 | } 63 | 64 | func (b *Bolt) Find(key string) ([]byte, error) { 65 | return nil, nil 66 | } 67 | 68 | func (b *Bolt) Delete(key string) error { 69 | return nil 70 | } 71 | 72 | func (b *Bolt) Keys(parentKey string) (KeyIterator, error) { 73 | return nil, nil 74 | } 75 | 76 | func (b *Bolt) FindLastKey(prefixKey string) (string, error) { 77 | return "", nil 78 | } 79 | -------------------------------------------------------------------------------- /docs/openvnet_integration.md: -------------------------------------------------------------------------------- 1 | ## Install 2 | 3 | ``` 4 | yum install -y http://openvdc.org/openvdc-release.rpm 5 | yum install -y openvdc 6 | yum install -y http://openvnet.org/openvnet.repo 7 | yum install -y openvnet 8 | ``` 9 | 10 | ## Setup 11 | 12 | 13 | ``` 14 | systemctl enable zookeeper 15 | systemctl enable mesos-master 16 | systemctl enable mesos-slave 17 | systemctl enable openvdc-api 18 | systemctl enable openvdc-executor 19 | systemctl start openvdc-api 20 | systemctl start openvdc-executor 21 | systemctl enable mysql-server 22 | systemctl enable vnet-vnmgr 23 | systemctl enable vnet-vna 24 | systemctl enable redis 25 | systemctl enable openvswitch 26 | ``` 27 | 28 | Setup basic network for OpenVNet. 29 | 30 | ``` 31 | vnctl networks add \ 32 | --uuid nw-test1 \ 33 | --display-name testnet1 \ 34 | --ipv4-network 10.100.0.0 \ 35 | --ipv4-prefix 24 \ 36 | --network-mode virtual 37 | vnctl interfaces add \ 38 | --uuid if-inst1 \ 39 | --mode vif \ 40 | --owner-datapath-uuid dp-test1 \ 41 | --mac-address 10:54:ff:00:00:01 \ 42 | --network-uuid nw-test1 \ 43 | --ipv4-address 10.100.0.10 \ 44 | --port-name inst1 45 | ``` 46 | 47 | 48 | ## Start an instance with virtual network 49 | 50 | ``` 51 | % openvdc run centos/7 --bridge[0]=localovs1 --interface[0]=10:54:ff:00:00:01 --ipv4[0]=10.100.0.10/24 --ipv4-gw[0]=10.100.0.1 52 | abdcefg12345678 53 | % openvdc ssh user@abdcefg12345678 54 | % openvdc destroy abdcefg12345678 55 | ``` 56 | 57 | ``` 58 | % openvdc run centos/7 --networkmode=openvnet --bridge[0]=nw-test1 --interface[0]=if-inst1 59 | abdcefg12345678 60 | % openvdc ssh user@abdcefg12345678 61 | % openvdc destroy abdcefg12345678 62 | ``` 63 | -------------------------------------------------------------------------------- /api/executor/executor.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // source: executor.proto 3 | 4 | /* 5 | Package executor is a generated protocol buffer package. 6 | 7 | It is generated from these files: 8 | executor.proto 9 | 10 | It has these top-level messages: 11 | */ 12 | package executor 13 | 14 | import proto "github.com/golang/protobuf/proto" 15 | import fmt "fmt" 16 | import math "math" 17 | import _ "github.com/axsh/openvdc/api" 18 | 19 | // Reference imports to suppress errors if they are not otherwise used. 20 | var _ = proto.Marshal 21 | var _ = fmt.Errorf 22 | var _ = math.Inf 23 | 24 | // This is a compile-time assertion to ensure that this generated file 25 | // is compatible with the proto package it is being compiled against. 26 | // A compilation error at this line likely means your copy of the 27 | // proto package needs to be updated. 28 | const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package 29 | 30 | func init() { proto.RegisterFile("executor.proto", fileDescriptor0) } 31 | 32 | var fileDescriptor0 = []byte{ 33 | // 89 bytes of a gzipped FileDescriptorProto 34 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4b, 0xad, 0x48, 0x4d, 35 | 0x2e, 0x2d, 0xc9, 0x2f, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x80, 0xf1, 0xa5, 0x38, 36 | 0xca, 0x0c, 0x21, 0x62, 0x4e, 0x6a, 0x51, 0x2a, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 37 | 0xf9, 0xb9, 0xfa, 0x89, 0x15, 0xc5, 0x19, 0xfa, 0xf9, 0x05, 0xa9, 0x79, 0x65, 0x29, 0xc9, 0xfa, 38 | 0x89, 0x05, 0x99, 0xfa, 0x30, 0x1d, 0x49, 0x6c, 0x60, 0xe5, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 39 | 0xff, 0xde, 0x02, 0xd5, 0x98, 0x54, 0x00, 0x00, 0x00, 40 | } 41 | -------------------------------------------------------------------------------- /hypervisor/qemu/qemu_device_test.go: -------------------------------------------------------------------------------- 1 | package qemu 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func TestNewDevice(t *testing.T) { 10 | assert := assert.New(t) 11 | device := NewDevice(DevType) 12 | assert.NotNil(device) 13 | assert.Equal("device", device.DeviceType) 14 | assert.NotNil(device.Params) 15 | } 16 | 17 | func TestAddDriver(t *testing.T) { 18 | assert := assert.New(t) 19 | device := NewDevice(DevType) 20 | device.AddDriver("tap") 21 | assert.NotNil(device.Params.Driver) 22 | assert.Equal(device.Params.Driver, "tap") 23 | } 24 | 25 | func TestAddDriverOption(t *testing.T) { 26 | assert := assert.New(t) 27 | device := NewDevice(DevType) 28 | device.AddDriverOption("key", "value") 29 | assert.NotNil(device.Params.Options[0]) 30 | assert.Equal(len(device.Params.Options), 1) 31 | assert.Equal("key", device.Params.Options[0].key) 32 | assert.Equal("value", device.Params.Options[0].value) 33 | } 34 | 35 | func TestLinkToGuestDevice(t *testing.T) { 36 | assert := assert.New(t) 37 | device1 := NewDevice(NetType) 38 | device2 := NewDevice(DevType) 39 | device1.LinkToGuestDevice("dev", device2) 40 | 41 | assert.Equal(device1.Params.Options[0].key, "id") 42 | assert.Equal(device1.Params.Options[0].value, "dev") 43 | 44 | assert.Equal(device2.Params.Options[0].key, "netdev") 45 | assert.Equal(device2.Params.Options[0].value, "dev") 46 | } 47 | 48 | func TestBuildArg(t *testing.T) { 49 | assert := assert.New(t) 50 | device := NewDevice(DevType) 51 | device.AddDriver("driver") 52 | device.AddDriverOption("id", "driver") 53 | args := device.BuildArg() 54 | 55 | assert.NotNil(args) 56 | assert.Equal(len(args), 2) 57 | } 58 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/build_and_run_in_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex -o pipefail 4 | 5 | whereami="$(cd "$(dirname $(readlink -f "$0"))" && pwd -P)" 6 | 7 | BUILD_ENV_PATH=${1:?"ERROR: env file is not given."} 8 | if [[ -n "${BUILD_ENV_PATH}" && ! -f "${BUILD_ENV_PATH}" ]]; then 9 | echo "ERROR: Can't find the file: ${BUILD_ENV_PATH}" >&2 10 | exit 1 11 | fi 12 | 13 | set -a 14 | . ${BUILD_ENV_PATH} 15 | set +a 16 | 17 | DATA_DIR="${DATA_DIR:-/data2}" 18 | CACHE_DIR="/data/openvdc-ci/branches" 19 | 20 | repo_and_tag="openvdc/acceptance-test:${BRANCH}.${RELEASE_SUFFIX}" 21 | 22 | function cleanup() { 23 | if [[ -z "${LEAVE_CONTAINER}" || "${LEAVE_CONTAINER}" == "0" ]]; then 24 | # Clean up containers 25 | # Images don't need to be cleaned up. Removing them immediately would slow down 26 | # builds and they can be garbage collected later. 27 | for CID in $(sudo docker ps -af ancestor="${repo_and_tag}" --format "{{.ID}}"); do 28 | sudo docker rm "${CID}" 29 | done 30 | else 31 | echo "LEAVE_CONTAINER was set and not 0. Skip container cleanup." 32 | fi 33 | 34 | # Give the newly created cache to this user instead of root so we can clean it up 35 | # later without needing sudo 36 | local user=$(/usr/bin/id -run) 37 | sudo chown -R $user:$user "${CACHE_DIR}"/"${BRANCH}" 38 | } 39 | trap "cleanup" EXIT 40 | 41 | sudo docker build -t "${repo_and_tag}" --build-arg BRANCH="${BRANCH}" \ 42 | --build-arg RELEASE_SUFFIX="${RELEASE_SUFFIX}" \ 43 | --build-arg REBUILD="${REBUILD}" \ 44 | "${whereami}" 45 | 46 | sudo docker run --privileged -v "${DATA_DIR}":/data "${repo_and_tag}" 47 | -------------------------------------------------------------------------------- /cmd/openvdc/cmd/force_state.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "strings" 5 | 6 | log "github.com/Sirupsen/logrus" 7 | "github.com/axsh/openvdc/api" 8 | "github.com/axsh/openvdc/cmd/openvdc/internal/util" 9 | "github.com/axsh/openvdc/model" 10 | "github.com/spf13/cobra" 11 | "golang.org/x/net/context" 12 | "google.golang.org/grpc" 13 | ) 14 | 15 | var forceStateCmd = &cobra.Command{ 16 | Use: "force-state [Instance ID] [State]", 17 | Short: "Forcefully sets instance to specified state", 18 | Long: "Forcefully sets instance to specified state", 19 | Example: ` 20 | % openvdc force-state i-0000000001 running 21 | `, 22 | RunE: func(cmd *cobra.Command, args []string) error { 23 | 24 | if len(args) == 0 { 25 | log.Fatalf("Please provide an instance ID.") 26 | } 27 | 28 | if len(args) == 1 { 29 | log.Fatalf("Please provide a desired instance state.") 30 | } 31 | 32 | instanceID := args[0] 33 | 34 | if instanceID == "" { 35 | log.Fatalf("Invalid Instance ID") 36 | } 37 | 38 | state := strings.ToUpper(args[1]) 39 | 40 | goalState, ok := model.InstanceState_State_value[state] 41 | if !ok { 42 | log.Fatalf("Unknown instance state: %s", state) 43 | } 44 | 45 | req := &api.ForceStateRequest{ 46 | InstanceId: instanceID, 47 | State: model.InstanceState_State(goalState), 48 | } 49 | 50 | var res *api.ForceStateReply 51 | 52 | err := util.RemoteCall(func(conn *grpc.ClientConn) error { 53 | c := api.NewInstanceClient(conn) 54 | var err error 55 | res, err = c.ForceState(context.Background(), req) 56 | return err 57 | }) 58 | 59 | if err != nil { 60 | log.WithError(err).Fatal("Disconnected abnormally") 61 | } 62 | 63 | return nil 64 | }, 65 | } 66 | -------------------------------------------------------------------------------- /cmd/openvdc/cmd/template/validate.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import ( 4 | log "github.com/Sirupsen/logrus" 5 | "github.com/axsh/openvdc/cmd/openvdc/internal/util" 6 | "github.com/axsh/openvdc/registry" 7 | "github.com/spf13/cobra" 8 | "github.com/spf13/pflag" 9 | ) 10 | 11 | var ValidateCmd = &cobra.Command{ 12 | Use: "validate [Resource Template Path] [template options]", 13 | Aliases: []string{"test"}, 14 | Short: "Validate resource template", 15 | Long: "Validate resource template", 16 | Example: ` 17 | % openvdc template validate centos/7/lxc 18 | % openvdc template validate ./templates/centos/7/null.json 19 | % openvdc template validate https://raw.githubusercontent.com/axsh/openvdc/master/templates/centos/7/lxc.json 20 | ` + util.ExampleMergeTemplateOptions("openvdc template validate"), 21 | DisableFlagParsing: true, 22 | PreRunE: util.PreRunHelpFlagCheckAndQuit, 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | if len(args) < 1 { 25 | return pflag.ErrHelp 26 | } 27 | templateSlug := args[0] 28 | 29 | finder, err := util.TemplateFinder(templateSlug) 30 | if err != nil { 31 | log.WithError(err).Fatal("Failed util.TemplateFinder") 32 | } 33 | buf, err := finder.LoadRaw(templateSlug) 34 | if err != nil { 35 | log.WithError(err).Fatal("Failed finder.LoadRaw") 36 | } 37 | if err, ok := registry.ValidateTemplate(buf).(*registry.ErrInvalidTemplate); ok && err != nil { 38 | log.Fatal(err.Errors) 39 | } 40 | 41 | if len(args) > 1 { 42 | rt, err := util.FetchTemplate(templateSlug) 43 | if err != nil { 44 | log.WithError(err).Fatal("util.FetchTemplate") 45 | } 46 | util.MergeTemplateParams(rt, args[1:]) 47 | } 48 | return nil 49 | }, 50 | } 51 | -------------------------------------------------------------------------------- /docs/computing_resources.md: -------------------------------------------------------------------------------- 1 | # Computing resources 2 | 3 | OpenVDC uses the mesos frameworks resource handling to keep track of available 4 | cpu/memory on each executor. By default the values are fetched from the 5 | physical resources available on the host running the executor. 6 | 7 | Depending on the hypervisor driver being used, we need to manually define the 8 | resources available. 9 | 10 | * LXC are simple containers and does not fully virtualize memory/cpu. 11 | Resource configuration is not required unless there is a reason to restrict the 12 | resources offered. 13 | 14 | * Qemu assigns virtual cpu cores to instances booted. Here we can overwrite the 15 | default cpus value to a larger number since we are not using physical cores for 16 | our instances. Memory is calculated based on the available memory when the agent 17 | is started and should be left alone as it is a physical resource. 18 | 19 | * ESXi requires the executor to run on a remote host. In this case all computing 20 | resources needs to be set manually as the mesos agent is only able to fetch local 21 | resources. Like with qemu cpus are virtual resources and can be overwritten to 22 | fit requirements. Memory should be set to match the available memory on the 23 | ESXi host. 24 | 25 | 26 | To overwrite the default values create `/etc/mesos-slave/resources` before 27 | starting the mesos-slave agent 28 | 29 | Following is a basic example 30 | 31 | ``` 32 | [ 33 | { 34 | "name": "cpus", 35 | "type": "SCALAR", 36 | "scalar": { 37 | "value": 20 38 | } 39 | }, 40 | { 41 | "name": "mem", 42 | "type": "SCALAR", 43 | "scalar": { 44 | "value": 20480 45 | } 46 | } 47 | ] 48 | ``` 49 | 50 | reference http://mesos.apache.org/documentation/latest/attributes-resources/ 51 | -------------------------------------------------------------------------------- /ci/garbage_collection/repo_cleanups/rpm_garbage_collection.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | . ../garbage_collection_misc.sh 6 | . ../prune_branches.sh 7 | 8 | time_limit=14 ## Days. Set this to give the "deadline". 9 | ## All branches older than this a removed. 10 | 11 | rpm_base_dir=/var/www/html/openvdc-repos 12 | 13 | ## Remove all directories whose branch (on git) no longer exists 14 | ## or which has not beenm pushed to within $time_limit days. 15 | for directory in $(TIME_LIMIT=${time_limit} dirs_to_prune ${rpm_base_dir}); do 16 | remove_dir ${rpm_base_dir}/${directory} 17 | done 18 | 19 | ## Now delete "old" (> ${time_limit} days) rpm's from the master directory 20 | 21 | here=$PWD 22 | cd ${rpm_base_dir}/master 23 | 24 | nrepos=$(ls -1 . | wc -l) 25 | if [[ ${nrepos} -lt 2 ]]; then 26 | echo "Something is wrong. The master directory contains one or less repos. Quitting." 27 | exit 1 28 | fi 29 | 30 | current=$(readlink current) 31 | if [[ -z ${current} ]]; then 32 | echo "No 'current' symlink in master! " 33 | exit 1 # There is no "current" symlink. Don't remove anything! 34 | fi 35 | echo "'current' rpm repo is ${current}" 36 | 37 | readlink current 38 | current=${current##*\/} 39 | 40 | cutoff_date=$(get_cutoff_date) 41 | 42 | echo "Checking for stale rpm repos under master..." 43 | for directory in $(ls -d 2*); do 44 | dr=${directory} 45 | rpmdate=${dr:0:8} # yyyymmddgitxxxx is the rpm repo directory format 46 | 47 | if [[ "${dr}" = "${current}" ]]; then 48 | continue 49 | fi 50 | 51 | if [[ "${rpmdate}" < "${cutoff_date}" ]]; then 52 | full_dir_name=${rpm_base_dir}/master/${dr} 53 | remove_dir ${full_dir_name} 54 | fi 55 | 56 | done 57 | 58 | exit 0 ## Explicit notice: We are done. 59 | -------------------------------------------------------------------------------- /ci/citest/unit-tests/unit-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex -o pipefail 4 | SCRIPT_DIR="$(cd "$(dirname $(readlink -f "$0"))" && pwd -P)" 5 | 6 | CID= 7 | docker_rm() { 8 | if [[ -z "${CID}" ]]; then 9 | return 0 10 | fi 11 | if [[ -n "$LEAVE_CONTAINER" ]]; then 12 | if [[ "${LEAVE_CONTAINER}" != "0" ]]; then 13 | echo "Skip to clean container: ${CID}" 14 | return 0 15 | fi 16 | fi 17 | docker rm -f "${CID}" 18 | } 19 | trap 'docker_rm' EXIT 20 | 21 | BUILD_ENV_PATH=${1:?"ERROR: env file is not given."} 22 | if [[ -n "${BUILD_ENV_PATH}" && ! -f "${BUILD_ENV_PATH}" ]]; then 23 | echo "ERROR: Can't find the file: ${BUILD_ENV_PATH}" >&2 24 | exit 1 25 | fi 26 | 27 | set -a 28 | . ${BUILD_ENV_PATH} 29 | set +a 30 | 31 | if [[ -n "$JENKINS_HOME" ]]; then 32 | # openvdc-axsh/branch1/el7 33 | img_tag=$(echo "unit-tests.${JOB_NAME}/${BUILD_OS}" | tr '/' '.') 34 | else 35 | img_tag="unit-tests.openvdc.$(git rev-parse --abbrev-ref HEAD).${BUILD_OS}" 36 | fi 37 | # Docker 1.10 fails with uppercase image tag name. need letter case translation. 38 | # https://github.com/docker/docker/issues/20056 39 | img_tag="${img_tag,,}" 40 | 41 | docker build -t "${img_tag}" -f "${SCRIPT_DIR}/${BUILD_OS}-unit-tests.Dockerfile" . 42 | CID=$(docker run --add-host="devrepo:${IPV4_DEVREPO:-192.168.56.60}" -d ${BUILD_ENV_PATH:+--env-file $BUILD_ENV_PATH} "${img_tag}") 43 | 44 | 45 | docker cp . "${CID}:/var/tmp/go/src/github.com/axsh/openvdc" 46 | 47 | ## Run unit tests 48 | docker exec $CID /bin/bash -c "/usr/bin/env" 49 | docker exec $CID /bin/bash -c "cd /var/tmp/go/src/github.com/axsh/openvdc; govendor sync" 50 | docker exec $CID /bin/bash -c 'cd /var/tmp/go/src/github.com/axsh/openvdc; ZK=127.0.0.1 GITHUB_DEFAULT_REF=${GIT_BRANCH} go test $(go list ./... | grep -v /vendor/)' 51 | -------------------------------------------------------------------------------- /hypervisor/qemu/qemu_cmd.go: -------------------------------------------------------------------------------- 1 | package qemu 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | type cmdLine struct { 9 | args []string 10 | } 11 | 12 | func (c *cmdLine) appendArgs(args ...string) { 13 | for _, arg := range args { 14 | c.args = append(c.args, arg) 15 | } 16 | } 17 | 18 | func (cmd *cmdLine) QemuBootCmd(m *Machine) []string { 19 | cmd.appendArgs("-smp", strconv.Itoa(m.Cores), "-m", strconv.FormatUint(m.Memory, 10)) 20 | if m.Kvm { 21 | cmd.appendArgs("-enable-kvm") 22 | } 23 | if len(m.SerialSocketPath) > 0 { 24 | cmd.appendArgs("-serial", fmt.Sprintf("unix:%s,server,nowait", m.SerialSocketPath)) 25 | } 26 | if len(m.MonitorSocketPath) > 0 { 27 | cmd.appendArgs("-monitor", fmt.Sprintf("unix:%s,server,nowait", m.MonitorSocketPath)) 28 | } 29 | if len(m.Vnc) > 0 { 30 | cmd.appendArgs("-vnc", m.Vnc) 31 | } 32 | if len(m.Pidfile) > 0 { 33 | cmd.appendArgs("-pidfile", m.Pidfile) 34 | } 35 | for _, d := range m.Drives { 36 | drive := fmt.Sprintf("file=%s,format=%s", d.Image.Path, d.Image.Format) 37 | if len(d.If) > 0 { 38 | drive = fmt.Sprintf("%s,if=%s", drive, d.If) 39 | } 40 | cmd.appendArgs("-drive", drive) 41 | } 42 | if len(m.Nics) == 0 { 43 | cmd.appendArgs("-net", "none") 44 | } 45 | for _, device := range m.Devices { 46 | for _, arg := range device.BuildArg() { 47 | cmd.appendArgs(arg) 48 | } 49 | } 50 | cmd.appendArgs("-display", m.Display) 51 | cmd.appendArgs("-daemonize") 52 | return cmd.args 53 | } 54 | 55 | func (cmd *cmdLine) QemuImgCmd(i *Image) []string { 56 | cmd.appendArgs("create", "-f", i.Format) 57 | cmd.appendArgs(i.Path) 58 | 59 | if len(i.baseImage) > 0 { 60 | cmd.appendArgs("-b", i.baseImage) 61 | } else { 62 | cmd.appendArgs(fmt.Sprintf("%sK", strconv.Itoa(i.Size))) 63 | } 64 | return cmd.args 65 | } 66 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/multibox/external_libraries/bashsteps/ind-steps/kvmsteps/monitor-process.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # don't run unless this script is the process leader 4 | kill -0 -$$ || { 5 | echo "This script must be started with setsid" 1>&2 6 | exit 255 7 | } 8 | 9 | proc_info_prefix="$1" 10 | shift 11 | 12 | cmdline=( "$@" ) 13 | 14 | stillrunning() 15 | { 16 | # probably not worth doing, but this catches the (very) rare case 17 | # where some similar looking process reuses the same pid 18 | env="$(cat /proc/$orgpid/environ 2>/dev/null)" && [[ "$env" == *${marker}* ]] 19 | } 20 | 21 | monitor() 22 | { 23 | while true; do 24 | sleep ${mp_interval:=30} 25 | nowpid="$(cat "$proc_info_prefix.pid")" 26 | [ "$nowpid" == "$orgpid" ] || break 27 | stillrunning || break 28 | done 29 | kill -TERM 0 30 | # see man kill(2), should kill all processes in same process group 31 | # including the background process $orgpid 32 | } 33 | 34 | export marker=aaa-$$-$RANDOM-zzz 35 | echo "$marker" >"$proc_info_prefix.marker" 36 | 37 | echo "$$" >"$proc_info_prefix.wrapperpid" 38 | 39 | echo "${cmdline[@]}" >"$proc_info_prefix.cmdline" 40 | 41 | # the process of interest gets started here 42 | "${cmdline[@]}" 1>"$proc_info_prefix.stdout" 2>"$proc_info_prefix.stderr" "$proc_info_prefix.pid" 45 | 46 | # monitor the process, and if anything looks amiss, kill it and related processes 47 | monitor & 48 | echo "$!" >"$proc_info_prefix.monitorpid" 49 | 50 | # if the process exits normally, note its return code 51 | rm -f "$proc_info_prefix.returncode" 52 | wait "$orgpid" 53 | rc="$?" 54 | echo "Exited with rc=$rc" >>"$proc_info_prefix.stdout" 55 | echo "$rc" >"$proc_info_prefix.returncode" 56 | kill -TERM 0 # should also kill monitor() 57 | -------------------------------------------------------------------------------- /cmd/openvdc/cmd/run.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | 6 | log "github.com/Sirupsen/logrus" 7 | "github.com/axsh/openvdc/api" 8 | "github.com/axsh/openvdc/cmd/openvdc/internal/util" 9 | "github.com/spf13/cobra" 10 | "github.com/spf13/pflag" 11 | "golang.org/x/net/context" 12 | "google.golang.org/grpc" 13 | ) 14 | 15 | func init() { 16 | runCmd.Flags().Bool("auto-recovery", true, "Set auto recovery flag") 17 | } 18 | 19 | var runCmd = &cobra.Command{ 20 | Use: "run [ResourceTemplate ID/URI]", 21 | Short: "Run an instance", 22 | Long: "Run an instance", 23 | Example: ` 24 | % openvdc run centos/7/lxc 25 | % openvdc run https://raw.githubusercontent.com/axsh/openvdc/master/templates/centos/7/lxc.json 26 | ` + util.ExampleMergeTemplateOptions("openvdc run"), 27 | DisableFlagParsing: true, 28 | PersistentPreRunE: func(cmd *cobra.Command, args []string) error { 29 | err := util.PreRunHelpFlagCheckAndQuit(cmd, args) 30 | if err != nil { 31 | return err 32 | } 33 | err = cmd.ParseFlags(args) 34 | if err != nil { 35 | fmt.Println(err) 36 | } 37 | return nil 38 | }, 39 | RunE: func(cmd *cobra.Command, args []string) error { 40 | left := cmd.Flags().Args() 41 | if len(left) < 1 { 42 | return pflag.ErrHelp 43 | } 44 | 45 | templateSlug := left[0] 46 | for i, a := range args { 47 | if a == templateSlug { 48 | left = args[i:] 49 | break 50 | } 51 | } 52 | req := prepareCreateAPICall(templateSlug, left, cmd.Flags()) 53 | return util.RemoteCall(func(conn *grpc.ClientConn) error { 54 | c := api.NewInstanceClient(conn) 55 | res, err := c.Run(context.Background(), req) 56 | if err != nil { 57 | log.WithError(err).Fatal("Disconnected abnormaly") 58 | return err 59 | } 60 | fmt.Println(res.GetInstanceId()) 61 | return err 62 | }) 63 | }} 64 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/tests/cmd_console_test.go: -------------------------------------------------------------------------------- 1 | // +build acceptance 2 | 3 | package tests 4 | 5 | import ( 6 | "fmt" 7 | "strings" 8 | "testing" 9 | "time" 10 | ) 11 | 12 | func runConsoleCmdPiped(instance_id string, t *testing.T) { 13 | RunCmdAndReportFail(t, "sh", "-c", fmt.Sprintf("echo 'ls' | openvdc console %s", instance_id)) 14 | RunCmdAndExpectFail(t, "sh", "-c", fmt.Sprintf("echo 'false' | openvdc console %s", instance_id)) 15 | } 16 | 17 | func runConsoleCmd(instance_id string, t *testing.T) { 18 | RunCmdAndReportFail(t, "openvdc", "console", instance_id, "--show") 19 | RunCmdAndReportFail(t, "sh", "-c", fmt.Sprintf("openvdc console %s ls", instance_id)) 20 | RunCmdAndReportFail(t, "sh", "-c", fmt.Sprintf("openvdc console %s -- ls", instance_id)) 21 | RunCmdAndExpectFail(t, "sh", "-c", fmt.Sprintf("openvdc console %s -- false", instance_id)) 22 | } 23 | 24 | func TestLXCCmdConsole_ShowOption(t *testing.T) { 25 | stdout, _ := RunCmdAndReportFail(t, "openvdc", "run", "centos/7/lxc") 26 | instance_id := strings.TrimSpace(stdout.String()) 27 | WaitInstance(t, 5*time.Minute, instance_id, "RUNNING", []string{"QUEUED", "STARTING"}) 28 | runConsoleCmd(instance_id, t) 29 | runConsoleCmdPiped(instance_id, t) 30 | RunCmdWithTimeoutAndReportFail(t, 10, 5, "openvdc", "destroy", instance_id) 31 | WaitInstance(t, 5*time.Minute, instance_id, "TERMINATED", nil) 32 | } 33 | 34 | func TestQEMUCmdConsole_ShowOption(t *testing.T) { 35 | stdout, _ := RunCmdAndReportFail(t, "openvdc", "run", "centos/7/qemu_ga") 36 | instance_id := strings.TrimSpace(stdout.String()) 37 | WaitInstance(t, 10*time.Minute, instance_id, "RUNNING", []string{"QUEUED", "STARTING"}) 38 | runConsoleCmd(instance_id, t) 39 | RunCmdWithTimeoutAndReportFail(t, 10, 5, "openvdc", "destroy", instance_id) 40 | WaitInstance(t, 10*time.Minute, instance_id, "TERMINATED", nil) 41 | } 42 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/tests/local_image_test.go: -------------------------------------------------------------------------------- 1 | // +build acceptance 2 | 3 | package tests 4 | 5 | import ( 6 | "fmt" 7 | "path/filepath" 8 | "strings" 9 | "testing" 10 | "time" 11 | ) 12 | 13 | func init() { 14 | if err := RestoreAssets("/var/tmp", "fixtures"); err != nil { 15 | panic(err) 16 | } 17 | } 18 | 19 | func TestLocalImage(t *testing.T) { 20 | 21 | stdout, _, err := RunSsh(scheduler_ip, fmt.Sprintf("[ -f /var/www/html/images/centos/7/amd64/meta.tar.xz ] && echo meta.tar.xz found || echo meta.tar.xz not found")) 22 | 23 | if err != nil { 24 | t.Error(err) 25 | } 26 | 27 | t.Log(stdout.String()) 28 | 29 | // Use custom lxc-template. 30 | stdout, _ = RunCmdAndReportFail(t, "openvdc", "run", "/var/tmp/fixtures/lxc2.json", `{"node_groups":["linuxbr"]}`) 31 | instance_id := strings.TrimSpace(stdout.String()) 32 | 33 | WaitInstance(t, 10*time.Minute, instance_id, "RUNNING", []string{"QUEUED", "STARTING"}) 34 | 35 | configFile := filepath.Join("/var/lib/lxc/", instance_id, "config") 36 | stdout, _, err = RunSsh(executor_lxc_ip, fmt.Sprintf("echo | sudo head -n 1 %s", configFile)) 37 | 38 | if err != nil { 39 | t.Error(err) 40 | } 41 | if stdout.Len() == 0 { 42 | t.Errorf("Couldn't read %s", configFile) 43 | } 44 | 45 | if testing.Verbose() { 46 | t.Log(stdout.String()) 47 | } 48 | 49 | s := strings.Split(strings.TrimSpace(stdout.String()), "/") 50 | templateUsed := s[len(s)-1] 51 | if templateUsed != "lxc-openvdc" { 52 | t.Errorf("Expected templateUsed to be 'lxc-openvdc', got: %s", templateUsed) 53 | } 54 | 55 | _, _ = RunCmdAndReportFail(t, "openvdc", "stop", instance_id) 56 | 57 | WaitInstance(t, 5*time.Minute, instance_id, "STOPPED", []string{"RUNNING", "STOPPING"}) 58 | 59 | _, _ = RunCmdWithTimeoutAndReportFail(t, 10, 5, "openvdc", "destroy", instance_id) 60 | WaitInstance(t, 5*time.Minute, instance_id, "TERMINATED", nil) 61 | } 62 | -------------------------------------------------------------------------------- /model/backend/types.go: -------------------------------------------------------------------------------- 1 | package backend 2 | 3 | import "errors" 4 | 5 | var ErrConnectionNotReady = errors.New("Connection is not established yet.") 6 | var ErrConnectionExists = errors.New("Connection is established") 7 | var ErrUnknownKey = func(key string) error { 8 | return errors.New("Unknown key name: " + key) 9 | } 10 | 11 | type KeyIterator interface { 12 | Next() bool 13 | Value() string 14 | } 15 | 16 | type ConnectionAddress interface { 17 | isConnectionAddress() 18 | } 19 | 20 | type ModelBackend interface { 21 | BackendConnection 22 | Create(key string, value []byte) error 23 | CreateWithID(key string, value []byte) (string, error) 24 | Update(key string, value []byte) error 25 | Find(key string) ([]byte, error) 26 | Delete(key string) error 27 | Keys(parentKey string) (KeyIterator, error) 28 | FindLastKey(prefixKey string) (string, error) 29 | } 30 | 31 | type WatchEvent int 32 | 33 | const ( 34 | EventErr WatchEvent = iota 35 | EventUnknown 36 | EventCreated 37 | EventDeleted 38 | EventModified 39 | ) 40 | 41 | var eventToName = map[WatchEvent]string{ 42 | EventErr: "Error", 43 | EventUnknown: "Unknown", 44 | EventCreated: "Created", 45 | EventDeleted: "Deleted", 46 | EventModified: "Modified", 47 | } 48 | 49 | func (e WatchEvent) String() string { 50 | return eventToName[e] 51 | } 52 | 53 | type ModelWatcher interface { 54 | Watch(key string) (WatchEvent, error) 55 | } 56 | 57 | type ModelSchema interface { 58 | Schema() SchemaHandler 59 | } 60 | 61 | type SchemaHandler interface { 62 | Install(subkeys []string) error 63 | } 64 | 65 | type ClusterBackend interface { 66 | BackendConnection 67 | Register(nodeID string, value []byte) error 68 | Find(nodeID string) ([]byte, error) 69 | UnRegister(nodeID string) error 70 | } 71 | 72 | type BackendConnection interface { 73 | Connect(dest ConnectionAddress) error 74 | Close() error 75 | } 76 | -------------------------------------------------------------------------------- /registry/local.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "os" 7 | "path/filepath" 8 | 9 | "github.com/pkg/errors" 10 | ) 11 | 12 | // Handle resource template file locates on the local system. 13 | type LocalRegistry struct { 14 | } 15 | 16 | func NewLocalRegistry() *LocalRegistry { 17 | return &LocalRegistry{} 18 | } 19 | 20 | func (r *LocalRegistry) LocateURI(name string) string { 21 | abs := filepath.Clean(name) 22 | if !filepath.IsAbs(abs) { 23 | var err error 24 | abs, err = filepath.Abs(abs) 25 | if err != nil { 26 | return "" 27 | } 28 | } 29 | return "file://" + filepath.ToSlash(abs) 30 | } 31 | 32 | func (r *LocalRegistry) Find(templateName string) (*RegistryTemplate, error) { 33 | f, err := r.open(templateName) 34 | if err != nil { 35 | return nil, err 36 | } 37 | defer f.Close() 38 | 39 | tmpl, err := parseResourceTemplate(f) 40 | if err != nil { 41 | return nil, errors.Wrapf(err, "Failed to parse template %s", templateName) 42 | } 43 | rt := &RegistryTemplate{ 44 | Name: templateName, 45 | Template: tmpl, 46 | source: r, 47 | } 48 | return rt, nil 49 | } 50 | 51 | func (r *LocalRegistry) LoadRaw(templateName string) ([]byte, error) { 52 | buf := new(bytes.Buffer) 53 | f, err := r.open(templateName) 54 | if err != nil { 55 | return nil, err 56 | } 57 | defer f.Close() 58 | if _, err := io.Copy(buf, f); err != nil { 59 | return nil, err 60 | } 61 | return buf.Bytes(), nil 62 | } 63 | 64 | func (r *LocalRegistry) open(templateName string) (*os.File, error) { 65 | abs := filepath.Clean(templateName) 66 | if !filepath.IsAbs(abs) { 67 | var err error 68 | abs, err = filepath.Abs(abs) 69 | if err != nil { 70 | return nil, err 71 | } 72 | } 73 | f, err := os.Open(abs) 74 | if err != nil { 75 | if os.IsNotExist(err) { 76 | return nil, ErrUnknownTemplateName 77 | } 78 | return nil, err 79 | } 80 | return f, nil 81 | } 82 | -------------------------------------------------------------------------------- /hypervisor/types_test.go: -------------------------------------------------------------------------------- 1 | package hypervisor 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/axsh/openvdc/model" 7 | "github.com/spf13/viper" 8 | ) 9 | 10 | type testProvider struct{} 11 | 12 | func (p *testProvider) Name() string { 13 | return "test" 14 | } 15 | 16 | func (p *testProvider) LoadConfig(sub *viper.Viper) error { 17 | return nil 18 | } 19 | 20 | func (p *testProvider) CreateDriver(*model.Instance, model.ResourceTemplate) (HypervisorDriver, error) { 21 | return &testDriver{}, nil 22 | } 23 | 24 | type testDriver struct{} 25 | 26 | func (d *testDriver) StartInstance() error { 27 | return nil 28 | } 29 | 30 | func (d *testDriver) StopInstance() error { 31 | return nil 32 | } 33 | 34 | func (d *testDriver) RebootInstance() error { 35 | return nil 36 | } 37 | 38 | func (d *testDriver) InstanceConsole() Console { 39 | return &testConsole{} 40 | } 41 | 42 | func (d *testDriver) CreateInstance() error { 43 | return nil 44 | } 45 | 46 | func (d *testDriver) DestroyInstance() error { 47 | return nil 48 | } 49 | 50 | func (d *testDriver) Recover(model.InstanceState) error { 51 | return nil 52 | } 53 | 54 | type testConsole struct { 55 | } 56 | 57 | func (d *testConsole) Attach(param *ConsoleParam) (<-chan Closed, error) { 58 | return nil, nil 59 | } 60 | 61 | func (d *testConsole) Exec(param *ConsoleParam, args []string) (<-chan Closed, error) { 62 | return nil, nil 63 | } 64 | 65 | func (d *testConsole) Wait() error { 66 | return nil 67 | } 68 | 69 | func (d *testConsole) ForceClose() error { 70 | return nil 71 | } 72 | 73 | func TestProviderRegistry(t *testing.T) { 74 | { 75 | RegisterProvider("test", &testProvider{}) 76 | p, _ := FindProvider("test") 77 | if p == nil { 78 | t.Errorf("Could not find test provider.") 79 | } 80 | } 81 | 82 | { 83 | p, _ := FindProvider("unknown") 84 | if p != nil { 85 | t.Error("Fails to detect the provider does not exist.") 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test-esxi/tests/01_start_and_terminate_esxi_instance_test.go: -------------------------------------------------------------------------------- 1 | // +build acceptance 2 | 3 | package tests 4 | 5 | import ( 6 | "strings" 7 | "testing" 8 | "time" 9 | 10 | tests "github.com/axsh/openvdc/ci/citest/acceptance-test/tests" 11 | ) 12 | 13 | var tmpl = `{ 14 | "interfaces": [ 15 | { 16 | "network_id": "Internal2", 17 | "type": "vmxnet3", 18 | "ipv4addr": "192.168.2.123" 19 | } 20 | ] 21 | }` 22 | 23 | var tmpl2 = `{ 24 | "esxi_image": { 25 | "datastore": "datastore2", 26 | "name": "CentOS7_stripped" 27 | }, 28 | "interfaces": [ 29 | { 30 | "network_id": "Internal2", 31 | "type": "vmxnet3", 32 | "ipv4addr": "192.168.2.123" 33 | } 34 | ] 35 | }` 36 | 37 | func TestEsxiInstance(t *testing.T) { 38 | stdout, _ := tests.RunCmdAndReportFail(t, "openvdc", "run", "centos/7/esxi", tmpl) 39 | instance_id := strings.TrimSpace(stdout.String()) 40 | 41 | _, _ = tests.RunCmdAndReportFail(t, "openvdc", "show", instance_id) 42 | tests.WaitInstance(t, 5*time.Minute, instance_id, "RUNNING", []string{"QUEUED", "STARTING"}) 43 | 44 | _, _ = tests.RunCmdWithTimeoutAndReportFail(t, 10, 5, "openvdc", "destroy", instance_id) 45 | tests.WaitInstance(t, 5*time.Minute, instance_id, "TERMINATED", nil) 46 | 47 | //TODO: Use Esxi api to make sure that the vm gets properly created and destroyed. 48 | } 49 | 50 | func TestEsxiInstanceStripped(t *testing.T) { 51 | stdout, _ := tests.RunCmdAndReportFail(t, "openvdc", "run", "centos/7/esxi", tmpl2) 52 | instance_id := strings.TrimSpace(stdout.String()) 53 | 54 | _, _ = tests.RunCmdAndReportFail(t, "openvdc", "show", instance_id) 55 | tests.WaitInstance(t, 5*time.Minute, instance_id, "RUNNING", []string{"QUEUED", "STARTING"}) 56 | 57 | _, _ = tests.RunCmdWithTimeoutAndReportFail(t, 10, 5, "openvdc", "destroy", instance_id) 58 | tests.WaitInstance(t, 5*time.Minute, instance_id, "TERMINATED", nil) 59 | 60 | } 61 | -------------------------------------------------------------------------------- /registry/github_test.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import ( 4 | "io/ioutil" 5 | "os" 6 | "path/filepath" 7 | "testing" 8 | 9 | "github.com/axsh/openvdc/internal/unittest" 10 | "github.com/stretchr/testify/assert" 11 | 12 | // To pass TestFind 13 | _ "github.com/axsh/openvdc/handlers/vm/lxc" 14 | ) 15 | 16 | func init() { 17 | GithubDefaultRef = unittest.GithubDefaultRef 18 | } 19 | 20 | func TestNewGithubRegistry(t *testing.T) { 21 | assert := assert.New(t) 22 | reg := NewGithubRegistry("xxx") 23 | assert.Implements((*CachedRegistry)(nil), reg) 24 | } 25 | 26 | func TestGithubFetch(t *testing.T) { 27 | assert := assert.New(t) 28 | dir, err := ioutil.TempDir("", "reg-test") 29 | assert.NoError(err, "Could not create temp dir for testing.") 30 | defer func() { 31 | os.RemoveAll(dir) 32 | }() 33 | reg := NewGithubRegistry(dir) 34 | err = reg.Fetch() 35 | assert.NoError(err) 36 | _, err = os.Stat(filepath.Join(dir, "registry", "github.com-axsh-openvdc", reg.Branch)) 37 | assert.NoError(err) 38 | _, err = os.Stat(filepath.Join(dir, "registry", "github.com-axsh-openvdc", reg.Branch+".sha")) 39 | assert.NoError(err) 40 | } 41 | 42 | func TestGitLsRemote(t *testing.T) { 43 | assert := assert.New(t) 44 | refs, err := gitLsRemote(githubRepoSlug) 45 | assert.NoError(err) 46 | assert.NotNil(findRef(refs, "master")) 47 | } 48 | 49 | func TestFind(t *testing.T) { 50 | assert := assert.New(t) 51 | dir, err := ioutil.TempDir("", "reg-test") 52 | assert.NoError(err, "Could not create temp dir for testing.") 53 | defer func() { 54 | os.RemoveAll(dir) 55 | }() 56 | 57 | reg := NewGithubRegistry(dir) 58 | err = reg.Fetch() 59 | assert.NoError(err) 60 | // Try finding existing template name. 61 | rt, err := reg.Find("centos/7/lxc") 62 | assert.NoError(err) 63 | assert.NotNil(rt) 64 | assert.Equal(rt.source, reg) 65 | 66 | // Try finding unknown template name. 67 | rt, err = reg.Find("should-not-exist") 68 | assert.Error(err) 69 | assert.Nil(rt) 70 | } 71 | -------------------------------------------------------------------------------- /terraform/openvdc/provider.go: -------------------------------------------------------------------------------- 1 | // +build terraform 2 | 3 | package openvdc 4 | 5 | import ( 6 | "bytes" 7 | "encoding/json" 8 | "os/exec" 9 | 10 | "github.com/hashicorp/terraform/helper/schema" 11 | "github.com/hashicorp/terraform/terraform" 12 | ) 13 | 14 | func Provider() terraform.ResourceProvider { 15 | return &schema.Provider{ 16 | Schema: map[string]*schema.Schema{ 17 | "api_endpoint": &schema.Schema{ 18 | Type: schema.TypeString, 19 | Required: true, 20 | DefaultFunc: schema.EnvDefaultFunc("OPENVDC_API_ENDPOINT", nil), 21 | Description: "Endpoint URL for API.", 22 | }, 23 | }, 24 | 25 | ResourcesMap: map[string]*schema.Resource{ 26 | "openvdc_instance": OpenVdcInstance(), 27 | }, 28 | 29 | ConfigureFunc: func(d *schema.ResourceData) (interface{}, error) { 30 | return config{ 31 | apiEndpoint: d.Get("api_endpoint").(string), 32 | }, nil 33 | }, 34 | } 35 | } 36 | 37 | func RunCmd(name string, arg ...string) (*bytes.Buffer, *bytes.Buffer, error) { 38 | var stdout bytes.Buffer 39 | var stderr bytes.Buffer 40 | 41 | cmd := exec.Command(name, arg...) 42 | cmd.Stdout = &stdout 43 | cmd.Stderr = &stderr 44 | 45 | err := cmd.Run() 46 | 47 | return &stdout, &stderr, err 48 | } 49 | 50 | func ParseJson(cmdStdOut *bytes.Buffer) (string, error) { 51 | var parsed map[string]interface{} 52 | 53 | err := json.Unmarshal(cmdStdOut.Bytes(), &parsed) 54 | if err != nil { 55 | return "", err 56 | } 57 | var x map[string]interface{} 58 | x = parsed["instance"].(map[string]interface{}) 59 | 60 | x = x["last_state"].(map[string]interface{}) 61 | 62 | return x["state"].(string), nil 63 | 64 | } 65 | 66 | func CheckInstanceTerminatedOrFailed(cmdStdOut *bytes.Buffer) (bool, error) { 67 | status, err := ParseJson(cmdStdOut) 68 | 69 | if err != nil { 70 | return false, err 71 | } 72 | 73 | if status == "TERMINATED" || status == "FAILED" { 74 | return true, nil 75 | } 76 | 77 | return false, nil 78 | 79 | } 80 | -------------------------------------------------------------------------------- /cmd/openvdc/cmd/template/show.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import ( 4 | log "github.com/Sirupsen/logrus" 5 | "github.com/axsh/openvdc/cmd/openvdc/internal/util" 6 | "github.com/golang/protobuf/jsonpb" 7 | "github.com/golang/protobuf/proto" 8 | "github.com/spf13/cobra" 9 | "github.com/spf13/pflag" 10 | ) 11 | 12 | func init() { 13 | ShowCmd.Flags().String("format", "json", "Output format: (json, protobuf)") 14 | } 15 | 16 | var ShowCmd = &cobra.Command{ 17 | Use: "show [Resource Template Path] [template options]", 18 | Short: "Show resource template details", 19 | Long: "Show resource template details", 20 | Example: ` 21 | % openvdc template show centos/7/lxc 22 | % openvdc template show ./templates/centos/7/null.json 23 | % openvdc template show https://raw.githubusercontent.com/axsh/openvdc/master/templates/centos/7/lxc.json 24 | ` + util.ExampleMergeTemplateOptions("openvdc template show"), 25 | DisableFlagParsing: true, 26 | PreRunE: util.PreRunHelpFlagCheckAndQuit, 27 | RunE: func(cmd *cobra.Command, args []string) error { 28 | if len(args) < 1 { 29 | return pflag.ErrHelp 30 | } 31 | templateSlug := args[0] 32 | rt, err := util.FetchTemplate(templateSlug) 33 | if err != nil { 34 | log.Fatal(err) 35 | } 36 | 37 | merged := rt.Template.Template 38 | if len(args) > 1 { 39 | merged = util.MergeTemplateParams(rt, args[1:]) 40 | } 41 | 42 | fmt_type, err := cmd.Flags().GetString("format") 43 | switch fmt_type { 44 | case "json": 45 | if err := (&jsonpb.Marshaler{Indent: " "}).Marshal(cmd.OutOrStdout(), merged.(proto.Message)); err != nil { 46 | log.WithError(err).Fatal("Faild to format to pretty JSON.") 47 | } 48 | case "protobuf": 49 | //TODO: Show difference between rt.ToModel() and merged objects. 50 | m := &proto.TextMarshaler{Compact: false} 51 | return m.Marshal(cmd.OutOrStdout(), merged.(proto.Message)) 52 | default: 53 | log.Fatalf("Unknown format: %s", fmt_type) 54 | } 55 | return nil 56 | }, 57 | } 58 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: build-{build}.{branch} 2 | 3 | clone_folder: C:\gopath\src\github.com\axsh\openvdc 4 | clone_depth: 10 5 | 6 | environment: 7 | GOPATH: C:\gopath 8 | JAVA_HOME: C:\Program Files\Java\jdk1.8.0_121 9 | 10 | cache: 11 | - '%GOPATH%\.cache -> vendor\vendor.json' 12 | 13 | platform: 14 | - x64 15 | 16 | init: 17 | - git config --global core.autocrlf input 18 | - netsh advfirewall firewall add rule name="Zookeeper - in" dir=in action=allow protocol=TCP localport=2181 19 | - netsh advfirewall firewall add rule name="Zookeeper - out" dir=out action=allow protocol=TCP localport=2181 20 | - netsh advfirewall firewall add rule name="Zookeeper quorum - in" dir=in action=allow protocol=TCP localport=2888 21 | - netsh advfirewall firewall add rule name="Zookeeper quorum - out" dir=out action=allow protocol=TCP localport=2888 22 | - netsh advfirewall firewall add rule name="Zookeeper leader - in" dir=in action=allow protocol=TCP localport=3888 23 | - netsh advfirewall firewall add rule name="Zookeeper leader - out" dir=out action=allow protocol=TCP localport=3888 24 | 25 | install: 26 | # some helpful output for debugging builds 27 | - go version 28 | - go env 29 | - cinst jdk8 30 | - ps: New-Item C:\ZooKeeper -type directory 31 | - powershell -ExecutionPolicy Bypass .\ci\appveyor\install-zk.ps1 C:\ZooKeeper 32 | - ps: $ZkProcess = Start-Process -FilePath "C:\ZooKeeper\bin\zkServer.cmd" -PassThru -NoNewWindow 33 | - dir C:\ZooKeeper 34 | - ps: $ZkProcess | fl 35 | - ps: if ( $ZkProcess.HasExited -eq $True ) { Write-Error "Failed to start zookeeper"; exit 1; } 36 | 37 | build_script: 38 | - set PATH=C:\gopath\bin;%PATH% 39 | - go run ./build.go 40 | 41 | test_script: 42 | - set ZK=127.0.0.1 43 | - set GITHUB_DEFAULT_REF=%APPVEYOR_REPO_BRANCH% 44 | - ps: go list ./... | Select-String -NotMatch "/vendor/" | ForEach-Object { go test -v $_.Line } 45 | 46 | on_finish: 47 | - ps: Stop-Process -Id $ZkProcess.Id -ErrorAction Ignore 48 | 49 | deploy: off 50 | -------------------------------------------------------------------------------- /ci/citest/acceptance-test/tests/copy_local_file_to_instance_test.go: -------------------------------------------------------------------------------- 1 | // +build acceptance 2 | 3 | package tests 4 | 5 | import ( 6 | "fmt" 7 | "io/ioutil" 8 | "path/filepath" 9 | "strings" 10 | "testing" 11 | "time" 12 | ) 13 | 14 | func TestCopyLocalFileToInstance(t *testing.T) { 15 | stdout, _ := RunCmdAndReportFail(t, "openvdc", "run", "centos/7/lxc", `{"interfaces":[{"type":"veth"}], "node_groups":["linuxbr"]}`) 16 | instance_id := strings.TrimSpace(stdout.String()) 17 | 18 | WaitInstance(t, 5*time.Minute, instance_id, "RUNNING", []string{"QUEUED", "STARTING"}) 19 | RunSshWithTimeoutAndReportFail(t, executor_lxc_ip, "sudo lxc-info -n "+instance_id, 10, 5) 20 | 21 | testFileContent := "Hi, this is a test." 22 | testFileFolder := "/tmp/" 23 | testFileName := "testfile" 24 | testFilePath := filepath.Join(testFileFolder, testFileName) 25 | 26 | err := ioutil.WriteFile(testFilePath, []byte(testFileContent), 0644) 27 | if err != nil { 28 | t.Error(err) 29 | } 30 | RunCmdAndReportFail(t, "openvdc", "copy", testFilePath, instance_id+":"+testFileFolder) 31 | copiedFile := filepath.Join("/var/lib/lxc/", instance_id, "/rootfs/", testFilePath) 32 | stdout, _, err = RunSsh(executor_lxc_ip, fmt.Sprintf("sudo cat %s", copiedFile)) 33 | if err != nil { 34 | t.Error(err) 35 | } 36 | if stdout.Len() == 0 { 37 | t.Errorf("Couldn't read %s", copiedFile) 38 | } 39 | if stdout.String() != testFileContent { 40 | t.Errorf("Content mismatch. Got: %s, expected: %s", stdout.String(), testFileContent) 41 | } 42 | 43 | _, _ = RunCmdWithTimeoutAndReportFail(t, 10, 5, "openvdc", "stop", instance_id) 44 | t.Log("Waiting for instance to become STOPPED...") 45 | WaitInstance(t, 5*time.Minute, instance_id, "STOPPED", []string{"RUNNING", "STOPPING"}) 46 | 47 | _, _ = RunCmdWithTimeoutAndReportFail(t, 10, 5, "openvdc", "destroy", instance_id) 48 | 49 | t.Log("Waiting for instance " + instance_id + " to become TERMINATED...") 50 | WaitInstance(t, 5*time.Minute, instance_id, "TERMINATED", nil) 51 | } 52 | --------------------------------------------------------------------------------