Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ycai
simbricks
Commits
3bbc0c04
Unverified
Commit
3bbc0c04
authored
Nov 26, 2024
by
Jakob Görgen
Browse files
added json deserialization to system module
parent
7fac851b
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
420 additions
and
186 deletions
+420
-186
experiments/simbricks/orchestration/simulation/channel.py
experiments/simbricks/orchestration/simulation/channel.py
+2
-0
experiments/simbricks/orchestration/system/base.py
experiments/simbricks/orchestration/system/base.py
+107
-34
experiments/simbricks/orchestration/system/eth.py
experiments/simbricks/orchestration/system/eth.py
+29
-23
experiments/simbricks/orchestration/system/host/app.py
experiments/simbricks/orchestration/system/host/app.py
+59
-35
experiments/simbricks/orchestration/system/host/base.py
experiments/simbricks/orchestration/system/host/base.py
+52
-34
experiments/simbricks/orchestration/system/host/disk_images.py
...iments/simbricks/orchestration/system/host/disk_images.py
+42
-23
experiments/simbricks/orchestration/system/mem.py
experiments/simbricks/orchestration/system/mem.py
+25
-13
experiments/simbricks/orchestration/system/nic.py
experiments/simbricks/orchestration/system/nic.py
+43
-6
experiments/simbricks/orchestration/system/pcie.py
experiments/simbricks/orchestration/system/pcie.py
+17
-9
experiments/simbricks/orchestration/utils/base.py
experiments/simbricks/orchestration/utils/base.py
+44
-9
No files found.
experiments/simbricks/orchestration/simulation/channel.py
View file @
3bbc0c04
...
@@ -44,6 +44,8 @@ class Channel(utils_base.IdObj):
...
@@ -44,6 +44,8 @@ class Channel(utils_base.IdObj):
def
toJSON
(
self
):
def
toJSON
(
self
):
json_obj
=
super
().
toJSON
()
json_obj
=
super
().
toJSON
()
json_obj
[
"type"
]
=
self
.
__class__
.
__name__
json_obj
[
"module"
]
=
self
.
__class__
.
__module__
json_obj
[
"synchronized"
]
=
self
.
_synchronized
json_obj
[
"synchronized"
]
=
self
.
_synchronized
json_obj
[
"sync_period"
]
=
self
.
sync_period
json_obj
[
"sync_period"
]
=
self
.
sync_period
json_obj
[
"sys_channel"
]
=
self
.
sys_channel
.
id
()
json_obj
[
"sys_channel"
]
=
self
.
sys_channel
.
id
()
...
...
experiments/simbricks/orchestration/system/base.py
View file @
3bbc0c04
...
@@ -35,11 +35,36 @@ class System(util_base.IdObj):
...
@@ -35,11 +35,36 @@ class System(util_base.IdObj):
def
__init__
(
self
)
->
None
:
def
__init__
(
self
)
->
None
:
super
().
__init__
()
super
().
__init__
()
self
.
all_component
:
list
[
Component
]
=
[]
self
.
_all_components
:
dict
[
int
,
Component
]
=
{}
self
.
_all_interfaces
:
dict
[
int
,
Interface
]
=
{}
self
.
_all_channels
:
dict
[
int
,
Channel
]
=
{}
def
add_component
(
self
,
c
:
Component
)
->
None
:
def
_
add_component
(
self
,
c
:
Component
)
->
None
:
assert
c
.
system
==
self
assert
c
.
system
==
self
self
.
all_component
.
append
(
c
)
assert
c
.
id
()
not
in
self
.
_all_components
self
.
_all_components
[
c
.
id
()]
=
c
def
get_comp
(
self
,
ident
:
int
)
->
Component
:
assert
ident
in
self
.
_all_components
return
self
.
_all_components
[
ident
]
def
_add_interface
(
self
,
i
:
Interface
)
->
None
:
assert
i
.
component
.
id
()
in
self
.
_all_components
assert
i
.
id
()
not
in
self
.
_all_interfaces
self
.
_all_interfaces
[
i
.
id
()]
=
i
def
get_inf
(
self
,
ident
:
int
)
->
Interface
:
assert
ident
in
self
.
_all_interfaces
return
self
.
_all_interfaces
[
ident
]
def
_add_channel
(
self
,
c
:
Channel
)
->
None
:
assert
c
.
a
.
id
()
in
self
.
_all_interfaces
and
c
.
b
.
id
()
in
self
.
_all_interfaces
assert
c
.
id
()
not
in
self
.
_all_channels
self
.
_all_channels
[
c
.
id
()]
=
c
def
get_chan
(
self
,
ident
:
int
)
->
Channel
:
assert
ident
in
self
.
_all_channels
return
self
.
_all_channels
[
ident
]
def
toJSON
(
self
)
->
dict
:
def
toJSON
(
self
)
->
dict
:
json_obj
=
super
().
toJSON
()
json_obj
=
super
().
toJSON
()
...
@@ -47,19 +72,15 @@ class System(util_base.IdObj):
...
@@ -47,19 +72,15 @@ class System(util_base.IdObj):
json_obj
[
"module"
]
=
self
.
__class__
.
__module__
json_obj
[
"module"
]
=
self
.
__class__
.
__module__
components_json
=
[]
components_json
=
[]
channels
:
set
[
Channel
]
=
set
()
for
_
,
comp
in
self
.
_all_components
.
items
():
for
comp
in
self
.
all_component
:
util_base
.
has_attribute
(
comp
,
"toJSON"
)
util_base
.
has_attribute
(
comp
,
"toJSON"
)
comp_json
=
comp
.
toJSON
()
comp_json
=
comp
.
toJSON
()
components_json
.
append
(
comp_json
)
components_json
.
append
(
comp_json
)
for
inf
in
comp
.
interfaces
():
json_obj
[
"all_components"
]
=
components_json
channels
.
add
(
inf
.
channel
)
json_obj
[
"all_component"
]
=
components_json
channels_json
=
[]
channels_json
=
[]
for
chan
in
channels
:
for
_
,
chan
in
self
.
_all_channels
.
items
()
:
util_base
.
has_attribute
(
chan
,
"toJSON"
)
util_base
.
has_attribute
(
chan
,
"toJSON"
)
channels_json
.
append
(
chan
.
toJSON
())
channels_json
.
append
(
chan
.
toJSON
())
...
@@ -67,10 +88,26 @@ class System(util_base.IdObj):
...
@@ -67,10 +88,26 @@ class System(util_base.IdObj):
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
json_obj
:
dict
)
->
System
:
# TODO
instance
=
super
().
fromJSON
(
json_obj
)
pass
instance
.
_all_components
=
{}
instance
.
_all_interfaces
=
{}
instance
.
_all_channels
=
{}
components_json
=
util_base
.
get_json_attr_top
(
json_obj
,
"all_components"
)
for
comp_json
in
components_json
:
comp_class
=
util_base
.
get_cls_by_json
(
comp_json
)
util_base
.
has_attribute
(
comp_class
,
"fromJSON"
)
comp
=
comp_class
.
fromJSON
(
instance
,
comp_json
)
channels_json
=
util_base
.
get_json_attr_top
(
json_obj
,
"channels"
)
for
chan_json
in
channels_json
:
chan_class
=
util_base
.
get_cls_by_json
(
chan_json
)
util_base
.
has_attribute
(
chan_class
,
"fromJSON"
)
chan
=
chan_class
.
fromJSON
(
instance
,
chan_json
)
return
instance
class
Component
(
util_base
.
IdObj
):
class
Component
(
util_base
.
IdObj
):
...
@@ -78,17 +115,17 @@ class Component(util_base.IdObj):
...
@@ -78,17 +115,17 @@ class Component(util_base.IdObj):
def
__init__
(
self
,
s
:
System
)
->
None
:
def
__init__
(
self
,
s
:
System
)
->
None
:
super
().
__init__
()
super
().
__init__
()
self
.
system
=
s
self
.
system
=
s
self
.
ifs
:
list
[
Interface
]
=
[]
s
.
parameters
=
{}
s
.
parameters
=
{}
s
.
add_component
(
self
)
s
.
_
add_component
(
self
)
self
.
name
:
str
=
""
self
.
name
:
str
|
None
=
None
@
abc
.
abstractmethod
def
interfaces
(
self
)
->
list
[
Interface
]:
def
interfaces
(
self
)
->
list
[
Interface
]:
return
[]
return
self
.
ifs
@
abc
.
abstractmethod
# NOTE: overwrite and call in subclasses
def
add_if
(
self
,
interface
:
tp
.
Any
)
->
None
:
def
add_if
(
self
,
interface
:
Interface
)
->
None
:
raise
Exception
(
"must be overwritten by subclass"
)
self
.
ifs
.
append
(
interface
)
def
channels
(
self
)
->
list
[
Channel
]:
def
channels
(
self
)
->
list
[
Channel
]:
return
[
i
.
channel
for
i
in
self
.
interfaces
()
if
i
.
is_connected
()]
return
[
i
.
channel
for
i
in
self
.
interfaces
()
if
i
.
is_connected
()]
...
@@ -111,16 +148,29 @@ class Component(util_base.IdObj):
...
@@ -111,16 +148,29 @@ class Component(util_base.IdObj):
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
System
,
json_obj
:
dict
)
->
Component
:
# TODO
instance
=
super
().
fromJSON
(
json_obj
)
pass
instance
.
name
=
util_base
.
get_json_attr_top_or_none
(
json_obj
,
"name"
)
instance
.
system
=
system
system
.
_add_component
(
instance
)
instance
.
ifs
=
[]
interfaces_json
=
util_base
.
get_json_attr_top
(
json_obj
,
"interfaces"
)
for
inf_json
in
interfaces_json
:
inf_class
=
util_base
.
get_cls_by_json
(
inf_json
)
util_base
.
has_attribute
(
inf_class
,
"fromJSON"
)
# NOTE: this will add the interface to the system map for retrieval in sub-classes
inf
=
inf_class
.
fromJSON
(
system
,
inf_json
)
return
instance
class
Interface
(
util_base
.
IdObj
):
class
Interface
(
util_base
.
IdObj
):
def
__init__
(
self
,
c
:
Component
)
->
None
:
def
__init__
(
self
,
c
:
Component
)
->
None
:
super
().
__init__
()
super
().
__init__
()
self
.
component
=
c
self
.
component
=
c
c
.
system
.
_add_interface
(
self
)
self
.
channel
:
Channel
|
None
=
None
self
.
channel
:
Channel
|
None
=
None
def
is_connected
(
self
)
->
bool
:
def
is_connected
(
self
)
->
bool
:
...
@@ -130,7 +180,10 @@ class Interface(util_base.IdObj):
...
@@ -130,7 +180,10 @@ class Interface(util_base.IdObj):
self
.
channel
=
None
self
.
channel
=
None
def
connect
(
self
,
c
:
Channel
)
->
None
:
def
connect
(
self
,
c
:
Channel
)
->
None
:
assert
self
.
channel
is
None
if
self
.
channel
is
not
None
:
raise
Exception
(
f
"cannot connect interface
{
self
.
id
()
}
to channel
{
c
.
id
()
}
. interface is already connected to channel
{
self
.
channel
.
id
()
}
"
)
self
.
channel
=
c
self
.
channel
=
c
def
find_peer
(
self
)
->
Interface
:
def
find_peer
(
self
)
->
Interface
:
...
@@ -164,10 +217,16 @@ class Interface(util_base.IdObj):
...
@@ -164,10 +217,16 @@ class Interface(util_base.IdObj):
json_obj
[
"channel"
]
=
self
.
channel
.
id
()
json_obj
[
"channel"
]
=
self
.
channel
.
id
()
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
System
,
json_obj
:
dict
)
->
Interface
:
# TODO
instance
=
super
().
fromJSON
(
json_obj
)
pass
comp_id
=
util_base
.
get_json_attr_top
(
json_obj
,
"component"
)
comp
=
system
.
get_comp
(
comp_id
)
instance
.
component
=
comp
comp
.
add_if
(
instance
)
system
.
_add_interface
(
instance
)
instance
.
channel
=
None
return
instance
class
Channel
(
util_base
.
IdObj
):
class
Channel
(
util_base
.
IdObj
):
...
@@ -178,6 +237,7 @@ class Channel(util_base.IdObj):
...
@@ -178,6 +237,7 @@ class Channel(util_base.IdObj):
self
.
a
.
connect
(
self
)
self
.
a
.
connect
(
self
)
self
.
b
:
Interface
=
b
self
.
b
:
Interface
=
b
self
.
b
.
connect
(
self
)
self
.
b
.
connect
(
self
)
a
.
component
.
system
.
_add_channel
(
self
)
def
interfaces
(
self
)
->
list
[
Interface
]:
def
interfaces
(
self
)
->
list
[
Interface
]:
return
[
self
.
a
,
self
.
b
]
return
[
self
.
a
,
self
.
b
]
...
@@ -206,7 +266,20 @@ class Channel(util_base.IdObj):
...
@@ -206,7 +266,20 @@ class Channel(util_base.IdObj):
json_obj
[
"interface_b"
]
=
self
.
b
.
id
()
json_obj
[
"interface_b"
]
=
self
.
b
.
id
()
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
System
,
json_obj
:
dict
)
->
Channel
:
# TODO
instance
=
super
().
fromJSON
(
json_obj
)
pass
instance
.
latency
=
int
(
util_base
.
get_json_attr_top
(
json_obj
,
"latency"
))
inf_id_a
=
int
(
util_base
.
get_json_attr_top
(
json_obj
,
"interface_a"
))
inf_id_b
=
int
(
util_base
.
get_json_attr_top
(
json_obj
,
"interface_b"
))
inf_a
=
system
.
get_inf
(
ident
=
inf_id_a
)
inf_b
=
system
.
get_inf
(
ident
=
inf_id_b
)
instance
.
a
=
inf_a
instance
.
a
.
connect
(
instance
)
instance
.
b
=
inf_b
instance
.
b
.
connect
(
instance
)
system
.
_add_channel
(
instance
)
return
instance
experiments/simbricks/orchestration/system/eth.py
View file @
3bbc0c04
...
@@ -20,6 +20,8 @@
...
@@ -20,6 +20,8 @@
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
from
__future__
import
annotations
from
simbricks.orchestration.system
import
base
from
simbricks.orchestration.system
import
base
from
simbricks.orchestration.utils
import
base
as
utils_base
from
simbricks.orchestration.utils
import
base
as
utils_base
...
@@ -44,13 +46,20 @@ class EthSimpleNIC(base.Component):
...
@@ -44,13 +46,20 @@ class EthSimpleNIC(base.Component):
super
().
__init__
(
s
)
super
().
__init__
(
s
)
self
.
_ip
:
str
|
None
=
None
self
.
_ip
:
str
|
None
=
None
self
.
_eth_if
:
EthInterface
=
EthInterface
(
self
)
self
.
_eth_if
:
EthInterface
=
EthInterface
(
self
)
super
().
add_if
(
self
.
_eth_if
)
def
add_ipv4
(
self
,
ip
:
str
)
->
None
:
def
add_ipv4
(
self
,
ip
:
str
)
->
None
:
assert
self
.
_ip
is
None
assert
self
.
_ip
is
None
self
.
_ip
=
ip
self
.
_ip
=
ip
def
add_if
(
self
,
interface
:
EthInterface
)
->
None
:
def
add_if
(
self
,
interface
:
EthInterface
)
->
None
:
raise
Exception
(
"EthSimpleNIC already has ethernet interface"
)
utils_base
.
has_expected_type
(
interface
,
EthInterface
)
if
hasattr
(
self
,
"_eth_if"
)
and
self
.
_eth_if
:
raise
Exception
(
f
"you overwrite EthSimpleNIC._eth_if (
{
self
.
_eth_if
.
id
()
}
->
{
interface
.
id
()
}
) "
)
self
.
_eth_if
=
interface
super
().
add_if
(
self
.
_eth_if
)
def
toJSON
(
self
)
->
dict
:
def
toJSON
(
self
)
->
dict
:
json_obj
=
super
().
toJSON
()
json_obj
=
super
().
toJSON
()
...
@@ -58,32 +67,29 @@ class EthSimpleNIC(base.Component):
...
@@ -58,32 +67,29 @@ class EthSimpleNIC(base.Component):
json_obj
[
"eth_if"
]
=
self
.
_eth_if
.
id
()
json_obj
[
"eth_if"
]
=
self
.
_eth_if
.
id
()
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
base
.
System
,
json_obj
:
dict
)
->
EthSimpleNIC
:
# TODO
instance
=
super
().
fromJSON
(
system
,
json_obj
)
pass
instance
.
_ip
=
utils_base
.
get_json_attr_top
(
json_obj
,
"ip"
)
eth_inf_id
=
int
(
utils_base
.
get_json_attr_top
(
json_obj
,
"eth_if"
))
instance
.
_eth_if
=
system
.
get_inf
(
eth_inf_id
)
return
instance
class
BaseEthNetComponent
(
base
.
Component
):
class
BaseEthNetComponent
(
base
.
Component
):
def
__init__
(
self
,
s
:
base
.
System
)
->
None
:
def
__init__
(
self
,
s
:
base
.
System
)
->
None
:
super
().
__init__
(
s
)
super
().
__init__
(
s
)
self
.
eth_ifs
:
list
[
EthInterface
]
=
[]
def
add_if
(
self
,
i
:
EthInterface
)
->
None
:
def
add_if
(
self
,
i
:
EthInterface
)
->
None
:
self
.
eth_ifs
.
append
(
i
)
utils_base
.
has_expected_type
(
i
,
EthInterface
)
super
().
add_if
(
i
)
def
interfaces
(
self
)
->
list
[
EthInterface
]:
return
self
.
eth_ifs
def
toJSON
(
self
)
->
dict
:
def
toJSON
(
self
)
->
dict
:
json_obj
=
super
().
toJSON
()
return
super
().
toJSON
()
eth_interfaces
=
[
inf
.
id
()
for
inf
in
self
.
eth_ifs
]
json_obj
[
"eth_if"
]
=
eth_interfaces
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
base
.
System
,
json_obj
:
dict
)
->
BaseEthNetComponent
:
# TODO
return
super
().
fromJSON
(
system
,
json_obj
)
pass
class
EthWire
(
BaseEthNetComponent
):
class
EthWire
(
BaseEthNetComponent
):
...
@@ -91,9 +97,9 @@ class EthWire(BaseEthNetComponent):
...
@@ -91,9 +97,9 @@ class EthWire(BaseEthNetComponent):
super
().
__init__
(
s
)
super
().
__init__
(
s
)
def
add_if
(
self
,
i
:
EthInterface
)
->
None
:
def
add_if
(
self
,
i
:
EthInterface
)
->
None
:
if
len
(
self
.
eth_
ifs
)
>
2
:
if
len
(
self
.
ifs
)
>
2
:
raise
Exception
(
"one can only add 2 interfaces to a EthWire"
)
raise
Exception
(
"one can only add 2 interfaces to a EthWire"
)
s
elf
.
eth_ifs
.
append
(
i
)
s
uper
().
add_if
(
i
)
class
EthSwitch
(
BaseEthNetComponent
):
class
EthSwitch
(
BaseEthNetComponent
):
...
...
experiments/simbricks/orchestration/system/host/app.py
View file @
3bbc0c04
...
@@ -27,6 +27,7 @@ import abc
...
@@ -27,6 +27,7 @@ import abc
import
io
import
io
from
simbricks.orchestration.instantiation
import
base
as
inst_base
from
simbricks.orchestration.instantiation
import
base
as
inst_base
from
simbricks.orchestration.utils
import
base
as
utils_base
from
simbricks.orchestration.utils
import
base
as
utils_base
from
simbricks.orchestration.system
import
base
as
sys_base
if
tp
.
TYPE_CHECKING
:
if
tp
.
TYPE_CHECKING
:
from
simbricks.orchestration.system
import
host
as
sys_host
from
simbricks.orchestration.system
import
host
as
sys_host
...
@@ -35,19 +36,21 @@ if tp.TYPE_CHECKING:
...
@@ -35,19 +36,21 @@ if tp.TYPE_CHECKING:
class
Application
(
utils_base
.
IdObj
):
class
Application
(
utils_base
.
IdObj
):
def
__init__
(
self
,
h
:
sys_host
.
Host
)
->
None
:
def
__init__
(
self
,
h
:
sys_host
.
Host
)
->
None
:
super
().
__init__
()
super
().
__init__
()
self
.
host
=
h
self
.
host
:
sys_host
.
Host
=
h
def
toJSON
(
self
)
->
dict
:
def
toJSON
(
self
)
->
dict
:
json_obj
=
{}
json_obj
=
super
().
toJSON
()
json_obj
[
"type"
]
=
self
.
__class__
.
__name__
json_obj
[
"type"
]
=
self
.
__class__
.
__name__
json_obj
[
"module"
]
=
self
.
__class__
.
__module__
json_obj
[
"module"
]
=
self
.
__class__
.
__module__
json_obj
[
"host"
]
=
self
.
host
.
id
()
json_obj
[
"host"
]
=
self
.
host
.
id
()
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
sys_base
.
System
,
json_obj
:
dict
):
# TODO
instance
=
super
().
fromJSON
(
json_obj
)
pass
host_id
=
utils_base
.
get_json_attr_top
(
json_obj
,
"host"
)
instance
.
host
=
system
.
get_comp
(
host_id
)
return
instance
# Note AK: Maybe we can factor most of the duplicate calls with the host out
# Note AK: Maybe we can factor most of the duplicate calls with the host out
...
@@ -57,7 +60,7 @@ class BaseLinuxApplication(Application):
...
@@ -57,7 +60,7 @@ class BaseLinuxApplication(Application):
super
().
__init__
(
h
)
super
().
__init__
(
h
)
self
.
start_delay
:
float
|
None
=
None
self
.
start_delay
:
float
|
None
=
None
self
.
end_delay
:
float
|
None
=
None
self
.
end_delay
:
float
|
None
=
None
self
.
wait
=
False
self
.
wait
:
bool
=
False
@
abc
.
abstractmethod
@
abc
.
abstractmethod
def
run_cmds
(
self
,
inst
:
inst_base
.
Instantiation
)
->
list
[
str
]:
def
run_cmds
(
self
,
inst
:
inst_base
.
Instantiation
)
->
list
[
str
]:
...
@@ -109,16 +112,21 @@ class BaseLinuxApplication(Application):
...
@@ -109,16 +112,21 @@ class BaseLinuxApplication(Application):
json_obj
[
"wait"
]
=
self
.
wait
json_obj
[
"wait"
]
=
self
.
wait
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
sys_base
.
System
,
json_obj
:
dict
):
# TODO
instance
=
super
().
fromJSON
(
system
,
json_obj
)
pass
instance
.
start_delay
=
utils_base
.
get_json_attr_top_or_none
(
json_obj
,
"start_delay"
)
instance
.
end_delay
=
utils_base
.
get_json_attr_top_or_none
(
json_obj
,
"end_delay"
)
instance
.
wait
=
utils_base
.
get_json_attr_top
(
json_obj
,
"wait"
)
return
instance
class
PingClient
(
BaseLinuxApplication
):
class
PingClient
(
BaseLinuxApplication
):
def
__init__
(
self
,
h
:
sys_host
.
LinuxHost
,
server_ip
:
str
=
"192.168.64.1"
)
->
None
:
def
__init__
(
self
,
h
:
sys_host
.
LinuxHost
,
server_ip
:
str
=
"192.168.64.1"
)
->
None
:
super
().
__init__
(
h
)
super
().
__init__
(
h
)
self
.
server_ip
=
server_ip
self
.
server_ip
:
str
=
server_ip
def
run_cmds
(
self
,
inst
:
inst_base
.
Instantiation
)
->
tp
.
List
[
str
]:
def
run_cmds
(
self
,
inst
:
inst_base
.
Instantiation
)
->
tp
.
List
[
str
]:
return
[
f
"ping
{
self
.
server_ip
}
-c 10"
]
return
[
f
"ping
{
self
.
server_ip
}
-c 10"
]
...
@@ -128,17 +136,20 @@ class PingClient(BaseLinuxApplication):
...
@@ -128,17 +136,20 @@ class PingClient(BaseLinuxApplication):
json_obj
[
"server_ip"
]
=
self
.
server_ip
json_obj
[
"server_ip"
]
=
self
.
server_ip
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
sys_base
.
System
,
json_obj
:
dict
):
# TODO
instance
=
super
().
fromJSON
(
system
,
json_obj
)
pass
instance
.
server_ip
=
utils_base
.
get_json_attr_top
(
json_obj
,
"server_ip"
)
return
instance
class
Sleep
(
BaseLinuxApplication
):
class
Sleep
(
BaseLinuxApplication
):
def
__init__
(
self
,
h
:
sys_host
.
LinuxHost
,
delay
:
float
=
10
,
infinite
:
bool
=
False
)
->
None
:
def
__init__
(
self
,
h
:
sys_host
.
LinuxHost
,
delay
:
float
=
10
,
infinite
:
bool
=
False
)
->
None
:
super
().
__init__
(
h
)
super
().
__init__
(
h
)
self
.
infinite
:
bool
=
infinite
self
.
infinite
:
bool
=
infinite
self
.
delay
=
delay
self
.
delay
:
float
=
delay
def
run_cmds
(
self
,
inst
:
inst_base
.
Instantiation
)
->
list
[
str
]:
def
run_cmds
(
self
,
inst
:
inst_base
.
Instantiation
)
->
list
[
str
]:
if
self
.
infinite
:
if
self
.
infinite
:
...
@@ -151,10 +162,12 @@ class Sleep(BaseLinuxApplication):
...
@@ -151,10 +162,12 @@ class Sleep(BaseLinuxApplication):
json_obj
[
"delay"
]
=
self
.
delay
json_obj
[
"delay"
]
=
self
.
delay
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
sys_base
.
System
,
json_obj
:
dict
)
->
Sleep
:
# TODO
instance
=
super
().
fromJSON
(
system
,
json_obj
)
pass
instance
.
infinite
=
bool
(
utils_base
.
get_json_attr_top
(
json_obj
,
"infinite"
))
instance
.
delay
=
float
(
utils_base
.
get_json_attr_top
(
json_obj
,
"delay"
))
return
instance
class
NetperfServer
(
BaseLinuxApplication
):
class
NetperfServer
(
BaseLinuxApplication
):
...
@@ -164,6 +177,10 @@ class NetperfServer(BaseLinuxApplication):
...
@@ -164,6 +177,10 @@ class NetperfServer(BaseLinuxApplication):
def
run_cmds
(
self
,
inst
:
inst_base
.
Instantiation
)
->
list
[
str
]:
def
run_cmds
(
self
,
inst
:
inst_base
.
Instantiation
)
->
list
[
str
]:
return
[
"netserver"
,
"sleep infinity"
]
return
[
"netserver"
,
"sleep infinity"
]
@
classmethod
def
fromJSON
(
cls
,
system
:
sys_base
.
System
,
json_obj
:
dict
)
->
NetperfServer
:
return
super
().
fromJSON
(
system
,
json_obj
)
class
NetperfClient
(
BaseLinuxApplication
):
class
NetperfClient
(
BaseLinuxApplication
):
def
__init__
(
self
,
h
:
sys_host
.
LinuxHost
,
server_ip
:
str
=
"192.168.64.1"
)
->
None
:
def
__init__
(
self
,
h
:
sys_host
.
LinuxHost
,
server_ip
:
str
=
"192.168.64.1"
)
->
None
:
...
@@ -190,7 +207,14 @@ class NetperfClient(BaseLinuxApplication):
...
@@ -190,7 +207,14 @@ class NetperfClient(BaseLinuxApplication):
json_obj
[
"duration_lat"
]
=
self
.
duration_lat
json_obj
[
"duration_lat"
]
=
self
.
duration_lat
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
sys_base
.
System
,
json_obj
:
dict
)
->
NetperfClient
:
# TODO
instance
=
super
().
fromJSON
(
system
,
json_obj
)
pass
instance
.
server_ip
=
utils_base
.
get_json_attr_top
(
json_obj
,
"server_ip"
)
instance
.
duration_tp
=
int
(
utils_base
.
get_json_attr_top
(
json_obj
,
"duration_tp"
)
)
instance
.
duration_lat
=
int
(
utils_base
.
get_json_attr_top
(
json_obj
,
"duration_lat"
)
)
return
instance
experiments/simbricks/orchestration/system/host/base.py
View file @
3bbc0c04
...
@@ -39,15 +39,8 @@ if tp.TYPE_CHECKING:
...
@@ -39,15 +39,8 @@ if tp.TYPE_CHECKING:
class
Host
(
base
.
Component
):
class
Host
(
base
.
Component
):
def
__init__
(
self
,
s
:
base
.
System
):
def
__init__
(
self
,
s
:
base
.
System
):
super
().
__init__
(
s
)
super
().
__init__
(
s
)
self
.
ifs
:
list
[
base
.
Interface
]
=
[]
self
.
applications
:
list
[
app
.
Application
]
=
[]
self
.
applications
:
list
[
app
.
Application
]
=
[]
def
interfaces
(
self
)
->
list
[
base
.
Interface
]:
return
self
.
ifs
def
add_if
(
self
,
interface
:
base
.
Interface
)
->
None
:
self
.
ifs
.
append
(
interface
)
def
add_app
(
self
,
a
:
app
.
Application
)
->
None
:
def
add_app
(
self
,
a
:
app
.
Application
)
->
None
:
self
.
applications
.
append
(
a
)
self
.
applications
.
append
(
a
)
...
@@ -56,24 +49,33 @@ class Host(base.Component):
...
@@ -56,24 +49,33 @@ class Host(base.Component):
applications_json
=
[]
applications_json
=
[]
for
app
in
self
.
applications
:
for
app
in
self
.
applications
:
utils_base
.
has_attribute
(
app
,
'
toJSON
'
)
utils_base
.
has_attribute
(
app
,
"
toJSON
"
)
applications_json
.
append
(
app
.
toJSON
())
applications_json
.
append
(
app
.
toJSON
())
json_obj
[
"applications"
]
=
applications_json
json_obj
[
"applications"
]
=
applications_json
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
base
.
System
,
json_obj
:
dict
)
->
Host
:
# TODO
instance
=
super
().
fromJSON
(
system
=
system
,
json_obj
=
json_obj
)
pass
instance
.
applications
=
[]
applications_json
=
utils_base
.
get_json_attr_top
(
json_obj
,
"applications"
)
for
app_json
in
applications_json
:
app_class
=
utils_base
.
get_cls_by_json
(
app_json
)
utils_base
.
has_attribute
(
app_class
,
"fromJSON"
)
app
=
app_class
.
fromJSON
(
system
,
app_json
)
instance
.
add_app
(
app
)
return
instance
class
FullSystemHost
(
Host
):
class
FullSystemHost
(
Host
):
def
__init__
(
self
,
s
:
base
.
System
)
->
None
:
def
__init__
(
self
,
s
:
base
.
System
)
->
None
:
super
().
__init__
(
s
)
super
().
__init__
(
s
)
self
.
memory
=
512
self
.
memory
:
int
=
512
self
.
cores
=
1
self
.
cores
:
int
=
1
self
.
cpu_freq
=
"3GHz"
self
.
cpu_freq
:
str
=
"3GHz"
self
.
disks
:
list
[
disk_images
.
DiskImage
]
=
[]
self
.
disks
:
list
[
disk_images
.
DiskImage
]
=
[]
def
add_disk
(
self
,
disk
:
disk_images
.
DiskImage
)
->
None
:
def
add_disk
(
self
,
disk
:
disk_images
.
DiskImage
)
->
None
:
...
@@ -91,16 +93,28 @@ class FullSystemHost(Host):
...
@@ -91,16 +93,28 @@ class FullSystemHost(Host):
disks_json
=
[]
disks_json
=
[]
for
disk
in
self
.
disks
:
for
disk
in
self
.
disks
:
utils_base
.
has_attribute
(
disk
,
'
toJSON
'
)
utils_base
.
has_attribute
(
disk
,
"
toJSON
"
)
disks_json
.
append
(
disk
.
toJSON
())
disks_json
.
append
(
disk
.
toJSON
())
json_obj
[
"disks"
]
=
disks_json
json_obj
[
"disks"
]
=
disks_json
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
base
.
System
,
json_obj
:
dict
)
->
FullSystemHost
:
# TODO
instance
=
super
().
fromJSON
(
system
,
json_obj
)
pass
instance
.
memory
=
int
(
utils_base
.
get_json_attr_top
(
json_obj
,
"memory"
))
instance
.
cores
=
int
(
utils_base
.
get_json_attr_top
(
json_obj
,
"cores"
))
instance
.
cpu_freq
=
utils_base
.
get_json_attr_top
(
json_obj
,
"cpu_freq"
)
instance
.
disks
=
[]
disks_json
=
utils_base
.
get_json_attr_top
(
json_obj
,
"disks"
)
for
disk_js
in
disks_json
:
disk_class
=
utils_base
.
get_cls_by_json
(
disk_js
)
utils_base
.
has_attribute
(
disk_class
,
"fromJSON"
)
disk
=
disk_class
.
fromJSON
(
system
,
disk_js
)
instance
.
add_disk
(
disk
)
return
instance
class
BaseLinuxHost
(
FullSystemHost
):
class
BaseLinuxHost
(
FullSystemHost
):
...
@@ -207,10 +221,12 @@ class BaseLinuxHost(FullSystemHost):
...
@@ -207,10 +221,12 @@ class BaseLinuxHost(FullSystemHost):
json_obj
[
"kcmd_append"
]
=
self
.
kcmd_append
json_obj
[
"kcmd_append"
]
=
self
.
kcmd_append
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
base
.
System
,
json_obj
:
dict
)
->
BaseLinuxHost
:
# TODO
instance
=
super
().
fromJSON
(
system
,
json_obj
)
pass
instance
.
load_modules
=
utils_base
.
get_json_attr_top
(
json_obj
,
"load_modules"
)
instance
.
kcmd_append
=
utils_base
.
get_json_attr_top
(
json_obj
,
"kcmd_append"
)
return
instance
class
LinuxHost
(
BaseLinuxHost
):
class
LinuxHost
(
BaseLinuxHost
):
...
@@ -282,10 +298,12 @@ class LinuxHost(BaseLinuxHost):
...
@@ -282,10 +298,12 @@ class LinuxHost(BaseLinuxHost):
json_obj
[
"hostname"
]
=
self
.
hostname
json_obj
[
"hostname"
]
=
self
.
hostname
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
base
.
System
,
json_obj
:
dict
)
->
LinuxHost
:
# TODO
instance
=
super
().
fromJSON
(
system
,
json_obj
)
pass
instance
.
drivers
=
utils_base
.
get_json_attr_top
(
json_obj
,
"drivers"
)
instance
.
hostname
=
utils_base
.
get_json_attr_top
(
json_obj
,
"hostname"
)
return
instance
class
I40ELinuxHost
(
LinuxHost
):
class
I40ELinuxHost
(
LinuxHost
):
...
...
experiments/simbricks/orchestration/system/host/disk_images.py
View file @
3bbc0c04
...
@@ -29,6 +29,7 @@ import tarfile
...
@@ -29,6 +29,7 @@ import tarfile
import
typing
as
tp
import
typing
as
tp
from
simbricks.orchestration.utils
import
base
as
utils_base
from
simbricks.orchestration.utils
import
base
as
utils_base
from
simbricks.orchestration.instantiation
import
base
as
inst_base
from
simbricks.orchestration.instantiation
import
base
as
inst_base
from
simbricks.orchestration.system
import
base
as
sys_base
if
tp
.
TYPE_CHECKING
:
if
tp
.
TYPE_CHECKING
:
from
simbricks.orchestration.system
import
host
as
sys_host
from
simbricks.orchestration.system
import
host
as
sys_host
...
@@ -85,17 +86,22 @@ class DiskImage(utils_base.IdObj):
...
@@ -85,17 +86,22 @@ class DiskImage(utils_base.IdObj):
await
self
.
_prepare_format
(
inst
,
format
)
await
self
.
_prepare_format
(
inst
,
format
)
def
toJSON
(
self
)
->
dict
:
def
toJSON
(
self
)
->
dict
:
json_obj
=
{}
json_obj
=
super
().
toJSON
()
json_obj
[
"type"
]
=
self
.
__class__
.
__name__
json_obj
[
"type"
]
=
self
.
__class__
.
__name__
json_obj
[
"module"
]
=
self
.
__class__
.
__module__
json_obj
[
"module"
]
=
self
.
__class__
.
__module__
json_obj
[
"host"
]
=
self
.
host
.
id
()
json_obj
[
"host"
]
=
self
.
host
.
id
()
json_obj
[
"qemu_img_exec"
]
=
self
.
_qemu_img_exec
json_obj
[
"qemu_img_exec"
]
=
self
.
_qemu_img_exec
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
sys_base
.
System
,
json_obj
:
dict
)
->
DiskImage
:
# TODO
instance
=
super
().
fromJSON
(
json_obj
)
pass
host_id
=
int
(
utils_base
.
get_json_attr_top
(
json_obj
,
"host"
))
instance
.
host
=
system
.
get_comp
(
host_id
)
instance
.
_qemu_img_exec
=
utils_base
.
get_json_attr_top
(
json_obj
,
"qemu_img_exec"
)
return
instance
# Disk image where user just provides a path
# Disk image where user just provides a path
...
@@ -118,10 +124,12 @@ class ExternalDiskImage(DiskImage):
...
@@ -118,10 +124,12 @@ class ExternalDiskImage(DiskImage):
json_obj
[
"formats"
]
=
self
.
formats
json_obj
[
"formats"
]
=
self
.
formats
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
sys_base
.
System
,
json_obj
:
dict
)
->
DiskImage
:
# TODO
instance
=
super
().
fromJSON
(
system
,
json_obj
)
pass
instance
.
_path
=
utils_base
.
get_json_attr_top
(
json_obj
,
"path"
)
instance
.
formats
=
utils_base
.
get_json_attr_top
(
json_obj
,
"formats"
)
return
instance
# Disk images shipped with simbricks
# Disk images shipped with simbricks
...
@@ -151,10 +159,12 @@ class DistroDiskImage(DiskImage):
...
@@ -151,10 +159,12 @@ class DistroDiskImage(DiskImage):
json_obj
[
"formats"
]
=
self
.
formats
json_obj
[
"formats"
]
=
self
.
formats
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
sys_base
.
System
,
json_obj
:
dict
)
->
DiskImage
:
# TODO
instance
=
super
().
fromJSON
(
system
,
json_obj
)
pass
instance
.
name
=
utils_base
.
get_json_attr_top
(
json_obj
,
"name"
)
instance
.
formats
=
utils_base
.
get_json_attr_top
(
json_obj
,
"formats"
)
return
instance
# Abstract base class for dynamically generated images
# Abstract base class for dynamically generated images
...
@@ -169,6 +179,10 @@ class DynamicDiskImage(DiskImage):
...
@@ -169,6 +179,10 @@ class DynamicDiskImage(DiskImage):
async
def
_prepare_format
(
self
,
inst
:
inst_base
.
Instantiation
,
format
:
str
)
->
None
:
async
def
_prepare_format
(
self
,
inst
:
inst_base
.
Instantiation
,
format
:
str
)
->
None
:
pass
pass
@
classmethod
def
fromJSON
(
cls
,
system
:
sys_base
.
System
,
json_obj
:
dict
)
->
DynamicDiskImage
:
return
super
().
fromJSON
(
system
,
json_obj
)
# Builds the Tar with the commands to run etc.
# Builds the Tar with the commands to run etc.
class
LinuxConfigDiskImage
(
DynamicDiskImage
):
class
LinuxConfigDiskImage
(
DynamicDiskImage
):
...
@@ -206,6 +220,10 @@ class LinuxConfigDiskImage(DynamicDiskImage):
...
@@ -206,6 +220,10 @@ class LinuxConfigDiskImage(DynamicDiskImage):
tar
.
addfile
(
tarinfo
=
f_i
,
fileobj
=
f
)
tar
.
addfile
(
tarinfo
=
f_i
,
fileobj
=
f
)
f
.
close
()
f
.
close
()
@
classmethod
def
fromJSON
(
cls
,
system
:
sys_base
.
System
,
json_obj
:
dict
)
->
LinuxConfigDiskImage
:
return
super
().
fromJSON
(
system
,
json_obj
)
# This is an additional example: building disk images directly from python
# This is an additional example: building disk images directly from python
# Could of course also have a version that generates the packer config from
# Could of course also have a version that generates the packer config from
...
@@ -227,7 +245,8 @@ class PackerDiskImage(DynamicDiskImage):
...
@@ -227,7 +245,8 @@ class PackerDiskImage(DynamicDiskImage):
json_obj
[
"config_path"
]
=
self
.
config_path
json_obj
[
"config_path"
]
=
self
.
config_path
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
sys_base
.
System
,
json_obj
:
dict
)
->
PackerDiskImage
:
# TODO
instance
=
super
().
fromJSON
(
system
,
json_obj
)
pass
instance
.
config_path
=
utils_base
.
get_json_attr_top
(
json_obj
,
"config_path"
)
return
instance
experiments/simbricks/orchestration/system/mem.py
View file @
3bbc0c04
...
@@ -20,6 +20,8 @@
...
@@ -20,6 +20,8 @@
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
from
__future__
import
annotations
from
simbricks.orchestration.system
import
base
from
simbricks.orchestration.system
import
base
from
simbricks.orchestration.utils
import
base
as
utils_base
from
simbricks.orchestration.utils
import
base
as
utils_base
...
@@ -38,7 +40,7 @@ class MemDeviceInterface(base.Interface):
...
@@ -38,7 +40,7 @@ class MemDeviceInterface(base.Interface):
def
connect
(
self
,
c
:
base
.
Channel
)
->
None
:
def
connect
(
self
,
c
:
base
.
Channel
)
->
None
:
# Note AK: a bit ugly, but I think we can't get around a rt check here
# Note AK: a bit ugly, but I think we can't get around a rt check here
if
not
c
is
isinstance
(
c
,
MemChannel
):
if
not
c
is
isinstance
(
c
,
MemChannel
):
raise
TypeError
(
'
MemDeviceInterface only connects to MemChannel
'
)
raise
TypeError
(
"
MemDeviceInterface only connects to MemChannel
"
)
super
().
connect
(
c
)
super
().
connect
(
c
)
...
@@ -57,17 +59,19 @@ class MemSimpleDevice(base.Component):
...
@@ -57,17 +59,19 @@ class MemSimpleDevice(base.Component):
def
__init__
(
self
,
s
:
base
.
System
):
def
__init__
(
self
,
s
:
base
.
System
):
super
().
__init__
(
s
)
super
().
__init__
(
s
)
self
.
_mem_if
:
MemDeviceInterface
=
MemDeviceInterface
(
c
=
self
)
self
.
_mem_if
:
MemDeviceInterface
=
MemDeviceInterface
(
c
=
self
)
self
.
_addr
=
0xe000000000000000
super
().
add_if
(
self
.
_mem_if
)
self
.
_addr
=
0xE000000000000000
self
.
_size
=
1024
*
1024
*
1024
# 1GB
self
.
_size
=
1024
*
1024
*
1024
# 1GB
self
.
_as_id
=
0
self
.
_as_id
=
0
def
interfaces
(
self
)
->
list
[
base
.
Interface
]:
return
[
self
.
_mem_if
]
def
add_if
(
self
,
interface
:
MemDeviceInterface
)
->
None
:
def
add_if
(
self
,
interface
:
MemDeviceInterface
)
->
None
:
utils_base
.
has_expected_type
(
obj
=
interface
,
expected_type
=
MemDeviceInterface
)
utils_base
.
has_expected_type
(
interface
,
MemDeviceInterface
)
assert
self
.
_mem_if
is
None
if
self
.
_mem_if
:
raise
Exception
(
f
"you overwrite MemDeviceInterface._mem_if (
{
self
.
_mem_if
.
id
()
}
->
{
interface
.
id
()
}
) "
)
self
.
_mem_if
=
interface
self
.
_mem_if
=
interface
super
().
add_if
(
self
.
_mem_if
)
def
toJSON
(
self
)
->
dict
:
def
toJSON
(
self
)
->
dict
:
json_obj
=
super
().
toJSON
()
json_obj
=
super
().
toJSON
()
...
@@ -77,7 +81,15 @@ class MemSimpleDevice(base.Component):
...
@@ -77,7 +81,15 @@ class MemSimpleDevice(base.Component):
json_obj
[
"as_id"
]
=
self
.
_as_id
json_obj
[
"as_id"
]
=
self
.
_as_id
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
base
.
System
,
json_obj
:
dict
)
->
MemSimpleDevice
:
# TODO
instance
=
super
().
fromJSON
(
system
,
json_obj
)
pass
mem_if_id
=
int
(
utils_base
.
get_json_attr_top
(
json_obj
,
"mem_if"
))
\ No newline at end of file
addr
=
utils_base
.
get_json_attr_top
(
json_obj
,
"addr"
)
size
=
utils_base
.
get_json_attr_top
(
json_obj
,
"size"
)
as_id
=
utils_base
.
get_json_attr_top
(
json_obj
,
"as_id"
)
instance
.
mem_if
=
system
.
get_inf
(
mem_if_id
)
instance
.
addr
=
addr
instance
.
size
=
size
instance
.
as_id
=
as_id
return
instance
experiments/simbricks/orchestration/system/nic.py
View file @
3bbc0c04
...
@@ -20,28 +20,65 @@
...
@@ -20,28 +20,65 @@
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
from
__future__
import
annotations
from
simbricks.orchestration.system
import
base
from
simbricks.orchestration.system
import
base
from
simbricks.orchestration.system
import
pcie
from
simbricks.orchestration.system
import
pcie
from
simbricks.orchestration.system
import
eth
from
simbricks.orchestration.system
import
eth
from
simbricks.orchestration.utils
import
base
as
utils_base
class
SimplePCIeNIC
(
pcie
.
PCIeSimpleDevice
,
eth
.
EthSimpleNIC
):
class
SimplePCIeNIC
(
base
.
Component
):
def
__init__
(
self
,
s
:
base
.
System
)
->
None
:
def
__init__
(
self
,
s
:
base
.
System
)
->
None
:
super
().
__init__
(
s
)
super
().
__init__
(
s
)
self
.
_ip
:
str
|
None
=
None
def
interfaces
(
self
)
->
list
[
base
.
Interface
]:
self
.
_eth_if
:
eth
.
EthInterface
=
eth
.
EthInterface
(
self
)
return
[
self
.
_pci_if
,
self
.
_eth_if
]
super
().
add_if
(
self
.
_eth_if
)
self
.
_pci_if
:
pcie
.
PCIeDeviceInterface
=
pcie
.
PCIeDeviceInterface
(
self
)
super
().
add_if
(
self
.
_pci_if
)
def
add_if
(
self
,
interface
:
eth
.
EthInterface
|
pcie
.
PCIeDeviceInterface
)
->
None
:
def
add_if
(
self
,
interface
:
eth
.
EthInterface
|
pcie
.
PCIeDeviceInterface
)
->
None
:
match
interface
:
match
interface
:
case
eth
.
EthInterface
():
case
eth
.
EthInterface
():
eth
.
EthSimpleNIC
.
add_if
(
self
,
interface
=
interface
)
if
hasattr
(
self
,
"_eth_if"
)
and
self
.
_eth_if
:
print
(
interface
)
print
(
self
.
_eth_if
)
raise
Exception
(
f
"you overwrite SimplePCIeNIC._eth_if (
{
self
.
_eth_if
.
id
()
}
->
{
interface
.
id
()
}
) "
)
self
.
_eth_if
=
interface
case
pcie
.
PCIeDeviceInterface
():
case
pcie
.
PCIeDeviceInterface
():
pcie
.
PCIeSimpleDevice
.
add_if
(
self
,
interface
=
interface
)
if
hasattr
(
self
,
"_pci_if"
)
and
self
.
_pci_if
:
raise
Exception
(
f
"you overwrite SimplePCIeNIC._pci_if. (
{
self
.
_pci_if
.
id
()
}
->
{
interface
.
id
()
}
)"
)
self
.
_pci_if
=
interface
case
_
:
case
_
:
raise
Exception
(
raise
Exception
(
f
"interface must have type EthInterface or PCIeDeviceInterface but has type
{
type
(
interface
)
}
"
f
"interface must have type EthInterface or PCIeDeviceInterface but has type
{
type
(
interface
)
}
"
)
)
super
().
add_if
(
interface
)
def
add_ipv4
(
self
,
ip
:
str
)
->
None
:
assert
self
.
_ip
is
None
self
.
_ip
=
ip
def
toJSON
(
self
)
->
dict
:
json_obj
=
super
().
toJSON
()
json_obj
[
"ip"
]
=
self
.
_ip
json_obj
[
"eth_if"
]
=
self
.
_eth_if
.
id
()
json_obj
[
"pci_if"
]
=
self
.
_pci_if
.
id
()
return
json_obj
@
classmethod
def
fromJSON
(
cls
,
system
:
base
.
System
,
json_obj
:
dict
)
->
SimplePCIeNIC
:
instance
=
super
().
fromJSON
(
system
,
json_obj
)
instance
.
_ip
=
utils_base
.
get_json_attr_top
(
json_obj
,
"ip"
)
eth_inf_id
=
int
(
utils_base
.
get_json_attr_top
(
json_obj
,
"eth_if"
))
instance
.
_eth_if
=
system
.
get_inf
(
eth_inf_id
)
inf_id
=
int
(
utils_base
.
get_json_attr_top
(
json_obj
,
"pci_if"
))
instance
.
_pci_if
=
system
.
get_inf
(
inf_id
)
return
instance
class
IntelI40eNIC
(
SimplePCIeNIC
):
class
IntelI40eNIC
(
SimplePCIeNIC
):
...
...
experiments/simbricks/orchestration/system/pcie.py
View file @
3bbc0c04
...
@@ -20,6 +20,8 @@
...
@@ -20,6 +20,8 @@
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
from
__future__
import
annotations
from
simbricks.orchestration.system
import
base
from
simbricks.orchestration.system
import
base
from
simbricks.orchestration.utils
import
base
as
utils_base
from
simbricks.orchestration.utils
import
base
as
utils_base
...
@@ -57,19 +59,25 @@ class PCIeSimpleDevice(base.Component):
...
@@ -57,19 +59,25 @@ class PCIeSimpleDevice(base.Component):
def
__init__
(
self
,
s
:
base
.
System
):
def
__init__
(
self
,
s
:
base
.
System
):
super
().
__init__
(
s
)
super
().
__init__
(
s
)
self
.
_pci_if
:
PCIeDeviceInterface
=
PCIeDeviceInterface
(
self
)
self
.
_pci_if
:
PCIeDeviceInterface
=
PCIeDeviceInterface
(
self
)
super
().
add_if
(
self
.
_pci_if
)
def
interfaces
(
self
)
->
list
[
base
.
Interface
]:
return
[
self
.
_pci_if
]
def
add_if
(
self
,
interface
:
PCIeDeviceInterface
)
->
None
:
def
add_if
(
self
,
interface
:
PCIeDeviceInterface
)
->
None
:
raise
Exception
(
"PCIeSimpleDevice already has PCI device interface"
)
utils_base
.
has_expected_type
(
interface
,
PCIeDeviceInterface
)
if
self
.
_pci_if
:
raise
Exception
(
f
"you overwrite PCIeSimpleDevice._pci_if. (
{
self
.
_pci_if
.
id
()
}
->
{
interface
.
id
()
}
)"
)
self
.
_pci_if
=
interface
super
().
add_if
(
interface
)
def
toJSON
(
self
)
->
dict
:
def
toJSON
(
self
)
->
dict
:
json_obj
=
super
().
toJSON
()
json_obj
=
super
().
toJSON
()
json_obj
[
"pci_if"
]
=
self
.
_pci_if
.
id
()
json_obj
[
"pci_if"
]
=
self
.
_pci_if
.
id
()
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
system
:
base
.
System
,
json_obj
:
dict
)
->
PCIeSimpleDevice
:
# TODO
instance
=
super
().
fromJSON
(
system
=
system
,
json_obj
=
json_obj
)
pass
inf_id
=
int
(
utils_base
.
get_json_attr_top
(
json_obj
,
"pci_if"
))
\ No newline at end of file
instance
.
_pci_if
=
system
.
get_inf
(
inf_id
)
return
instance
experiments/simbricks/orchestration/utils/base.py
View file @
3bbc0c04
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
import
abc
import
abc
import
itertools
import
itertools
import
importlib
class
IdObj
(
abc
.
ABC
):
class
IdObj
(
abc
.
ABC
):
...
@@ -38,10 +39,12 @@ class IdObj(abc.ABC):
...
@@ -38,10 +39,12 @@ class IdObj(abc.ABC):
json_obj
[
"id"
]
=
self
.
_id
json_obj
[
"id"
]
=
self
.
_id
return
json_obj
return
json_obj
@
staticmethod
@
classmethod
def
fromJSON
(
json_obj
):
def
fromJSON
(
cls
,
json_obj
):
# TODO
instance
=
cls
.
__new__
(
cls
)
pass
instance
.
_id
=
get_json_attr_top
(
json_obj
,
"id"
)
return
instance
def
check_type
(
obj
,
expected_type
)
->
bool
:
def
check_type
(
obj
,
expected_type
)
->
bool
:
"""
"""
...
@@ -58,8 +61,40 @@ def has_expected_type(obj, expected_type) -> None:
...
@@ -58,8 +61,40 @@ def has_expected_type(obj, expected_type) -> None:
f
"obj of type
{
type
(
obj
)
}
has not the type or is not a subtype of
{
expected_type
}
"
f
"obj of type
{
type
(
obj
)
}
has not the type or is not a subtype of
{
expected_type
}
"
)
)
def
has_attribute
(
obj
,
attr
:
str
)
->
None
:
def
has_attribute
(
obj
,
attr
:
str
)
->
None
:
if
not
hasattr
(
obj
,
attr
):
if
not
hasattr
(
obj
,
attr
):
raise
Exception
(
raise
Exception
(
f
"obj of type
{
type
(
obj
)
}
no attribute called
{
attr
}
"
)
f
"obj of type
{
type
(
obj
)
}
no attribute called
{
attr
}
"
)
def
get_json_attr_top_or_none
(
json_obj
:
dict
,
attr
:
str
)
->
dict
|
None
:
if
attr
in
json_obj
:
return
json_obj
[
attr
]
return
None
def
has_json_attr_top
(
json_obj
:
dict
,
attr
:
str
)
->
None
:
if
not
attr
in
json_obj
:
raise
Exception
(
f
"
{
json_obj
}
does not contain key
{
attr
}
"
)
def
get_json_attr_top
(
json_obj
:
dict
,
attr
:
str
)
->
dict
:
has_json_attr_top
(
json_obj
,
attr
)
return
json_obj
[
attr
]
def
get_cls_from_type_module
(
type_name
:
str
,
module_name
:
str
):
# Import the module
module
=
importlib
.
import_module
(
module_name
)
# Get the class from the module
cls
=
getattr
(
module
,
type_name
)
return
cls
def
get_cls_by_json
(
json_obj
:
dict
):
type_name
=
get_json_attr_top
(
json_obj
,
"type"
)
module_name
=
get_json_attr_top
(
json_obj
,
"module"
)
return
get_cls_from_type_module
(
type_name
,
module_name
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment