{"id":25649788,"url":"https://github.com/openchami/ochami-vm","last_synced_at":"2025-06-22T00:35:51.249Z","repository":{"id":223954533,"uuid":"758250788","full_name":"OpenCHAMI/ochami-vm","owner":"OpenCHAMI","description":null,"archived":false,"fork":false,"pushed_at":"2024-10-24T15:31:03.000Z","size":33,"stargazers_count":0,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-25T21:08:36.008Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenCHAMI.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-15T23:13:30.000Z","updated_at":"2024-10-24T15:31:07.000Z","dependencies_parsed_at":"2024-05-22T20:50:18.475Z","dependency_job_id":null,"html_url":"https://github.com/OpenCHAMI/ochami-vm","commit_stats":null,"previous_names":["openchami/ochami-vm"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenCHAMI%2Fochami-vm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenCHAMI%2Fochami-vm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenCHAMI%2Fochami-vm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenCHAMI%2Fochami-vm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenCHAMI","download_url":"https://codeload.github.com/OpenCHAMI/ochami-vm/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240329481,"owners_count":19784456,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-23T14:33:53.679Z","updated_at":"2025-02-23T14:33:54.183Z","avatar_url":"https://github.com/OpenCHAMI.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ochami-vm\nThis VM only runs on a linux host at the moment, specifically on a RHEL8 flavor of linux\n## Prerequisites\nThese are required if you would like to run the ochami services in VM.  \nThe next few steps set up the environment for the VM to boot and run\n\n### Install Packages\n```bash\ndnf install \\ \n    podman \\\n    libvirt \\\n    grub2-efi-x64 \\\n    shim-x64 \\\n    qemu-kvm\n```\n\n\n### Create local service containers\nYou can skip these steps if you have an existing s3 and/or cloud-init instances running.\n\n#### create dummy interface\nWe create a dummy interface to attach our local service containers to.\n```bash\nexport DUMMY_IP=10.100.0.1\nexport DUMMY_MASK=24\n./dummy-interface.sh\n```\n\n#### start minio\nStart a local s3 instance using minio.  \nYou can change the minio user, passwd, and storage location\n```bash\nexport MINIO_USER=\"admin\"\nexport MINIO_PASSWD=\"admin123\"\nexport MINIO_DIR=\"/data/minio\"\n./containers/minio/minio-start.sh\n```\n\n#### start simple cloud init server\nStart a local cloud init instance.  \n```bash\nexport CI_DATA=\"/data/cloud-init/\"\n./containers/simple-cloud-init/cloud-init-start.sh\n```\nYou can add cloud-init configs to the `CI_DATA` directory and point to `http://$DUMMY_IP/cloud-init/` for the cloud-init clients.  \nSee examples in the `examples/cloud-init`\n\n## VM booting\nThis VM uses libvirt and http to boot. \n\n### Build test image\nThe following steps will build a test image and push it to s3\n```bash\nsource s3-utils/s3-setup.sh\n./vm-images/build-test-image.sh\ns3-list --bucket-name boot-images \n```\nYou should now have at least one image and kernel and initramfs\n\n### Get EFI boot binaries\nWe are going to boot the VM via the network using grub.  \nYou'll need two things pushed to s3 to make this work: `BOOTX64.EFI` and `grubx64.efi `.  \nThese are provided by two packages: `grub2-efi-x64` and `shim-x64`.  \nThe locations of these on Rocky8 are in `/boot/efi/EFI/BOOT/BOOTX64.EFI ` and `/boot/efi/EFI/rocky/grubx64.efi` respectively.   \nOnce these packages are installed we can push them to s3:\n```bash\ns3_push --bucket-name efi --key-name BOOTX64.EFI --file-name /boot/efi/EFI/BOOT/BOOTX64.EFI\ns3_push --bucket-name efi --key-name grubx64.efi --file-name /boot/efi/EFI/rocky/grubx64.efi\n```\n\n### Configure grub\nThis is just an example setup but you can configure grub however you wish\n\n#### Setup grub.cfg\nWe first start with an entry point grub.cfg. This is so we can have multiple VMs if desired.  \nMake a file called `grub.cfg` with the contents below.  \n```\nset prefix=(http,10.100.0.1:9000)/efi\nconfigfile ${prefix}/grub.cfg-${net_default_mac}\n```\nThis will key off of the MAC of the VM.  \n\n#### Choose a MAC address for you VM\nAgain, this is up to you but a simple way to do this that was shamelessly stolen from StacOverflow:\n```bash\nVM_MAC=$(printf '02:00:00:%02X:%02X:%02X\\n' $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)))\n```\n\n#### Configure VM specific grub\nHere we will create a grub.cfg that is specific for the VM.  \nIt's name will be based on the MAC address chosen above. \nMake a file called `grub.cfg-$VM_MAC` with contents below: \n```bash\nset default=\"1\"\n\nfunction load_video {\n  insmod efi_gop\n  insmod efi_uga\n  insmod video_bochs\n  insmod video_cirrus\n  insmod all_video\n}\n\nload_video\nset gfxpayload=keep\ninsmod gzio\ninsmod part_gpt\ninsmod ext2\n\nset timeout=10\n\nmenuentry 'Netboot OchamiVM' --class fedora --class gnu-linux --class gnu --class os {\n        linuxefi /boot-images/efi-images/vmlinuz-4.18.0-477.27.1.el8_8.x86_64 nomodeset ro root=live:http://10.100.0.1:9000/boot-images/vm-images/ochami-vm-image.squashfs ip=dhcp overlayroot=tmpfs overlayroot_cfgdisk=disabled apparmor=0 console=ttyS0,115200 ip6=off \"ds=nocloud-net;s=http://10.100.0.1:8000/cloud-init/${net_default_mac}/\"\n        initrdefi /boot-images/efi-images/initramfs-4.18.0-477.27.1.el8_8.x86_64.img\n}\n```\nSome things to note here.\n- linuxefi points to your kernel. It will have to match what is in s3 (`s3-list --bucketname boot-images`)\n    - on the same line there is a `root=live` option. The IP here should match your `DUMMY_IP` setting (10.100.0.1 in our case)\n    - another one on the same line is the `ds=nocloud-net`, you will again want to point this at the `DUMMY_IP`. We will cover cloud-init later\n- initrdefi points to the initramfs in s3, so check the `boot-images` bucket to get the right option\n- there are a few other options you can tweek, like the `timeout=10`\n\nOnce this file looks ok, push it to s3\n```bash\ns3_push --bucket-name efi --key-name grub.cfg-$VM_MAC  --file-name grub.cfg-$VM_MAC\n```\n\n### Cloud-init\nThe first thing is to take of where you set `CI_DATA` when setting up the cloud-init server. The default listed above was \n```bash\nCI_DATA='/data/cloud-init'\n```\n\nIn `$CI_DATA` we will place our VM configs\n```bash\ncd $CI_DATA\nmkdir $VM_MAC\n```\nThen create a blank `vendor-data` file. We don't need this for the VM\n```bash\ntouch $VM_MAC/vendor-data\n```\n\nThen create a `$VM_MAC/meta-data` file. This should look something like:\n```bash\ninstance-id: myinstance123\nlocal-hostname: ochami-vm\n```\nYou can change either to be whatever you wish\n\nThe next file needed is `$VM_MAC/user-data`, this is where all the magic happens and is probably the most site specific setting you'll have to configure.\n\nIt's recommended to go through the cloud-init modules seen here: https://cloudinit.readthedocs.io/en/latest/reference/modules.html\n\nEach has an example and most are not too confusing. \n\nAn example is if you want to login as the root user to the VM from the host, you can add something like this to `$VM_MAC/user-data`:\n```yaml\nwrite_files:\n- content: |\n    \u003chost_pub_key\u003e\n  path: /root/.ssh/authorized_keys\n```\nJust replace `host_pub_key` with the hosts public ssh key\n\nOnce cloud-init runs on the VM locally that key will be in place.\n\n### configure libvirt\nThe last step before attempting to boot is to configure libvirt.  \nWe will use a custom libvirt network and it to use http network booting.\n\n#### ENV variables\nBefore we begin lets set some things. You can change these to whatever you want:\n```bash\nexport VM_NAME=\"ochami-vm\"\nexport VM_MEMORY=\"16777216\"\nexport VM_CPUS=\"1\"\nexport VM_NETWORK=\"ochami\"\nexport VM_BRIDGE=\"br0\"\nexport VM_NET_MAC=$(printf '02:00:00:%02X:%02X:%02X\\n' $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256)))\n```\n#### make a libvirt network\nThere is a template provided in `libvirt/ochami-network-template.xml`that will use the above variables to make a libvirt network\n\nLet's modify our template:\n```bash\nmkdir -p /data/libvirt\nVM_NET_FILE=/data/libvirt/ochami-network.xml\ncp libvirt/ochami-network-template.xml $VM_NET_FILE\nsed -i \"s/@@@VM_NETWORK@@@/$VM_NETWORK/g\" $VM_NET_FILE\nsed -i \"s/@@@VM_NET_MAC@@@/$VM_NET_MAC/g\" $VM_NET_FILE\nsed -i \"s/@@@VM_MAC@@@/$VM_MAC/g\" $VM_NET_FILE\nsed -i \"s/@@@VM_NAME@@@/$VM_NAME/g\" $VM_NET_FILE\n```\ninspect the contents of `VM_NET_FILE`, and if it looks good run\n```bash\nvirsh net-create $VM_NET_FILE\n```\nand check it is running and enable\n```bash\nvirsh net-list\n```\n\n#### create the VM config file\nWe'll do a similar thing as above to create the VM config file\n\nNOTE:\nthe `VM_BRIDGE` assumes you created a bridged interface for the VM to use in the prerequisites. If you didn't you'll need to modify the template and remove this stanza: \n```xml\n    \u003cinterface type='bridge'\u003e\n      \u003csource bridge=\"@@@VM_BRIDGE@@@\"/\u003e\n      \u003cmodel type=\"virtio\"/\u003e\n    \u003c/interface\u003e\n```\n\nNow lets create the VM config file\n```bash\nVM_CONFIG_FILE=/data/libvirt/ochami-vm.xml\ncp libvirt/ochami-vm-template.xml $VM_CONFIG_FILE\nsed -i \"s/@@@VM_NAME@@@/$VM_NAME/g\" $VM_CONFIG_FILE\nsed -i \"s/@@@VM_MEMORY@@@/$VM_MEMORY/g\" $VM_CONFIG_FILE\nsed -i \"s/@@@VM_CPUS@@@/$VM_CPUS/g\" $VM_CONFIG_FILE\nsed -i \"s/@@@VM_NETWORK@@@/$VM_NETWORK/g\" $VM_CONFIG_FILE\nsed -i \"s/@@@VM_MAC@@@/$VM_MAC/g\" $VM_CONFIG_FILE\nsed -i \"s/@@@VM_BRIDGE@@@/$VM_BRIDGE/g\" $VM_CONFIG_FILE\n```\n\nInspect `VM_CONFIG_FILE` and if things look ok then boot the VM:\n```bash\nvirsh create $VM_CONFIG_FILE\n```\ncheck to make sure it started:\n```bash\nvirsh list\n```\nYou can watch the VM boot with \n```bash\nvirsh console $VM_NAME\n```\nThe escape sequence is `ctl + ]`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenchami%2Fochami-vm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenchami%2Fochami-vm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenchami%2Fochami-vm/lists"}