new book manual

This commit is contained in:
2024-04-15 17:42:25 +00:00
parent b46a6df7e0
commit a567404ef3
1772 changed files with 450 additions and 32 deletions

View File

@@ -0,0 +1,30 @@
#!/bin/bash
# This is the same as the first case at qemu/README.md in a single script
sudo ip link add zos0 type bridge
sudo ip link set zos0 up
sudo ip addr add 192.168.123.1/24 dev zos0
md5=$(echo $USER| md5sum )
ULA=${md5:0:2}:${md5:2:4}:${md5:6:4}
sudo ip addr add fd${ULA}::1/64 dev zos0
# you might want to add fe80::1/64
sudo ip addr add fe80::1/64 dev zos0
sudo iptables -t nat -I POSTROUTING -s 192.168.123.0/24 -j MASQUERADE
sudo ip6tables -t nat -I POSTROUTING -s fd${ULA}::/64 -j MASQUERADE
sudo iptables -t filter -I FORWARD --source 192.168.123.0/24 -j ACCEPT
sudo iptables -t filter -I FORWARD --destination 192.168.123.0/24 -j ACCEPT
sudo sysctl -w net.ipv4.ip_forward=1
sudo dnsmasq --strict-order \
--except-interface=lo \
--interface=zos0 \
--bind-interfaces \
--dhcp-range=192.168.123.20,192.168.123.50 \
--dhcp-range=::1000,::1fff,constructor:zos0,ra-stateless,12h \
--conf-file="" \
--pid-file=/var/run/qemu-dnsmasq-zos0.pid \
--dhcp-leasefile=/var/run/qemu-dnsmasq-zos0.leases \
--dhcp-no-override

View File

@@ -0,0 +1,61 @@
# Adding a new package
Binary packages are added via providing [a build script](../../bins/), then an automated workflow will build/publish an flist with this binary.
For example, to add `rmb` binary, we need to provide a bash script with a `build_rmb` function:
```bash
RMB_VERSION="0.1.2"
RMB_CHECKSUM="4fefd664f261523b348fc48e9f1c980b"
RMB_LINK="https://github.com/threefoldtech/rmb-rs/releases/download/v${RMB_VERSION}/rmb"
download_rmb() {
echo "download rmb"
download_file ${RMB_LINK} ${RMB_CHECKSUM} rmb
}
prepare_rmb() {
echo "[+] prepare rmb"
github_name "rmb-${RMB_VERSION}"
}
install_rmb() {
echo "[+] install rmb"
mkdir -p "${ROOTDIR}/bin"
cp ${DISTDIR}/rmb ${ROOTDIR}/bin/
chmod +x ${ROOTDIR}/bin/*
}
build_rmb() {
pushd "${DISTDIR}"
download_rmb
popd
prepare_rmb
install_rmb
}
```
Note that, you can just download a statically build binary instead of building it.
The other step is to add it to workflow to be built automatically, in [bins workflow](../../.github/workflows/bins.yaml), add your binary's job:
```yaml
jobs:
containerd:
...
...
rmb:
uses: ./.github/workflows/bin-package.yaml
with:
package: rmb
secrets:
token: ${{ secrets.HUB_JWT }}
```
Once e.g. a `devnet` release is published, your package will be built then pushed to an flist repository. After that, you can start your local zos node, wait for it to finish downloading, then you should find your binary available.

View File

@@ -0,0 +1,70 @@
# Quick start
- [Quick start](#quick-start)
- [Starting a local zos node](#starting-a-local-zos-node)
- [Accessing node](#accessing-node)
- [Development](#development)
## Starting a local zos node
* Make sure `qemu` and `dnsmasq` are installed
* [Create a farm](../manual/manual.md#creating-a-farm)
* [Download a zos image](https://bootstrap.grid.tf/kernel/zero-os-development-zos-v3-generic-7e587e499a.efi)
* Make sure `zos0` bridge is allowed by qemu, you can add `allow zos0` in `/etc/qemu/bridge.conf` (create the file if it's not there)
* Setup the network using this script [this script](./net.sh)
Then, inside zos repository
```
make -C cmds
cd qemu
mv <downloaded image path> ./zos.efi
sudo ./vm.sh -n myzos-01 -c "farmer_id=<your farm id here> printk.devmsg=on runmode=dev"
```
You should see the qemu console and boot logs, wait for awhile and you can [browse farms](https://dashboard.dev.grid.tf/explorer/farms) to see your node is added/detected automatically.
To stop the machine you can do `Control + a` then `x`.
You can read more about setting up a qemu development environment and more network options [here](../../qemu/README.md).
## Accessing node
After booting up, the node should start downloading external packages, this would take some time depending on your internet connection.
See [how to ssh into it.](../../qemu/README.md#to-ssh-into-the-machine)
How to get the node IP?
Given the network script `dhcp-range`, it usually would be one of `192.168.123.43`, `192.168.123.44` or `192.168.123.45`.
Or you can simply install `arp-scan` then do something like:
```
✗ sudo arp-scan --interface=zos0 --localnet
Interface: zos0, type: EN10MB, MAC: de:26:45:e6:87:95, IPv4: 192.168.123.1
Starting arp-scan 1.9.7 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.123.44 54:43:83:1f:eb:81 (Unknown)
```
Now we know for sure it's `192.168.123.44`.
To check logs and see if the downloading of packages is still in progress, you can simply do:
```
zinit log
```
## Development
While the overlay will enable your to boot with the binaries that's been built locally, sometimes you'll need to test the changes of certain modules without restarting the node (or intending to do so for e.g. testing a migration).
For example if we changed anything related to `noded`, we can do the following:
Inside zos repository:
* Build binaries locally
* `make -C cmds`
* Copy the binary inside the machine
* `scp bin/zos root@192.168.123.44:/bin/noded`
* SSH into the machine then use `zinit` to restart it:
* `zinit stop noded && zinit start noded`

View File

@@ -0,0 +1,6 @@
Development
===========
* [Quick start](./quickstart.md)
* [Testing](./testing.md)
* [Binary packages](./packages.md)

View File

@@ -0,0 +1,157 @@
# Testing
Beside unit testing, you might want to test your change in an integrated environment, the following are two options to do it.
- [Testing](#testing)
- [Using grid/node client](#using-gridnode-client)
- [Using a test app](#using-a-test-app)
- [An example to talk to container and qsfs modules](#an-example-to-talk-to-container-and-qsfs-modules)
- [An example of directly using zinit package](#an-example-of-directly-using-zinit-package)
## Using grid/node client
You can simply use any grid client to deploy a workload of any type, you should specify your node's twin ID (and make sure you are on the correct network).
Inside the node, you can do `noded -id` and `noded -net` to get your current node ID and network. Also, [you can check your farm](https://dashboard.dev.grid.tf/explorer/farms) and get node information from there.
Another option is the golang [node client](../manual/manual.md#interaction).
While deploying on your local node, logs with `zinit log` would be helpful to see any possible errors and to debug your code.
## Using a test app
If you need to test a specific module or functionality, you can create a simple test app inside e.g. [tools directory](../../tools/).
Inside this simple test app, you can import any module or talk to another one using [zbus](../internals/internals.md#ipc).
### An example to talk to container and qsfs modules
```go
// tools/del/main.go
package main
import (
"context"
"flag"
"strings"
"time"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/threefoldtech/zbus"
"github.com/threefoldtech/zos/pkg"
"github.com/threefoldtech/zos/pkg/stubs"
)
func main() {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
zbus, err := zbus.NewRedisClient("unix:///var/run/redis.sock")
if err != nil {
log.Err(err).Msg("cannot init zbus client")
return
}
var workloadType, workloadID string
flag.StringVar(&workloadType, "type", "", "workload type (qsfs or container)")
flag.StringVar(&workloadID, "id", "", "workload ID")
flag.Parse()
if workloadType == "" || workloadID == "" {
log.Error().Msg("you need to provide both type and id")
return
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if workloadType == "qsfs" {
qsfsd := stubs.NewQSFSDStub(zbus)
err := qsfsd.SignalDelete(ctx, workloadID)
if err != nil {
log.Err(err).Msg("cannot delete qsfs workload")
}
} else if workloadType == "container" {
args := strings.Split(workloadID, ":")
if len(args) != 2 {
log.Error().Msg("container id must contain namespace, e.g. qsfs:wl129")
}
containerd := stubs.NewContainerModuleStub(zbus)
err := containerd.SignalDelete(ctx, args[0], pkg.ContainerID(args[1]))
if err != nil {
log.Err(err).Msg("cannot delete container workload")
}
}
}
```
Then we can simply build, upload and execute this in our node:
```
cd tools/del
go build
scp del root@192.168.123.44:/root/del
```
Then ssh into `192.168.123.44` and simply execute your test app:
```
./del
```
### An example of directly using zinit package
```go
// tools/zinit_test
package main
import (
"encoding/json"
"fmt"
"regexp"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/threefoldtech/zos/pkg/zinit"
)
func main() {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
z := zinit.New("/var/run/zinit.sock")
regex := fmt.Sprintf(`^ip netns exec %s %s`, "ndmz", "/sbin/udhcpc")
_, err := regexp.Compile(regex)
if err != nil {
log.Err(err).Msgf("cannot compile %s", regex)
return
}
// try match
matched, err := z.Matches(zinit.WithExecRegex(regex))
if err != nil {
log.Err(err).Msg("cannot filter services")
}
matchedStr, err := json.Marshal(matched)
if err != nil {
log.Err(err).Msg("cannot convert matched map to json")
}
log.Debug().Str("matched", string(matchedStr)).Msg("matched services")
// // try destroy
// err = z.Destroy(10*time.Second, matched...)
// if err != nil {
// log.Err(err).Msg("cannot destroy matched services")
// }
}
```