diff:
@@ -168,6 +168,13 @@ class InstrumentationObserver {
QuicSocket*, /* socket */
const PacketRTT& /* RTT sample */) {}
+ /**
+ * pmtuProbingStarted() is invoked when server starts d6d.
+ *
+ * @param socket Socket when the callback is processed.
+ */
+ virtual void pmtuProbingStarted(QuicSocket* /* socket */) {}
+
/**
* pmtuBlackholeDetected() is invoked when a PMTU blackhole is detected.
*

diff:
@@ -338,6 +338,7 @@ class MockInstrumentationObserver : public InstrumentationObserver {
,
rttSampleGenerated,
void(QuicSocket*, const PacketRTT&));
+ GMOCK_METHOD1_(, noexcept, , pmtuProbingStarted, void(QuicSocket*));
GMOCK_METHOD2_(
,
noexcept,

diff:
@@ -537,6 +537,9 @@ void QuicServerTransport::maybeStartD6DProbing() {
// valuable
conn_->pendingEvents.d6d.sendProbeDelay = kDefaultD6DKickStartDelay;
QUIC_STATS(conn_->statsCallback, onConnectionD6DStarted);
+ for (const auto& cb : conn_->instrumentationObservers_) {
+ cb->pmtuProbingStarted(this);
+ }
}
}

diff:
@@ -4230,5 +4230,21 @@ TEST_P(
}
testSetupConnection();
}
+
+TEST_P(QuicServerTransportHandshakeTest, TestD6DStartInstrumentationCallback) {
+ auto mockObserver = std::make_unique<MockInstrumentationObserver>();
+ server->addInstrumentationObserver(mockObserver.get());
+ // Set oneRttReader so that maybeStartD6DPriobing passes its check
+ auto codec = std::make_unique<QuicReadCodec>(QuicNodeType::Server);
+ codec->setOneRttReadCipher(createNoOpAead());
+ server->getNonConstConn().readCodec = std::move(codec);
+ // And the state too
+ server->getNonConstConn().d6d.state = D6DMachineState::BASE;
+ EXPECT_CALL(*mockObserver, pmtuProbingStarted(_)).Times(1);
+ // CHLO should be enough to trigger probing
+ recvClientHello();
+ server->removeInstrumentationObserver(mockObserver.get());
+}
+
} // namespace test
} // namespace quic

diff:
@@ -78,6 +78,7 @@ DEFINE_uint32(
DEFINE_bool(log_rtt_sample, false, "Log rtt sample events");
DEFINE_bool(log_loss, false, "Log packet loss events");
DEFINE_bool(log_app_rate_limited, false, "Log app rate limited events");
+DEFINE_bool(log_pmtu_probing_started, false, "Log pmtu probing started events");
DEFINE_bool(log_pmtu_upperbound, false, "Log pmtu upper bound events");
DEFINE_bool(log_pmtu_blackhole, false, "Log pmtu blackbole events");
DEFINE_bool(d6d_enabled, false, "Enable d6d");
@@ -154,6 +155,12 @@ class TPerfInstrumentationObserver : public InstrumentationObserver {
}
}
+ void pmtuProbingStarted(QuicSocket* /* socket */) override {
+ if (FLAGS_log_pmtu_probing_started) {
+ LOG(INFO) << "pmtu probing started";
+ }
+ }
+
void pmtuBlackholeDetected(
QuicSocket*, /* socket */
const PMTUBlackholeEvent& /* Blackhole event */) override {

original_message:
Add pmtuProbingStarted event to instrumentation observer

Summary: ^

Reviewed By: bschlinker

Differential Revision: D24464391

fbshipit-source-id: c976b9496031290cb4b6c3f29862c1f7d4ebf065


change_type: MODIFY

diff:
@@ -729,7 +729,7 @@ class QuicTransportBase : public QuicSocket {
/**
* Callback when we receive a transport knob
*/
- void onTransportKnobs(Buf knobBlob);
+ virtual void onTransportKnobs(Buf knobBlob);
struct ByteEventDetail {
ByteEventDetail(uint64_t offsetIn, ByteEventCallback* callbackIn)

diff:
@@ -92,6 +92,28 @@ target_link_libraries(
Folly::folly
)
+add_library(
+ mvfst_transport_knobs STATIC
+ TransportKnobs.cpp
+)
+
+target_include_directories(
+ mvfst_transport_knobs PUBLIC
+ $<BUILD_INTERFACE:${QUIC_FBCODE_ROOT}>
+ $<INSTALL_INTERFACE:include/>
+)
+
+target_compile_options(
+ mvfst_transport_knobs
+ PRIVATE
+ ${_QUIC_COMMON_COMPILE_OPTIONS}
+)
+
+target_link_libraries(
+ mvfst_transport_knobs PUBLIC
+ Folly::folly
+)
+
file(
GLOB_RECURSE QUIC_API_HEADERS_TOINSTALL
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
@@ -127,4 +149,10 @@ install(
DESTINATION lib
)
+install(
+ TARGETS mvfst_transport_knobs
+ EXPORT mvfst-exports
+ DESTINATION lib
+)
+
add_subdirectory(test)

change_type: ADD

diff:
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+#include "quic/common/TransportKnobs.h"
+#include <folly/json.h>
+#include <glog/logging.h>
+
+namespace quic {
+
+namespace {
+
+bool compareTransportKnobParam(
+ const TransportKnobParam& lhs,
+ const TransportKnobParam& rhs) {
+ // Sort param by id, then value
+ if (lhs.id != rhs.id) {
+ return lhs.id < rhs.id;
+ }
+ return lhs.val < rhs.val;
+}
+
+} // namespace
+
+folly::Optional<TransportKnobParams> parseTransportKnobs(
+ const std::string& serializedParams) {
+ TransportKnobParams knobParams;
+ try {
+ folly::dynamic params = folly::parseJson(serializedParams);
+ for (const auto& id : params.keys()) {
+ auto paramId = folly::to<uint64_t>(id.asInt());
+ auto val = params[id];
+ switch (val.type()) {
+ case folly::dynamic::Type::BOOL:
+ case folly::dynamic::Type::INT64:
+ knobParams.push_back({paramId, folly::to<uint64_t>(val.asInt())});
+ continue;
+ default:
+ // Quic transport knob param values cannot be of type STRING, ARRAY,
+ // NULLT or OBJECT
+ LOG(ERROR) << "Invalid transport knob param value type";
+ return folly::none;
+ }
+ }
+ } catch (const std::exception& e) {
+ LOG(ERROR) << "fail to parse knobs: " << e.what();
+ return folly::none;
+ }
+
+ std::sort(knobParams.begin(), knobParams.end(), compareTransportKnobParam);
+ return knobParams;
+}
+
+} // namespace quic

diff:
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+#pragma once
+#include <folly/Optional.h>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+namespace quic {
+
+/**
+ * This is not to be confused with the structure of knob frame, or QUIC's
+ * transport parameter. Knob frame has space, id and a blob. Arbitrary data can
+ * be stored in the blob. TransportKnobParam is a kind of blob that designated
+ * to pass transport-level parameter that's no transferable via existing
+ * methods (e.g. transport parameter).
+ */
+struct TransportKnobParam {
+ uint64_t id;
+ uint64_t val;
+};
+
+using TransportKnobParams = std::vector<TransportKnobParam>;
+
+folly::Optional<TransportKnobParams> parseTransportKnobs(
+ const std::string& serializedParams);
+
+} // namespace quic

diff:
+// (c) Facebook, Inc. and its affiliates. Confidential and proprietary.
+
+#include <quic/common/TransportKnobs.h>
+#include <folly/portability/GTest.h>
+
+using namespace ::testing;
+
+namespace quic {
+namespace test {
+
+struct QuicKnobsParsingTestFixture {
+ std::string serializedKnobs;
+ bool expectError;
+ TransportKnobParams expectParams;
+};
+
+void run(const QuicKnobsParsingTestFixture& fixture) {
+ auto result = parseTransportKnobs(fixture.serializedKnobs);
+ if (fixture.expectError) {
+ EXPECT_FALSE(result.hasValue());
+ } else {
+ EXPECT_EQ(result->size(), fixture.expectParams.size());
+ for (size_t i = 0; i < result->size(); i++) {
+ auto& actualKnob = (*result)[i];
+ auto& expectKnob = fixture.expectParams[i];
+ EXPECT_EQ(actualKnob.id, expectKnob.id) << "Knob " << i;
+ EXPECT_EQ(actualKnob.val, expectKnob.val) << "Knob " << i;
+ }
+ }
+}
+
+TEST(QuicKnobsParsingTest, Simple) {
+ QuicKnobsParsingTestFixture fixture = {
+ "{ \"0\": 1,"
+ " \"1\": 5,"
+ " \"19\": 6,"
+ " \"2\": 3"
+ " }",
+ false,
+ {{0, 1}, {1, 5}, {2, 3}, {19, 6}}};
+ run(fixture);
+}
+
+TEST(QuicKnobsParsingTest, ObjectValue) {
+ QuicKnobsParsingTestFixture fixture = {
+ "{ \"1\": "
+ " {"
+ " \"0\" : 1"
+ " }"
+ "}",
+ true,
+ {}};
+ run(fixture);
+}
+
+TEST(QuicKnobsParsingTest, InvalidJson) {
+ QuicKnobsParsingTestFixture fixture = {
+ "{\"0\": "
+ " \"1\": "
+ " {"
+ " \"0\" : 1"
+ " }"
+ "}",
+ true,
+ {}};
+ run(fixture);
+}
+
+TEST(QuicKnobsParsingTest, Characters) {
+ QuicKnobsParsingTestFixture fixture = {"{ \"o\" : 1 }", true, {}};
+ run(fixture);
+}
+
+TEST(QuicKnobsParsingTest, NegativeNumbers) {
+ QuicKnobsParsingTestFixture fixture = {"{ \"1\" : -1 }", true, {}};
+ run(fixture);
+}
+
+TEST(QuicKnobsParsingTest, StringValue) {
+ QuicKnobsParsingTestFixture fixture = {"{ \"1\" : \"1\" }", true, {}};
+ run(fixture);
+}
+
+TEST(QuicKnobsParsingTest, NonStringKey) {
+ QuicKnobsParsingTestFixture fixture = {"{ 1 : 1 }", true, {}};
+ run(fixture);
+}
+
+TEST(QuicKnobsParsingTest, DoubleKey) {
+ QuicKnobsParsingTestFixture fixture = {"{ \"3.14\" : 1 }", true, {}};
+ run(fixture);
+}
+
+TEST(QuicKnobsParsingTest, DoubleValue) {
+ QuicKnobsParsingTestFixture fixture = {"{ \"10\" : 0.1 }", true, {}};
+ run(fixture);
+}
+
+} // namespace test
+} // namespace quic

diff:
@@ -49,6 +49,7 @@ add_dependencies(
mvfst_qlogger
mvfst_state_ack_handler
mvfst_transport
+ mvfst_transport_knobs
)
if(DEFINED CCP_ENABLED)
@@ -74,6 +75,7 @@ target_link_libraries(
mvfst_qlogger
mvfst_state_ack_handler
mvfst_transport
+ mvfst_transport_knobs
${LIBCCP_LIBRARY}
${LIBSTARTCCP_LIBRARY}
)

diff:
@@ -563,4 +563,12 @@ QuicServerTransport::getPeerCertificate() const {
return nullptr;
}
+void QuicServerTransport::onTransportKnobs(Buf knobBlob) {
+ std::string serializedKnobs = std::string(
+ reinterpret_cast<const char*>(knobBlob->data()), knobBlob->length());
+ VLOG(4) << "Received transport knobs: " << serializedKnobs;
+ auto params = parseTransportKnobs(serializedKnobs);
+ // Handling not yet implemented
+}
+
} // namespace quic

diff:
#include <quic/api/QuicTransportBase.h>
#include <quic/api/QuicTransportFunctions.h>
#include <quic/codec/ConnectionIdAlgo.h>
+#include <quic/common/TransportKnobs.h>
#include <quic/congestion_control/CongestionControllerFactory.h>
#include <quic/server/handshake/ServerTransportParametersExtension.h>
#include <quic/server/state/ServerConnectionIdRejector.h>
@@ -132,6 +133,15 @@ class QuicServerTransport
// From ServerHandshake::HandshakeCallback
virtual void onCryptoEventAvailable() noexcept override;
+ void onTransportKnobs(Buf knobBlob) override;
+
+ void handleTransportKnobParams(const TransportKnobParams& params);
+
+ // Made it protected for testing purpose
+ void registerTransportKnobParamHandler(
+ uint64_t paramId,
+ std::function<void(QuicServerConnectionState*, uint64_t)>&& handler);
+
private:
void processPendingData(bool async);
void maybeNotifyTransportReady();

license: MIT License

repo: facebookincubator/mvfst

original_message:
Deserialize transport knob

Summary: Temporarily, we use a simple json-format for transport knob. Currently it's limited to a single packet, but that should be enough for current usage.

Reviewed By: mjoras

Differential Revision: D24584261

fbshipit-source-id: f51ed0fb7560cda2ca447a49d9ad6575c1b2a59f


diff:
@@ -115,6 +115,9 @@ constexpr uint64_t kDefaultQuicTransportKnobSpace = 0xfaceb001;
// Default knob id for transport knobs
constexpr uint64_t kDefaultQuicTransportKnobId = 1;
+// Default transport knob param id for disabling pmtu blackhole detection
+constexpr uint64_t kTransportKnobParamIdZeroBlackholeDetection = 0x8830;
+
enum class FrameType : uint64_t {
PADDING = 0x00,
PING = 0x01,

diff:
@@ -243,7 +243,7 @@ void detectPMTUBlackhole(
// less than base pmtu, then the loss is not caused by pmtu blackhole
if (d6d.state == D6DMachineState::DISABLED || packet.metadata.isD6DProbe ||
packet.metadata.encodedSize <= d6d.basePMTU ||
- conn.udpSendPacketLen <= d6d.basePMTU) {
+ conn.udpSendPacketLen <= d6d.basePMTU || d6d.noBlackholeDetection) {
return;
}

diff:
@@ -37,6 +37,7 @@ QuicServerTransport::QuicServerTransport(
// correctly.
// conn_->nextSequenceNum = folly::Random::secureRandom<PacketNum>();
setConnectionCallback(&cb);
+ registerAllTransportKnobParamHandlers();
}
QuicServerTransport::~QuicServerTransport() {
@@ -589,4 +590,17 @@ void QuicServerTransport::onTransportKnobs(Buf knobBlob) {
}
}
+void QuicServerTransport::registerAllTransportKnobParamHandlers() {
+ registerTransportKnobParamHandler(
+ kTransportKnobParamIdZeroBlackholeDetection,
+ [](QuicServerConnectionState* server_conn, uint64_t val) {
+ CHECK(server_conn);
+ if (static_cast<bool>(val)) {
+ server_conn->d6d.noBlackholeDetection = true;
+ LOG(INFO)
+ << "Knob param received, pmtu blackhole detection is turned off";
+ }
+ });
+}
+
} // namespace quic

diff:
@@ -150,6 +150,7 @@ class QuicServerTransport
void maybeIssueConnectionIds();
bool hasReadCipher() const;
void maybeStartD6DProbing();
+ void registerAllTransportKnobParamHandlers();
private:
RoutingCallback* routingCb_{nullptr};

diff:
@@ -4288,5 +4288,10 @@ TEST_F(QuicServerTransportTest, TestRegisterAndHandleTransportKnobParams) {
});
EXPECT_EQ(flag, 1);
}
+
+TEST_F(QuicServerTransportTest, TestRegisterPMTUZeroBlackholeDetection) {
+ server->handleKnobParams({{kTransportKnobParamIdZeroBlackholeDetection, 1}});
+ EXPECT_TRUE(server->getConn().d6d.noBlackholeDetection);
+}
} // namespace test
} // namespace quic

diff:
@@ -813,6 +813,9 @@ struct QuicConnectionStateBase : public folly::DelayedDestruction {
// Meta state
D6DMetaState meta;
+ // Turn off blackhole detection
+ bool noBlackholeDetection{false};
+
// D6D Machine State
D6DMachineState state{D6DMachineState::DISABLED};
};

original_message:
Add transport knob to turn off blackhole detection

Summary: Blackhole detection has quite a lot false positives, we want to have a way to run d6d without it.

Reviewed By: mjoras

Differential Revision: D24584357

fbshipit-source-id: ab27655ec38d62fd6deffe41cb156de0c981cf6d


diff:
@@ -115,8 +115,13 @@ constexpr uint64_t kDefaultQuicTransportKnobSpace = 0xfaceb001;
// Default knob id for transport knobs
constexpr uint64_t kDefaultQuicTransportKnobId = 1;
-// Default transport knob param id for disabling pmtu blackhole detection
-constexpr uint64_t kTransportKnobParamIdZeroBlackholeDetection = 0x8830;
+enum class TransportKnobParamId : uint64_t {
+ // Disabling pmtu blackhole detection
+ ZERO_PMTU_BLACKHOLE_DETECTION = 0x8830,
+ // Force udp payload size to be equal to max
+ // udp payload size
+ FORCIBLY_SET_UDP_PAYLOAD_SIZE = 0xba92,
+};
enum class FrameType : uint64_t {
PADDING = 0x00,

diff:
@@ -592,7 +592,8 @@ void QuicServerTransport::onTransportKnobs(Buf knobBlob) {
void QuicServerTransport::registerAllTransportKnobParamHandlers() {
registerTransportKnobParamHandler(
- kTransportKnobParamIdZeroBlackholeDetection,
+ static_cast<uint64_t>(
+ TransportKnobParamId::ZERO_PMTU_BLACKHOLE_DETECTION),
[](QuicServerConnectionState* server_conn, uint64_t val) {
CHECK(server_conn);
if (static_cast<bool>(val)) {
@@ -601,6 +602,18 @@ void QuicServerTransport::registerAllTransportKnobParamHandlers() {
<< "Knob param received, pmtu blackhole detection is turned off";
}
});
+
+ registerTransportKnobParamHandler(
+ static_cast<uint64_t>(
+ TransportKnobParamId::FORCIBLY_SET_UDP_PAYLOAD_SIZE),
+ [](QuicServerConnectionState* server_conn, uint64_t val) {
+ CHECK(server_conn);
+ if (static_cast<bool>(val)) {
+ server_conn->udpSendPacketLen = server_conn->peerMaxUdpPayloadSize;
+ LOG(INFO)
+ << "Knob param received, udpSendPacketLen is forcibly set to max UDP payload size advertised by peer";
+ }
+ });
}
} // namespace quic

diff:
@@ -192,6 +192,7 @@ void processClientInitialParams(
uint64_t maxUdpPayloadSize = kDefaultMaxUDPPayload;
if (packetSize) {
maxUdpPayloadSize = std::min(*packetSize, maxUdpPayloadSize);
+ conn.peerMaxUdpPayloadSize = maxUdpPayloadSize;
if (conn.transportSettings.canIgnorePathMTU) {
if (*packetSize > kDefaultMaxUDPPayload) {
// A good peer should never set oversized limit, so to be safe we

diff:
@@ -333,7 +333,8 @@ class QuicServerTransportTest : public Test {
server->getNonConstConn().handshakeLayer.reset(fakeHandshake);
server->getNonConstConn().serverHandshakeLayer = fakeHandshake;
// Allow ignoring path mtu for testing negotiation.
- server->getNonConstConn().transportSettings.canIgnorePathMTU = true;
+ server->getNonConstConn().transportSettings.canIgnorePathMTU =
+ getCanIgnorePathMTU();
server->getNonConstConn().transportSettings.disableMigration =
getDisableMigration();
server->setConnectionIdAlgo(connIdAlgo_.get());
@@ -372,6 +373,10 @@ class QuicServerTransportTest : public Test {
return true;
}
+ virtual bool getCanIgnorePathMTU() {
+ return true;
+ }
+
std::unique_ptr<Aead> getInitialCipher(
QuicVersion version = QuicVersion::MVFST) {
FizzCryptoFactory cryptoFactory;
@@ -584,9 +589,11 @@ class QuicServerTransportTest : public Test {
void verifyTransportParameters(std::chrono::milliseconds idleTimeout) {
EXPECT_EQ(server->getConn().peerIdleTimeout, idleTimeout);
+ if (getCanIgnorePathMTU()) {
EXPECT_EQ(
server->getConn().udpSendPacketLen, fakeHandshake->maxRecvPacketSize);
}
+ }
void deliverDataWithoutErrorCheck(
Buf data,
@@ -4290,8 +4297,31 @@ TEST_F(QuicServerTransportTest, TestRegisterAndHandleTransportKnobParams) {
}
TEST_F(QuicServerTransportTest, TestRegisterPMTUZeroBlackholeDetection) {
- server->handleKnobParams({{kTransportKnobParamIdZeroBlackholeDetection, 1}});
+ server->handleKnobParams(
+ {{static_cast<uint64_t>(
+ TransportKnobParamId::ZERO_PMTU_BLACKHOLE_DETECTION),
+ 1}});
EXPECT_TRUE(server->getConn().d6d.noBlackholeDetection);
}
+
+class QuicServerTransportForciblySetUDUPayloadSizeTest
+ : public QuicServerTransportTest {
+ public:
+ bool getCanIgnorePathMTU() override {
+ return false;
+ }
+};
+
+TEST_F(
+ QuicServerTransportForciblySetUDUPayloadSizeTest,
+ TestHandleTransportKnobParamForciblySetUDPPayloadSize) {
+ EXPECT_LT(server->getConn().udpSendPacketLen, 1452);
+ server->handleKnobParams(
+ {{static_cast<uint64_t>(
+ TransportKnobParamId::FORCIBLY_SET_UDP_PAYLOAD_SIZE),
+ 1}});
+ EXPECT_EQ(server->getConn().udpSendPacketLen, 1452);
+}
+
} // namespace test
} // namespace quic

diff:
@@ -716,6 +716,10 @@ struct QuicConnectionStateBase : public folly::DelayedDestruction {
// max_packet_size in Transport Parameters and PMTU
uint64_t udpSendPacketLen{kDefaultUDPSendPacketLen};
+ // Peer-advertised max UDP payload size, stored as an opportunistic value to
+ // use when receiving the forciblySetUdpPayloadSize transport knob param
+ uint64_t peerMaxUdpPayloadSize{kDefaultUDPSendPacketLen};
+
struct PacketSchedulingState {
StreamId nextScheduledStream{0};
StreamId nextScheduledControlStream{0};

original_message:
Add transport knob to enforce udp payload size

Summary: Adds another knob param to enforce udp payload size. This is basically a "canIgnorePathMTU" knob that client has.

Reviewed By: mjoras

Differential Revision: D24586165

fbshipit-source-id: befb265a24fae8f450f323cf2d652a8b448e698c


diff:
@@ -581,6 +581,7 @@ QuicServerTransport::getPeerCertificate() const {
}
void QuicServerTransport::onTransportKnobs(Buf knobBlob) {
+ if (knobBlob->length() > 0) {
std::string serializedKnobs = std::string(
reinterpret_cast<const char*>(knobBlob->data()), knobBlob->length());
VLOG(4) << "Received transport knobs: " << serializedKnobs;
@@ -589,6 +590,7 @@ void QuicServerTransport::onTransportKnobs(Buf knobBlob) {
handleTransportKnobParams(*params);
}
}
+}
void QuicServerTransport::registerAllTransportKnobParamHandlers() {
registerTransportKnobParamHandler(

original_message:
Check for empty knob in client and server

Summary: ^

Reviewed By: mjoras

Differential Revision: D24707524

fbshipit-source-id: ae8fd88ed1f1b05e44f8f5a7f8523c654d6de937


diff:
@@ -102,11 +102,11 @@ struct D6DConfig {
ProbeSizeRaiserType raiserType{ProbeSizeRaiserType::ConstantStep};
};
-// JSON-serialized transoprt knobs
+// JSON-serialized transport knobs
struct SerializedKnob {
uint64_t space;
uint64_t id;
- folly::StringPiece blob;
+ std::string blob;
};
struct TransportSettings {

original_message:
Use string not StringPiece for knobs

Summary:
quicConfig is passed by value(https://fburl.com/codesearch/rydlyc2x), StringPiece doesn't do copy, resulting in junk values.

```
E1112 10:45:19.545003  1377 TransportKnobs.cpp:44] fail to parse knobs: json parse error on line 0 near |??
```

Reviewed By: yangchi

Differential Revision: D24928201

fbshipit-source-id: 57f391516689b3e5a4fa941d22f464c9830ad660


diff:
@@ -165,6 +165,16 @@ class LogQuicStats : public quic::QuicTransportStatsCallback {
VLOG(2) << prefix_ << "onConnectionPMTUUpperBoundDetected";
}
+ void onTransportKnobApplied(TransportKnobType knobType) override {
+ VLOG(2) << prefix_
+ << "onTransportKnobApplied knobType=" << toString(knobType);
+ }
+
+ void onTransportKnobError(TransportKnobType knobType) override {
+ VLOG(2) << prefix_
+ << "onTransportKnboError knobType=" << toString(knobType);
+ }
+
private:
std::string prefix_;
};

diff:
@@ -382,6 +382,15 @@ void QuicServerTransport::handleTransportKnobParams(
auto maybeParamHandler = transportKnobParamHandlers_.find(param.id);
if (maybeParamHandler != transportKnobParamHandlers_.end()) {
(maybeParamHandler->second)(serverConn_, param.val);
+ QUIC_STATS(
+ conn_->statsCallback,
+ onTransportKnobApplied,
+ QuicTransportStatsCallback::paramIdToTransportKnobType(param.id));
+ } else {
+ QUIC_STATS(
+ conn_->statsCallback,
+ onTransportKnobError,
+ QuicTransportStatsCallback::paramIdToTransportKnobType(param.id));
}
}
}
@@ -588,6 +597,11 @@ void QuicServerTransport::onTransportKnobs(Buf knobBlob) {
auto params = parseTransportKnobs(serializedKnobs);
if (params.hasValue()) {
handleTransportKnobParams(*params);
+ } else {
+ QUIC_STATS(
+ conn_->statsCallback,
+ onTransportKnobError,
+ QuicTransportStatsCallback::TransportKnobType::UNKNOWN);
}
}
}

diff:
@@ -67,6 +67,13 @@ class QuicTransportStatsCallback {
MAX
};
+ enum class TransportKnobType : uint8_t {
+ ZERO_PMTU_BLACKHOLE,
+ FORCIBLY_SET_UDP_PAYLOAD_SIZE,
+ UNKNOWN,
+ MAX
+ };
+
virtual ~QuicTransportStatsCallback() = default;
// packet level metrics
@@ -144,6 +151,10 @@ class QuicTransportStatsCallback {
virtual void onConnectionPMTUUpperBoundDetected() = 0;
+ virtual void onTransportKnobApplied(TransportKnobType knobType) = 0;
+
+ virtual void onTransportKnobError(TransportKnobType knobType) = 0;
+
static const char* toString(ConnectionCloseReason reason) {
switch (reason) {
case ConnectionCloseReason::NONE:
@@ -237,6 +248,34 @@ class QuicTransportStatsCallback {
return SocketErrorType::OTHER;
}
}
+
+ static const char* toString(TransportKnobType knobType) {
+ switch (knobType) {
+ case TransportKnobType::ZERO_PMTU_BLACKHOLE:
+ return "ZERO_PMTU_BLACKHOLE";
+ case TransportKnobType::FORCIBLY_SET_UDP_PAYLOAD_SIZE:
+ return "FORCIBLY_SET_UDP_PAYLOAD_SIZE";
+ case TransportKnobType::UNKNOWN:
+ return "UNKNOWN";
+ case TransportKnobType::MAX:
+ return "MAX";
+ default:
+ throw std::runtime_error("Undefined TransportKnobType passed");
+ }
+ }
+
+ static TransportKnobType paramIdToTransportKnobType(uint64_t paramId) {
+ switch (paramId) {
+ case static_cast<uint64_t>(
+ TransportKnobParamId::ZERO_PMTU_BLACKHOLE_DETECTION):
+ return TransportKnobType::ZERO_PMTU_BLACKHOLE;
+ case static_cast<uint64_t>(
+ TransportKnobParamId::FORCIBLY_SET_UDP_PAYLOAD_SIZE):
+ return TransportKnobType::FORCIBLY_SET_UDP_PAYLOAD_SIZE;
+ default:
+ return TransportKnobType::UNKNOWN;
+ }
+ }
};
/**

diff:
@@ -51,6 +51,8 @@ class MockQuicStats : public QuicTransportStatsCallback {
MOCK_METHOD0(onConnectionPMTURaised, void());
MOCK_METHOD0(onConnectionPMTUBlackholeDetected, void());
MOCK_METHOD0(onConnectionPMTUUpperBoundDetected, void());
+ MOCK_METHOD1(onTransportKnobApplied, void(TransportKnobType));
+ MOCK_METHOD1(onTransportKnobError, void(TransportKnobType));
};
class MockQuicStatsFactory : public QuicTransportStatsCallbackFactory {

original_message:
Add stats for transport knobs

Summary:
This adds visibility over the transport knobs. Will be helpful when we add more knobs (e.g. canary token).

I'll remove them for the sake of storage once we're sure the plumbing works.

Reviewed By: avasylev

Differential Revision: D24929923

fbshipit-source-id: a64bb6e613f3a69a47bf9b32e8c31890ad1afdfc


diff:
@@ -233,6 +233,9 @@ void processClientInitialParams(
conn.d6d.state = D6DMachineState::BASE;
conn.d6d.meta.lastNonSearchState = D6DMachineState::DISABLED;
conn.d6d.meta.timeLastNonSearchState = Clock::now();
+
+ // Temporary, should be removed after transport knob pipeline works
+ conn.d6d.noBlackholeDetection = true;
} else {
LOG(ERROR) << "client d6dBasePMTU fails sanity check: " << *d6dBasePMTU;
// We treat base pmtu transport param as client's swich to activate d6d,

original_message:
turn off blackhole detection

Summary: Speed up the experiment by disabling blackhole detection all together temporarily.

Reviewed By: mjoras

Differential Revision: D24997566

fbshipit-source-id: 2781e586f5ba9896633ab0716e78cfc49e0e34a4


diff:
@@ -757,7 +757,8 @@ SchedulingResult CloningScheduler::scheduleFramesForPacket(
std::move(builder).releaseOutputBuffer();
// Look for an outstanding packet that's no larger than the writableBytes
for (auto& outstandingPacket : conn_.outstandings.packets) {
- if (outstandingPacket.declaredLost) {
+ if (outstandingPacket.declaredLost ||
+ outstandingPacket.metadata.isD6DProbe) {
continue;
}
auto opPnSpace = outstandingPacket.packet.header.getPacketNumberSpace();

original_message:
Don't clone d6d packet

Summary: Sending a potentially over-sized d6d packet on PTO might be a bad idea. Plus, a PTO probe containing app data sounds more useful than only "empty" packet.

Reviewed By: yangchi

Differential Revision: D25109633

fbshipit-source-id: ded0c02397b7dc4c346f3aa9b61869836791baec


diff:
@@ -480,11 +480,12 @@ void updateConnection(
bool retransmittable = false; // AckFrame and PaddingFrame are not retx-able.
bool isHandshake = false;
bool isPing = false;
- bool isD6DProbe =
- conn.d6d.lastProbe ? (packetNum == conn.d6d.lastProbe->packetNum) : false;
uint32_t connWindowUpdateSent = 0;
uint32_t ackFrameCounter = 0;
auto packetNumberSpace = packet.header.getPacketNumberSpace();
+ bool isD6DProbe = packetNumberSpace == PacketNumberSpace::AppData &&
+ conn.d6d.lastProbe.hasValue() &&
+ conn.d6d.lastProbe->packetNum == packetNum;
VLOG(10) << nodeToString(conn.nodeType) << " sent packetNum=" << packetNum
<< " in space=" << packetNumberSpace << " size=" << encodedSize
<< " " << conn;

diff:
@@ -374,6 +374,18 @@ TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionD6DNotConsumeSendPing) {
EXPECT_TRUE(conn->pendingEvents.sendPing);
}
+TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionD6DNeedsAppDataPNSpace) {
+ auto conn = createConn();
+ auto packet = buildEmptyPacket(*conn, PacketNumberSpace::Handshake);
+ packet.packet.frames.push_back(PingFrame());
+ auto packetNum = packet.packet.header.getPacketSequenceNum();
+ conn->d6d.lastProbe = D6DProbePacket(packetNum, 50);
+ updateConnection(*conn, folly::none, packet.packet, Clock::now(), 50);
+ EXPECT_EQ(1, conn->outstandings.packets.size());
+ EXPECT_FALSE(conn->outstandings.packets.front().metadata.isD6DProbe);
+ EXPECT_EQ(0, conn->d6d.outstandingProbes);
+}
+
TEST_F(QuicTransportFunctionsTest, TestUpdateConnectionPacketSorting) {
auto conn = createConn();
conn->qLogger = std::make_shared<quic::FileQLogger>(VantagePoint::Client);

original_message:
Require AppData packet number space when checking D6D packet

Summary: ^

Reviewed By: yangchi

Differential Revision: D25539225

fbshipit-source-id: 7d68917c73228c006ebec38be1ee86ccb12362f1


diff:
@@ -643,7 +643,7 @@ void QuicServerTransport::registerAllTransportKnobParamHandlers() {
CHECK(server_conn);
if (static_cast<bool>(val)) {
server_conn->d6d.noBlackholeDetection = true;
- LOG(INFO)
+ VLOG(3)
<< "Knob param received, pmtu blackhole detection is turned off";
}
});
@@ -655,7 +655,7 @@ void QuicServerTransport::registerAllTransportKnobParamHandlers() {
CHECK(server_conn);
if (static_cast<bool>(val)) {
server_conn->udpSendPacketLen = server_conn->peerMaxUdpPayloadSize;
- LOG(INFO)
+ VLOG(3)
<< "Knob param received, udpSendPacketLen is forcibly set to max UDP payload size advertised by peer";
}
});
@@ -665,7 +665,7 @@ void QuicServerTransport::registerAllTransportKnobParamHandlers() {
[](QuicServerConnectionState* server_conn, uint64_t val) {
CHECK(server_conn);
auto cctype = static_cast<CongestionControlType>(val);
- LOG(INFO) << "Knob param received, set congestion control type to "
+ VLOG(3) << "Knob param received, set congestion control type to "
<< congestionControlTypeToString(cctype);
if (cctype == server_conn->congestionController->type()) {
return;
@@ -691,7 +691,7 @@ void QuicServerTransport::registerAllTransportKnobParamHandlers() {
CHECK(server_conn);
uint8_t numerator = (val / 100);
uint8_t denominator = (val - (numerator * 100));
- LOG(INFO) << "Knob param received, set STARTUP rtt factor to ("
+ VLOG(3) << "Knob param received, set STARTUP rtt factor to ("
<< unsigned(numerator) << "," << unsigned(denominator) << ")";
server_conn->transportSettings.startupRttFactor =
std::make_pair(numerator, denominator);
@@ -703,7 +703,7 @@ void QuicServerTransport::registerAllTransportKnobParamHandlers() {
CHECK(server_conn);
auto numerator = (uint8_t)(val / 100);
auto denominator = (uint8_t)(val - (numerator * 100));
- LOG(INFO) << "Knob param received, set DEFAULT rtt factor to ("
+ VLOG(3) << "Knob param received, set DEFAULT rtt factor to ("
<< unsigned(numerator) << "," << unsigned(denominator) << ")";
server_conn->transportSettings.defaultRttFactor =
std::make_pair(numerator, denominator);
@@ -713,8 +713,7 @@ void QuicServerTransport::registerAllTransportKnobParamHandlers() {
static_cast<uint64_t>(TransportKnobParamId::NOTSENT_BUFFER_SIZE_KNOB),
[](QuicServerConnectionState* server_conn, uint64_t val) {
CHECK(server_conn);
- LOG(INFO)
- << "Knob param received, set total buffer space available to ("
+ VLOG(3) << "Knob param received, set total buffer space available to ("
<< unsigned(val) << ")";
server_conn->transportSettings.totalBufferSpaceAvailable = val;
});

original_message:
reduce log spam in QuicServerTransport

Summary: Reduced the log level on transport knob updates to avoid excessive logs

Reviewed By: lnicco

Differential Revision: D29151246

fbshipit-source-id: f718792736c1aa7e03511c409912b58a981c2c64


diff:
@@ -12,7 +12,7 @@ requests are cherry-picked into our repo and then pushed back out.
## Pull Requests
We actively welcome your pull requests.
-1. Fork the repo and create your branch from `master`.
+1. Fork the repo and create your branch from `main`.
1. If you've added code that should be tested, add tests
1. If you've changed APIs, update the documentation.
1. Ensure the test suite passes.

diff:
![alt text](logo.png "MVFST")
-[![Linux Build Status](https://github.com/facebookincubator/mvfst/workflows/linux/badge.svg?branch=master)](https://github.com/facebookincubator/mvfst/actions?workflow=linux)
-[![macOS Build Status](https://github.com/facebookincubator/mvfst/workflows/mac/badge.svg?branch=master)](https://github.com/facebookincubator/mvfst/actions?workflow=mac)
-[![Windows Build Status](https://github.com/facebookincubator/mvfst/workflows/windows/badge.svg?branch=master)](https://github.com/facebookincubator/mvfst/actions?workflow=windows)
+[![Linux Build Status](https://github.com/facebookincubator/mvfst/workflows/linux/badge.svg)](https://github.com/facebookincubator/mvfst/actions?workflow=linux)
+[![macOS Build Status](https://github.com/facebookincubator/mvfst/workflows/mac/badge.svg)](https://github.com/facebookincubator/mvfst/actions?workflow=mac)
+[![Windows Build Status](https://github.com/facebookincubator/mvfst/workflows/windows/badge.svg)](https://github.com/facebookincubator/mvfst/actions?workflow=windows)
## Introduction
`mvfst` (Pronounced *move fast*) is a client and server implementation of [IETF QUIC](https://quicwg.org/) protocol in C++ by Facebook. QUIC is a UDP based reliable, multiplexed transport protocol that will become an internet standard. The goal of `mvfst` is to build a performant implementation of the QUIC transport protocol that applications could adapt for use cases on both the internet and the data-center. `mvfst` has been tested at scale on android, iOS apps, as well as servers and has several features to support large scale deployments.

original_message:
remove reference to 'master' branch in quic

Summary: https://github.com/facebookincubator/mvfst/issues/219

Reviewed By: kvtsoy

Differential Revision: D31022876

fbshipit-source-id: 6dc4e76136d5a2e43f3daf8dd708b2cf3e688e54


diff:
@@ -27,8 +27,11 @@ func (r *ReconcilePerconaXtraDBCluster) reconcileBackups(cr *api.PerconaXtraDBCl
return fmt.Errorf("storage %s doesn't exist", bcp.StorageName)
}
- bcpjob := bcpObj.Scheduled(&bcp, strg, cr)
- err := setControllerReference(cr, bcpjob, r.scheme)
+ bcpjob, err := bcpObj.Scheduled(&bcp, strg, cr)
+ if err != nil {
+ return fmt.Errorf("unable to schedule backup: %w", err)
+ }
+ err = setControllerReference(cr, bcpjob, r.scheme)
if err != nil {
return fmt.Errorf("set owner ref to backup %s: %v", bcp.Name, err)
}

diff:
@@ -137,7 +137,10 @@ func (r *ReconcilePerconaXtraDBClusterBackup) Reconcile(request reconcile.Reques
bcp := backup.New(cluster)
job := bcp.Job(instance, cluster)
- job.Spec = bcp.JobSpec(instance.Spec, cluster.Spec, job)
+ job.Spec, err = bcp.JobSpec(instance.Spec, cluster.Spec, job)
+ if err != nil {
+ return reconcile.Result{}, fmt.Errorf("can't create job spec: %w", err)
+ }
var destination string
var s3status *api.BackupStorageS3Spec

diff:
@@ -34,16 +34,22 @@ func (r *ReconcilePerconaXtraDBClusterRestore) restore(cr *api.PerconaXtraDBClus
func (r *ReconcilePerconaXtraDBClusterRestore) restorePVC(cr *api.PerconaXtraDBClusterRestore, bcp *api.PerconaXtraDBClusterBackup, pvcName string, cluster api.PerconaXtraDBClusterSpec) error {
svc := backup.PVCRestoreService(cr, bcp)
k8s.SetControllerReference(cr, svc, r.scheme)
- pod := backup.PVCRestorePod(cr, bcp, pvcName, cluster)
+ pod, err := backup.PVCRestorePod(cr, bcp, pvcName, cluster)
+ if err != nil {
+ return errors.Wrap(err, "restore pod")
+ }
k8s.SetControllerReference(cr, pod, r.scheme)
- job := backup.PVCRestoreJob(cr, bcp, cluster)
+ job, err := backup.PVCRestoreJob(cr, bcp, cluster)
+ if err != nil {
+ return errors.Wrap(err, "restore job")
+ }
k8s.SetControllerReference(cr, job, r.scheme)
r.client.Delete(context.TODO(), svc)
r.client.Delete(context.TODO(), pod)
- err := r.client.Create(context.TODO(), svc)
+ err = r.client.Create(context.TODO(), svc)
if err != nil {
return errors.Wrap(err, "create service")
}

diff:
package backup
import (
+ "fmt"
"net/url"
"strings"
@@ -37,10 +38,10 @@ func (*Backup) Job(cr *api.PerconaXtraDBClusterBackup, cluster *api.PerconaXtraD
}
}
-func (bcp *Backup) JobSpec(spec api.PXCBackupSpec, cluster api.PerconaXtraDBClusterSpec, job *batchv1.Job) batchv1.JobSpec {
+func (bcp *Backup) JobSpec(spec api.PXCBackupSpec, cluster api.PerconaXtraDBClusterSpec, job *batchv1.Job) (batchv1.JobSpec, error) {
resources, err := app.CreateResources(cluster.Backup.Storages[spec.StorageName].Resources)
if err != nil {
- log.Info("cannot parse Backup resources: ", err)
+ return batchv1.JobSpec{}, fmt.Errorf("cannot parse Backup resources: %w", err)
}
manualSelector := true
@@ -93,7 +94,7 @@ func (bcp *Backup) JobSpec(spec api.PXCBackupSpec, cluster api.PerconaXtraDBClus
PriorityClassName: cluster.Backup.Storages[spec.StorageName].PriorityClassName,
},
},
- }
+ }, nil
}
func appendStorageSecret(job *batchv1.JobSpec, cr *api.PerconaXtraDBCluster) error {

diff:
package backup
import (
+ "fmt"
"strconv"
"strings"
@@ -42,7 +43,7 @@ func PVCRestoreService(cr *api.PerconaXtraDBClusterRestore, bcp *api.PerconaXtra
}
}
-func PVCRestorePod(cr *api.PerconaXtraDBClusterRestore, bcp *api.PerconaXtraDBClusterBackup, pvcName string, cluster api.PerconaXtraDBClusterSpec) *corev1.Pod {
+func PVCRestorePod(cr *api.PerconaXtraDBClusterRestore, bcp *api.PerconaXtraDBClusterBackup, pvcName string, cluster api.PerconaXtraDBClusterSpec) (*corev1.Pod, error) {
if _, ok := cluster.Backup.Storages[bcp.Spec.StorageName]; !ok {
log.Info("storage " + bcp.Spec.StorageName + " doesn't exist")
if len(cluster.Backup.Storages) == 0 {
@@ -53,7 +54,7 @@ func PVCRestorePod(cr *api.PerconaXtraDBClusterRestore, bcp *api.PerconaXtraDBCl
resources, err := app.CreateResources(cluster.Backup.Storages[bcp.Status.StorageName].Resources)
if err != nil {
- log.Info("cannot parse backup resources: ", err)
+ return nil, fmt.Errorf("cannot parse backup resources: %w", err)
}
// Copy from the original labels to the restore labels
@@ -125,13 +126,13 @@ func PVCRestorePod(cr *api.PerconaXtraDBClusterRestore, bcp *api.PerconaXtraDBCl
SchedulerName: cluster.Backup.Storages[bcp.Status.StorageName].SchedulerName,
PriorityClassName: cluster.Backup.Storages[bcp.Status.StorageName].PriorityClassName,
},
- }
+ }, nil
}
-func PVCRestoreJob(cr *api.PerconaXtraDBClusterRestore, bcp *api.PerconaXtraDBClusterBackup, cluster api.PerconaXtraDBClusterSpec) *batchv1.Job {
+func PVCRestoreJob(cr *api.PerconaXtraDBClusterRestore, bcp *api.PerconaXtraDBClusterBackup, cluster api.PerconaXtraDBClusterSpec) (*batchv1.Job, error) {
resources, err := app.CreateResources(cluster.PXC.Resources)
if err != nil {
- log.Info("cannot parse PXC resources: ", err)
+ return nil, fmt.Errorf("cannot parse PXC resources: %w", err)
}
jobPVC := corev1.Volume{
@@ -230,14 +231,14 @@ func PVCRestoreJob(cr *api.PerconaXtraDBClusterRestore, bcp *api.PerconaXtraDBCl
}
}
- return job
+ return job, nil
}
// S3RestoreJob returns restore job object for s3
func S3RestoreJob(cr *api.PerconaXtraDBClusterRestore, bcp *api.PerconaXtraDBClusterBackup, s3dest string, cluster api.PerconaXtraDBClusterSpec) (*batchv1.Job, error) {
resources, err := app.CreateResources(cluster.PXC.Resources)
if err != nil {
- log.Info("cannot parse PXC resources: ", err)
+ return nil, fmt.Errorf("cannot parse PXC resources: %w", err)
}
if bcp.Status.S3 == nil {

diff:
package backup
import (
+ "fmt"
+
batchv1 "k8s.io/api/batch/v1"
batchv1beta1 "k8s.io/api/batch/v1beta1"
corev1 "k8s.io/api/core/v1"
@@ -10,7 +12,7 @@ import (
"github.com/percona/percona-xtradb-cluster-operator/pkg/pxc/app"
)
-func (bcp *Backup) Scheduled(spec *api.PXCScheduledBackupSchedule, strg *api.BackupStorageSpec, cr *api.PerconaXtraDBCluster) *batchv1beta1.CronJob {
+func (bcp *Backup) Scheduled(spec *api.PXCScheduledBackupSchedule, strg *api.BackupStorageSpec, cr *api.PerconaXtraDBCluster) (*batchv1beta1.CronJob, error) {
// Copy from the original labels to the backup labels
labels := make(map[string]string)
for key, value := range strg.Labels {
@@ -20,6 +22,10 @@ func (bcp *Backup) Scheduled(spec *api.PXCScheduledBackupSchedule, strg *api.Bac
labels["cluster"] = bcp.cluster
labels["schedule"] = genScheduleLabel(spec.Schedule)
+ cjts, err := bcp.scheduledJob(spec, strg, labels)
+ if err != nil {
+ return nil, fmt.Errorf("scheduled job: %w", err)
+ }
jb := &batchv1beta1.CronJob{
TypeMeta: metav1.TypeMeta{
APIVersion: "batch/v1beta1",
@@ -35,7 +41,7 @@ func (bcp *Backup) Scheduled(spec *api.PXCScheduledBackupSchedule, strg *api.Bac
Schedule: spec.Schedule,
SuccessfulJobsHistoryLimit: func(i int32) *int32 { return &i }(1),
JobTemplate: batchv1beta1.JobTemplateSpec{
- Spec: bcp.scheduledJob(spec, strg, labels),
+ Spec: cjts,
},
},
}
@@ -51,13 +57,13 @@ func (bcp *Backup) Scheduled(spec *api.PXCScheduledBackupSchedule, strg *api.Bac
),
)
- return jb
+ return jb, nil
}
-func (bcp *Backup) scheduledJob(spec *api.PXCScheduledBackupSchedule, strg *api.BackupStorageSpec, labels map[string]string) batchv1.JobSpec {
+func (bcp *Backup) scheduledJob(spec *api.PXCScheduledBackupSchedule, strg *api.BackupStorageSpec, labels map[string]string) (batchv1.JobSpec, error) {
resources, err := app.CreateResources(strg.Resources)
if err != nil {
- log.Info("cannot parse backup resources: ", err)
+ return batchv1.JobSpec{}, fmt.Errorf("cannot parse backup resources: %w", err)
}
return batchv1.JobSpec{
@@ -115,5 +121,5 @@ func (bcp *Backup) scheduledJob(spec *api.PXCScheduledBackupSchedule, strg *api.
PriorityClassName: strg.PriorityClassName,
},
},
- }
+ }, nil
}

license: Apache License 2.0

repo: percona/percona-xtradb-cluster-operator

original_message:
CLOUD-474: error handling for wrong resources

Return error instead of logging if failed to process given resources


message: add required env

diff:
@@ -27,5 +27,9 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name
- name: OPERATOR_NAME
value: "percona-xtradb-cluster-operator"
\ No newline at end of file

original_message: K8SPXC-297: add required env


message: Update vs url path

diff:
@@ -15,7 +15,7 @@ func (vs VersionServiceClient) GetExactVersion(vm versionMeta) (DepVersion, erro
}
requestURL, err := url.Parse(
- fmt.Sprintf("%s/api/versions/v1/pxc/%s/%s",
+ fmt.Sprintf("%s/versions/v1/pxc/%s/%s",
strings.TrimRight(vs.URL, "/"),
vs.OpVersion,
vm.Apply,

original_message: Update vs url path


message: add functionality to provide own proxysql config

diff:
@@ -176,6 +176,54 @@ spec:
enabled: false
size: 3
image: percona/percona-xtradb-cluster-operator:1.5.0-proxysql
+# configuration: |
+# datadir="/var/lib/proxysql"
+#
+# admin_variables =
+# {
+# admin_credentials="admin:admin"
+# mysql_ifaces="0.0.0.0:6032"
+# refresh_interval=2000
+#
+# cluster_username="admin"
+# cluster_password="admin"
+# cluster_check_interval_ms=200
+# cluster_check_status_frequency=100
+# cluster_mysql_query_rules_save_to_disk=true
+# cluster_mysql_servers_save_to_disk=true
+# cluster_mysql_users_save_to_disk=true
+# cluster_proxysql_servers_save_to_disk=true
+# cluster_mysql_query_rules_diffs_before_sync=1
+# cluster_mysql_servers_diffs_before_sync=1
+# cluster_mysql_users_diffs_before_sync=1
+# cluster_proxysql_servers_diffs_before_sync=1
+# }
+#
+# mysql_variables=
+# {
+# monitor_password="monitor"
+# monitor_galera_healthcheck_interval=1000
+# threads=2
+# max_connections=2048
+# default_query_delay=0
+# default_query_timeout=10000
+# poll_timeout=2000
+# interfaces="0.0.0.0:3306"
+# default_schema="information_schema"
+# stacksize=1048576
+# connect_timeout_server=10000
+# monitor_history=60000
+# monitor_connect_interval=20000
+# monitor_ping_interval=10000
+# ping_timeout_server=200
+# commands_stats=true
+# sessions_sort=true
+# have_ssl=false
+# ssl_p2s_ca=""
+# ssl_p2s_cert=""
+# ssl_p2s_key=""
+# ssl_p2s_cipher=""
+# }
# schedulerName: mycustom-scheduler
# imagePullSecrets:
# - name: private-registry-credentials

diff:
@@ -63,8 +63,10 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE
github.com/OneOfOne/xxhash v1.2.6/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
@@ -88,6 +90,7 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
+github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 h1:zV3ejI06GQ59hwDQAvmK1qxOQGB3WuVTRoY0okPTAv0=
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
@@ -261,32 +264,38 @@ github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpR
github.com/go-openapi/analysis v0.17.2/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
+github.com/go-openapi/analysis v0.19.5 h1:8b2ZgKfKIUTVQpTb77MoRDIMEIwvDVw40o3aOXdfYzI=
github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU=
github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
github.com/go-openapi/errors v0.17.2/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
+github.com/go-openapi/errors v0.19.2 h1:a2kIyV3w+OS3S97zxUndRVD46+FhGOUBDFY7nmu4CsY=
github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.17.2/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
+github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.17.2/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
+github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.17.2/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs=
+github.com/go-openapi/loads v0.19.4 h1:5I4CCSqoWzT+82bBkNIvmLc0UOsoKKQ4Fz+3VxOB7SY=
github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk=
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
github.com/go-openapi/runtime v0.18.0/go.mod h1:uI6pHuxWYTy94zZxgcwJkUWa9wbIlhteGfloI10GD4U=
github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
+github.com/go-openapi/runtime v0.19.4 h1:csnOgcgAiuGoM/Po7PEpKDoNulCcF3FGbSnbHfxgjMI=
github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
@@ -294,26 +303,31 @@ github.com/go-openapi/spec v0.17.2/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsd
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
+github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo=
github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
github.com/go-openapi/strfmt v0.17.2/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
+github.com/go-openapi/strfmt v0.19.3 h1:eRfyY5SkaNJCAwmmMcADjY31ow9+N7MCLW7oRkbsINA=
github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.17.2/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/validate v0.17.2/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
+github.com/go-openapi/validate v0.19.5 h1:QhCBKRYqZR+SKo4gl1lPhPahope8/RLt6EVgY8X80w0=
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ=
@@ -530,6 +544,7 @@ github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/maorfr/helm-plugin-utils v0.0.0-20200216074820-36d2fcf6ae86/go.mod h1:p3gwmRSFqbWw6plBpR0sKl3n3vpu8kX70gvCJKMvvCA=
github.com/markbates/inflect v1.0.4/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs=
@@ -575,6 +590,7 @@ github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:
github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
@@ -785,6 +801,7 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/thanos-io/thanos v0.11.0/go.mod h1:N/Yes7J68KqvmY+xM6J5CJqEvWIvKSR5sqGtmuD6wDc=
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
+github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=

diff:
@@ -719,6 +719,23 @@ func (r *ReconcilePerconaXtraDBCluster) reconcileConfigMap(cr *api.PerconaXtraDB
}
}
+ if cr.Spec.ProxySQL != nil && cr.Spec.ProxySQL.Configuration != "" {
+ configMap := config.NewConfigMap(cr, ls["app.kubernetes.io/instance"]+"-proxysql", "proxysql.cnf", cr.Spec.ProxySQL.Configuration)
+ err := setControllerReference(cr, configMap, r.scheme)
+ if err != nil {
+ return errors.Wrap(err, "set controller ref ProxySQL")
+ }
+ err = r.client.Create(context.TODO(), configMap)
+ if err != nil && k8serrors.IsAlreadyExists(err) {
+ err = r.client.Update(context.TODO(), configMap)
+ if err != nil {
+ return errors.Wrap(err, "update ConfigMap HAProxy")
+ }
+ } else if err != nil {
+ return errors.Wrap(err, "create ConfigMap HAProxy")
+ }
+ }
+
if cr.Spec.HAProxy != nil && cr.Spec.HAProxy.Configuration != "" {
configMap := config.NewConfigMap(cr, ls["app.kubernetes.io/instance"]+"-haproxy", "haproxy-global.cfg", cr.Spec.HAProxy.Configuration)
err := setControllerReference(cr, configMap, r.scheme)

diff:
@@ -76,6 +76,10 @@ func (c *Proxy) AppContainer(spec *api.PodSpec, secrets string, cr *api.PerconaX
Name: "ssl-internal",
MountPath: "/etc/proxysql/ssl-internal",
},
+ {
+ Name: "config",
+ MountPath: "/etc/proxysql/",
+ },
},
Env: []corev1.EnvVar{
{
@@ -295,10 +299,13 @@ func (c *Proxy) PMMContainer(spec *api.PMMSpec, secrets string, cr *api.PerconaX
func (c *Proxy) Volumes(podSpec *api.PodSpec, cr *api.PerconaXtraDBCluster) (*api.Volume, error) {
vol := app.Volumes(podSpec, proxyDataVolumeName)
+ ls := c.Labels()
vol.Volumes = append(
vol.Volumes,
app.GetSecretVolumes("ssl-internal", podSpec.SSLInternalSecretName, true),
- app.GetSecretVolumes("ssl", podSpec.SSLSecretName, cr.Spec.AllowUnsafeConfig))
+ app.GetSecretVolumes("ssl", podSpec.SSLSecretName, cr.Spec.AllowUnsafeConfig),
+ app.GetConfigVolumes("config", ls["app.kubernetes.io/instance"]+"-proxysql"),
+ )
return vol, nil
}


message: fix empty config mount

diff:
@@ -75,12 +75,7 @@ func (c *Proxy) AppContainer(spec *api.PodSpec, secrets string, cr *api.PerconaX
{
Name: "ssl-internal",
MountPath: "/etc/proxysql/ssl-internal",
- },
- {
- Name: "config",
- MountPath: "/etc/proxysql/",
- },
- },
+ }},
Env: []corev1.EnvVar{
{
Name: "PXC_SERVICE",
@@ -111,7 +106,12 @@ func (c *Proxy) AppContainer(spec *api.PodSpec, secrets string, cr *api.PerconaX
},
SecurityContext: spec.ContainerSecurityContext,
}
-
+ if cr.Spec.ProxySQL != nil && cr.Spec.ProxySQL.Configuration != "" {
+ appc.VolumeMounts = append(appc.VolumeMounts, corev1.VolumeMount{
+ Name: "config",
+ MountPath: "/etc/proxysql/",
+ })
+ }
if cr.CompareVersionWith("1.5.0") >= 0 {
appc.Env[1] = corev1.EnvVar{
Name: "OPERATOR_PASSWORD",
@@ -304,8 +304,10 @@ func (c *Proxy) Volumes(podSpec *api.PodSpec, cr *api.PerconaXtraDBCluster) (*ap
vol.Volumes,
app.GetSecretVolumes("ssl-internal", podSpec.SSLInternalSecretName, true),
app.GetSecretVolumes("ssl", podSpec.SSLSecretName, cr.Spec.AllowUnsafeConfig),
- app.GetConfigVolumes("config", ls["app.kubernetes.io/instance"]+"-proxysql"),
)
+ if cr.Spec.ProxySQL != nil && cr.Spec.ProxySQL.Configuration != "" {
+ vol.Volumes = append(vol.Volumes, app.GetConfigVolumes("config", ls["app.kubernetes.io/instance"]+"-proxysql"))
+ }
return vol, nil
}

original_message: fix empty config mount


message: config with credentials from secrets.yaml

diff:
@@ -181,12 +181,12 @@ spec:
#
# admin_variables =
# {
-# admin_credentials="admin:admin"
+# admin_credentials="proxyadmin:admin_password"
# mysql_ifaces="0.0.0.0:6032"
# refresh_interval=2000
#
-# cluster_username="admin"
-# cluster_password="admin"
+# cluster_username="proxyadmin"
+# cluster_password="admin_password"
# cluster_check_interval_ms=200
# cluster_check_status_frequency=100
# cluster_mysql_query_rules_save_to_disk=true
@@ -218,11 +218,11 @@ spec:
# ping_timeout_server=200
# commands_stats=true
# sessions_sort=true
-# have_ssl=false
-# ssl_p2s_ca=""
-# ssl_p2s_cert=""
-# ssl_p2s_key=""
-# ssl_p2s_cipher=""
+# have_ssl=true
+# ssl_p2s_ca="/etc/proxysql/ssl-internal/ca.crt"
+# ssl_p2s_cert="/etc/proxysql/ssl-internal/tls.crt"
+# ssl_p2s_key="/etc/proxysql/ssl-internal/tls.key"
+# ssl_p2s_cipher="ECDHE-RSA-AES128-GCM-SHA256"
# }
# schedulerName: mycustom-scheduler
# imagePullSecrets:


message: Make build-proto.sh generic to be able to build proto files locally

old_path: build/Dockerfile

new_path: build/Dockerfile

diff:
@@ -10,6 +10,8 @@ ARG GOOS=linux
ARG GOARCH=amd64
ARG CGO_ENABLED=0
+RUN build/build-proto.sh
+
RUN mkdir -p build/_output/bin \
&& GOOS=$GOOS GOARCH=$GOARCH CGO_ENABLED=$CGO_ENABLED GO_LDFLAGS=$GO_LDFLAGS \
go build -mod=vendor -ldflags "-w -s -X main.GitCommit=$GIT_COMMIT -X main.GitBranch=$GIT_BRANCH" \

diff:
set -o errexit
set -o xtrace
+proto_compiler=protoc
+
go get \
github.com/golang/protobuf/protoc-gen-go \
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \
@@ -11,6 +13,22 @@ go get \
go install github.com/go-swagger/go-swagger/cmd/swagger
-protoc -I build/third_party/googleapis -I build/third_party/grpc-gateway -I vendor/github.com/Percona-Lab/percona-version-service/api --openapiv2_out=./openapi vendor/github.com/Percona-Lab/percona-version-service/api/version.proto
+rm -rf versionserviceclient
+
+if ! protoc --version &> /dev/null
+then
+ apt-get update && apt-get install unzip
+
+ curl -LO https://github.com/protocolbuffers/protobuf/releases/download/v3.12.1/protoc-3.12.1-linux-x86_64.zip
+
+ unzip protoc-3.12.1-linux-x86_64.zip -d $HOME/.local
+
+ proto_compiler=$HOME/.local/bin/protoc
+
+fi
+
+mkdir -p openapi
+
+$proto_compiler -I build/third_party/googleapis -I build/third_party/grpc-gateway -I vendor/github.com/Percona-Lab/percona-version-service/api --openapiv2_out=./openapi vendor/github.com/Percona-Lab/percona-version-service/api/version.proto
swagger generate client -f openapi/version.swagger.json -c versionserviceclient -m versionserviceclient/models


message: add client build to jenkins job

old_path: Jenkinsfile

new_path: Jenkinsfile

diff:
@@ -186,7 +186,6 @@ pipeline {
./e2e-tests/build
docker logout
"
- sudo rm -rf ./build
'''
}
stash includes: 'results/docker/TAG', name: 'IMAGE'
@@ -222,7 +221,7 @@ pipeline {
-v $WORKSPACE/src/github.com/percona/percona-xtradb-cluster-operator:/go/src/github.com/percona/percona-xtradb-cluster-operator \
-w /go/src/github.com/percona/percona-xtradb-cluster-operator \
-e GO111MODULE=on \
- golang:1.14 sh -c 'go build -v -mod=vendor -o percona-xtradb-cluster-operator github.com/percona/percona-xtradb-cluster-operator/cmd/manager'
+ golang:1.14 sh -c 'cd /go/src/github.com/percona/percona-xtradb-cluster-operator && build/build-proto.sh && cd - && go build -v -mod=vendor -o percona-xtradb-cluster-operator github.com/percona/percona-xtradb-cluster-operator/cmd/manager'
"
'''

diff:
-#!/bin/bash
+#!/bin/sh
set -o errexit
set -o xtrace

original_message: add client build to jenkins job


message:
install actual version of go-license-detector
add swagger check to build-proto.sh

diff:
@@ -153,11 +153,11 @@ pipeline {
curl -s -L https://github.com/mitchellh/golicense/releases/latest/download/golicense_0.2.0_linux_x86_64.tar.gz \
| sudo tar -C /usr/local/bin --wildcards -zxvpf -
- # curl -s -L https://github.com/src-d/go-license-detector/releases/latest/download/license-detector.linux_amd64.gz \
- # | gunzip | sudo tee /usr/local/bin/license-detector > /dev/null
- curl -s -L https://github.com/src-d/go-license-detector/releases/download/v3.0.2/license-detector.linux_amd64.gz \
- | gunzip | sudo tee /usr/local/bin/license-detector > /dev/null
+ sudo curl -s -L https://github.com/go-swagger/go-swagger/releases/download/v0.24.0/swagger_linux_amd64 -o /usr/local/bin/swagger
+ curl -s -L https://github.com/go-enry/go-license-detector/releases/download/v4.0.0/license-detector-v4.0.0-linux-amd64.tar.gz \
+ | sudo tar -C /usr/local/bin --wildcards -zxvpf -
sudo chmod +x /usr/local/bin/license-detector
+ sudo chmod +x /usr/local/bin/swagger
'''
withCredentials([file(credentialsId: 'cloud-secret-file', variable: 'CLOUD_SECRET_FILE')]) {
sh '''
@@ -179,13 +179,13 @@ pipeline {
docker_tag_file='./results/docker/TAG'
mkdir -p $(dirname ${docker_tag_file})
echo ${DOCKER_TAG} > "${docker_tag_file}"
-
sg docker -c "
docker login -u '${USER}' -p '${PASS}'
export IMAGE=\$DOCKER_TAG
./e2e-tests/build
docker logout
"
+ sudo rm -rf ./build
'''
}
stash includes: 'results/docker/TAG', name: 'IMAGE'
@@ -221,7 +221,9 @@ pipeline {
-v $WORKSPACE/src/github.com/percona/percona-xtradb-cluster-operator:/go/src/github.com/percona/percona-xtradb-cluster-operator \
-w /go/src/github.com/percona/percona-xtradb-cluster-operator \
-e GO111MODULE=on \
- golang:1.14 sh -c 'cd /go/src/github.com/percona/percona-xtradb-cluster-operator && build/build-proto.sh && cd - && go build -v -mod=vendor -o percona-xtradb-cluster-operator github.com/percona/percona-xtradb-cluster-operator/cmd/manager'
+ golang:1.14 sh -c 'go install github.com/go-swagger/go-swagger/cmd/swagger \
+ && swagger generate client -f vendor/github.com/Percona-Lab/percona-version-service/api/version.swagger.yaml -c versionserviceclient -m versionserviceclient/models \
+ && go build -v -mod=vendor -o percona-xtradb-cluster-operator github.com/percona/percona-xtradb-cluster-operator/cmd/manager'
"
'''

diff:
set -o errexit
set -o xtrace
-proto_compiler=protoc
-
-go get \
- github.com/golang/protobuf/protoc-gen-go \
- github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \
- github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \
- github.com/rakyll/statik
-
+if ! swagger version &>/dev/null; then
go install github.com/go-swagger/go-swagger/cmd/swagger
-
-rm -rf versionserviceclient
-
-if ! protoc --version &>/dev/null; then
- apt-get update && apt-get install unzip
-
- curl -LO https://github.com/protocolbuffers/protobuf/releases/download/v3.12.1/protoc-3.12.1-linux-x86_64.zip
-
- unzip protoc-3.12.1-linux-x86_64.zip -d $HOME/.local
-
- proto_compiler=$HOME/.local/bin/protoc
fi
-rm -rf build/third_party
-
-mkdir -p openapi
-mkdir -p build/third_party/openapi_proto
-
-git clone https://github.com/googleapis/googleapis build/third_party/googleapis
-git clone -b v2 https://github.com/grpc-ecosystem/grpc-gateway build/third_party/openapi
-
-cd build/third_party/googleapis && git checkout 76905ffe7e3b0605f64ef889fb88913634f9f836 && cd ../../..
-cd build/third_party/openapi && git checkout fcec199c8378122670cbf93a72d7363e9bd460fe && mv protoc-gen-openapiv2 ../openapi_proto/ && cd ../../..
-
-$proto_compiler -I build/third_party/googleapis -I build/third_party/openapi_proto -I vendor/github.com/Percona-Lab/percona-version-service/api --openapiv2_out=./openapi vendor/github.com/Percona-Lab/percona-version-service/api/version.proto
-
-swagger generate client -f openapi/version.swagger.json -c versionserviceclient -m versionserviceclient/models
+rm -rf versionserviceclient
-rm -rf openapi
-rm -rf build/third_party
+swagger generate client -f vendor/github.com/Percona-Lab/percona-version-service/api/version.swagger.yaml -c versionserviceclient -m versionserviceclient/models

diff:
@@ -3,7 +3,7 @@ module github.com/percona/percona-xtradb-cluster-operator
go 1.13
require (
- github.com/Percona-Lab/percona-version-service/api v0.0.0-20200702140248-ad469044aacf
+ github.com/Percona-Lab/percona-version-service/api v0.0.0-20200707073643-e3dd469db8be
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/go-openapi/errors v0.19.6
github.com/go-openapi/runtime v0.19.16

diff:
@@ -61,8 +61,8 @@ github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMo
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OneOfOne/xxhash v1.2.6/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
-github.com/Percona-Lab/percona-version-service/api v0.0.0-20200702140248-ad469044aacf h1:GeAiiL7NlH1q/j3emyXKYeRWCqv0ML7jJ1AZsMv0mmY=
-github.com/Percona-Lab/percona-version-service/api v0.0.0-20200702140248-ad469044aacf/go.mod h1:QDbZ+DHh0CkTHN6LRkMQd1pEl3b30EaNZ9FA97Mb3TA=
+github.com/Percona-Lab/percona-version-service/api v0.0.0-20200707073643-e3dd469db8be h1:TL1Q7CRBmK3vUC9Z6EMdcra6wHmL0fkcMjDgs3ypEyI=
+github.com/Percona-Lab/percona-version-service/api v0.0.0-20200707073643-e3dd469db8be/go.mod h1:QDbZ+DHh0CkTHN6LRkMQd1pEl3b30EaNZ9FA97Mb3TA=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=

diff:
@@ -2,6 +2,7 @@ package pxc
import (
"fmt"
+ "net/http"
"net/url"
"time"
@@ -10,9 +11,9 @@ import (
"github.com/percona/percona-xtradb-cluster-operator/versionserviceclient/version_service"
)
-const productName = "pxc"
+const productName = "pxc-operator"
-func (vs VersionServiceClient) GetExactVersion(desiredVersion, currentVersion string, versionMeta currVersionMeta) (DepVersion, error) {
+func (vs VersionServiceClient) GetExactVersion(vm versionMeta) (DepVersion, error) {
requestURL, err := url.Parse(vs.URL)
if err != nil {
return DepVersion{}, err
@@ -24,12 +25,21 @@ func (vs VersionServiceClient) GetExactVersion(desiredVersion, currentVersion st
Schemes: []string{requestURL.Scheme},
})
- params := version_service.NewVersionServiceApplyParamsWithTimeout(10 * time.Second).WithProduct(productName).
- WithOperatorVersion(vs.OpVersion).WithApply(desiredVersion).WithDatabaseVersion(&currentVersion).
- WithKubeVersion(&versionMeta.KubeVersion).WithPlatform(&versionMeta.Platform).WithCustomResourceOid(&versionMeta.CRUID).
- WithPmmVersion(&versionMeta.PMMVersion).WithBackupVersion(&versionMeta.BackupVersion)
+ applyParams := &version_service.VersionServiceApplyParams{
+ Apply: vm.Apply,
+ BackupVersion: &vm.BackupVersion,
+ CustomResourceOid: &vm.CRUID,
+ DatabaseVersion: &vm.PXCVersion,
+ KubeVersion: &vm.KubeVersion,
+ OperatorVersion: vs.OpVersion,
+ Platform: &vm.Platform,
+ PmmVersion: &vm.PMMVersion,
+ Product: productName,
+ HTTPClient: &http.Client{Timeout: 10 * time.Second},
+ }
+ applyParams = applyParams.WithTimeout(10 * time.Second)
- resp, err := srvCl.VersionService.VersionServiceApply(params)
+ resp, err := srvCl.VersionService.VersionServiceApply(applyParams)
if err != nil {
return DepVersion{}, err
@@ -101,7 +111,7 @@ type DepVersion struct {
}
type VersionService interface {
- GetExactVersion(vm versionMeta) (DepVersion, error)
+ GetExactVersion(versionMeta versionMeta) (DepVersion, error)
}
type VersionServiceClient struct {
@@ -109,7 +119,9 @@ type VersionServiceClient struct {
OpVersion string
}
-type currVersionMeta struct {
+type versionMeta struct {
+ Apply string
+ PXCVersion string
KubeVersion string
Platform string
PMMVersion string

diff:
@@ -2,30 +2,33 @@ syntax="proto3";
package version;
-import "google/api/annotations.proto";
-import "protoc-gen-openapiv2/options/annotations.proto";
-
-// Defines the import path that should be used to import the generated package,
-// and the package name.
-option go_package = "github.com/Percona-Lab/percona-version-service/proto;version";
-
// These annotations are used when generating the OpenAPI file.
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
info: {
- version: "1.0";
- };
+ version: "1.0"
+ }
external_docs: {
- url: "https://github.com/Percona-Lab/percona-version-service";
- description: "gRPC-gateway boilerplate repository";
+ url: "https://github.com/Percona-Lab/percona-version-service"
+ description: "This service provides version information and image paths for supporting the use of Percona Kubernetes Operators in a variety of scenarios while enabling specific version deployments and automated upgrades."
}
- schemes: [HTTP, HTTPS];
+ schemes: [
+ HTTP,
+ HTTPS
+ ]
};
+// Defines the import path that should be used to import the generated package,
+// and the package name.
+option go_package = "github.com/Percona-Lab/percona-version-service/version";
+
+import "google/api/annotations.proto";
+import "protoc-gen-openapiv2/options/annotations.proto";
+// VersionService provides public API methods for version service usage.
service VersionService {
+ // Apply provides information about specific product version and its dependencies.
rpc Apply(ApplyRequest) returns (VersionResponse) {
option (google.api.http) = {
- // Route to this method from GET requests to /versions/v1/{product}/{operatorVersion}/{apply}
- get: "/api/versions/v1/{product}/{operator_version}/{apply}"
+ get: "/versions/v1/{product}/{operator_version}/{apply}"
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
summary: "Specific version"
@@ -44,16 +47,27 @@ message ApplyRequest {
string pmm_version = 7;
string backup_version = 8;
string namespace_oid = 9;
- string customResource_oid = 10;
+ string custom_resource_oid = 10;
+}
+
+// Status describes the current version status.
+enum Status {
+ status_invalid = 0;
+ recommended = 1;
+ available = 2;
+ required = 3;
+ disabled = 4;
}
+// Version represents product version information.
message Version {
string image_path = 1;
string image_hash = 2;
- string status = 3;
+ Status status = 3;
bool critical = 4;
}
+// VersionMatrix represents set of possible product versions.
message VersionMatrix {
map<string, Version> mongod = 1;
map<string, Version> pxc = 2;
@@ -64,9 +78,10 @@ message VersionMatrix {
map<string, Version> operator = 7;
}
+// OperatorVersion represents operator version.
message OperatorVersion {
- string operator = 1;
- string database = 2;
+ string product = 1;
+ string operator = 2;
VersionMatrix matrix = 3;
}

diff:
+swagger: "2.0"
+info:
+ title: api/version.proto
+ version: "1.0"
+schemes:
+ - http
+ - https
+consumes:
+ - application/json
+produces:
+ - application/json
+paths:
+ /versions/v1/{product}/{operatorVersion}/{apply}:
+ get:
+ summary: Specific version
+ description: Return specific product version
+ operationId: VersionService_Apply
+ responses:
+ "200":
+ description: A successful response.
+ schema:
+ $ref: '#/definitions/versionVersionResponse'
+ default:
+ description: An unexpected error response
+ schema:
+ $ref: '#/definitions/googlerpcStatus'
+ parameters:
+ - name: product
+ in: path
+ required: true
+ type: string
+ - name: operatorVersion
+ in: path
+ required: true
+ type: string
+ - name: apply
+ in: path
+ required: true
+ type: string
+ - name: databaseVersion
+ in: query
+ required: false
+ type: string
+ - name: kubeVersion
+ in: query
+ required: false
+ type: string
+ - name: platform
+ in: query
+ required: false
+ type: string
+ - name: pmmVersion
+ in: query
+ required: false
+ type: string
+ - name: backupVersion
+ in: query
+ required: false
+ type: string
+ - name: namespaceOid
+ in: query
+ required: false
+ type: string
+ - name: customResourceOid
+ in: query
+ required: false
+ type: string
+ tags:
+ - VersionService
+definitions:
+ googlerpcStatus:
+ type: object
+ properties:
+ code:
+ type: integer
+ format: int32
+ message:
+ type: string
+ details:
+ type: array
+ items:
+ $ref: '#/definitions/protobufAny'
+ protobufAny:
+ type: object
+ properties:
+ typeUrl:
+ type: string
+ description: |-
+ A URL/resource name that uniquely identifies the type of the serialized
+ protocol buffer message. This string must contain at least
+ one "/" character. The last segment of the URL's path must represent
+ the fully qualified name of the type (as in
+ `path/google.protobuf.Duration`). The name should be in a canonical form
+ (e.g., leading "." is not accepted).
+
+ In practice, teams usually precompile into the binary all types that they
+ expect it to use in the context of Any. However, for URLs which use the
+ scheme `http`, `https`, or no scheme, one can optionally set up a type
+ server that maps type URLs to message definitions as follows:
+
+ * If no scheme is provided, `https` is assumed.
+ * An HTTP GET on the URL must yield a [google.protobuf.Type][]
+ value in binary format, or produce an error.
+ * Applications are allowed to cache lookup results based on the
+ URL, or have them precompiled into a binary to avoid any
+ lookup. Therefore, binary compatibility needs to be preserved
+ on changes to types. (Use versioned type names to manage
+ breaking changes.)
+
+ Note: this functionality is not currently available in the official
+ protobuf release, and it is not used for type URLs beginning with
+ type.googleapis.com.
+
+ Schemes other than `http`, `https` (or the empty scheme) might be
+ used with implementation specific semantics.
+ value:
+ type: string
+ format: byte
+ description: Must be a valid serialized protocol buffer of the above specified type.
+ description: |-
+ `Any` contains an arbitrary serialized protocol buffer message along with a
+ URL that describes the type of the serialized message.
+
+ Protobuf library provides support to pack/unpack Any values in the form
+ of utility functions or additional generated methods of the Any type.
+
+ Example 1: Pack and unpack a message in C++.
+
+ Foo foo = ...;
+ Any any;
+ any.PackFrom(foo);
+ ...
+ if (any.UnpackTo(&foo)) {
+ ...
+ }
+
+ Example 2: Pack and unpack a message in Java.
+
+ Foo foo = ...;
+ Any any = Any.pack(foo);
+ ...
+ if (any.is(Foo.class)) {
+ foo = any.unpack(Foo.class);
+ }
+
+ Example 3: Pack and unpack a message in Python.
+
+ foo = Foo(...)
+ any = Any()
+ any.Pack(foo)
+ ...
+ if any.Is(Foo.DESCRIPTOR):
+ any.Unpack(foo)
+ ...
+
+ Example 4: Pack and unpack a message in Go
+
+ foo := &pb.Foo{...}
+ any, err := ptypes.MarshalAny(foo)
+ ...
+ foo := &pb.Foo{}
+ if err := ptypes.UnmarshalAny(any, foo); err != nil {
+ ...
+ }
+
+ The pack methods provided by protobuf library will by default use
+ 'type.googleapis.com/full.type.name' as the type URL and the unpack
+ methods only use the fully qualified type name after the last '/'
+ in the type URL, for example "foo.bar.com/x/y.z" will yield type
+ name "y.z".
+
+
+ JSON
+ ====
+ The JSON representation of an `Any` value uses the regular
+ representation of the deserialized, embedded message, with an
+ additional field `@type` which contains the type URL. Example:
+
+ package google.profile;
+ message Person {
+ string first_name = 1;
+ string last_name = 2;
+ }
+
+ {
+ "@type": "type.googleapis.com/google.profile.Person",
+ "firstName": <string>,
+ "lastName": <string>
+ }
+
+ If the embedded message type is well-known and has a custom JSON
+ representation, that representation will be embedded adding a field
+ `value` which holds the custom JSON in addition to the `@type`
+ field. Example (for message [google.protobuf.Duration][]):
+
+ {
+ "@type": "type.googleapis.com/google.protobuf.Duration",
+ "value": "1.212s"
+ }
+ versionOperatorVersion:
+ type: object
+ properties:
+ product:
+ type: string
+ operator:
+ type: string
+ matrix:
+ $ref: '#/definitions/versionVersionMatrix'
+ description: OperatorVersion represents operator version.
+ versionStatus:
+ type: string
+ enum:
+ - status_invalid
+ - recommended
+ - available
+ - required
+ - disabled
+ default: status_invalid
+ description: Status describes the current version status.
+ versionVersion:
+ type: object
+ properties:
+ imagePath:
+ type: string
+ imageHash:
+ type: string
+ status:
+ $ref: '#/definitions/versionStatus'
+ critical:
+ type: boolean
+ format: boolean
+ description: Version represents product version information.
+ versionVersionMatrix:
+ type: object
+ properties:
+ mongod:
+ type: object
+ additionalProperties:
+ $ref: '#/definitions/versionVersion'
+ pxc:
+ type: object
+ additionalProperties:
+ $ref: '#/definitions/versionVersion'
+ pmm:
+ type: object
+ additionalProperties:
+ $ref: '#/definitions/versionVersion'
+ proxysql:
+ type: object
+ additionalProperties:
+ $ref: '#/definitions/versionVersion'
+ haproxy:
+ type: object
+ additionalProperties:
+ $ref: '#/definitions/versionVersion'
+ backup:
+ type: object
+ additionalProperties:
+ $ref: '#/definitions/versionVersion'
+ operator:
+ type: object
+ additionalProperties:
+ $ref: '#/definitions/versionVersion'
+ description: VersionMatrix represents set of possible product versions.
+ versionVersionResponse:
+ type: object
+ properties:
+ versions:
+ type: array
+ items:
+ $ref: '#/definitions/versionOperatorVersion'
+externalDocs:
+ description: This service provides version information and image paths for supporting the use of Percona Kubernetes Operators in a variety of scenarios while enabling specific version deployments and automated upgrades.
+ url: https://github.com/Percona-Lab/percona-version-service

diff:
# cloud.google.com/go v0.49.0
cloud.google.com/go/compute/metadata
-# github.com/Percona-Lab/percona-version-service/api v0.0.0-20200702140248-ad469044aacf
+# github.com/Percona-Lab/percona-version-service/api v0.0.0-20200707073643-e3dd469db8be
github.com/Percona-Lab/percona-version-service/api
# github.com/PuerkitoBio/purell v1.1.1
github.com/PuerkitoBio/purell


message: final version of version service

diff:
@@ -3,7 +3,6 @@ package v1
import (
"encoding/json"
"fmt"
- "github.com/percona/percona-xtradb-cluster-operator/version"
"strings"
v "github.com/hashicorp/go-version"
@@ -514,11 +513,7 @@ func (cr *PerconaXtraDBCluster) CheckNSetDefaults(serverVersion *ServerVersion)
}
cr.setSecurityContext()
-
- ver,err := version.GetServer()
- if err == nil {
- cr.Spec.Platform = &ver.Platform
- }
+ cr.Spec.Platform = serverVersion.Platform
return changed, nil
}

diff:
@@ -111,7 +111,7 @@ type DepVersion struct {
}
type VersionService interface {
- GetExactVersion(versionMeta versionMeta) (DepVersion, error)
+ GetExactVersion(vm versionMeta) (DepVersion, error)
}
type VersionServiceClient struct {

original_message: final version of version service


message:
add haproxy and proxysql to version-service request
fetch swagger generator by tag

diff:
@@ -221,7 +221,7 @@ pipeline {
-v $WORKSPACE/src/github.com/percona/percona-xtradb-cluster-operator:/go/src/github.com/percona/percona-xtradb-cluster-operator \
-w /go/src/github.com/percona/percona-xtradb-cluster-operator \
-e GO111MODULE=on \
- golang:1.14 sh -c 'go install github.com/go-swagger/go-swagger/cmd/swagger \
+ golang:1.14 sh -c 'go install github.com/go-swagger/go-swagger/cmd/swagger@v0.24.0 \
&& swagger generate client -f vendor/github.com/Percona-Lab/percona-version-service/api/version.swagger.yaml -c versionserviceclient -m versionserviceclient/models \
&& go build -v -mod=vendor -o percona-xtradb-cluster-operator github.com/percona/percona-xtradb-cluster-operator/cmd/manager'
"

diff:
@@ -4,7 +4,7 @@ set -o errexit
set -o xtrace
if ! swagger version &>/dev/null; then
- go install github.com/go-swagger/go-swagger/cmd/swagger
+ go install github.com/go-swagger/go-swagger/cmd/swagger@v0.24.0
fi
rm -rf versionserviceclient

diff:
@@ -3,7 +3,7 @@ module github.com/percona/percona-xtradb-cluster-operator
go 1.13
require (
- github.com/Percona-Lab/percona-version-service/api v0.0.0-20200707073643-e3dd469db8be
+ github.com/Percona-Lab/percona-version-service/api v0.0.0-20200714141734-e9fed619b55c
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/go-openapi/errors v0.19.6
github.com/go-openapi/runtime v0.19.16

diff:
@@ -61,8 +61,8 @@ github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMo
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OneOfOne/xxhash v1.2.6/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
-github.com/Percona-Lab/percona-version-service/api v0.0.0-20200707073643-e3dd469db8be h1:TL1Q7CRBmK3vUC9Z6EMdcra6wHmL0fkcMjDgs3ypEyI=
-github.com/Percona-Lab/percona-version-service/api v0.0.0-20200707073643-e3dd469db8be/go.mod h1:QDbZ+DHh0CkTHN6LRkMQd1pEl3b30EaNZ9FA97Mb3TA=
+github.com/Percona-Lab/percona-version-service/api v0.0.0-20200714141734-e9fed619b55c h1:wyHFENXN6jvd8UFy9z+nNgTBmUXVbUjCETqVYwooi40=
+github.com/Percona-Lab/percona-version-service/api v0.0.0-20200714141734-e9fed619b55c/go.mod h1:QDbZ+DHh0CkTHN6LRkMQd1pEl3b30EaNZ9FA97Mb3TA=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=

diff:
@@ -111,7 +111,7 @@ func (r *ReconcilePerconaXtraDBCluster) ensurePXCVersion(cr *api.PerconaXtraDBCl
PXCVersion: cr.Status.PXC.Version,
PMMVersion: cr.Status.PMM.Version,
HAProxyVersion: cr.Status.HAProxy.Version,
- ProxySqlVersion: cr.Status.ProxySQL.Version,
+ ProxySQLVersion: cr.Status.ProxySQL.Version,
BackupVersion: cr.Status.Backup.Version,
CRUID: string(cr.GetUID()),
})

diff:
@@ -28,12 +28,14 @@ func (vs VersionServiceClient) GetExactVersion(vm versionMeta) (DepVersion, erro
applyParams := &version_service.VersionServiceApplyParams{
Apply: vm.Apply,
BackupVersion: &vm.BackupVersion,
- CustomResourceOid: &vm.CRUID,
+ CustomResourceUID: &vm.CRUID,
DatabaseVersion: &vm.PXCVersion,
KubeVersion: &vm.KubeVersion,
OperatorVersion: vs.OpVersion,
Platform: &vm.Platform,
PmmVersion: &vm.PMMVersion,
+ ProxysqlVersion: &vm.ProxySQLVersion,
+ HaproxyVersion: &vm.HAProxyVersion,
Product: productName,
HTTPClient: &http.Client{Timeout: 10 * time.Second},
}
@@ -69,7 +71,7 @@ func (vs VersionServiceClient) GetExactVersion(vm versionMeta) (DepVersion, erro
return DepVersion{}, err
}
- haproxyVersion, err := getVersion(r.Versions[0].Matrix.HAProxy)
+ haproxyVersion, err := getVersion(resp.Payload.Versions[0].Matrix.Haproxy)
if err != nil {
return DepVersion{}, err
}
@@ -83,6 +85,8 @@ func (vs VersionServiceClient) GetExactVersion(vm versionMeta) (DepVersion, erro
ProxySqlVersion: proxySqlVersion,
PMMImage: resp.Payload.Versions[0].Matrix.Pmm[pmmVersion].ImagePath,
PMMVersion: pmmVersion,
+ HAProxyImage: resp.Payload.Versions[0].Matrix.Haproxy[haproxyVersion].ImagePath,
+ HAProxyVersion: haproxyVersion,
}, nil
}
@@ -126,5 +130,7 @@ type versionMeta struct {
Platform string
PMMVersion string
BackupVersion string
+ ProxySQLVersion string
+ HAProxyVersion string
CRUID string
}

diff:
@@ -46,8 +46,10 @@ message ApplyRequest {
string platform = 6;
string pmm_version = 7;
string backup_version = 8;
- string namespace_oid = 9;
- string custom_resource_oid = 10;
+ string proxysql_version = 9;
+ string haproxy_version = 10;
+ string namespace_uid = 11;
+ string custom_resource_uid = 12;
}
// Status describes the current version status.

diff:
@@ -57,11 +57,19 @@ paths:
in: query
required: false
type: string
- - name: namespaceOid
+ - name: proxysqlVersion
in: query
required: false
type: string
- - name: customResourceOid
+ - name: haproxyVersion
+ in: query
+ required: false
+ type: string
+ - name: namespaceUid
+ in: query
+ required: false
+ type: string
+ - name: customResourceUid
in: query
required: false
type: string

diff:
# cloud.google.com/go v0.49.0
cloud.google.com/go/compute/metadata
-# github.com/Percona-Lab/percona-version-service/api v0.0.0-20200707073643-e3dd469db8be
+# github.com/Percona-Lab/percona-version-service/api v0.0.0-20200714141734-e9fed619b55c
github.com/Percona-Lab/percona-version-service/api
# github.com/PuerkitoBio/purell v1.1.1
github.com/PuerkitoBio/purell


message: fix go-get command

diff:
@@ -221,7 +221,7 @@ pipeline {
-v $WORKSPACE/src/github.com/percona/percona-xtradb-cluster-operator:/go/src/github.com/percona/percona-xtradb-cluster-operator \
-w /go/src/github.com/percona/percona-xtradb-cluster-operator \
-e GO111MODULE=on \
- golang:1.14 sh -c 'go install github.com/go-swagger/go-swagger/cmd/swagger@v0.24.0 \
+ golang:1.14 sh -c 'go get github.com/go-swagger/go-swagger/cmd/swagger@v0.24.0 \
&& swagger generate client -f vendor/github.com/Percona-Lab/percona-version-service/api/version.swagger.yaml -c versionserviceclient -m versionserviceclient/models \
&& go build -v -mod=vendor -o percona-xtradb-cluster-operator github.com/percona/percona-xtradb-cluster-operator/cmd/manager'
"

diff:
@@ -4,7 +4,7 @@ set -o errexit
set -o xtrace
if ! swagger version &>/dev/null; then
- go install github.com/go-swagger/go-swagger/cmd/swagger@v0.24.0
+ go get github.com/go-swagger/go-swagger/cmd/swagger@v0.24.0
fi
rm -rf versionserviceclient

diff:
@@ -104,7 +104,7 @@ func (r *ReconcilePerconaXtraDBCluster) ensurePXCVersion(cr *api.PerconaXtraDBCl
return errors.New("cluster is not ready")
}
- newVersion, err := vs.GetExactVersion(cr.Spec.UpgradeOptions.VersionServiceEndpoint, VersionMeta{
+ newVersion, err := vs.GetExactVersion(cr.Spec.UpgradeOptions.VersionServiceEndpoint, versionMeta{
Apply: cr.Spec.UpgradeOptions.Apply,
Platform: string(cr.Spec.Platform),
KubeVersion: r.serverVersion.Info.GitVersion,

diff:
@@ -13,8 +13,8 @@ import (
const productName = "pxc-operator"
-func (vs VersionServiceClient) GetExactVersion(vm versionMeta) (DepVersion, error) {
- requestURL, err := url.Parse(vs.URL)
+func (vs VersionServiceClient) GetExactVersion(endpoint string,vm versionMeta) (DepVersion, error) {
+ requestURL, err := url.Parse(endpoint)
if err != nil {
return DepVersion{}, err
}
@@ -115,11 +115,10 @@ type DepVersion struct {
}
type VersionService interface {
- GetExactVersion(vm versionMeta) (DepVersion, error)
+ GetExactVersion(endpoint string,vm versionMeta) (DepVersion, error)
}
type VersionServiceClient struct {
- URL string
OpVersion string
}

original_message: fix go-get command


message:
Comment tls section
Comment the beginning of tls section because all it should be commented

diff:
@@ -14,7 +14,7 @@ spec:
vaultSecretName: keyring-secret-vault
sslSecretName: my-cluster-ssl
sslInternalSecretName: my-cluster-ssl-internal
- tls:
+# tls:
# SANs:
# - pxc-1.example.com
# - pxc-2.example.com

original_message:
Comment tls section (#550)

Comment the beginning of tls section because all it should be commented


message:
Update cr.yaml
Update version service URL

diff:
@@ -27,7 +27,7 @@ spec:
# pause: false
updateStrategy: SmartUpdate
upgradeOptions:
- versionServiceEndpoint: https://check.percona.com/versions
+ versionServiceEndpoint: https://check.percona.com
apply: recommended
schedule: "0 4 * * *"
pxc:


diff:
@@ -22,4 +22,4 @@ spec:
volumes:
- name: backup
persistentVolumeClaim:
- claimName: some-name-xb-on-demand-backup-pvc
+ claimName: xb-on-demand-backup-pvc

diff:
@@ -619,7 +619,7 @@ spinup_pxc() {
run_mysql \
'INSERT myApp.myApp (id) VALUES (100500)' \
"-h $proxy -uroot -proot_password"
- sleep 10
+ sleep 30
for i in $(seq 0 $(($size - 1))); do
compare_mysql_cmd "select-1" "SELECT * from myApp.myApp;" "-h $cluster-pxc-$i.$cluster-pxc -uroot -proot_password"
done

original_message:
K8SPXC-448: fix demand-backup-encrypted-with-tls test

Fix test, which was falling because of small sleep, and test unable to read from cluster


message: add certificate checks

diff:
@@ -562,8 +562,8 @@ func (r *ReconcilePerconaXtraDBCluster) deploy(cr *api.PerconaXtraDBCluster) err
}
sslInternalHash, err := r.getSecretHash(cr, cr.Spec.PXC.SSLInternalSecretName, cr.Spec.AllowUnsafeConfig)
- if err != nil && !k8serrors.IsNotFound(err) {
- return fmt.Errorf("get secret hash error: %v", err)
+ if err != nil {
+ return fmt.Errorf("get internal secret hash error: %v", err)
}
if sslInternalHash != "" && cr.CompareVersionWith("1.1.0") >= 0 {
nodeSet.Spec.Template.Annotations["percona.com/ssl-internal-hash"] = sslInternalHash

diff:
@@ -173,7 +173,7 @@ func (r *ReconcilePerconaXtraDBCluster) smartUpdate(sfs api.StatefulApp, cr *api
return nil
}
- log.Info("statefullSet was changed, run smart update")
+ log.Info("statefulSet was changed, run smart update")
if err := r.isBackupRunning(cr); err != nil {
log.Error(err, "can't start 'SmartUpdate'")
@@ -477,6 +477,11 @@ func (r *ReconcilePerconaXtraDBCluster) getSecretHash(cr *api.PerconaXtraDBClust
return "", err
}
+ if secretName == cr.Spec.PXC.SSLSecretName || secretName == cr.Spec.PXC.SSLInternalSecretName{
+ if secretObj.Data["ca.crt"] == nil || secretObj.Data["tls.crt"] == nil || secretObj.Data["tls.key"] == nil {
+ return "", errors.New("one or more tls certificates are not found in secret")
+ }
+ }
secretString := fmt.Sprintln(secretObj.Data)
hash := fmt.Sprintf("%x", md5.Sum([]byte(secretString)))

original_message: add certificate checks


message:
Repair e2e tests
Fix e2e tests issues caused by validation webhook

diff:
@@ -37,21 +37,6 @@ check_cr_config() {
-f $test_dir/conf/$cluster.yml
}
-no_storage() {
- local cluster="no-storage"
-
- # apply cr config
- apply_config $test_dir/conf/$cluster.yml
-
- # check operator logs
- kubectl_bin logs $(get_operator_pod) ${OPERATOR_NS:+-n $OPERATOR_NS} \
- | grep "volume.resources.storage can't be empty"
-
- # delete cluster
- kubectl_bin delete \
- -f $test_dir/conf/$cluster.yml
-}
-
main() {
create_infra $namespace
kubectl_bin apply -f $conf_dir/secrets.yml
@@ -65,9 +50,6 @@ main() {
desc 'check if possible to create cluster without CPU/Memory requests and limits'
check_cr_config "no-requests-no-limits"
- desc 'check if possible to create cluster without storage size'
- no_storage
-
destroy $namespace
}

diff:
@@ -8,7 +8,6 @@ spec:
pause: false
pxc:
size: 1
- allowUnsafeConfigurations: true
image: -pxc
configuration: |
[mysqld]

diff:
@@ -87,6 +87,10 @@ netem_pod() {
main() {
create_infra $namespace
+
+ kubectl_bin patch clusterrole percona-xtradb-cluster-operator --type=json -p '[{"op":"remove","path":"/rules/1"}]'
+ kubectl_bin delete validatingwebhookconfigurations.admissionregistration.k8s.io percona-xtradbcluster-webhook
+
kubectl_bin apply -f "$test_dir/conf/pumba.yml" ${OPERATOR_NS:+-n $OPERATOR_NS}
desc 'create PXC cluster'

diff:
@@ -30,7 +30,7 @@ admin-stats_system_memory 60
admin-telnet_admin_ifaces (null)
admin-telnet_stats_ifaces (null)
admin-vacuum_stats true
-admin-version 2.0.14-percona-1.1
+admin-version 2.0.15-percona-1.1
admin-web_enabled false
admin-web_port 6080
mysql-add_ldap_user_comment
@@ -88,6 +88,7 @@ mysql-max_allowed_packet 67108864
mysql-max_connections 2048
mysql-max_stmts_cache 10000
mysql-max_stmts_per_connection 20
+mysql-max_transaction_idle_time 14400000
mysql-max_transaction_time 14400000
mysql-min_num_servers_lantency_awareness 1000
mysql-mirror_max_concurrency 16

change_type: RENAME

diff:
@@ -9,34 +9,34 @@ spec:
pxc:
size: 3
image: -pxc
- volumeSpec:
+# volumeSpec:
# emptyDir: {}
# hostPath:
# path: /data
# type: Directory
# persistentVolumeClaim:
# storageClassName: standard
- accessModes: [ "ReadWriteOnce" ]
- resources:
- requests:
- storage: 6Gi
+# accessModes: [ "ReadWriteOnce" ]
+# resources:
+# requests:
+# storage: 6Gi
affinity:
antiAffinityTopologyKey: none
proxysql:
enabled: true
size: 1
image: -proxysql
- volumeSpec:
+# volumeSpec:
# emptyDir: {}
# hostPath:
# path: /data
# type: Directory
# persistentVolumeClaim:
# storageClassName: standard
- accessModes: [ "ReadWriteOnce" ]
- resources:
- requests:
- storage: 6Gi
+# accessModes: [ "ReadWriteOnce" ]
+# resources:
+# requests:
+# storage: 6Gi
affinity:
antiAffinityTopologyKey: none
pmm:

diff:
@@ -23,4 +23,11 @@ if [[ $output != *"can't enable both HAProxy and ProxySQL"* ]]; then
exit 1
fi
+output=$(kubectl 2>&1 apply -f "$test_dir/conf/cr-with-no-storage.yaml")
+
+if [[ $output != *"PXC: volumeSpec should be specified"* ]]; then
+ echo 'invalid hook response'
+ exit 1
+fi
+
destroy $namespace

diff:
@@ -13,12 +13,13 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
api "github.com/percona/percona-xtradb-cluster-operator/pkg/apis/pxc/v1"
+ "github.com/percona/percona-xtradb-cluster-operator/pkg/k8s"
"github.com/percona/percona-xtradb-cluster-operator/pkg/pxc/backup"
)
func (r *ReconcilePerconaXtraDBCluster) reconcileBackups(cr *api.PerconaXtraDBCluster) error {
backups := make(map[string]api.PXCScheduledBackupSchedule)
- operatorPod, err := r.operatorPod()
+ operatorPod, err := k8s.OperatorPod(r.client)
if err != nil {
return errors.Wrap(err, "get operator deployment")
}

diff:
@@ -4,8 +4,6 @@ import (
"context"
"crypto/md5"
"fmt"
- "io/ioutil"
- "os"
"strings"
"sync"
"sync/atomic"
@@ -33,6 +31,7 @@ import (
"github.com/percona/percona-xtradb-cluster-operator/clientcmd"
api "github.com/percona/percona-xtradb-cluster-operator/pkg/apis/pxc/v1"
+ "github.com/percona/percona-xtradb-cluster-operator/pkg/k8s"
"github.com/percona/percona-xtradb-cluster-operator/pkg/pxc"
"github.com/percona/percona-xtradb-cluster-operator/pkg/pxc/app/config"
"github.com/percona/percona-xtradb-cluster-operator/pkg/pxc/app/statefulset"
@@ -258,7 +257,7 @@ func (r *ReconcilePerconaXtraDBCluster) Reconcile(request reconcile.Request) (re
return reconcile.Result{}, err
}
- operatorPod, err := r.operatorPod()
+ operatorPod, err := k8s.OperatorPod(r.client)
if err != nil {
return reconcile.Result{}, errors.Wrap(err, "get operator deployment")
}
@@ -525,26 +524,6 @@ func (r *ReconcilePerconaXtraDBCluster) Reconcile(request reconcile.Request) (re
return rr, nil
}
-func (r *ReconcilePerconaXtraDBCluster) operatorPod() (corev1.Pod, error) {
- operatorPod := corev1.Pod{}
-
- nsBytes, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace")
- if err != nil {
- return operatorPod, err
- }
-
- ns := strings.TrimSpace(string(nsBytes))
-
- if err := r.client.Get(context.TODO(), types.NamespacedName{
- Namespace: ns,
- Name: os.Getenv("HOSTNAME"),
- }, &operatorPod); err != nil {
- return operatorPod, err
- }
-
- return operatorPod, nil
-}
-
func (r *ReconcilePerconaXtraDBCluster) deploy(cr *api.PerconaXtraDBCluster) error {
stsApp := statefulset.NewNode(cr)
err := r.reconcileConfigMap(cr)
@@ -552,7 +531,7 @@ func (r *ReconcilePerconaXtraDBCluster) deploy(cr *api.PerconaXtraDBCluster) err
return err
}
- operatorPod, err := r.operatorPod()
+ operatorPod, err := k8s.OperatorPod(r.client)
if err != nil {
return errors.Wrap(err, "get operator deployment")
}

diff:
+package k8s
+
+import (
+ "context"
+ "io/ioutil"
+ "os"
+ "strings"
+
+ corev1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/types"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+func OperatorPod(cl client.Client) (corev1.Pod, error) {
+ operatorPod := corev1.Pod{}
+
+ nsBytes, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace")
+ if err != nil {
+ return operatorPod, err
+ }
+
+ ns := strings.TrimSpace(string(nsBytes))
+
+ if err := cl.Get(context.TODO(), types.NamespacedName{
+ Namespace: ns,
+ Name: os.Getenv("HOSTNAME"),
+ }, &operatorPod); err != nil {
+ return operatorPod, err
+ }
+
+ return operatorPod, nil
+}

diff:
@@ -14,12 +14,14 @@ import (
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
+ "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/util/cert"
"sigs.k8s.io/controller-runtime/pkg/client"
log "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/manager"
v1 "github.com/percona/percona-xtradb-cluster-operator/pkg/apis/pxc/v1"
+ "github.com/percona/percona-xtradb-cluster-operator/pkg/k8s"
"github.com/percona/percona-xtradb-cluster-operator/pkg/pxctls"
)
@@ -34,7 +36,11 @@ type hook struct {
}
func (h *hook) Start(i <-chan struct{}) error {
- err := h.createWebhook()
+ err := h.createService()
+ if err != nil {
+ log.Log.Info("Can't create service", "err", err.Error())
+ }
+ err = h.createWebhook()
if err != nil {
log.Log.Info("Can't create webhook", "error", err.Error())
}
@@ -42,6 +48,42 @@ func (h *hook) Start(i <-chan struct{}) error {
return nil
}
+func (h *hook) createService() error {
+ opPod, err := k8s.OperatorPod(h.cl)
+ if err != nil {
+ return errors.Wrap(err, "get operator pod")
+ }
+ svc := &corev1.Service{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "percona-xtradb-cluster-operator",
+ Namespace: h.namespace,
+ Labels: map[string]string{"name": "percona-xtradb-cluster-operator"},
+ },
+ Spec: corev1.ServiceSpec{
+ Ports: []corev1.ServicePort{{Port: 443, TargetPort: intstr.FromInt(9443)}},
+ Selector: opPod.Labels,
+ },
+ }
+ err = h.cl.Create(context.TODO(), svc)
+ if err != nil {
+ if k8serrors.IsAlreadyExists(err) {
+ service := &corev1.Service{}
+ err = h.cl.Get(context.TODO(), types.NamespacedName{
+ Name: "percona-xtradb-cluster-operator",
+ Namespace: h.namespace,
+ }, service)
+ if err != nil {
+ return err
+ }
+
+ service.Spec.Selector = opPod.Labels
+ return h.cl.Update(context.TODO(), service)
+ }
+ return err
+ }
+ return nil
+}
+
func (h *hook) createWebhook() error {
failPolicy := admissionregistration.Fail
sideEffects := admissionregistration.SideEffectClassNone

original_message:
K8SPXC-537: Repair e2e tests (#672)

Fix e2e tests issues caused by validation webhook