{"id":20111478,"url":"https://github.com/openstack/charm-magpie","last_synced_at":"2026-03-04T14:31:38.487Z","repository":{"id":59913176,"uuid":"317778566","full_name":"openstack/charm-magpie","owner":"openstack","description":"Juju Charm - Magpie infra testing. Mirror of code maintained at opendev.org.","archived":false,"fork":false,"pushed_at":"2024-07-05T08:16:03.000Z","size":245,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-02-22T20:46:59.860Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://opendev.org/openstack/charm-magpie","language":"Python","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openstack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-02T07:06:35.000Z","updated_at":"2024-07-05T08:16:07.000Z","dependencies_parsed_at":"2024-06-28T23:47:20.593Z","dependency_job_id":"f1d064a4-b82e-49c4-a694-00cd865446d2","html_url":"https://github.com/openstack/charm-magpie","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/openstack/charm-magpie","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openstack%2Fcharm-magpie","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openstack%2Fcharm-magpie/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openstack%2Fcharm-magpie/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openstack%2Fcharm-magpie/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openstack","download_url":"https://codeload.github.com/openstack/charm-magpie/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openstack%2Fcharm-magpie/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30083744,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T13:22:36.021Z","status":"ssl_error","status_checked_at":"2026-03-04T13:20:45.750Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-13T18:16:14.113Z","updated_at":"2026-03-04T14:31:38.469Z","avatar_url":"https://github.com/openstack.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Magpie\n\nMagpie is a charm used for testing the networking of a Juju provider/substrate.\n\nIt provides tools for testing:\n\n- DNS functionality\n- network connectivity between nodes (iperf, ping)\n- network benchmarking\n- MTU\n- local hostname lookup\n\n## Usage\n\nDeploy the charm to two or more units,\nthen run the provided actions to retrieve debug information about the nodes or run network diagnostic tests.\n\n```\njuju deploy magpie -n 3\n\njuju actions magpie\njuju run magpie/leader info\njuju run magpie/leader ping\n# etc.\n```\n\nCheck the charm config before deploying for values you may wish to tweak,\nand see the parameters accepted by each action.\n\n## TODO: document each action and the expected results\n\n## Network spaces\n\nIf you use network spaces in your Juju deployment (as you should) use\n`--bind '\u003cspace-name\u003e magpie=\u003cspace-name\u003e'` to force magpie to test that\nparticular network space.\n\nIt is possible to deploy several magpie charms\n(as different Juju applications) to the same server each in a different\nnetwork space.\n\nExample:\n\n```\njuju deploy magpie magpie-space1 --bind \"space1 magpie=space1\" -n 5 --to 0,2,1,4,3\njuju deploy magpie magpie-space2 --bind \"space2 magpie=space2\" -n 3 --to 3,2,0\njuju deploy magpie magpie-space3 --bind \"space3 magpie=space3\" -n 4 --to 3,2,1,0\njuju deploy magpie magpie-space4 --bind \"space4 magpie=space4\" -n 4 --to 3,2,1,0\n```\n\n## Benchmarking network with iperf and grafana\n\nAssumes juju 3.1\n\nStep 1, deploy COS:\n\n```\n# Deploy COS on microk8s.\n# https://charmhub.io/topics/canonical-observability-stack/tutorials/install-microk8s\njuju bootstrap microk8s microk8s\njuju add-model cos\njuju deploy cos-lite\n\n# Expose the endpoints for the magpie model to consume.\njuju offer grafana:grafana-dashboard\njuju offer prometheus:receive-remote-write\n```\n\nStep 2, deploy magpie and relate to COS\n\n```\njuju switch \u003ccontroller for cloud to be benchmarked\u003e\njuju add-model magpie\n\njuju consume microk8s:cos.prometheus\njuju consume microk8s:cos.grafana\n\n# adjust as required\njuju deploy magpie -n 3\njuju deploy ./magpie_ubuntu-22.04-amd64.charm -n 3\n\njuju deploy grafana-agent --channel edge\njuju relate magpie grafana-agent\njuju relate grafana-agent prometheus\njuju relate grafana-agent grafana\n```\n\nStep 3, run the iperf action and view results in grafana:\n\n```\n# adjust as needed\njuju run magpie/0 iperf\n\n# you may wish to run against one unit pair at a time:\njuju run magpie/0 iperf units=magpie/1\njuju run magpie/0 iperf units=magpie/2\n# etc.\n```\n\n\nObtain details to access grafana from COS:\n\n```\njuju show-unit -m microk8s:cos catalogue/0 --format json | jq -r '.[\"catalogue/0\"].\"relation-info\"[] | select(.\"application-data\".name == \"Grafana\") | .\"application-data\".url'\njuju config -m microk8s:cos grafana admin_user\njuju run -m microk8s:cos grafana/0 get-admin-password\n```\n\nFind the dashboard titled \"Magpie Network Benchmarking\",\nand limit the time range as required.\n\n## Bonded links testing and troubleshooting\n\nNetwork bonding enables the combination of two or more network interfaces into a single-bonded\n(logical) interface, which increases the bandwidth and provides redundancy. While Magpie does some\nsanity checks and could reveal some configuration problems, this part of README contains some\nadvanced troubleshooting information, which might be useful, while identifying and fixing the issue.\n\nThere are six bonding modes:\n\n### `balance-rr`\n\nRound-robin policy: Transmit packets in sequential order from the first available slave through the\nlast. This mode provides load balancing and fault tolerance.\n\n### `active-backup`\n\nActive-backup policy: Only one slave in the bond is active. A different slave becomes active if, and\nonly if, the active slave fails. The bond's MAC address is externally visible on only one port\n(network adapter) to avoid confusing the switch. This mode provides fault tolerance. The primary\noption affects the behavior of this mode.\n\n### `balance-xor`\n\nXOR policy: Transmit based on selectable hashing algorithm. The default policy is a simple\nsource+destination MAC address algorithm. Alternate transmit policies may be selected via the\n`xmit_hash_policy` option, described below. This mode provides load balancing and fault tolerance.\n\n### `broadcast`\n\nBroadcast policy: transmits everything on all slave interfaces. This mode provides fault tolerance.\n\n### `802.3ad` (LACP)\n\nLink Aggregation Control Protocol (IEEE 802.3ad LACP) is a control protocol that automatically\ndetects multiple links between two LACP enabled devices and configures them to use their maximum\npossible bandwidth by automatically trunking the links together. This mode has a prerequisite -\nthe switch(es) ports should have LACP configured and enabled.\n\n### `balance-tlb`\n\nAdaptive transmit load balancing: channel bonding that does not require any special switch support.\nThe outgoing traffic is distributed according to the current load (computed relative to the speed)\non each slave. Incoming traffic is received by the current slave. If the receiving slave fails,\nanother slave takes over the MAC address of the failed receiving slave.\n\n### `balance-alb`\n\nAdaptive load balancing: includes balance-tlb plus receive load balancing (rlb) for IPV4 traffic,\nand does not require any special switch support. The receive load balancing is achieved by ARP\nnegotiation.\n\nThe most commonly used modes are `active-backup` and `802.3ad` (LACP), and while active-backup\ndoes not require any third party configuration, it has its own cons - for example, it can't multiply\nthe total bandwidth of the link, while 802.3ad-based bond could utilize all bond members, therefore\nmultiplying the bandwidth. However, in order to get a fully working LACP link, an appropriate\nconfiguration has to be done both on the actor (link initiator) and partner (switch) side. Any\nmisconfiguration could lead to the link loss or instability, therefore it's very important to have\ncorrect settings applied to the both sides of the link.\n\nA quick overview of the LACP link status could be obtained by reading the\n`/proc/net/bonding/\u003cbond_name\u003e` file.\n\n```\n$ sudo cat /proc/net/bonding/bondM\nEthernet Channel Bonding Driver: v3.7.1 (April 27, 2011)\n\nBonding Mode: IEEE 802.3ad Dynamic link aggregation\nTransmit Hash Policy: layer3+4 (1)\nMII Status: up\nMII Polling Interval (ms): 100\nUp Delay (ms): 0\nDown Delay (ms): 0\n\n802.3ad info\nLACP rate: fast\nMin links: 0\nAggregator selection policy (ad_select): stable\nSystem priority: 65535\nSystem MAC address: 82:23:80:a1:a9:d3\nActive Aggregator Info:\n Aggregator ID: 1\n Number of ports: 2\n Actor Key: 15\n Partner Key: 201\n Partner Mac Address: 02:01:00:00:01:01\n\nSlave Interface: eno3\nMII Status: up\nSpeed: 10000 Mbps\nDuplex: full\nLink Failure Count: 0\nPermanent HW addr: 3c:ec:ef:19:eb:30\nSlave queue ID: 0\nAggregator ID: 1\nActor Churn State: none\nPartner Churn State: none\nActor Churned Count: 0\nPartner Churned Count: 0\ndetails actor lacp pdu:\n    system priority: 65535\n    system mac address: 82:23:80:a1:a9:d3\n    port key: 15\n    port priority: 255\n    port number: 1\n    port state: 63\ndetails partner lacp pdu:\n    system priority: 65534\n    system mac address: 02:01:00:00:01:01\n    oper key: 201\n    port priority: 1\n    port number: 12\n    port state: 63\n\nSlave Interface: eno1\nMII Status: up\nSpeed: 10000 Mbps\nDuplex: full\nLink Failure Count: 0\nPermanent HW addr: 3c:ec:ef:19:eb:2e\nSlave queue ID: 0\nAggregator ID: 1\nActor Churn State: none\nPartner Churn State: none\nActor Churned Count: 0\nPartner Churned Count: 0\ndetails actor lacp pdu:\n    system priority: 65535\n    system mac address: 82:23:80:a1:a9:d3\n    port key: 15\n    port priority: 255\n    port number: 2\n    port state: 63\ndetails partner lacp pdu:\n    system priority: 65534\n    system mac address: 02:01:00:00:01:01\n    oper key: 201\n    port priority: 1\n    port number: 1012\n    port state: 63\n```\n\nThe key things an operator should take a look at is:\n\n- LACP rate\n- Actor Churn State\n- Partner Churn State\n- Port State\n\n### LACP rate\n\nThe Link Aggregation Control Protocol (LACP) provides a standardized means for exchanging\ninformation between Partner Systems on a link to allow their Link Aggregation Control instances to\nreach agreement on the identity of the LAG to which the link belongs, move the link to that LAG, and\nenable its transmission and reception functions in an orderly manner. The protocol depends upon the\ntransmission of information and state, rather than the transmission of commands. LACPDUs (LACP Data\nUnit) sent by the first party (the Actor) convey to the second party (the Actor’s protocol Partner)\nwhat the Actor knows, both about its own state and that of the Partner.\n\nPeriodic transmission of LACPDUs occurs if the LACP Activity control of either the Actor or the\nPartner is Active LACP. These periodic transmissions will occur at either a slow or fast\ntransmission rate depending upon the expressed LACP_Timeout preference (Long Timeout or Short\nTimeout) of the Partner System.\n\n### Actor/Partner Churn State\n\nIn general, \"Churned\" port status means that the parties are unable to reach agreement upon the\ndesired state of a link. Under normal operation of the protocol, such a resolution would be reached\nvery rapidly; continued failure to reach agreement can be symptomatic of component failure, of the\npresence of non-standard devices on the link concerned, or of mis-configuration. Hence, detection of\nsuch failures is signalled by the Churn Detection algorithm to the operator in order to prompt\nadministrative action to further resolution.\n\n### Port State\n\nBoth of the Actor and Partner state are variables, encoded as individual bits within a single octet,\nas follows.\n\n0) LACP_Activity: Device intends to transmit periodically in order to find potential\nmembers for the aggregate. Active LACP is encoded as a 1; Passive LACP as a 0.\n1) LACP_Timeout: This flag indicates the Timeout control value with regard to this link. Short\nTimeout is encoded as a 1; Long Timeout as a 0.\n2) Aggregability: This flag indicates that the system considers this link to be Aggregateable; i.e.,\na potential candidate for aggregation. If FALSE (encoded as a 0), the link is considered to be\nIndividual; i.e., this link can be operated only as an individual link. Aggregatable is encoded as a\n1; Individual is encoded as a 0.\n3) Synchronization: Indicates that the bond on the transmitting machine is in sync with what’s being\nadvertised in the LACP frames, meaning the link has been allocated to the correct LAG, the group has\nbeen associated with a compatible Aggregator, and the identity of the LAG is consistent with the\nSystem ID and operational Key information transmitted. \"In Sync\" is encoded as a 1; \"Out of sync\" is\nencoded as a 0.\n4) Collecting: Bond is accepting traffic received on this port, collection of incoming frames on\nthis link is definitely enabled and is not expected to be disabled in the absence of administrative\nchanges or changes in received protocol information. True is encoded as a 1; False is encoded as a\n0.\n5) Distributing: Bond is sending traffic using these ports encoded. Same as above, but for egress\ntraffic. True is encoded as a 1; False is encoded as a 0.\n6) Defaulted: Determines, whether the receiving bond is using default (administratively defined)\nparameters, if the information was received in an LACP PDU. Default settings are encoded as a 1,\nLACP PDU is encoded as 0.\n7) Expired: Is the bond in the expired state. Yes encoded as a 1, No encoded as a 0.\n\nIn the example output above, both of the port states are equal to 63. Let's decode:\n\n```\n$ python3\nPython 3.8.4 (default, Jul 17 2020, 15:44:37)\n[Clang 11.0.3 (clang-1103.0.32.62)] on darwin\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n\u003e\u003e\u003e bin(63)\n'0b111111'\n```\n\nReading right to the left:\n\nLACP Activity: Active\nLACP Timeout: Short\nAggregability: Link is Aggregatable\nSynchronization: Link in sync\nCollecting: True - bond is accepting the traffic\nDistributing: True - bond is sending the traffic\nDefaulted: Info received from LACP PDU\nExpired: False - link is not expired\n\nThe above status represents the **fully healthy bond** without any LACP-related issues. Also, for\nthe operators' convenience, the [lacp_decoder.py](src/tools/lacp_decoder.py) script could be used to\nquickly convert the status to some human-friendly format.\n\nHowever, the situations where one of the links is misconfigured are happening too, so let's assume\nwe have the following:\n\n```\n$ sudo cat /proc/net/bonding/bondm\nEthernet Channel Bonding Driver: v3.7.1 (April 27, 2011)\n\nBonding Mode: IEEE 802.3ad Dynamic link aggregation\nTransmit Hash Policy: layer3+4 (1)\nMII Status: up\nMII Polling Interval (ms): 100\nUp Delay (ms): 0\nDown Delay (ms): 0\n\n802.3ad info\nLACP rate: fast\nMin links: 0\nAggregator selection policy (ad_select): stable\nSystem priority: 65535\nSystem MAC address: b4:96:91:6d:20:fc\nActive Aggregator Info:\n        Aggregator ID: 2\n        Number of ports: 1\n        Actor Key: 9\n        Partner Key: 32784\n        Partner Mac Address: 00:23:04:ee:be:66\n\nSlave Interface: enp197s0f2\nMII Status: up\nSpeed: 100 Mbps\nDuplex: full\nLink Failure Count: 0\nPermanent HW addr: b4:96:91:6d:20:fe\nSlave queue ID: 0\nAggregator ID: 1\nActor Churn State: churned\nPartner Churn State: none\nActor Churned Count: 1\nPartner Churned Count: 0\ndetails actor lacp pdu:\n    system priority: 65535\n    system mac address: b4:96:91:6d:20:fc\n    port key: 7\n    port priority: 255\n    port number: 1\n    port state: 7\ndetails partner lacp pdu:\n    system priority: 32667\n    system mac address: 00:23:04:ee:be:66\n    oper key: 32784\n    port priority: 32768\n    port number: 16661\n    port state: 13\n\nSlave Interface: enp197s0f0\nMII Status: up\nSpeed: 1000 Mbps\nDuplex: full\nLink Failure Count: 0\nPermanent HW addr: b4:96:91:6d:20:fc\nSlave queue ID: 0\nAggregator ID: 2\nActor Churn State: none\nPartner Churn State: none\nActor Churned Count: 0\nPartner Churned Count: 0\ndetails actor lacp pdu:\n    system priority: 65535\n    system mac address: b4:96:91:6d:20:fc\n    port key: 9\n    port priority: 255\n    port number: 2\n    port state: 63\ndetails partner lacp pdu:\n    system priority: 32667\n    system mac address: 00:23:04:ee:be:66\n    oper key: 32784\n    port priority: 32768\n    port number: 277\n    port state: 63\n```\n\nAs we could see, one of the links has different port states for both partner and actor, while the second\none has 63 for both - meaning, the first one is problematic and we'd need to dive more into this\nproblem.\n\nLet's decode both of the statuses, using the mentioned script:\n\n```\n$ python ./lacp-decoder.py 7 13\n(Equal for both ports) LACP Activity: Active LACP\nLACP Timeout: Short (Port 1) / Long (Port 2)\n(Equal for both ports) Aggregability: Aggregatable\nSynchronization: Link out of sync (Port 1) / Link in sync (Port 2)\n(Equal for both ports) Collecting: Ingress traffic: Rejecting\n(Equal for both ports) Distributing: Egress traffic: Not sending\n(Equal for both ports) Is Defaulted: Settings are received from LACP PDU\n(Equal for both ports) Link Expiration: No\n```\n\nThe above output means that there are two differences between these statuses: LACP Timeout and\nSynchronization. That means two things:\n\n1) the Partner side (a switch side in most of the cases) has incorrectly configured LACP timeout\ncontrol. To resolve this, an operator has to either change the LACP rate from the Actor (e.g a\nserver) side to \"Slow\", or adjust the Partner (e.g switch) LACP rate to \"Fast\".\n2) the Partner side considers this physical link as a part of a different link aggregation group. The\nswitch config has to be revisited and link aggregation group members need to be verified again,\nensuring there is no extra or wrong links configured as part of the single LAG.\n\nAfter addressing the above issues, the port state will change to 63, which means \"LACP link is fully\nfunctional\".\n\n# Bugs\n\nPlease report bugs on [Launchpad](https://bugs.launchpad.net/charm-magpie/+filebug).\n\nFor general questions please refer to the OpenStack [Charm Guide](https://docs.openstack.org/charm-guide/latest/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenstack%2Fcharm-magpie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenstack%2Fcharm-magpie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenstack%2Fcharm-magpie/lists"}