From 4b555bd125c7fd957139e33bd24a6d62c44109c6 Mon Sep 17 00:00:00 2001 From: mvelosob <miguel.veloso.barros@cern.ch> Date: Fri, 1 Apr 2022 16:08:25 +0200 Subject: [PATCH] add verification column to tape table (#1043) --- catalogue/10.0/oracle_catalogue_schema.sql | 1 + catalogue/10.0/postgres_catalogue_schema.sql | 1 + catalogue/10.0/sqlite_catalogue_schema.sql | 1 + catalogue/AllCatalogueSchema.hpp | 3 + catalogue/Catalogue.hpp | 2 + catalogue/CatalogueRetryWrapper.hpp | 5 +- catalogue/CatalogueTest.cpp | 78 +++++++++++++++++++ catalogue/DummyCatalogue.hpp | 1 + catalogue/RdbmsCatalogue.cpp | 49 ++++++++++++ catalogue/RdbmsCatalogue.hpp | 1 + catalogue/common_catalogue_schema.sql | 1 + .../migrations/liquibase/oracle/4.6to10.0.sql | 33 ++++++++ cmdline/CtaAdminCmdParse.hpp | 4 +- common/dataStructures/Tape.hpp | 1 + xroot_plugins/XrdCtaTapeLs.hpp | 3 + xroot_plugins/XrdSsiCtaRequestMessage.cpp | 26 ++++--- xrootd-ssi-protobuf-interface | 2 +- 17 files changed, 198 insertions(+), 14 deletions(-) create mode 100644 catalogue/migrations/liquibase/oracle/4.6to10.0.sql diff --git a/catalogue/10.0/oracle_catalogue_schema.sql b/catalogue/10.0/oracle_catalogue_schema.sql index 327f8145e3..d6957953cf 100644 --- a/catalogue/10.0/oracle_catalogue_schema.sql +++ b/catalogue/10.0/oracle_catalogue_schema.sql @@ -278,6 +278,7 @@ CREATE TABLE TAPE( LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT TAPE_LUUN_NN NOT NULL, LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT TAPE_LUHN_NN NOT NULL, LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT TAPE_LUT_NN NOT NULL, + VERIFICATION_STATUS VARCHAR2(1000), CONSTRAINT TAPE_PK PRIMARY KEY(VID), CONSTRAINT TAPE_LOGICAL_LIBRARY_FK FOREIGN KEY(LOGICAL_LIBRARY_ID) REFERENCES LOGICAL_LIBRARY(LOGICAL_LIBRARY_ID), CONSTRAINT TAPE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID), diff --git a/catalogue/10.0/postgres_catalogue_schema.sql b/catalogue/10.0/postgres_catalogue_schema.sql index bc46f24c78..e8bbac31a9 100644 --- a/catalogue/10.0/postgres_catalogue_schema.sql +++ b/catalogue/10.0/postgres_catalogue_schema.sql @@ -260,6 +260,7 @@ CREATE TABLE TAPE( LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT TAPE_LUUN_NN NOT NULL, LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_LUHN_NN NOT NULL, LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT TAPE_LUT_NN NOT NULL, + VERIFICATION_STATUS VARCHAR(1000), CONSTRAINT TAPE_PK PRIMARY KEY(VID), CONSTRAINT TAPE_LOGICAL_LIBRARY_FK FOREIGN KEY(LOGICAL_LIBRARY_ID) REFERENCES LOGICAL_LIBRARY(LOGICAL_LIBRARY_ID), CONSTRAINT TAPE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID), diff --git a/catalogue/10.0/sqlite_catalogue_schema.sql b/catalogue/10.0/sqlite_catalogue_schema.sql index 0191c093ee..46e414bd7b 100644 --- a/catalogue/10.0/sqlite_catalogue_schema.sql +++ b/catalogue/10.0/sqlite_catalogue_schema.sql @@ -232,6 +232,7 @@ CREATE TABLE TAPE( LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT TAPE_LUUN_NN NOT NULL, LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_LUHN_NN NOT NULL, LAST_UPDATE_TIME INTEGER CONSTRAINT TAPE_LUT_NN NOT NULL, + VERIFICATION_STATUS VARCHAR(1000), CONSTRAINT TAPE_PK PRIMARY KEY(VID), CONSTRAINT TAPE_LOGICAL_LIBRARY_FK FOREIGN KEY(LOGICAL_LIBRARY_ID) REFERENCES LOGICAL_LIBRARY(LOGICAL_LIBRARY_ID), CONSTRAINT TAPE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID), diff --git a/catalogue/AllCatalogueSchema.hpp b/catalogue/AllCatalogueSchema.hpp index dd25b23f47..dda1c81adc 100644 --- a/catalogue/AllCatalogueSchema.hpp +++ b/catalogue/AllCatalogueSchema.hpp @@ -1212,6 +1212,7 @@ namespace catalogue{ " LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT TAPE_LUUN_NN NOT NULL," " LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT TAPE_LUHN_NN NOT NULL," " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT TAPE_LUT_NN NOT NULL," + " VERIFICATION_STATUS VARCHAR2(1000)," " CONSTRAINT TAPE_PK PRIMARY KEY(VID)," " CONSTRAINT TAPE_LOGICAL_LIBRARY_FK FOREIGN KEY(LOGICAL_LIBRARY_ID) REFERENCES LOGICAL_LIBRARY(LOGICAL_LIBRARY_ID)," " CONSTRAINT TAPE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID)," @@ -1687,6 +1688,7 @@ namespace catalogue{ " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT TAPE_LUUN_NN NOT NULL," " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_LUHN_NN NOT NULL," " LAST_UPDATE_TIME INTEGER CONSTRAINT TAPE_LUT_NN NOT NULL," + " VERIFICATION_STATUS VARCHAR(1000)," " CONSTRAINT TAPE_PK PRIMARY KEY(VID)," " CONSTRAINT TAPE_LOGICAL_LIBRARY_FK FOREIGN KEY(LOGICAL_LIBRARY_ID) REFERENCES LOGICAL_LIBRARY(LOGICAL_LIBRARY_ID)," " CONSTRAINT TAPE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID)," @@ -2187,6 +2189,7 @@ namespace catalogue{ " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT TAPE_LUUN_NN NOT NULL," " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_LUHN_NN NOT NULL," " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT TAPE_LUT_NN NOT NULL," + " VERIFICATION_STATUS VARCHAR(1000)," " CONSTRAINT TAPE_PK PRIMARY KEY(VID)," " CONSTRAINT TAPE_LOGICAL_LIBRARY_FK FOREIGN KEY(LOGICAL_LIBRARY_ID) REFERENCES LOGICAL_LIBRARY(LOGICAL_LIBRARY_ID)," " CONSTRAINT TAPE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID)," diff --git a/catalogue/Catalogue.hpp b/catalogue/Catalogue.hpp index b705fd16a3..2165c516fc 100644 --- a/catalogue/Catalogue.hpp +++ b/catalogue/Catalogue.hpp @@ -699,6 +699,8 @@ public: virtual void modifyTapeLogicalLibraryName(const common::dataStructures::SecurityIdentity &admin, const std::string &vid, const std::string &logicalLibraryName) = 0; virtual void modifyTapeTapePoolName(const common::dataStructures::SecurityIdentity &admin, const std::string &vid, const std::string &tapePoolName) = 0; virtual void modifyTapeEncryptionKeyName(const common::dataStructures::SecurityIdentity &admin, const std::string &vid, const std::string &encryptionKeyName) = 0; + virtual void modifyTapeVerificationStatus(const common::dataStructures::SecurityIdentity &admin, const std::string &vid, const std::string &verificationStatus) = 0; + /** * Modify the state of the specified tape * @param admin, the person or the system who modified the state of the tape diff --git a/catalogue/CatalogueRetryWrapper.hpp b/catalogue/CatalogueRetryWrapper.hpp index 5fcbdea4cf..f7853acf58 100644 --- a/catalogue/CatalogueRetryWrapper.hpp +++ b/catalogue/CatalogueRetryWrapper.hpp @@ -387,7 +387,10 @@ public: void modifyTapeEncryptionKeyName(const common::dataStructures::SecurityIdentity &admin, const std::string &vid, const std::string &encryptionKeyName) override { return retryOnLostConnection(m_log, [&]{return m_catalogue->modifyTapeEncryptionKeyName(admin, vid, encryptionKeyName);}, m_maxTriesToConnect); } - + void modifyTapeVerificationStatus(const common::dataStructures::SecurityIdentity &admin, const std::string &vid, const std::string &verificationStatus) override { + return retryOnLostConnection(m_log, [&]{return m_catalogue->modifyTapeVerificationStatus(admin, vid, verificationStatus);}, m_maxTriesToConnect); + } + void modifyTapeState(const common::dataStructures::SecurityIdentity &admin,const std::string &vid, const common::dataStructures::Tape::State & state, const cta::optional<std::string> & stateReason) override { return retryOnLostConnection(m_log, [&]{return m_catalogue->modifyTapeState(admin,vid, state, stateReason);}, m_maxTriesToConnect); } diff --git a/catalogue/CatalogueTest.cpp b/catalogue/CatalogueTest.cpp index e079b8635a..dd28d48e16 100644 --- a/catalogue/CatalogueTest.cpp +++ b/catalogue/CatalogueTest.cpp @@ -5976,6 +5976,84 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeEncryptionKeyName_emptyStringEncry } } +TEST_P(cta_catalogue_CatalogueTest, modifyTapeVerificationStatus) { + using namespace cta; + + const bool logicalLibraryIsDisabled= false; + const uint64_t nbPartialTapes = 2; + const bool isEncrypted = true; + const cta::optional<std::string> supply("value for the supply pool mechanism"); + + m_catalogue->createMediaType(m_admin, m_mediaType); + m_catalogue->createLogicalLibrary(m_admin, m_tape1.logicalLibraryName, logicalLibraryIsDisabled, "Create logical library"); + + m_catalogue->createVirtualOrganization(m_admin, m_vo); + m_catalogue->createTapePool(m_admin, m_tape1.tapePoolName, m_vo.name, nbPartialTapes, isEncrypted, supply, "Create tape pool"); + + m_catalogue->createTape(m_admin, m_tape1); + + { + const std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes(); + + ASSERT_EQ(1, tapes.size()); + + const common::dataStructures::Tape tape = tapes.front(); + ASSERT_EQ(m_tape1.vid, tape.vid); + ASSERT_EQ(m_tape1.mediaType, tape.mediaType); + ASSERT_EQ(m_tape1.vendor, tape.vendor); + ASSERT_EQ(m_tape1.logicalLibraryName, tape.logicalLibraryName); + ASSERT_EQ(m_tape1.tapePoolName, tape.tapePoolName); + ASSERT_EQ(m_vo.name, tape.vo); + ASSERT_EQ(m_mediaType.capacityInBytes, tape.capacityInBytes); + ASSERT_EQ(m_tape1.full, tape.full); + + ASSERT_FALSE(tape.isFromCastor); + ASSERT_EQ(m_tape1.comment, tape.comment); + ASSERT_FALSE(tape.labelLog); + ASSERT_FALSE(tape.lastReadLog); + ASSERT_FALSE(tape.lastWriteLog); + + const common::dataStructures::EntryLog creationLog = tape.creationLog; + ASSERT_EQ(m_admin.username, creationLog.username); + ASSERT_EQ(m_admin.host, creationLog.host); + + const common::dataStructures::EntryLog lastModificationLog = tape.lastModificationLog; + ASSERT_EQ(creationLog, lastModificationLog); + ASSERT_FALSE(tape.verificationStatus); + } + + const std::string modifiedVerificationStatus = "verification_status"; + m_catalogue->modifyTapeVerificationStatus(m_admin, m_tape1.vid, modifiedVerificationStatus); + + { + const std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes(); + + ASSERT_EQ(1, tapes.size()); + + const common::dataStructures::Tape tape = tapes.front(); + ASSERT_EQ(m_tape1.vid, tape.vid); + ASSERT_EQ(m_tape1.mediaType, tape.mediaType); + ASSERT_EQ(m_tape1.vendor, tape.vendor); + ASSERT_EQ(m_tape1.logicalLibraryName, tape.logicalLibraryName); + ASSERT_EQ(m_tape1.tapePoolName, tape.tapePoolName); + ASSERT_EQ(m_vo.name, tape.vo); + ASSERT_EQ(m_mediaType.capacityInBytes, tape.capacityInBytes); + ASSERT_EQ(m_tape1.full, tape.full); + + ASSERT_FALSE(tape.isFromCastor); + ASSERT_EQ(m_tape1.comment, tape.comment); + ASSERT_FALSE(tape.labelLog); + ASSERT_FALSE(tape.lastReadLog); + ASSERT_FALSE(tape.lastWriteLog); + + const common::dataStructures::EntryLog creationLog = tape.creationLog; + ASSERT_EQ(m_admin.username, creationLog.username); + ASSERT_EQ(m_admin.host, creationLog.host); + ASSERT_EQ(tape.verificationStatus.value(), modifiedVerificationStatus); + + } +} + TEST_P(cta_catalogue_CatalogueTest, modifyTapeEncryptionKeyName_nonExistentTape) { using namespace cta; diff --git a/catalogue/DummyCatalogue.hpp b/catalogue/DummyCatalogue.hpp index 5da52bbdd5..f20fade6e8 100644 --- a/catalogue/DummyCatalogue.hpp +++ b/catalogue/DummyCatalogue.hpp @@ -160,6 +160,7 @@ public: void modifyStorageClassNbCopies(const common::dataStructures::SecurityIdentity& admin, const std::string& name, const uint64_t nbCopies) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyTapeComment(const common::dataStructures::SecurityIdentity& admin, const std::string& vid, const cta::optional<std::string> &comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyTapeEncryptionKeyName(const common::dataStructures::SecurityIdentity& admin, const std::string& vid, const std::string& encryptionKeyName) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } + void modifyTapeVerificationStatus(const common::dataStructures::SecurityIdentity& admin, const std::string& vid, const std::string& verificationStatus) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyTapeState(const common::dataStructures::SecurityIdentity &admin,const std::string &vid, const common::dataStructures::Tape::State & state, const cta::optional<std::string> & stateReason) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyTapeMediaType(const common::dataStructures::SecurityIdentity& admin, const std::string& vid, const std::string& mediaType) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyTapeVendor(const common::dataStructures::SecurityIdentity& admin, const std::string& vid, const std::string& vendor) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } diff --git a/catalogue/RdbmsCatalogue.cpp b/catalogue/RdbmsCatalogue.cpp index c57fe1244f..a245bdd8bf 100644 --- a/catalogue/RdbmsCatalogue.cpp +++ b/catalogue/RdbmsCatalogue.cpp @@ -3979,6 +3979,8 @@ std::list<common::dataStructures::Tape> RdbmsCatalogue::getTapes(rdbms::Conn &co "TAPE.READ_MOUNT_COUNT AS READ_MOUNT_COUNT," "TAPE.WRITE_MOUNT_COUNT AS WRITE_MOUNT_COUNT," + "TAPE.VERIFICATION_STATUS AS VERIFICATION_STATUS," + "TAPE.USER_COMMENT AS USER_COMMENT," "TAPE.TAPE_STATE AS TAPE_STATE," @@ -4145,6 +4147,8 @@ std::list<common::dataStructures::Tape> RdbmsCatalogue::getTapes(rdbms::Conn &co tape.readMountCount = rset.columnUint64("READ_MOUNT_COUNT"); tape.writeMountCount = rset.columnUint64("WRITE_MOUNT_COUNT"); + tape.verificationStatus = rset.columnOptionalString("VERIFICATION_STATUS"); + auto optionalComment = rset.columnOptionalString("USER_COMMENT"); tape.comment = optionalComment ? optionalComment.value() : ""; @@ -5013,6 +5017,51 @@ void RdbmsCatalogue::modifyTapeEncryptionKeyName(const common::dataStructures::S } } +//------------------------------------------------------------------------------ +// modifyTapeVerificationStatus +//------------------------------------------------------------------------------ +void RdbmsCatalogue::modifyTapeVerificationStatus(const common::dataStructures::SecurityIdentity &admin, + const std::string &vid, const std::string &verificationStatus) { + try { + const time_t now = time(nullptr); + const char *const sql = + "UPDATE TAPE SET " + "VERIFICATION_STATUS = :VERIFICATION_STATUS," + "LAST_UPDATE_USER_NAME = :LAST_UPDATE_USER_NAME," + "LAST_UPDATE_HOST_NAME = :LAST_UPDATE_HOST_NAME," + "LAST_UPDATE_TIME = :LAST_UPDATE_TIME " + "WHERE " + "VID = :VID"; + auto conn = m_connPool.getConn(); + auto stmt = conn.createStmt(sql); + stmt.bindString(":VERIFICATION_STATUS", verificationStatus); + stmt.bindString(":LAST_UPDATE_USER_NAME", admin.username); + stmt.bindString(":LAST_UPDATE_HOST_NAME", admin.host); + stmt.bindUint64(":LAST_UPDATE_TIME", now); + stmt.bindString(":VID", vid); + stmt.executeNonQuery(); + + if(0 == stmt.getNbAffectedRows()) { + throw exception::UserError(std::string("Cannot modify tape ") + vid + " because it does not exist"); + } + + log::LogContext lc(m_log); + log::ScopedParamContainer spc(lc); + spc.add("vid", vid) + .add("verificationStatus", verificationStatus) + .add("lastUpdateUserName", admin.username) + .add("lastUpdateHostName", admin.host) + .add("lastUpdateTime", now); + lc.log(log::INFO, "Catalogue - user modified tape - verificationStatus"); + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + + //------------------------------------------------------------------------------ // modifyTapeState //------------------------------------------------------------------------------ diff --git a/catalogue/RdbmsCatalogue.hpp b/catalogue/RdbmsCatalogue.hpp index 296a38f842..0d4cb14908 100644 --- a/catalogue/RdbmsCatalogue.hpp +++ b/catalogue/RdbmsCatalogue.hpp @@ -649,6 +649,7 @@ public: void modifyTapeLogicalLibraryName(const common::dataStructures::SecurityIdentity &admin, const std::string &vid, const std::string &logicalLibraryName) override; void modifyTapeTapePoolName(const common::dataStructures::SecurityIdentity &admin, const std::string &vid, const std::string &tapePoolName) override; void modifyTapeEncryptionKeyName(const common::dataStructures::SecurityIdentity &admin, const std::string &vid, const std::string &encryptionKeyName) override; + void modifyTapeVerificationStatus(const common::dataStructures::SecurityIdentity &admin, const std::string &vid, const std::string &verificationStatus) override; void modifyTapeState(const common::dataStructures::SecurityIdentity &admin,const std::string &vid, const common::dataStructures::Tape::State & state, const cta::optional<std::string> & stateReason) override; static std::string generateTapeStateModifiedBy(const common::dataStructures::SecurityIdentity & admin); /** diff --git a/catalogue/common_catalogue_schema.sql b/catalogue/common_catalogue_schema.sql index be57a24ede..7cc5646b99 100644 --- a/catalogue/common_catalogue_schema.sql +++ b/catalogue/common_catalogue_schema.sql @@ -211,6 +211,7 @@ CREATE TABLE TAPE( LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT TAPE_LUUN_NN NOT NULL, LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_LUHN_NN NOT NULL, LAST_UPDATE_TIME UINT64TYPE CONSTRAINT TAPE_LUT_NN NOT NULL, + VERIFICATION_STATUS VARCHAR(1000), CONSTRAINT TAPE_PK PRIMARY KEY(VID), CONSTRAINT TAPE_LOGICAL_LIBRARY_FK FOREIGN KEY(LOGICAL_LIBRARY_ID) REFERENCES LOGICAL_LIBRARY(LOGICAL_LIBRARY_ID), CONSTRAINT TAPE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID), diff --git a/catalogue/migrations/liquibase/oracle/4.6to10.0.sql b/catalogue/migrations/liquibase/oracle/4.6to10.0.sql new file mode 100644 index 0000000000..2b9d453f4b --- /dev/null +++ b/catalogue/migrations/liquibase/oracle/4.6to10.0.sql @@ -0,0 +1,33 @@ +--liquibase formatted sql + +--changeset mvelosob:1 failOnError:true dbms:oracle +--preconditions onFail:HALT onError:HALT +--precondition-sql-check expectedResult:"4.6" SELECT CONCAT(CONCAT(CAST(SCHEMA_VERSION_MAJOR as VARCHAR(10)),'.'), CAST(SCHEMA_VERSION_MINOR AS VARCHAR(10))) AS CATALOGUE_VERSION FROM CTA_CATALOGUE; +--precondition-sql-check expectedResult:"0.0" SELECT CONCAT(CONCAT(CAST(SCHEMA_VERSION_MAJOR as VARCHAR(10)),'.'), CAST(SCHEMA_VERSION_MINOR AS VARCHAR(10))) AS CATALOGUE_VERSION FROM CTA_CATALOGUE; +--!!!THIS FALSE PRECONDITION IS HERE TO BLOCK AN UPGRADE WHILE THE DEVELOPMENT OF THE NEW CATALOGUE VERSION IS BEING DEVELOPED!!! +UPDATE CTA_CATALOGUE SET STATUS='UPGRADING'; +UPDATE CTA_CATALOGUE SET NEXT_SCHEMA_VERSION_MAJOR=10; +UPDATE CTA_CATALOGUE SET NEXT_SCHEMA_VERSION_MINOR=0; +--rollback UPDATE CTA_CATALOGUE SET NEXT_SCHEMA_VERSION_MAJOR=NULL; +--rollback UPDATE CTA_CATALOGUE SET NEXT_SCHEMA_VERSION_MINOR=NULL; +--rollback UPDATE CTA_CATALOGUE SET STATUS='PRODUCTION'; + +--changeset mvelosob:2 failOnError:true dbms:oracle +--preconditions onFail:HALT onError:HALT +--precondition-sql-check expectedResult:"4.6" SELECT CONCAT(CONCAT(CAST(SCHEMA_VERSION_MAJOR as VARCHAR(10)),'.'), CAST(SCHEMA_VERSION_MINOR AS VARCHAR(10))) AS CATALOGUE_VERSION FROM CTA_CATALOGUE; +ALTER TABLE TAPE ADD (VERIFICATION_STATUS VARCHAR2(1000)); +--rollback ALTER TABLE TAPE DROP COLUMN VERIFICATION_STATUS + +--changeset mvelosob:3 failOnError:true dbms:oracle +--preconditions onFail:HALT onError:HALT +--precondition-sql-check expectedResult:"4.6" SELECT CONCAT(CONCAT(CAST(SCHEMA_VERSION_MAJOR as VARCHAR(10)),'.'), CAST(SCHEMA_VERSION_MINOR AS VARCHAR(10))) AS CATALOGUE_VERSION FROM CTA_CATALOGUE; +UPDATE CTA_CATALOGUE SET STATUS='PRODUCTION'; +UPDATE CTA_CATALOGUE SET SCHEMA_VERSION_MAJOR=10; +UPDATE CTA_CATALOGUE SET SCHEMA_VERSION_MINOR=0; +UPDATE CTA_CATALOGUE SET NEXT_SCHEMA_VERSION_MAJOR=NULL; +UPDATE CTA_CATALOGUE SET NEXT_SCHEMA_VERSION_MINOR=NULL; +--rollback UPDATE CTA_CATALOGUE SET STATUS='UPGRADING'; +--rollback UPDATE CTA_CATALOGUE SET SCHEMA_VERSION_MAJOR=4; +--rollback UPDATE CTA_CATALOGUE SET SCHEMA_VERSION_MINOR=6; +--rollback UPDATE CTA_CATALOGUE SET NEXT_SCHEMA_VERSION_MAJOR=10; +--rollback UPDATE CTA_CATALOGUE SET NEXT_SCHEMA_VERSION_MINOR=0; diff --git a/cmdline/CtaAdminCmdParse.hpp b/cmdline/CtaAdminCmdParse.hpp index 3f9d076ca0..a4d51ecf82 100644 --- a/cmdline/CtaAdminCmdParse.hpp +++ b/cmdline/CtaAdminCmdParse.hpp @@ -345,6 +345,7 @@ const std::map<std::string, OptionString::Key> strOptions = { { "--activityregex", OptionString::ACTIVITY_REGEX}, { "--diskinstance", OptionString::DISK_INSTANCE }, { "--diskinstancespace", OptionString::DISK_INSTANCE_SPACE }, + { "--verificationstatus", OptionString::VERIFICATION_STATUS }, }; @@ -544,6 +545,7 @@ const Option opt_diskinstance { Option::OPT_STR, "--diskinstance", const Option opt_diskinstance_alias { Option::OPT_STR, "--name", "-n", " <disk_instance_name>", "--diskinstance" }; const Option opt_diskinstancespace { Option::OPT_STR, "--diskinstancespace", "--dis", " <disk_instance_space_name>" }; const Option opt_diskinstancespace_alias { Option::OPT_STR, "--name", "-n", " <disk_instance_space_name>", "--diskinstancespace" }; +const Option opt_verificationstatus { Option::OPT_STR, "--verificationstatus", "--vs", " <verification_status>" }; /*! * Map valid options to commands @@ -630,7 +632,7 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = { opt_state.optional(), opt_reason.optional(), opt_comment.optional() }}, {{ AdminCmd::CMD_TAPE, AdminCmd::SUBCMD_CH }, { opt_vid, opt_mediatype.optional(), opt_vendor.optional(), opt_logicallibrary.optional(), - opt_tapepool.optional(), opt_encryptionkeyname.optional(), opt_full.optional(), + opt_tapepool.optional(), opt_encryptionkeyname.optional(), opt_full.optional(), opt_verificationstatus.optional(), opt_state.optional(), opt_reason.optional(), opt_comment.optional(), opt_dirtybit.optional() }}, {{ AdminCmd::CMD_TAPE, AdminCmd::SUBCMD_RM }, { opt_vid }}, {{ AdminCmd::CMD_TAPE, AdminCmd::SUBCMD_RECLAIM }, { opt_vid }}, diff --git a/common/dataStructures/Tape.hpp b/common/dataStructures/Tape.hpp index 6c1dd57c49..cdb48ad2c5 100644 --- a/common/dataStructures/Tape.hpp +++ b/common/dataStructures/Tape.hpp @@ -110,6 +110,7 @@ struct Tape { optional<std::string> stateReason; std::string stateModifiedBy; time_t stateUpdateTime; + optional<std::string> verificationStatus; bool isDisabled() const; diff --git a/xroot_plugins/XrdCtaTapeLs.hpp b/xroot_plugins/XrdCtaTapeLs.hpp index 2d40ee288c..3be29a6248 100644 --- a/xroot_plugins/XrdCtaTapeLs.hpp +++ b/xroot_plugins/XrdCtaTapeLs.hpp @@ -146,6 +146,9 @@ int TapeLsStream::fillBuffer(XrdSsiPb::OStreamBuffer<Data> *streambuf) { tape_item->set_state_reason(tape.stateReason ? tape.stateReason.value() : ""); tape_item->set_state_update_time(tape.stateUpdateTime); tape_item->set_state_modified_by(tape.stateModifiedBy); + if (tape.verificationStatus) { + tape_item->set_verification_status(tape.verificationStatus.value()); + } is_buffer_full = streambuf->Push(record); } diff --git a/xroot_plugins/XrdSsiCtaRequestMessage.cpp b/xroot_plugins/XrdSsiCtaRequestMessage.cpp index dafc9c00a2..291b6bfb51 100644 --- a/xroot_plugins/XrdSsiCtaRequestMessage.cpp +++ b/xroot_plugins/XrdSsiCtaRequestMessage.cpp @@ -1921,17 +1921,18 @@ void RequestMessage::processTape_Ch(cta::xrd::Response &response) { using namespace cta::admin; - auto &vid = getRequired(OptionString::VID); - auto mediaType = getOptional(OptionString::MEDIA_TYPE); - auto vendor = getOptional(OptionString::VENDOR); - auto logicallibrary = getOptional(OptionString::LOGICAL_LIBRARY); - auto tapepool = getOptional(OptionString::TAPE_POOL); - auto comment = getOptional(OptionString::COMMENT); - auto encryptionkeyName = getOptional(OptionString::ENCRYPTION_KEY_NAME); - auto full = getOptional(OptionBoolean::FULL); - auto state = getOptional(OptionString::STATE); - auto stateReason = getOptional(OptionString::REASON); - auto dirty = getOptional(OptionBoolean::DIRTY_BIT); + auto &vid = getRequired(OptionString::VID); + auto mediaType = getOptional(OptionString::MEDIA_TYPE); + auto vendor = getOptional(OptionString::VENDOR); + auto logicallibrary = getOptional(OptionString::LOGICAL_LIBRARY); + auto tapepool = getOptional(OptionString::TAPE_POOL); + auto comment = getOptional(OptionString::COMMENT); + auto encryptionkeyName = getOptional(OptionString::ENCRYPTION_KEY_NAME); + auto full = getOptional(OptionBoolean::FULL); + auto state = getOptional(OptionString::STATE); + auto stateReason = getOptional(OptionString::REASON); + auto dirty = getOptional(OptionBoolean::DIRTY_BIT); + auto verificationStatus = getOptional(OptionString::VERIFICATION_STATUS); if(mediaType) { m_catalogue.modifyTapeMediaType(m_cliIdentity, vid, mediaType.value()); @@ -1965,6 +1966,9 @@ void RequestMessage::processTape_Ch(cta::xrd::Response &response) if (dirty) { m_catalogue.setTapeDirty(m_cliIdentity, vid, dirty.value()); } + if (verificationStatus) { + m_catalogue.modifyTapeVerificationStatus(m_cliIdentity, vid, verificationStatus.value()); + } response.set_type(cta::xrd::Response::RSP_SUCCESS); } diff --git a/xrootd-ssi-protobuf-interface b/xrootd-ssi-protobuf-interface index 8df884a2ed..6a4cbde3b1 160000 --- a/xrootd-ssi-protobuf-interface +++ b/xrootd-ssi-protobuf-interface @@ -1 +1 @@ -Subproject commit 8df884a2ed9bef45f3d43e8e6ae7c0374f560338 +Subproject commit 6a4cbde3b1af09f2cab46c68c23c262e0f037b4b -- GitLab