Skip to content

Latest commit

 

History

History
39 lines (29 loc) · 3.12 KB

CONTRIBUTING.md

File metadata and controls

39 lines (29 loc) · 3.12 KB

Contributing to bmc

Thanks for your interest! Any questions, please submit an issue.

Getting Started

BMC is powered by google/gopacket. It is strongly recommended to read the documentation for this in full before digging into this codebase. The pkg/ipmi package essentially just implements IPMI layers. The root bmc package ties these together with transport and session establishment logic, and a friendlier API.

New Command

Commands are specified in their own file within pkg/ipmi, named after the lower-cased command, separated with underscores, e.g. get_channel_authentication_capabilities.go. This file contains request and/or response structs, named after the unabbreviated command name followed by Req for requests, and Rsp for responses. E.g. GetChannelAuthenticationCapabilitiesReq and GetChannelAuthenticationCapabilitiesRsp respectively. If a command has no request parameters (relying only on NetFn and Cmd), the *Req struct should be omitted. Likewise, if the response is empty and the completion code is sufficient, the *Rsp struct should be omitted. These structs correspond to layers that can be sent and received respectively. It is perfectly fine - and even encouraged - for request structs to not be decodable, and response struct to not be serialisable. Be sure to reference the relevant section(s) of the spec(s) in the struct documentation. Layers are defined in layer_types.go and simply returned in LayerType(). It is generally recommended for these to be exported. Tests are encouraged, especially for complex responses where there's lots of bit shifting.

For each struct, define a OperationX variable in operation.go, where X is the name of the struct. Be sure to add response operations to the operationLayerTypes map in this file, as otherwise the library will not know which layer to use.

If the request or response payload has any enum-style fields, e.g. ChassisControl, create a new type with constants for its possible values, then implement fmt.Stringer to make it print nicely. It is recommended not to embed any fields implementing fmt.Stringer in a layer, as this means it cannot be printed by gopacket (there is an issue here).

Session-less commands should be added to the SessionlessCommands interface, then the appropriate decoders in v(1|2)sessionless.go. Commands that must be sent inside a session should be added to the SessionCommands interface, then the appropriate decoders in v(1|2)session.go. Writing appropriate implementations for IPMI v1.5 and v2.0 in v1session(less).go and v2session(less).go respectively makes the command easy for users to execute.

Examples