Repository: threefoldtech/zos
Pull request #349 (2019-10-29 15:06:40)

provision: add code to convert workload descript from jsx schema to zos types
part of https://github.com/threefoldtech/zos/issues/334

zaibon: >  I only don't like that we have too much changes in a supposedly auto generated files.

I don't see these as generated in the sense we always generated them during build. As for now schemas is just a tool to help generate a bunch of types from a jsx notation format. Then once they are generated, we push them into the code base and managed them as normal types. So for now I don't mind. If we reach the point where we always generate these types for each build, then we can think about improving stuff.
I just don't think this is worth it to inverst time in this at the moment. jsx schema is still very young and who knows what can change there. But I hear you, more stable schema format would be nice.
codecov[bot]: # [Codecov](https://codecov.io/gh/threefoldtech/zos/pull/349?src=pr&el=h1) Report
> Merging [#349](https://codecov.io/gh/threefoldtech/zos/pull/349?src=pr&el=desc) into [master](https://codecov.io/gh/threefoldtech/zos/commit/86c098aed1b3fe3da1b7c77a4bf946841ac1ad7f?src=pr&el=desc) will **increase** coverage by `1.49%`.
> The diff coverage is `67.88%`.

[![Impacted file tree graph](https://codecov.io/gh/threefoldtech/zos/pull/349/graphs/tree.svg?width=650&token=f7Vmq1OAEm&height=150&src=pr)](https://codecov.io/gh/threefoldtech/zos/pull/349?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #349      +/-   ##
==========================================
+ Coverage   39.17%   40.66%   +1.49%     
==========================================
  Files          58       60       +2     
  Lines        3602     3718     +116     
==========================================
+ Hits         1411     1512     +101     
- Misses       1999     2007       +8     
- Partials      192      199       +7
```


| [Impacted Files](https://codecov.io/gh/threefoldtech/zos/pull/349?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pkg/provision/reservation.go](https://codecov.io/gh/threefoldtech/zos/pull/349/diff?src=pr&el=tree#diff-cGtnL3Byb3Zpc2lvbi9yZXNlcnZhdGlvbi5nbw==) | `12.5% <ø> (+2.5%)` | :arrow_up: |
| [.../provision/tfgrid\_reservation\_statsaggregator\_1.go](https://codecov.io/gh/threefoldtech/zos/pull/349/diff?src=pr&el=tree#diff-cGtnL2dlZGlzL3R5cGVzL3Byb3Zpc2lvbi90ZmdyaWRfcmVzZXJ2YXRpb25fc3RhdHNhZ2dyZWdhdG9yXzEuZ28=) | `0% <ø> (ø)` | :arrow_up: |
| [.../types/provision/tfgrid\_reservation\_container\_1.go](https://codecov.io/gh/threefoldtech/zos/pull/349/diff?src=pr&el=tree#diff-cGtnL2dlZGlzL3R5cGVzL3Byb3Zpc2lvbi90ZmdyaWRfcmVzZXJ2YXRpb25fY29udGFpbmVyXzEuZ28=) | `100% <100%> (ø)` | |
| [pkg/provision/container.go](https://codecov.io/gh/threefoldtech/zos/pull/349/diff?src=pr&el=tree#diff-cGtnL3Byb3Zpc2lvbi9jb250YWluZXIuZ28=) | `53.9% <33.33%> (ø)` | :arrow_up: |
| [pkg/gedis/commands\_provision.go](https://codecov.io/gh/threefoldtech/zos/pull/349/diff?src=pr&el=tree#diff-cGtnL2dlZGlzL2NvbW1hbmRzX3Byb3Zpc2lvbi5nbw==) | `45.24% <44.89%> (-2.04%)` | :arrow_down: |
| [...is/types/provision/tfgrid\_reservation\_network\_1.go](https://codecov.io/gh/threefoldtech/zos/pull/349/diff?src=pr&el=tree#diff-cGtnL2dlZGlzL3R5cGVzL3Byb3Zpc2lvbi90ZmdyaWRfcmVzZXJ2YXRpb25fbmV0d29ya18xLmdv) | `75.67% <75.67%> (ø)` | |
| [.../gedis/types/provision/tfgrid\_reservation\_zdb\_1.go](https://codecov.io/gh/threefoldtech/zos/pull/349/diff?src=pr&el=tree#diff-cGtnL2dlZGlzL3R5cGVzL3Byb3Zpc2lvbi90ZmdyaWRfcmVzZXJ2YXRpb25femRiXzEuZ28=) | `82.35% <80%> (+82.35%)` | :arrow_up: |
| [...dis/types/provision/tfgrid\_reservation\_volume\_1.go](https://codecov.io/gh/threefoldtech/zos/pull/349/diff?src=pr&el=tree#diff-cGtnL2dlZGlzL3R5cGVzL3Byb3Zpc2lvbi90ZmdyaWRfcmVzZXJ2YXRpb25fdm9sdW1lXzEuZ28=) | `83.33% <81.81%> (+83.33%)` | :arrow_up: |
| ... and [2 more](https://codecov.io/gh/threefoldtech/zos/pull/349/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/threefoldtech/zos/pull/349?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/threefoldtech/zos/pull/349?src=pr&el=footer). Last update [86c098a...41db050](https://codecov.io/gh/threefoldtech/zos/pull/349?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/docs/provision/provision.md b/docs/provision/provision.md
index bf7f909b..a800d0ed 100644
--- a/docs/provision/provision.md
+++ b/docs/provision/provision.md
@@ -45,7 +45,7 @@ Container provision schema
 ```go
 // Network struct
 type Network struct {
-	NetwokID string `json:"network_id"`
+	NetworkID string `json:"network_id"`
 }
 ```
 
diff --git a/go.mod b/go.mod
index 4d09e9d0..280f8720 100644
--- a/go.mod
+++ b/go.mod
@@ -46,4 +46,5 @@ require (
 	google.golang.org/appengine v1.6.5 // indirect
 	google.golang.org/grpc v1.24.0 // indirect
 	gopkg.in/yaml.v2 v2.2.4
+	gotest.tools v2.2.0+incompatible
 )
diff --git a/pkg/gedis/commands_provision.go b/pkg/gedis/commands_provision.go
index 1cc66c04..993d88a1 100644
--- a/pkg/gedis/commands_provision.go
+++ b/pkg/gedis/commands_provision.go
@@ -3,7 +3,6 @@ package gedis
 import (
 	"encoding/json"
 	"fmt"
-	"strconv"
 	"time"
 
 	"github.com/threefoldtech/zos/pkg/schema"
@@ -78,7 +77,7 @@ func (g *Gedis) Get(id string) (*provision.Reservation, error) {
 		return nil, err
 	}
 
-	return reservationFromSchema(workload), nil
+	return reservationFromSchema(workload)
 }
 
 // Poll implements provision.ReservationPoller
@@ -108,7 +107,11 @@ func (g *Gedis) Poll(nodeID pkg.Identifier, all bool, since time.Time) ([]*provi
 
 	reservations := make([]*provision.Reservation, len(out.Workloads))
 	for i, w := range out.Workloads {
-		reservations[i] = reservationFromSchema(w)
+		r, err := reservationFromSchema(w)
+		if err != nil {
+			return nil, err
+		}
+		reservations[i] = r
 	}
 
 	return reservations, nil
@@ -116,10 +119,7 @@ func (g *Gedis) Poll(nodeID pkg.Identifier, all bool, since time.Time) ([]*provi
 
 // Feedback implements provision.Feedbacker
 func (g *Gedis) Feedback(id string, r *provision.Result) error {
-	rID, err := strconv.ParseInt(id, 10, 64)
-	if err != nil {
-		return err
-	}
+
 	var rType types.TfgridReservationResult1CategoryEnum
 	switch r.Type {
 	case provision.VolumeReservation:
@@ -142,7 +142,7 @@ func (g *Gedis) Feedback(id string, r *provision.Result) error {
 
 	result := types.TfgridReservationResult1{
 		Category:   rType,
-		WorkloadID: rID,
+		WorkloadID: id,
 		DataJSON:   string(r.Data),
 		Signature:  r.Signature,
 		State:      rState,
@@ -150,8 +150,8 @@ func (g *Gedis) Feedback(id string, r *provision.Result) error {
 		Epoch:      schema.Date{r.Created},
 	}
 
-	_, err = g.Send("workload_manager", "set_workload_result", Args{
-		"reservation_id": rID,
+	_, err := g.Send("workload_manager", "set_workload_result", Args{
+		"reservation_id": id,
 		"result":         result,
 	})
 	return err
@@ -160,8 +160,8 @@ func (g *Gedis) Feedback(id string, r *provision.Result) error {
 // Deleted implements provision.Feedbacker
 func (g *Gedis) Deleted(id string) error { return nil }
 
-func reservationFromSchema(w types.TfgridReservationWorkload1) *provision.Reservation {
-	return &provision.Reservation{
+func reservationFromSchema(w types.TfgridReservationWorkload1) (*provision.Reservation, error) {
+	reservation := &provision.Reservation{
 		ID:        w.WorkloadID,
 		User:      w.User,
 		Type:      provision.ReservationType(w.Type.String()),
@@ -170,6 +170,65 @@ func reservationFromSchema(w types.TfgridReservationWorkload1) *provision.Reserv
 		Signature: []byte(w.Signature),
 		Data:      w.Workload,
 	}
+
+	var (
+		data interface{}
+		err  error
+	)
+
+	// convert the workload description from jsx schema to zos types
+	switch reservation.Type {
+	case provision.ZDBReservation:
+		tmp := types.TfgridReservationZdb1{}
+		if err := json.Unmarshal(reservation.Data, &tmp); err != nil {
+			return nil, err
+		}
+
+		data, err = tmp.ToProvisionType()
+		if err != nil {
+			return nil, err
+		}
+
+	case provision.VolumeReservation:
+		tmp := types.TfgridReservationVolume1{}
+		if err := json.Unmarshal(reservation.Data, &tmp); err != nil {
+			return nil, err
+		}
+
+		data, err = tmp.ToProvisionType()
+		if err != nil {
+			return nil, err
+		}
+
+	case provision.NetworkReservation:
+		tmp := types.TfgridReservationNetwork1{}
+		if err := json.Unmarshal(reservation.Data, &tmp); err != nil {
+			return nil, err
+		}
+
+		data, err = tmp.ToProvisionType()
+		if err != nil {
+			return nil, err
+		}
+
+	case provision.ContainerReservation:
+		tmp := types.TfgridReservationContainer1{}
+		if err := json.Unmarshal(reservation.Data, &tmp); err != nil {
+			return nil, err
+		}
+
+		data, err = tmp.ToProvisionType()
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	reservation.Data, err = json.Marshal(data)
+	if err != nil {
+		return nil, err
+	}
+
+	return reservation, nil
 }
 
 func workloadFromRaw(s json.RawMessage, t provision.ReservationType) (interface{}, error) {
@@ -182,7 +241,7 @@ func workloadFromRaw(s json.RawMessage, t provision.ReservationType) (interface{
 	case provision.VolumeReservation:
 		v := provision.Volume{}
 		err := json.Unmarshal([]byte(s), &v)
-		return v, err
+		return nil, err
 
 	case provision.NetworkReservation:
 		n := pkg.Network{}
@@ -243,7 +302,7 @@ func containerReservation(i interface{}, nodeID string) types.TfgridReservationC
 		Volumes:     make([]types.TfgridReservationContainerMount1, len(c.Mounts)),
 		NetworkConnection: []types.TfgridReservationNetworkConnection1{
 			{
-				NetworkID: string(c.Network.NetwokID),
+				NetworkID: string(c.Network.NetworkID),
 				Ipaddress: c.Network.IPs[0],
 			},
 		},
diff --git a/pkg/gedis/types/provision/tfgrid_reservation_container_1.go b/pkg/gedis/types/provision/tfgrid_reservation_container_1.go
index 11967ac7..4d9d61b0 100644
--- a/pkg/gedis/types/provision/tfgrid_reservation_container_1.go
+++ b/pkg/gedis/types/provision/tfgrid_reservation_container_1.go
@@ -2,12 +2,15 @@ package provision
 
 import (
 	"net"
+
+	"github.com/threefoldtech/zos/pkg"
+	"github.com/threefoldtech/zos/pkg/provision"
 )
 
 //TfgridReservationContainer1 jsx schema
 type TfgridReservationContainer1 struct {
 	WorkloadID        int64                                 `json:"workload_id"`
-	NodeID            int64                                 `json:"node_id"`
+	NodeID            string                                `json:"node_id"`
 	Flist             string                                `json:"flist"`
 	HubURL            string                                `json:"hub_url"`
 	Environment       map[string]string                     `json:"environment"`
@@ -16,7 +19,33 @@ type TfgridReservationContainer1 struct {
 	Volumes           []TfgridReservationContainerMount1    `json:"volumes"`
 	NetworkConnection []TfgridReservationNetworkConnection1 `json:"network_connection"`
 	StatsAggregator   []TfgridReservationStatsaggregator1   `json:"stats_aggregator"`
-	FarmerTid         int64                                 `json:"farmer_tid"`
+}
+
+// ToProvisionType converts TfgridReservationContainer1 to provision.Container
+func (c TfgridReservationContainer1) ToProvisionType() (provision.Container, error) {
+	container := provision.Container{
+		FList:        c.Flist,
+		FlistStorage: c.HubURL,
+		Env:          c.Environment,
+		Entrypoint:   c.Entrypoint,
+		Interactive:  c.Interactive,
+		Mounts:       make([]provision.Mount, len(c.Volumes)),
+	}
+	if len(c.NetworkConnection) > 0 {
+		container.Network = provision.Network{
+			IPs:       []net.IP{c.NetworkConnection[0].Ipaddress},
+			NetworkID: pkg.NetID(c.NetworkConnection[0].NetworkID),
+		}
+	}
+
+	for i, mount := range c.Volumes {
+		container.Mounts[i] = provision.Mount{
+			VolumeID:   mount.VolumeID,
+			Mountpoint: mount.Mountpoint,
+		}
+	}
+
+	return container, nil
 }
 
 //TfgridReservationContainerMount1 jsx schema
diff --git a/pkg/gedis/types/provision/tfgrid_reservation_network_1.go b/pkg/gedis/types/provision/tfgrid_reservation_network_1.go
index d19af9b7..958bb851 100644
--- a/pkg/gedis/types/provision/tfgrid_reservation_network_1.go
+++ b/pkg/gedis/types/provision/tfgrid_reservation_network_1.go
@@ -1,6 +1,8 @@
 package provision
 
 import (
+	"github.com/threefoldtech/zos/pkg"
+	"github.com/threefoldtech/zos/pkg/network/types"
 	schema "github.com/threefoldtech/zos/pkg/schema"
 )
 
@@ -13,18 +15,78 @@ type TfgridReservationNetwork1 struct {
 	NetworkResources []TfgridNetworkNetResource1         `json:"network_resources"`
 }
 
+// ToProvisionType convert TfgridReservationNetwork1 to pkg.Network
+func (n TfgridReservationNetwork1) ToProvisionType() (pkg.Network, error) {
+	network := pkg.Network{
+		Name:         n.Name,
+		NetID:        pkg.NetID(n.Name),
+		IPRange:      types.NewIPNetFromSchema(n.Iprange),
+		NetResources: make([]pkg.NetResource, len(n.NetworkResources)),
+	}
+
+	var err error
+	for i, nr := range n.NetworkResources {
+		network.NetResources[i], err = nr.ToProvisionType()
+		if err != nil {
+			return network, err
+		}
+	}
+	return network, nil
+}
+
 // TfgridNetworkNetResource1 jsx Schema
 type TfgridNetworkNetResource1 struct {
 	NodeID                       string           `json:"node_id"`
 	IPRange                      schema.IPRange   `json:"iprange"`
 	WireguardPrivateKeyEncrypted string           `json:"wireguard_private_key_encrypted"`
 	WireguardPublicKey           string           `json:"wireguard_public_key"`
+	WireguardListenPort          int64            `json:"wireguard_listen_port"`
 	Peers                        []WireguardPeer1 `json:"peers"`
 }
 
+//ToProvisionType converts TfgridNetworkNetResource1 to pkg.NetResource
+func (r TfgridNetworkNetResource1) ToProvisionType() (pkg.NetResource, error) {
+	nr := pkg.NetResource{
+		NodeID:       r.NodeID,
+		Subnet:       types.NewIPNetFromSchema(r.IPRange),
+		WGPrivateKey: r.WireguardPrivateKeyEncrypted,
+		WGPublicKey:  r.WireguardPublicKey,
+		WGListenPort: uint16(r.WireguardListenPort),
+		Peers:        make([]pkg.Peer, len(r.Peers)),
+	}
+
+	for i, peer := range r.Peers {
+		p, err := peer.ToProvisionType()
+		if err != nil {
+			return nr, err
+		}
+		nr.Peers[i] = p
+	}
+
+	return nr, nil
+}
+
 // WireguardPeer1 jsx Schema
 type WireguardPeer1 struct {
 	PublicKey  string   `json:"public_key"`
 	Endpoint   string   `json:"endpoint"`
 	AllowedIPs []string `json:"allowed_iprange"`
 }
+
+//ToProvisionType converts WireguardPeer1 to pkg.Peer
+func (p WireguardPeer1) ToProvisionType() (pkg.Peer, error) {
+	peer := pkg.Peer{
+		WGPublicKey: p.PublicKey,
+		Endpoint:    p.Endpoint,
+		AllowedIPs:  make([]types.IPNet, len(p.AllowedIPs)),
+	}
+
+	var err error
+	for i, ip := range p.AllowedIPs {
+		peer.AllowedIPs[i], err = types.ParseIPNet(ip)
+		if err != nil {
+			return peer, err
+		}
+	}
+	return peer, nil
+}
diff --git a/pkg/gedis/types/provision/tfgrid_reservation_statsaggregator_1.go b/pkg/gedis/types/provision/tfgrid_reservation_statsaggregator_1.go
index 144b1e51..96dddc24 100644
--- a/pkg/gedis/types/provision/tfgrid_reservation_statsaggregator_1.go
+++ b/pkg/gedis/types/provision/tfgrid_reservation_statsaggregator_1.go
@@ -14,7 +14,7 @@ type TfgridReservationStatsaggregator1 struct {
 //TfgridReservationResult1 jsx schema
 type TfgridReservationResult1 struct {
 	Category   TfgridReservationResult1CategoryEnum `json:"category"`
-	WorkloadID int64                                `json:"workload_id"`
+	WorkloadID string                               `json:"workload_id"`
 	DataJSON   string                               `json:"data_json"`
 	Signature  []byte                               `json:"signature"`
 	State      TfgridReservationResult1StateEnum    `json:"state"`
diff --git a/pkg/gedis/types/provision/tfgrid_reservation_volume_1.go b/pkg/gedis/types/provision/tfgrid_reservation_volume_1.go
index 3df6f3a2..48f20f4c 100644
--- a/pkg/gedis/types/provision/tfgrid_reservation_volume_1.go
+++ b/pkg/gedis/types/provision/tfgrid_reservation_volume_1.go
@@ -1,14 +1,34 @@
 package provision
 
+import (
+	"fmt"
+
+	"github.com/threefoldtech/zos/pkg/provision"
+)
+
 //TfgridReservationVolume1 jsx schema
 type TfgridReservationVolume1 struct {
 	WorkloadID      int64                               `json:"workload_id"`
-	NodeID          int64                               `json:"node_id"`
-	ReservationID   int64                               `json:"reservation_id"`
+	NodeID          string                              `json:"node_id"`
 	Size            int64                               `json:"size"`
 	Type            TfgridReservationVolume1TypeEnum    `json:"type"`
 	StatsAggregator []TfgridReservationStatsaggregator1 `json:"stats_aggregator"`
-	FarmerTid       int64                               `json:"farmer_tid"`
+}
+
+// ToProvisionType converts TfgridReservationVolume1 to provision.Volume
+func (v TfgridReservationVolume1) ToProvisionType() (provision.Volume, error) {
+	volume := provision.Volume{
+		Size: uint64(v.Size),
+	}
+	switch v.Type.String() {
+	case "HDD":
+		volume.Type = provision.HDDDiskType
+	case "SSD":
+		volume.Type = provision.SSDDiskType
+	default:
+		return volume, fmt.Errorf("disk type %s not supported", v.Type.String())
+	}
+	return volume, nil
 }
 
 //TfgridReservationVolume1TypeEnum jsx schema
diff --git a/pkg/gedis/types/provision/tfgrid_reservation_zdb_1.go b/pkg/gedis/types/provision/tfgrid_reservation_zdb_1.go
index 97ea76e9..0571065d 100644
--- a/pkg/gedis/types/provision/tfgrid_reservation_zdb_1.go
+++ b/pkg/gedis/types/provision/tfgrid_reservation_zdb_1.go
@@ -1,9 +1,16 @@
 package provision
 
+import (
+	"fmt"
+
+	"github.com/threefoldtech/zos/pkg"
+	"github.com/threefoldtech/zos/pkg/provision"
+)
+
 //TfgridReservationZdb1 jsx schema
 type TfgridReservationZdb1 struct {
 	WorkloadID      int64                               `json:"workload_id"`
-	NodeID          int64                               `json:"node_id"`
+	NodeID          string                              `json:"node_id"`
 	ReservationID   int64                               `json:"reservation_id"`
 	Size            int64                               `json:"size"`
 	Mode            TfgridReservationZdb1ModeEnum       `json:"mode"`
@@ -11,7 +18,34 @@ type TfgridReservationZdb1 struct {
 	DiskType        TfgridReservationZdb1DiskTypeEnum   `json:"disk_type"`
 	Public          bool                                `json:"public"`
 	StatsAggregator []TfgridReservationStatsaggregator1 `json:"stats_aggregator"`
-	FarmerTid       int64                               `json:"farmer_tid"`
+}
+
+//ToProvisionType converts TfgridReservationZdb1 to provision.ZDB
+func (z TfgridReservationZdb1) ToProvisionType() (provision.ZDB, error) {
+	zdb := provision.ZDB{
+		Size:     uint64(z.Size),
+		Password: z.Password,
+		Public:   z.Public,
+	}
+	switch z.DiskType.String() {
+	case "hdd":
+		zdb.DiskType = pkg.HDDDevice
+	case "ssd":
+		zdb.DiskType = pkg.SSDDevice
+	default:
+		return zdb, fmt.Errorf("device type %s not supported", z.DiskType.String())
+	}
+
+	switch z.Mode.String() {
+	case "seq":
+		zdb.Mode = pkg.ZDBModeSeq
+	case "user":
+		zdb.Mode = pkg.ZDBModeUser
+	default:
+		return zdb, fmt.Errorf("0-db mode %s not supported", z.Mode.String())
+	}
+
+	return zdb, nil
 }
 
 //TfgridReservationZdb1ModeEnum jsx schema
diff --git a/pkg/provision/container.go b/pkg/provision/container.go
index 98bcf61e..a52131b8 100644
--- a/pkg/provision/container.go
+++ b/pkg/provision/container.go
@@ -17,7 +17,7 @@ import (
 
 // Network struct
 type Network struct {
-	NetwokID pkg.NetID `json:"network_id"`
+	NetworkID pkg.NetID `json:"network_id"`
 	// IP to give to the container
 	IPs []net.IP `json:"ips"`
 }
@@ -90,7 +90,7 @@ func containerProvisionImpl(ctx context.Context, reservation *Reservation) (Cont
 		return ContainerResult{}, errors.Wrap(err, "container provision schema not valid")
 	}
 
-	netID := networkID(reservation.User, string(config.Network.NetwokID))
+	netID := networkID(reservation.User, string(config.Network.NetworkID))
 	log.Debug().
 		Str("network-id", string(netID)).
 		Str("config", fmt.Sprintf("%+v", config)).
@@ -227,7 +227,7 @@ func containerDecommission(ctx context.Context, reservation *Reservation) error
 		return errors.Wrapf(err, "failed to unmount flist at %s", rootFS)
 	}
 
-	netID := networkID(reservation.User, string(config.Network.NetwokID))
+	netID := networkID(reservation.User, string(config.Network.NetworkID))
 	if err := networkMgr.Leave(netID, string(containerID)); err != nil {
 		return errors.Wrap(err, "failed to delete container network namespace")
 	}
@@ -236,7 +236,7 @@ func containerDecommission(ctx context.Context, reservation *Reservation) error
 }
 
 func validateContainerConfig(config Container) error {
-	if config.Network.NetwokID == "" {
+	if config.Network.NetworkID == "" {
 		return fmt.Errorf("network ID cannot be empty")
 	}
 
diff --git a/pkg/provision/reservation.go b/pkg/provision/reservation.go
index 77bc6cef..f4e85dc0 100644
--- a/pkg/provision/reservation.go
+++ b/pkg/provision/reservation.go
@@ -6,8 +6,6 @@ import (
 	"fmt"
 	"time"
 
-	"github.com/pkg/errors"
-	"github.com/rs/zerolog/log"
 	"github.com/threefoldtech/zos/pkg/versioned"
 )
 
@@ -65,13 +63,14 @@ func (r *Reservation) Expired() bool {
 }
 
 func (r *Reservation) validate() error {
-	if err := Verify(r); err != nil {
-		log.Warn().
-			Err(err).
-			Str("id", string(r.ID)).
-			Msg("verification of reservation signature failed")
-		return errors.Wrapf(err, "verification of reservation %s signature failed", r.ID)
-	}
+	// TODO: during testnet phase seems we don't need to verify this
+	// if err := Verify(r); err != nil {
+	// 	log.Warn().
+	// 		Err(err).
+	// 		Str("id", string(r.ID)).
+	// 		Msg("verification of reservation signature failed")
+	// 	return errors.Wrapf(err, "verification of reservation %s signature failed", r.ID)
+	// }
 
 	if r.Duration <= 0 {
 		return fmt.Errorf("reservation %s has not duration", r.ID)
diff --git a/qemu/overlay/bin/upgraded b/qemu/overlay/bin/upgraded
deleted file mode 120000
index 89c0d08a..00000000
--- a/qemu/overlay/bin/upgraded
+++ /dev/null
@@ -1,1 +0,0 @@
-../../../bin/upgraded
\ No newline at end of file
diff --git a/tools/tfuser/cmds_container.go b/tools/tfuser/cmds_container.go
index bff3a6d3..81652351 100644
--- a/tools/tfuser/cmds_container.go
+++ b/tools/tfuser/cmds_container.go
@@ -31,7 +31,7 @@ func generateContainer(c *cli.Context) error {
 		Interactive:  c.Bool("corex"),
 		Mounts:       mounts,
 		Network: provision.Network{
-			NetwokID: pkg.NetID(c.String("network")),
+			NetworkID: pkg.NetID(c.String("network")),
 			IPs: []net.IP{
 				net.ParseIP(c.String("ip")),
 			},


Test patch:
diff --git a/pkg/gedis/commands_provision_test.go b/pkg/gedis/commands_provision_test.go
index 641f6ee9..d657b16e 100644
--- a/pkg/gedis/commands_provision_test.go
+++ b/pkg/gedis/commands_provision_test.go
@@ -29,17 +29,20 @@ func TestProvisionGet(t *testing.T) {
 		"gwid": id,
 	}
 
+	workload := `{"workload_id": 10, "type": 0, "size": 100}`
+
 	conn.On("Do", "default.workload_manager.workload_get", mustMarshal(t, args)).
 		Return(mustMarshal(t, Args{
 			"workload_id": id,
-			"content":     "raw message",
+			"type":        types.TfgridReservationWorkload1TypeVolume,
+			"content":     json.RawMessage(workload),
 		}), nil)
 
 	res, err := gedis.Get(id)
 
 	require.NoError(err)
 	require.Equal(id, res.ID)
-	require.Equal(`"raw message"`, string(res.Data))
+	EqualJSON(t, mustMarshal(t, Args{"type": "HDD", "size": 100}), res.Data)
 	//require.Equal(node.NodeID, "node-1")
 	conn.AssertCalled(t, "Close")
 }
@@ -60,11 +63,22 @@ func TestProvisionPoll(t *testing.T) {
 		"epoch":   time.Unix(),
 	}
 
+	workloadVol := `{"workload_id": 10, "type": 0, "size": 100}`
+	workloadZdb := `{"workload_id": 10, "mode": 0, "size": 100}`
+
 	conn.On("Do", "default.workload_manager.workloads_list", mustMarshal(t, args)).
 		Return(mustMarshal(t, Args{
 			"workloads": []types.TfgridReservationWorkload1{
-				{WorkloadID: "1", Type: types.TfgridReservationWorkload1TypeVolume},
-				{WorkloadID: "2", Type: types.TfgridReservationWorkload1TypeContainer},
+				{
+					WorkloadID: "1",
+					Type:       types.TfgridReservationWorkload1TypeVolume,
+					Workload:   json.RawMessage(workloadVol),
+				},
+				{
+					WorkloadID: "2",
+					Type:       types.TfgridReservationWorkload1TypeZdb,
+					Workload:   json.RawMessage(workloadZdb),
+				},
 			},
 		}), nil)
 
@@ -72,7 +86,8 @@ func TestProvisionPoll(t *testing.T) {
 
 	require.NoError(err)
 	require.Len(reservations, 2)
-	require.Equal(reservations[1].Type, provision.ContainerReservation)
+	require.Equal(reservations[0].Type, provision.VolumeReservation)
+	require.Equal(reservations[1].Type, provision.ZDBReservation)
 	conn.AssertCalled(t, "Close")
 
 	args = Args{
@@ -83,8 +98,16 @@ func TestProvisionPoll(t *testing.T) {
 	conn.On("Do", "default.workload_manager.workloads_list", mustMarshal(t, args)).
 		Return(mustMarshal(t, Args{
 			"workloads": []types.TfgridReservationWorkload1{
-				{WorkloadID: "1", Type: types.TfgridReservationWorkload1TypeVolume},
-				{WorkloadID: "2", Type: types.TfgridReservationWorkload1TypeContainer},
+				{
+					WorkloadID: "1",
+					Type:       types.TfgridReservationWorkload1TypeVolume,
+					Workload:   json.RawMessage(workloadVol),
+				},
+				{
+					WorkloadID: "2",
+					Type:       types.TfgridReservationWorkload1TypeZdb,
+					Workload:   json.RawMessage(workloadZdb),
+				},
 			},
 		}), nil)
 
@@ -92,7 +115,8 @@ func TestProvisionPoll(t *testing.T) {
 
 	require.NoError(err)
 	require.Len(reservations, 2)
-	require.Equal(reservations[1].Type, provision.ContainerReservation)
+	require.Equal(reservations[0].Type, provision.VolumeReservation)
+	require.Equal(reservations[1].Type, provision.ZDBReservation)
 	conn.AssertCalled(t, "Close")
 
 }
@@ -116,10 +140,10 @@ func TestProvisionFeedback(t *testing.T) {
 	}
 
 	args := Args{
-		"reservation_id": 101,
+		"reservation_id": "101",
 		"result": types.TfgridReservationResult1{
 			Category:   types.TfgridReservationResult1CategoryContainer,
-			WorkloadID: 101,
+			WorkloadID: "101",
 			DataJSON:   string(result.Data),
 			Signature:  result.Signature,
 			State:      types.TfgridReservationResult1StateOk,
@@ -153,8 +177,8 @@ func TestProvisionReserve(t *testing.T) {
 			FList:      "http://hub.grid.tf/test/test.flist",
 			Entrypoint: "/bin/app",
 			Network: provision.Network{
-				NetwokID: "123",
-				IPs:      []net.IP{net.ParseIP("192.168.1.1")},
+				NetworkID: "123",
+				IPs:       []net.IP{net.ParseIP("192.168.1.1")},
 			},
 		})),
 		Signature: []byte("signature"),
diff --git a/pkg/gedis/types/provision/model_test.go b/pkg/gedis/types/provision/model_test.go
index fc660c4b..84746d69 100644
--- a/pkg/gedis/types/provision/model_test.go
+++ b/pkg/gedis/types/provision/model_test.go
@@ -2,9 +2,17 @@ package provision
 
 import (
 	"encoding/json"
+	"net"
 	"testing"
 
+	"github.com/threefoldtech/zos/pkg/network/types"
+
+	"github.com/threefoldtech/zos/pkg"
+
 	"github.com/stretchr/testify/require"
+	"github.com/threefoldtech/zos/pkg/provision"
+	schema "github.com/threefoldtech/zos/pkg/schema"
+	"gotest.tools/assert"
 )
 
 func TestEnum(t *testing.T) {
@@ -21,3 +29,464 @@ func TestEnum(t *testing.T) {
 
 	require.Equal(t, r.Type, o.Type)
 }
+
+func TestTfgridReservationContainer1_ToProvisionType(t *testing.T) {
+	type fields struct {
+		WorkloadID        int64
+		NodeID            string
+		Flist             string
+		HubURL            string
+		Environment       map[string]string
+		Entrypoint        string
+		Interactive       bool
+		Volumes           []TfgridReservationContainerMount1
+		NetworkConnection []TfgridReservationNetworkConnection1
+		StatsAggregator   []TfgridReservationStatsaggregator1
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		want    provision.Container
+		wantErr bool
+	}{
+		{
+			name: "empty network and volume",
+			fields: fields{
+				WorkloadID:        1,
+				NodeID:            "node1",
+				Flist:             "https://hub.grid.tf/tf-official-apps/ubuntu-bionic-build.flist",
+				HubURL:            "zdb://hub.grid.tf:9900",
+				Environment:       map[string]string{"FOO": "BAR"},
+				Entrypoint:        "/sbin/my_init",
+				Interactive:       false,
+				Volumes:           nil,
+				NetworkConnection: nil,
+				StatsAggregator:   nil,
+			},
+			want: provision.Container{
+				FList:        "https://hub.grid.tf/tf-official-apps/ubuntu-bionic-build.flist",
+				FlistStorage: "zdb://hub.grid.tf:9900",
+				Env:          map[string]string{"FOO": "BAR"},
+				Entrypoint:   "/sbin/my_init",
+				Interactive:  false,
+				Mounts:       []provision.Mount{},
+				Network:      provision.Network{},
+			},
+			wantErr: false,
+		},
+		{
+			name: "with network and volumes",
+			fields: fields{
+				WorkloadID:  1,
+				NodeID:      "node1",
+				Flist:       "https://hub.grid.tf/tf-official-apps/ubuntu-bionic-build.flist",
+				HubURL:      "zdb://hub.grid.tf:9900",
+				Environment: map[string]string{"FOO": "BAR"},
+				Entrypoint:  "/sbin/my_init",
+				Interactive: false,
+				Volumes: []TfgridReservationContainerMount1{
+					{
+						VolumeID:   "volume1",
+						Mountpoint: "/mnt",
+					},
+					{
+						VolumeID:   "volume2",
+						Mountpoint: "/data",
+					},
+				},
+				NetworkConnection: []TfgridReservationNetworkConnection1{
+					{
+						NetworkID: "net1",
+						Ipaddress: net.ParseIP("10.0.0.1"),
+					},
+				},
+				StatsAggregator: nil,
+			},
+			want: provision.Container{
+				FList:        "https://hub.grid.tf/tf-official-apps/ubuntu-bionic-build.flist",
+				FlistStorage: "zdb://hub.grid.tf:9900",
+				Env:          map[string]string{"FOO": "BAR"},
+				Entrypoint:   "/sbin/my_init",
+				Interactive:  false,
+				Mounts: []provision.Mount{
+					{
+						VolumeID:   "volume1",
+						Mountpoint: "/mnt",
+					},
+					{
+						VolumeID:   "volume2",
+						Mountpoint: "/data",
+					},
+				},
+				Network: provision.Network{
+					NetworkID: "net1",
+					IPs:       []net.IP{net.ParseIP("10.0.0.1")},
+				},
+			},
+			wantErr: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			c := TfgridReservationContainer1{
+				WorkloadID:        tt.fields.WorkloadID,
+				NodeID:            tt.fields.NodeID,
+				Flist:             tt.fields.Flist,
+				HubURL:            tt.fields.HubURL,
+				Environment:       tt.fields.Environment,
+				Entrypoint:        tt.fields.Entrypoint,
+				Interactive:       tt.fields.Interactive,
+				Volumes:           tt.fields.Volumes,
+				NetworkConnection: tt.fields.NetworkConnection,
+				StatsAggregator:   tt.fields.StatsAggregator,
+			}
+			got, err := c.ToProvisionType()
+			if !tt.wantErr {
+				require.NoError(t, err)
+				assert.DeepEqual(t, tt.want, got)
+			} else {
+				require.Error(t, err)
+			}
+		})
+	}
+}
+
+func TestTfgridReservationVolume1_ToProvisionType(t *testing.T) {
+	type fields struct {
+		WorkloadID      int64
+		NodeID          string
+		ReservationID   int64
+		Size            int64
+		Type            TfgridReservationVolume1TypeEnum
+		StatsAggregator []TfgridReservationStatsaggregator1
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		want    provision.Volume
+		wantErr bool
+	}{
+		{
+			name: "HDD",
+			fields: fields{
+				WorkloadID:      1,
+				NodeID:          "node1",
+				Size:            10,
+				Type:            TfgridReservationVolume1TypeHDD,
+				StatsAggregator: nil,
+			},
+			want: provision.Volume{
+				Size: 10,
+				Type: provision.HDDDiskType,
+			},
+		},
+		{
+			name: "SSD",
+			fields: fields{
+				WorkloadID:      1,
+				NodeID:          "node1",
+				Size:            10,
+				Type:            TfgridReservationVolume1TypeSSD,
+				StatsAggregator: nil,
+			},
+			want: provision.Volume{
+				Size: 10,
+				Type: provision.SSDDiskType,
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			v := TfgridReservationVolume1{
+				WorkloadID:      tt.fields.WorkloadID,
+				NodeID:          tt.fields.NodeID,
+				Size:            tt.fields.Size,
+				Type:            tt.fields.Type,
+				StatsAggregator: tt.fields.StatsAggregator,
+			}
+			got, err := v.ToProvisionType()
+			if !tt.wantErr {
+				require.NoError(t, err)
+				assert.DeepEqual(t, tt.want, got)
+			} else {
+				require.Error(t, err)
+			}
+		})
+	}
+}
+
+func TestTfgridReservationZdb1_ToProvisionType(t *testing.T) {
+	type fields struct {
+		WorkloadID    int64
+		NodeID        string
+		ReservationID int64
+		Size          int64
+		Mode          TfgridReservationZdb1ModeEnum
+		Password      string
+		DiskType      TfgridReservationZdb1DiskTypeEnum
+		Public        bool
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		want    provision.ZDB
+		wantErr bool
+	}{
+		{
+			name: "seq hdd",
+			fields: fields{
+				WorkloadID: 1,
+				NodeID:     "node1",
+				// ReservationID:,
+				Size:     10,
+				Mode:     TfgridReservationZdb1ModeSeq,
+				Password: "supersecret",
+				DiskType: TfgridReservationZdb1DiskTypeHdd,
+				Public:   true,
+			},
+			want: provision.ZDB{
+				Size:     10,
+				Mode:     pkg.ZDBModeSeq,
+				Password: "supersecret",
+				DiskType: pkg.HDDDevice,
+				Public:   true,
+			},
+			wantErr: false,
+		},
+		{
+			name: "user hdd",
+			fields: fields{
+				WorkloadID: 1,
+				NodeID:     "node1",
+				// ReservationID:,
+				Size:     10,
+				Mode:     TfgridReservationZdb1ModeUser,
+				Password: "supersecret",
+				DiskType: TfgridReservationZdb1DiskTypeHdd,
+				Public:   true,
+			},
+			want: provision.ZDB{
+				Size:     10,
+				Mode:     pkg.ZDBModeUser,
+				Password: "supersecret",
+				DiskType: pkg.HDDDevice,
+				Public:   true,
+			},
+			wantErr: false,
+		},
+		{
+			name: "user ssd",
+			fields: fields{
+				WorkloadID: 1,
+				NodeID:     "node1",
+				// ReservationID:,
+				Size:     10,
+				Mode:     TfgridReservationZdb1ModeUser,
+				Password: "supersecret",
+				DiskType: TfgridReservationZdb1DiskTypeSsd,
+				Public:   true,
+			},
+			want: provision.ZDB{
+				Size:     10,
+				Mode:     pkg.ZDBModeUser,
+				Password: "supersecret",
+				DiskType: pkg.SSDDevice,
+				Public:   true,
+			},
+			wantErr: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			z := TfgridReservationZdb1{
+				WorkloadID:    tt.fields.WorkloadID,
+				NodeID:        tt.fields.NodeID,
+				ReservationID: tt.fields.ReservationID,
+				Size:          tt.fields.Size,
+				Mode:          tt.fields.Mode,
+				Password:      tt.fields.Password,
+				DiskType:      tt.fields.DiskType,
+				Public:        tt.fields.Public,
+			}
+			got, err := z.ToProvisionType()
+			if !tt.wantErr {
+				require.NoError(t, err)
+				assert.DeepEqual(t, tt.want, got)
+			} else {
+				require.Error(t, err)
+			}
+		})
+	}
+}
+
+func TestTfgridReservationNetwork1_ToProvisionType(t *testing.T) {
+	type fields struct {
+		Name             string
+		WorkloadID       int64
+		Iprange          schema.IPRange
+		StatsAggregator  []TfgridReservationStatsaggregator1
+		NetworkResources []TfgridNetworkNetResource1
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		want    pkg.Network
+		wantErr bool
+	}{
+		{
+			name: "main",
+			fields: fields{
+				Name:             "net1",
+				WorkloadID:       1,
+				Iprange:          schema.MustParseIPRange("192.168.0.0/16"),
+				NetworkResources: nil,
+			},
+			want: pkg.Network{
+				Name:         "net1",
+				NetID:        pkg.NetID("net1"),
+				IPRange:      types.MustParseIPNet("192.168.0.0/16"),
+				NetResources: []pkg.NetResource{},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			n := TfgridReservationNetwork1{
+				Name:             tt.fields.Name,
+				WorkloadID:       tt.fields.WorkloadID,
+				Iprange:          tt.fields.Iprange,
+				StatsAggregator:  tt.fields.StatsAggregator,
+				NetworkResources: tt.fields.NetworkResources,
+			}
+			got, err := n.ToProvisionType()
+			if !tt.wantErr {
+				require.NoError(t, err)
+				assert.DeepEqual(t, tt.want, got)
+			} else {
+				require.Error(t, err)
+			}
+		})
+	}
+}
+
+func TestTfgridNetworkNetResource1_ToProvisionType(t *testing.T) {
+	type fields struct {
+		NodeID                       string
+		IPRange                      schema.IPRange
+		WireguardPrivateKeyEncrypted string
+		WireguardPublicKey           string
+		WireguardListenPort          int64
+		Peers                        []WireguardPeer1
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		want    pkg.NetResource
+		wantErr bool
+	}{
+		{
+			name: "main",
+			fields: fields{
+				NodeID:                       "node1",
+				IPRange:                      schema.MustParseIPRange("192.168.0.0/16"),
+				WireguardPrivateKeyEncrypted: "6C6C6568726F776FA646C",
+				WireguardPublicKey:           "0t11OkPwUBPe6m6wL6JTVzJHNjjReBJbEcnSZPs+pFo=",
+				WireguardListenPort:          6380,
+			},
+			want: pkg.NetResource{
+				NodeID:       "node1",
+				Subnet:       types.MustParseIPNet("192.168.0.0/16"),
+				WGPrivateKey: "6C6C6568726F776FA646C",
+				WGPublicKey:  "0t11OkPwUBPe6m6wL6JTVzJHNjjReBJbEcnSZPs+pFo=",
+				WGListenPort: 6380,
+				Peers:        []pkg.Peer{},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			r := TfgridNetworkNetResource1{
+				NodeID:                       tt.fields.NodeID,
+				IPRange:                      tt.fields.IPRange,
+				WireguardPrivateKeyEncrypted: tt.fields.WireguardPrivateKeyEncrypted,
+				WireguardPublicKey:           tt.fields.WireguardPublicKey,
+				WireguardListenPort:          tt.fields.WireguardListenPort,
+				Peers:                        tt.fields.Peers,
+			}
+			got, err := r.ToProvisionType()
+			if !tt.wantErr {
+				require.NoError(t, err)
+				assert.DeepEqual(t, tt.want, got)
+			} else {
+				require.Error(t, err)
+			}
+		})
+	}
+}
+
+func TestWireguardPeer1_ToProvisionType(t *testing.T) {
+	type fields struct {
+		PublicKey  string
+		Endpoint   string
+		AllowedIPs []string
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		want    pkg.Peer
+		wantErr bool
+	}{
+		{
+			name: "main",
+			fields: fields{
+				PublicKey:  "0t11OkPwUBPe6m6wL6JTVzJHNjjReBJbEcnSZPs+pFo=",
+				Endpoint:   "192.168.1.1",
+				AllowedIPs: []string{"192.168.1.0/24", "172.20.0.0/16"},
+			},
+			want: pkg.Peer{
+				// Subnet: types.ParseIPNet("")
+				WGPublicKey: "0t11OkPwUBPe6m6wL6JTVzJHNjjReBJbEcnSZPs+pFo=",
+				AllowedIPs: []types.IPNet{
+					types.MustParseIPNet("192.168.1.0/24"),
+					types.MustParseIPNet("172.20.0.0/16"),
+				},
+				Endpoint: "192.168.1.1",
+			},
+			wantErr: false,
+		},
+		{
+			name: "wrong allowed IP",
+			fields: fields{
+				PublicKey:  "0t11OkPwUBPe6m6wL6JTVzJHNjjReBJbEcnSZPs+pFo=",
+				Endpoint:   "192.168.1.1",
+				AllowedIPs: []string{"192.168.1.0"},
+			},
+			want: pkg.Peer{
+				// Subnet: types.ParseIPNet("")
+				WGPublicKey: "0t11OkPwUBPe6m6wL6JTVzJHNjjReBJbEcnSZPs+pFo=",
+				AllowedIPs: []types.IPNet{
+					types.MustParseIPNet("192.168.1.0/24"),
+					types.MustParseIPNet("172.20.0.0/16"),
+				},
+				Endpoint: "192.168.1.1",
+			},
+			wantErr: true,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			p := WireguardPeer1{
+				PublicKey:  tt.fields.PublicKey,
+				Endpoint:   tt.fields.Endpoint,
+				AllowedIPs: tt.fields.AllowedIPs,
+			}
+			got, err := p.ToProvisionType()
+			if !tt.wantErr {
+				require.NoError(t, err)
+				assert.DeepEqual(t, tt.want, got)
+			} else {
+				require.Error(t, err)
+			}
+		})
+	}
+}
diff --git a/pkg/provision/container_test.go b/pkg/provision/container_test.go
index 077ee4ff..a3f5f1cb 100644
--- a/pkg/provision/container_test.go
+++ b/pkg/provision/container_test.go
@@ -27,7 +27,7 @@ func TestContainerProvisionExists(t *testing.T) {
 	container := Container{
 		FList: "https://hub.grid.tf/thabet/redis.flist",
 		Network: Network{
-			NetwokID: pkg.NetID("net1"),
+			NetworkID: pkg.NetID("net1"),
 			IPs: []net.IP{
 				net.ParseIP("192.168.1.1"),
 			},
@@ -70,7 +70,7 @@ func TestContainerProvisionNew(t *testing.T) {
 	container := Container{
 		FList: "https://hub.grid.tf/thabet/redis.flist",
 		Network: Network{
-			NetwokID: pkg.NetID("net1"),
+			NetworkID: pkg.NetID("net1"),
 			IPs: []net.IP{
 				net.ParseIP("192.168.1.1"),
 			},
@@ -94,7 +94,7 @@ func TestContainerProvisionNew(t *testing.T) {
 		pkg.ContainerID(reservation.ID)).
 		Return(pkg.Container{}, zbus.RemoteError{"does not exist"})
 
-	netID := networkID(reservation.User, string(container.Network.NetwokID))
+	netID := networkID(reservation.User, string(container.Network.NetworkID))
 
 	// since it's a new container, a call to join the network is made
 	client.On("Request",
@@ -148,7 +148,7 @@ func TestContainerProvisionWithMounts(t *testing.T) {
 	container := Container{
 		FList: "https://hub.grid.tf/thabet/redis.flist",
 		Network: Network{
-			NetwokID: pkg.NetID("net1"),
+			NetworkID: pkg.NetID("net1"),
 			IPs: []net.IP{
 				net.ParseIP("192.168.1.1"),
 			},
@@ -182,7 +182,7 @@ func TestContainerProvisionWithMounts(t *testing.T) {
 		pkg.ContainerID(reservation.ID)).
 		Return(pkg.Container{}, zbus.RemoteError{"does not exist"})
 
-	netID := networkID(reservation.User, string(container.Network.NetwokID))
+	netID := networkID(reservation.User, string(container.Network.NetworkID))
 
 	// since it's a new container, a call to join the network is made
 	client.On("Request",