coreemu / core

Common Open Research Emulator
BSD 2-Clause "Simplified" License
683 stars 165 forks source link

[BUG] Creating Custom Services Using Python Script #369

Closed ZhanLun-Chang closed 4 years ago

ZhanLun-Chang commented 4 years ago

Describe the bug The "Configuring Services" section in the documentation CORE Python Scripting should be updated. Because there is no longer a "services" package under the "session". There four key methods there set_service, get_service, set_service_file and add_services are now defined in the class "core.services.coreservices.Coreservices". But the key question I want to ask is that How to execute a shell script on nodes when the session starts using python script? For example, I would like the PC node to execute the following simple one-line script sudo mkdir xxx when the simulation session starts using python script. I can type the that command in the "UserDefined" options in CORE GUI, but in terms of python scripting, I don't even know how to create the "service_name" that can be used in set_service(self, node_id, service_name). I have tried everything I can think of for "service_name", but alway got an error: TypeError: 'NoneType' object is not callable Are there any minimal working examples concerning how to execute a shell script on nodes using python scripts?

To Reproduce Steps to reproduce the behavior:

  1. Go to here
  2. Copy the codes in "Configuring Services" and paste it to .py file.
  3. Execute the python file using "sudo python3" in the terminal
  4. See errors

Expected behavior I expect the custom services to execute the shell script I defined using python script.

Screenshots error

Desktop (please complete the following information):

Additional context I have to admit that I don't understand the usage even after I read the docstring shown by help commands in interactive Python shell. Only until I read issue #268 did I know exactly how to use CoreService. By the way, another question is that how to create a host using python script? I don't see this in core.emulator.enumerations.NodeTypes.

bharnden commented 4 years ago

The "Configuring Services" section in the documentation CORE Python Scripting should be updated. Because there is no longer a "services" package under the "session". There four key methods there set_service, get_service, set_service_file and add_services are now defined in the class "core.services.coreservices.Coreservices".

Those are not examples using the python module as reference, but a Session class instance, which does have a services member. Potentially more of the example could be provided to be more complete and clear to avoid confusion.

If you are scripting things, you can run any command directly from a node and since the node has root context, you do not need it.

node.cmd("mkdir xxx")
ZhanLun-Chang commented 4 years ago

@bharnden My apologies. When I opened the sources file /usr/local/lib/python3.6/dist-packages/core/emulator/session.py I saw that services member. Before, I just used help(core.emulator.session) in the interactive Python shell to check the methods defined.

If I have a multiple-line script, do I just concatenate those commands using Python string type and put that Python string in the node.cmd("multiple_line_command")? or should I execute the "script.sh" other ways?

bharnden commented 4 years ago

You could iterate over a list of commands running them one of a time, but it would probably be easier to execute some designed script as you noted

ZhanLun-Chang commented 4 years ago

If I understand correctly, node.cmd("sh script.sh") would server my purpose here?

In case you didn't see the question in "additional context", how can I add a host node instead of a PC node using python script? I didn't see the "host" type in NodeTypes or there aren't any differences between these two and they are just represented with different icons in CORE GUI?

Sorry to bother you with so many rudimentary questions.

bharnden commented 4 years ago

You would need to use the NodeOptions class. The different node types are for nodes that are truly different. The model field here is used to differentiate the default nodes and maps to the services they run, which is what makes them different.

from core.emulator.emudata import NodeOptions

options = NodeOptions(model="PC")
session.add_node(options=options)
ZhanLun-Chang commented 4 years ago

I have tried to create nodes both with session.add_node() and with the code you provided (using NodeOptions with model=PC). However, they all visualized in CORE GUI in the same icons. As shown by the following figure, although corenode3 ~ corenode6 are created with session.add_node() and corenode7 is created using NodeOptions with model=PC, they are the same in terms of type and the icon. What I desire is the node named "host" on the right side of this figure which I created using GUI.
image

bharnden commented 4 years ago

You want model="host" then

ZhanLun-Chang commented 4 years ago

I just tried changing the model="PC" to model="host" with all other parts of Python script being the same, I got an error and thus cannot be visualized in CORE GUI. image

Hence, I try model="Host". The type is "host" but with a router icon in CORE GUI as shown in the first figure below. But I got a message: warning: unknown node type 'Host' in Node message! as shown in the second figure below. Host image

bharnden commented 4 years ago

Some services require external software to be installed. Like the SSH service for Hosts above. If you use the GUI you can create custom nodes with different sets of services for whatever you need, with whatever icon you like. In case you are looking for a custom look and feel to what you are doing.

ZhanLun-Chang commented 4 years ago

After I installed and started the ssh service, adding the host node using model="host" worked perfectly. There is no such constraint to create a host node in GUI and therefore I didn't realize ssh service is the problem although the error message shows exactly the ssh service isn't available. The reason I would like to create network topology using Python script is the scalability. It's not practical to create, for example, 1000 nodes in GUI and make these nodes execute scripts.

I encountered another problem when executing the code node.cmd("sh ~/hostattack.sh") which I executed without any errors in the terminal opened by double-clicking the host node created using Python script. The error message I got is Can't open ~/hostattack.sh\n". I tried sudo sh hostattack.sh as well, but this doesn't help. sherror

bharnden commented 4 years ago

~/ is relative to the root users home and not your normal user, potentially the assumption about how this path is resolving is incorrect. Make your path absolute and you will likely avoid this problem.

ZhanLun-Chang commented 4 years ago

Yes, the absolute path solved that problem. It works great now. Thank you very much for your patience and quick reply.

The following question is uncorrelated to this issue. If you think opening a new issue is better, please let me know.

I want to ask if I can adjust how many cpu resources the host can use? For example, I would like to run an application on the host node, can I configure how many cpu resources used to run that application by adjusting maybe some parameters I don't know now? Even if the total resources owned by the host are fixed, as long as I can decide how many portions of the total cpu resources to run that application, this would serve my purpose.

bharnden commented 4 years ago

There is a Discord channel for conversation like this, so it doesn't have to be a formal issue etc. https://discord.gg/AKd7kmP

Otherwise, no, there is no parameters to try and configure or constrain system resources.

ZhanLun-Chang commented 4 years ago

I should have asked first if there are some places to ask questions like the Discord channel instead of opening a formal issue. Thanks for the link! It will definitely help me out if I have other problems.