Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 44 additions & 2 deletions cmake/CliFboss2.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
# In general, libraries and binaries in fboss/foo/bar are built by
# cmake/FooBar.cmake

add_fbthrift_cpp_library(
cli_metadata
fboss/cli/fboss2/cli_metadata.thrift
OPTIONS
json
)

add_fbthrift_cpp_library(
cli_model
fboss/cli/fboss2/cli.thrift
Expand Down Expand Up @@ -466,6 +473,8 @@ add_library(fboss2_lib
fboss/cli/fboss2/commands/show/interface/prbs/stats/CmdShowInterfacePrbsStats.h
fboss/cli/fboss2/commands/show/rif/CmdShowRif.h
fboss/cli/fboss2/commands/show/rif/CmdShowRif.cpp
fboss/cli/fboss2/commands/show/running_config/CmdShowRunningConfig.cpp
fboss/cli/fboss2/commands/show/running_config/CmdShowRunningConfig.h
fboss/cli/fboss2/commands/show/sdk/dump/CmdShowSdkDump.h
fboss/cli/fboss2/commands/show/systemport/CmdShowSystemPort.h
fboss/cli/fboss2/commands/show/systemport/CmdShowSystemPort.cpp
Expand All @@ -476,6 +485,7 @@ add_library(fboss2_lib
fboss/cli/fboss2/commands/show/transceiver/CmdShowTransceiver.cpp
fboss/cli/fboss2/commands/start/pcap/CmdStartPcap.h
fboss/cli/fboss2/commands/stop/pcap/CmdStopPcap.h
fboss/cli/fboss2/CliAppInit.h
fboss/cli/fboss2/CmdSubcommands.cpp
fboss/cli/fboss2/oss/CmdGlobalOptions.cpp
fboss/cli/fboss2/oss/CmdList.cpp
Expand Down Expand Up @@ -584,10 +594,31 @@ add_library(fboss2_config_lib
fboss/cli/fboss2/commands/config/CmdConfigReload.h
fboss/cli/fboss2/commands/config/CmdConfigReload.cpp
fboss/cli/fboss2/commands/config/interface/CmdConfigInterface.h
fboss/cli/fboss2/commands/config/interface/CmdConfigInterfaceDescription.h
fboss/cli/fboss2/commands/config/interface/CmdConfigInterfaceDescription.cpp
fboss/cli/fboss2/commands/config/interface/CmdConfigInterfaceMtu.h
fboss/cli/fboss2/commands/config/interface/CmdConfigInterfaceDescription.h
fboss/cli/fboss2/commands/config/interface/CmdConfigInterfaceMtu.cpp
fboss/cli/fboss2/commands/config/interface/CmdConfigInterfaceMtu.h
fboss/cli/fboss2/commands/config/interface/CmdConfigInterfaceQueuingPolicy.cpp
fboss/cli/fboss2/commands/config/interface/CmdConfigInterfaceQueuingPolicy.h
fboss/cli/fboss2/commands/config/interface/pfc_config/CmdConfigInterfacePfcConfig.cpp
fboss/cli/fboss2/commands/config/interface/pfc_config/CmdConfigInterfacePfcConfig.h
fboss/cli/fboss2/commands/config/interface/pfc_config/PfcConfigUtils.h
fboss/cli/fboss2/commands/config/interface/switchport/CmdConfigInterfaceSwitchport.h
fboss/cli/fboss2/commands/config/interface/switchport/access/CmdConfigInterfaceSwitchportAccess.h
fboss/cli/fboss2/commands/config/interface/switchport/access/vlan/CmdConfigInterfaceSwitchportAccessVlan.cpp
fboss/cli/fboss2/commands/config/interface/switchport/access/vlan/CmdConfigInterfaceSwitchportAccessVlan.h
fboss/cli/fboss2/commands/config/qos/CmdConfigQos.h
fboss/cli/fboss2/commands/config/qos/buffer_pool/CmdConfigQosBufferPool.cpp
fboss/cli/fboss2/commands/config/qos/buffer_pool/CmdConfigQosBufferPool.h
fboss/cli/fboss2/commands/config/qos/policy/CmdConfigQosPolicy.h
fboss/cli/fboss2/commands/config/qos/policy/CmdConfigQosPolicyMap.cpp
fboss/cli/fboss2/commands/config/qos/policy/CmdConfigQosPolicyMap.h
fboss/cli/fboss2/commands/config/qos/priority_group_policy/CmdConfigQosPriorityGroupPolicy.h
fboss/cli/fboss2/commands/config/qos/priority_group_policy/CmdConfigQosPriorityGroupPolicyGroupId.cpp
fboss/cli/fboss2/commands/config/qos/priority_group_policy/CmdConfigQosPriorityGroupPolicyGroupId.h
fboss/cli/fboss2/commands/config/qos/queuing_policy/CmdConfigQosQueuingPolicy.h
fboss/cli/fboss2/commands/config/qos/queuing_policy/CmdConfigQosQueuingPolicyQueueId.cpp
fboss/cli/fboss2/commands/config/qos/queuing_policy/CmdConfigQosQueuingPolicyQueueId.h
fboss/cli/fboss2/commands/config/history/CmdConfigHistory.h
fboss/cli/fboss2/commands/config/history/CmdConfigHistory.cpp
fboss/cli/fboss2/commands/config/rollback/CmdConfigRollback.h
Expand All @@ -596,15 +627,26 @@ add_library(fboss2_config_lib
fboss/cli/fboss2/commands/config/session/CmdConfigSessionCommit.cpp
fboss/cli/fboss2/commands/config/session/CmdConfigSessionDiff.h
fboss/cli/fboss2/commands/config/session/CmdConfigSessionDiff.cpp
fboss/cli/fboss2/commands/config/session/CmdConfigSessionRebase.h
fboss/cli/fboss2/commands/config/session/CmdConfigSessionRebase.cpp
fboss/cli/fboss2/commands/config/vlan/CmdConfigVlan.h
fboss/cli/fboss2/commands/config/vlan/static_mac/CmdConfigVlanStaticMac.h
fboss/cli/fboss2/commands/config/vlan/static_mac/add/CmdConfigVlanStaticMacAdd.h
fboss/cli/fboss2/commands/config/vlan/static_mac/add/CmdConfigVlanStaticMacAdd.cpp
fboss/cli/fboss2/commands/config/vlan/static_mac/delete/CmdConfigVlanStaticMacDelete.h
fboss/cli/fboss2/commands/config/vlan/static_mac/delete/CmdConfigVlanStaticMacDelete.cpp
fboss/cli/fboss2/session/ConfigSession.h
fboss/cli/fboss2/session/ConfigSession.cpp
fboss/cli/fboss2/session/Git.h
fboss/cli/fboss2/session/Git.cpp
fboss/cli/fboss2/utils/InterfaceList.h
fboss/cli/fboss2/utils/InterfaceList.cpp
fboss/cli/fboss2/CmdListConfig.cpp
fboss/cli/fboss2/CmdHandlerImplConfig.cpp
)

target_link_libraries(fboss2_config_lib
cli_metadata
fboss2_lib
agent_dir_util
)
Expand Down
39 changes: 38 additions & 1 deletion cmake/CliFboss2Test.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,20 @@ gtest_discover_tests(fboss2_framework_test)

# cmd_test - Command tests from BUCK file
add_executable(fboss2_cmd_test
fboss/cli/fboss2/oss/CmdListConfig.cpp
fboss/cli/fboss2/test/TestMain.cpp
fboss/cli/fboss2/test/CmdConfigAppliedInfoTest.cpp
fboss/cli/fboss2/test/CmdConfigHistoryTest.cpp
fboss/cli/fboss2/test/CmdConfigInterfaceDescriptionTest.cpp
fboss/cli/fboss2/test/CmdConfigInterfaceMtuTest.cpp
fboss/cli/fboss2/test/CmdConfigInterfaceSwitchportAccessVlanTest.cpp
fboss/cli/fboss2/test/CmdConfigQosBufferPoolTest.cpp
fboss/cli/fboss2/test/CmdConfigReloadTest.cpp
fboss/cli/fboss2/test/CmdConfigSessionDiffTest.cpp
fboss/cli/fboss2/test/CmdConfigSessionTest.cpp
fboss/cli/fboss2/test/CmdConfigVlanStaticMacTest.cpp
fboss/cli/fboss2/test/CmdGetPcapTest.cpp
fboss/cli/fboss2/test/CmdListConfigTest.cpp
fboss/cli/fboss2/test/CmdSetPortStateTest.cpp
fboss/cli/fboss2/test/CmdShowAclTest.cpp
fboss/cli/fboss2/test/CmdShowAgentSslTest.cpp
Expand All @@ -52,7 +58,6 @@ add_executable(fboss2_cmd_test
fboss/cli/fboss2/test/CmdShowL2Test.cpp
fboss/cli/fboss2/test/CmdShowLldpTest.cpp
fboss/cli/fboss2/test/CmdShowNdpTest.cpp
fboss/cli/fboss2/test/CmdGetPcapTest.cpp
fboss/cli/fboss2/test/CmdShowAggregatePortTest.cpp
fboss/cli/fboss2/test/CmdShowCpuPortTest.cpp
fboss/cli/fboss2/test/CmdShowExampleTest.cpp
Expand All @@ -69,10 +74,12 @@ add_executable(fboss2_cmd_test
fboss/cli/fboss2/test/CmdShowProductTest.cpp
fboss/cli/fboss2/test/CmdShowRouteDetailsTest.cpp
fboss/cli/fboss2/test/CmdShowRouteSummaryTest.cpp
fboss/cli/fboss2/test/CmdShowRunningConfigTest.cpp
fboss/cli/fboss2/test/CmdShowTeFlowTest.cpp
# fboss/cli/fboss2/test/CmdShowTransceiverTest.cpp - excluded (depends on configerator bgp namespace)
fboss/cli/fboss2/test/CmdStartPcapTest.cpp
fboss/cli/fboss2/test/CmdStopPcapTest.cpp
fboss/cli/fboss2/test/GitTest.cpp
fboss/cli/fboss2/test/PortMapTest.cpp
)

Expand Down Expand Up @@ -105,3 +112,33 @@ target_link_libraries(thrift_latency_test
Folly::folly
FBThrift::thriftcpp2
)

# cli_test - CLI E2E test binary
#
# CLI tests are platform/SAI independent - they test the CLI binary which
# communicates with the agent via Thrift, without running the actual fboss2-dev
# binary.
add_executable(cli_test
fboss/cli/fboss2/oss/CmdListConfig.cpp
fboss/cli/test/CliTest.cpp
fboss/cli/test/ConfigInterfaceDescriptionTest.cpp
fboss/cli/test/ConfigInterfaceMtuTest.cpp
)

target_link_libraries(cli_test
fboss2_lib
fboss2_config_lib
thrift_service_utils
CLI11::CLI11
${GTEST}
${LIBGMOCK_LIBRARIES}
Folly::folly
Folly::folly_test_util
FBThrift::thriftcpp2
gflags
fmt::fmt
)

target_include_directories(cli_test PUBLIC
${CMAKE_SOURCE_DIR}
)
44 changes: 44 additions & 0 deletions fboss/cli/fboss2/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ thrift_library(
thrift_srcs = {"cli.thrift": []},
)

thrift_library(
name = "cli_metadata",
languages = [
"cpp2",
],
thrift_cpp2_options = "json",
thrift_srcs = {"cli_metadata.thrift": []},
)

# NOTE: all of the actual command tree is managed inside CmdList.cpp
# CmdList.h defines the data structure
cpp_library(
Expand Down Expand Up @@ -70,6 +79,7 @@ cpp_library(
"CmdSubcommands.cpp",
],
headers = [
"CliAppInit.h",
"CmdArgsLists.h",
"CmdSubcommands.h",
],
Expand Down Expand Up @@ -321,6 +331,7 @@ cpp_library(
"commands/show/port/CmdShowPortQueue.cpp",
"commands/show/rif/CmdShowRif.cpp",
"commands/show/route/utils.cpp",
"commands/show/running_config/CmdShowRunningConfig.cpp",
"commands/show/systemport/CmdShowSystemPort.cpp",
"commands/show/transceiver/CmdShowTransceiver.cpp",
"facebook/CmdHandlerImpl.cpp",
Expand Down Expand Up @@ -495,6 +506,7 @@ cpp_library(
"commands/show/product/CmdShowProduct.h",
"commands/show/product/CmdShowProductDetails.h",
"commands/show/rif/CmdShowRif.h",
"commands/show/running_config/CmdShowRunningConfig.h",
"commands/show/route/CmdShowRoute.h",
"commands/show/route/CmdShowRouteDetails.h",
"commands/show/route/CmdShowRouteSummary.h",
Expand Down Expand Up @@ -792,10 +804,21 @@ cpp_library(
"commands/config/history/CmdConfigHistory.cpp",
"commands/config/interface/CmdConfigInterfaceDescription.cpp",
"commands/config/interface/CmdConfigInterfaceMtu.cpp",
"commands/config/interface/CmdConfigInterfaceQueuingPolicy.cpp",
"commands/config/interface/pfc_config/CmdConfigInterfacePfcConfig.cpp",
"commands/config/interface/switchport/access/vlan/CmdConfigInterfaceSwitchportAccessVlan.cpp",
"commands/config/qos/buffer_pool/CmdConfigQosBufferPool.cpp",
"commands/config/qos/policy/CmdConfigQosPolicyMap.cpp",
"commands/config/qos/priority_group_policy/CmdConfigQosPriorityGroupPolicyGroupId.cpp",
"commands/config/qos/queuing_policy/CmdConfigQosQueuingPolicyQueueId.cpp",
"commands/config/rollback/CmdConfigRollback.cpp",
"commands/config/session/CmdConfigSessionCommit.cpp",
"commands/config/session/CmdConfigSessionDiff.cpp",
"commands/config/session/CmdConfigSessionRebase.cpp",
"commands/config/vlan/static_mac/add/CmdConfigVlanStaticMacAdd.cpp",
"commands/config/vlan/static_mac/delete/CmdConfigVlanStaticMacDelete.cpp",
"session/ConfigSession.cpp",
"session/Git.cpp",
"utils/InterfaceList.cpp",
],
headers = [
Expand All @@ -805,16 +828,37 @@ cpp_library(
"commands/config/interface/CmdConfigInterface.h",
"commands/config/interface/CmdConfigInterfaceDescription.h",
"commands/config/interface/CmdConfigInterfaceMtu.h",
"commands/config/interface/CmdConfigInterfaceQueuingPolicy.h",
"commands/config/interface/pfc_config/CmdConfigInterfacePfcConfig.h",
"commands/config/interface/pfc_config/PfcConfigUtils.h",
"commands/config/interface/switchport/CmdConfigInterfaceSwitchport.h",
"commands/config/interface/switchport/access/CmdConfigInterfaceSwitchportAccess.h",
"commands/config/interface/switchport/access/vlan/CmdConfigInterfaceSwitchportAccessVlan.h",
"commands/config/qos/CmdConfigQos.h",
"commands/config/qos/buffer_pool/CmdConfigQosBufferPool.h",
"commands/config/qos/policy/CmdConfigQosPolicy.h",
"commands/config/qos/policy/CmdConfigQosPolicyMap.h",
"commands/config/qos/priority_group_policy/CmdConfigQosPriorityGroupPolicy.h",
"commands/config/qos/priority_group_policy/CmdConfigQosPriorityGroupPolicyGroupId.h",
"commands/config/qos/queuing_policy/CmdConfigQosQueuingPolicy.h",
"commands/config/qos/queuing_policy/CmdConfigQosQueuingPolicyQueueId.h",
"commands/config/rollback/CmdConfigRollback.h",
"commands/config/session/CmdConfigSessionCommit.h",
"commands/config/session/CmdConfigSessionDiff.h",
"commands/config/session/CmdConfigSessionRebase.h",
"commands/config/vlan/CmdConfigVlan.h",
"commands/config/vlan/static_mac/CmdConfigVlanStaticMac.h",
"commands/config/vlan/static_mac/add/CmdConfigVlanStaticMacAdd.h",
"commands/config/vlan/static_mac/delete/CmdConfigVlanStaticMacDelete.h",
"session/ConfigSession.h",
"session/Git.h",
"utils/InterfaceList.h",
],
exported_deps = [
"fbsource//third-party/fmt:fmt",
"fbsource//third-party/glog:glog",
"fbsource//third-party/re2:re2",
":cli_metadata-cpp2-types",
":cmd-common-utils",
":cmd-handler",
":fboss2-lib",
Expand Down
37 changes: 37 additions & 0 deletions fboss/cli/fboss2/CliAppInit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2004-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#pragma once

#include <CLI/App.hpp>
#include "fboss/cli/fboss2/CmdGlobalOptions.h"
#include "fboss/cli/fboss2/CmdList.h"
#include "fboss/cli/fboss2/CmdSubcommands.h"

namespace facebook::fboss::utils {

/**
* Initialize the CLI app with global options and command tree.
* This sets up the CLI infrastructure and should be called before parsing.
*
* This function is shared between the main CLI binary and CLI E2E tests
* to ensure consistent CLI initialization.
*/
inline void initApp(CLI::App& app) {
app.require_subcommand();

// Initialize global options (--fmt, --host, etc.)
CmdGlobalOptions::getInstance()->init(app);

// Initialize command tree with all available commands
CmdSubcommands::getInstance()->init(
app, kCommandTree(), kAdditionalCommandTree(), kSpecialCommands());
}

} // namespace facebook::fboss::utils
49 changes: 35 additions & 14 deletions fboss/cli/fboss2/CmdHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,38 @@
*/

#include "fboss/cli/fboss2/CmdHandler.h"
#include "fboss/cli/fboss2/CmdArgsLists.h"
#include "fboss/cli/fboss2/CmdGlobalOptions.h"
#include "fboss/cli/fboss2/CmdList.h"
#include "fboss/cli/fboss2/gen-cpp2/cli_types.h"
#include "fboss/cli/fboss2/utils/AggregateOp.h"
#include "fboss/cli/fboss2/utils/AggregateUtils.h"
#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h"
#include "thrift/lib/cpp/util/EnumUtils.h"
#include "thrift/lib/cpp2/protocol/Serializer.h"

#include <fmt/format.h>
#include <folly/Conv.h>
#include <folly/Demangle.h>
#include <folly/ScopeGuard.h>
#include <folly/Traits.h>
#include <folly/logging/xlog.h>
#include <folly/stop_watch.h>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <exception>
#include <future>
#include <iostream>
#include <map>
#include <memory>
#include <optional>
#include <queue>
#include <stdexcept>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
Comment on lines +22 to +43
Copy link
Contributor

Choose a reason for hiding this comment

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

Why suddenly includes so many libraries? Your change in the implementation below doesn't seem to rely on all these libraries


template <typename CmdTypeT>
void printTabular(
Expand Down Expand Up @@ -154,20 +175,10 @@ void printAggregate(

namespace facebook::fboss {

static bool hasRun = false;

template <typename CmdTypeT, typename CmdTypeTraits>
void CmdHandler<CmdTypeT, CmdTypeTraits>::runHelper() {
// Parsing library invokes every chained command handler, but we only need
// the 'leaf' command handler to be invoked. Thus, after the first (leaf)
// command handler is invoked, simply return.
// TODO: explore if the parsing library provides a better way to implement
// this.
if (hasRun) {
return;
}

hasRun = true;
// Note: The callback wrapper in CmdSubcommands.cpp ensures that only the
// leaf command handler is invoked. It checks if get_subcommands() is empty.
auto extraOptionsEC =
CmdGlobalOptions::getInstance()->validateNonFilterOptions();
if (extraOptionsEC != cli::CliOptionResult::EOK) {
Expand Down Expand Up @@ -273,11 +284,19 @@ void CmdHandler<CmdTypeT, CmdTypeTraits>::runHelper() {
}
}

// Collect errors and display at end of execution
// Collect errors and display at end of execution, then throw if any failures
std::string combinedErrors;
while (!executionFailures.empty()) {
auto [host, errStr] = executionFailures.front();
executionFailures.pop();
XLOG(ERR) << host << " - Error in command execution: " << errStr;
if (!combinedErrors.empty()) {
combinedErrors += "; ";
}
combinedErrors += fmt::format("{}: {}", host, errStr);
}
if (!combinedErrors.empty()) {
throw std::runtime_error(combinedErrors);
}
}

Expand Down Expand Up @@ -312,7 +331,9 @@ void CmdHandler<CmdTypeT, CmdTypeTraits>::run() {
runHelper();
} catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
exit(1);
// Rethrow so the caller can handle appropriately (e.g., tests can catch and
// check exit codes, CLI main() can exit with non-zero status)
throw;
}
}

Expand Down
Loading
Loading