Skip to content

Move data types used by the vm and api_server in a different crate #276

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed

Move data types used by the vm and api_server in a different crate #276

wants to merge 7 commits into from

Conversation

dianpopa
Copy link
Contributor

@dianpopa dianpopa commented May 15, 2018

Changes

  • moved all sync types defined inside api_server crate to data_model crate (i.e. logger, boot source, drive description, network related)
  • some additional cleanup inside api_server

Testing

Build Time

Prerequisite

## add the necessary musl target to the active toolchain
rustup target add x86_64-unknown-linux-musl

In-tree tests

sudo env "PATH=$PATH" pytest  functional/test_api.py

Coverage

  • overall 72.8%
  • per files relevant to this PR:
File Coverage %
data_model/src/vm/boot_source.rs 94.1%
data_model/src/vm/machine_config.rs 96.7%
data_model/src/device_config/drive.rs 97.8%
data_model/src/device_config/net.rs 98.0%
data_model/src/lib.rs 100%
data_model/src/vm/logger.rs 100%
data_model/src/device_config/mod.rs 100%

@dianpopa dianpopa requested a review from a team May 15, 2018 15:02
@dianpopa dianpopa self-assigned this May 15, 2018
@@ -87,7 +69,6 @@ impl GenerateResponse for OkStatus {
// Potential errors associated with sync requests.
#[derive(Debug)]
pub enum Error {
GuestCIDAlreadyInUse,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clarification question: is this going away because a PUT to the same ID will result in an update / bad request (depending on whether or not the guest has booted)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error was only used for the vsock devices (CID = Context Identifier and is a vsock specific concept), so no need for it anymore.

pub fn new(
drive_id: String,
path_on_host: String,
_is_attached: bool,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this isn't used, why not remove it altogether?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my comment on a different attached: The state of the device can be one of Attached, Detached and Detaching. We can't have the state as a boolean. I know we are not using it right now, but I wouldn't suggest removing it because we would break the compatibility with previous versions of Firecracker. The other option is to ask the clients if they are ok with that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andreeaflorescu pretty much concluded what I had in mind. We want to add more items to that enum and we will need it for the logic later on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let us not worry about this function since I will remove it once the vmm-no-api is out (which is gonna be pretty soon).

block_devices_configs.contains_drive_id(String::from("2")),
false
);
delete_dummy_path(dummy_filename_1);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test clash! :) I added the same test in #263 and removed it following feedback on it. To relay the feedback, there's too much test code for minor implementation details. The relevant assert!s can be moved to any other test.
As a side note, please clean up the temporary files before assert!s, if the test panics the files will remain on disk.

}

#[derive(Debug, Deserialize, PartialEq, Serialize)]
pub struct BootSourceBody {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this will be used by both API and VMM, I think we should stick with BootSource, not BootSourceBody because this names implies it belongs to the api.

}

impl BootSourceBody {
pub fn new(boot_source_id: String) -> Self {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be used only in tests. Can we add a cfg test to it? It doesn't look like we would ever use the constructor for anything else.

}
}

pub enum PutBootSourceConfigError {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked at the logger definition in data_model and I think it makes more sense to have them all named just BootSourceError instead of PutBootSourceConfigError, just like you already did for the Logger.

pub fn new(
drive_id: String,
path_on_host: String,
_is_attached: bool,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The state of the device can be one of Attached, Detached and Detaching. We can't have the state as a boolean. I know we are not using it right now, but I wouldn't suggest removing it because we would break the compatibility with previous versions of Firecracker. The other option is to ask the clients if they are ok with that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree but I did it this way to avoid including the DeviceState enum here also, since there is no logic for the moment...We could add it when we actually need the members of the enum. What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok.

self.permissions == DrivePermissions::ro
}

pub fn new(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we actually need this function? It seem like all the struct fields are public, thus we can create the object directly. Also, this is only used in tests and with vmm-no-api, which we plan to remove anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will leave it there for the moment and I will remove it completely once the vmm-no-api is removed.

// This struct represents the strongly typed equivalent of the json body from net iface
// related requests.
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct NetworkInterfaceBody {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove Body from the struct name.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While Body might not be the best choice in terms of naming, leaving this as just struct NetworkInterface feels a bit off in my opinion :-s

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that NetworkInterfaceConfig is an appropriate name since most of the things we have in the data model are actually configs.

}

impl NetworkInterfaceBody {
pub fn new(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also used only in tests and all fields are public.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem I see here is with the fields being public not with the presence of the new function. I suggest I add setters and getters for the ones that we actually set from outside. I think this is the correct way to do it. What do you think?


#[test]
fn test_machine_config_error() {
assert_eq!(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes more sense to test these errors as part of the vmm function put_virtual_machine_configuration. I would not add these here just for the coverage score.

@@ -1,3 +1,6 @@
pub mod boot_source;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this doesn't complicate things too much, I would avoid both having pub modules, and also pub using them :-s I think it's cleaner if we just leave the modules as public, without also re-exporting, at the cost of having to be a bit more verbose when we import different things :-s

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree since everything in boot_source is called BootSourceThis and BootSourceThat.

1 if method == Method::Put => {
let drive =
serde_json::from_slice::<BlockDeviceConfig>(body).map_err(Error::SerdeJson)?;
if id_from_path.unwrap() != drive.drive_id {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should do this check inside into_parsed_request(), because it's likely we'll need it for other methods also (PATCH for example, if we do end up using it). This implies adding a new argument to into_parsed_request() which provides a reference to the id from the path.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did it this way the first time which lead me to the discovery that it does not imply only that. It implies a lot of changes since basically I change the signature of a function inside a Trait that is implemented by all types.

// This struct represents the strongly typed equivalent of the json body from net iface
// related requests.
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct NetworkInterfaceBody {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While Body might not be the best choice in terms of naming, leaving this as just struct NetworkInterface feels a bit off in my opinion :-s

@@ -60,7 +60,7 @@ fn build_terminated_if_name(if_name: &str) -> Result<Vec<u8>> {
}

impl Tap {
pub fn open_named(if_name: &str) -> Result<Tap> {
pub fn open_named(if_name: &String) -> Result<Tap> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did this change to &String instead of &str?

@dianpopa
Copy link
Contributor Author

I will close this for now as files from this PR have been completely changed in the meantime and it would take less time recreating the changes than rebasing.

@dianpopa dianpopa closed this Jun 26, 2018
@dianpopa dianpopa deleted the api_server_to_dm branch November 9, 2018 09:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants