XׯdddlZddlZddlZddlZddlmZmZddlZddlZddl Z ddl Z dZ dZ d"dZ dZGddeZGd d eZGd d eZGd deZGddeZGddeZGddeZGddeZGddeZedkrdZ ejeZejeejd<deddzZ e j!e e j"e j!dd !eej#Z$ej%e$&dSdS)#N)strptimestrftimeTcZt|tr|n|dS)Nutf8) isinstancestrdecode)texts ..\mysqlwbmeb.py to_unicoder s'dC(( A44dkk&.A.AAc d}tjd|z|s| tjdkr|Stjt ddD]} tj|#YxYwtjddd|gn#t$r0}tj dt|zd}Yd}~nMd}~wwxYwtj |ddtj tj tjdtjd }|sE|r(t|jjd D] }||||j}|S) NrzExecuting command: %sdz/bin/shz-czError on command execution: %sTutf-8)bufsizeshellstdinstdoutstderr close_fds preexec_fnencoding)logginginfoosforksetpgrprangecloseexecvpOSErrorerrorr subprocessPopenPIPESTDOUTiterrreadlinewait returncode)commandspawnoutput_handlerresultiechildlines r call_systemr5$s F L(72333 C& wyyA~~ JLLL1S\\  HQKKKKD Ii)T7!; < < < <    M:SVVC D D DFFFFFF   !4z_i_nxBxIUYfhfp{BCCC "  %U\2B77 % %t$$$$ ! Ms4B%BA32B3A75B C &CC cBtj}td|zd|j}|dkr|}d}d}d} d} dt|D} t| dz} || dd}|d} t| d}t| d} t| d } || | f|||fkSdS) Nz %s --versionFrrc38K|]\}}|dks|dk|VdS)versionVerN).0r1items r z)check_version_at_least..Ws5 V V71d493D3DPU Q V Vr r-.) ioStringIOr5writegetvaluestripsplit enumeratenextint) r-majorminorrevnooutputret_valtokensr8 found_major found_minor found_revnoindexversion_tokenss r check_version_at_leastrUJs ;==& 0% F F' \\ __   $ $ & & , , . .FGKKK V Vi// V V VE KK!OEUm!!#&&q)G]]3''NnQ'((KnQ'((KnQ'((K +{ 3ue7L LL!\r ceZdZdZddZdS) ConfigReaderc||_t|d}|}tj|_|jtjt|dS)Nr) _fileopenread configparser ConfigParserdoc read_filerArBr )selffile profile_filedatas r __init__zConfigReader.__init__cse D#   "",.. 2;z$'7'78899999r FNcX|} |j||}n #|rYnxYw|SN)r_get)rasectionr< mandatorydefaultvalues r read_valuezConfigReader.read_valuelsA HLL$//EE   s ')FN)__name__ __module__ __qualname__rermr:r r rWrWbs7:::      r rWc eZdZdZdZdZdS) ConfigUpdatercd|_dSrg)configras r rezConfigUpdater.__init__zs DKKKr c.t||_dSrg)rWrt)ra file_names r load_configzConfigUpdater.load_config}s&y11DKKKr ct|d}t|dzd}d}|D]}|}|dr |dr |dd}n|ds|d dkri|d d \}}|}|}|r&|j||d d}||d |}|d |z| | tj |tj |dz|dS)NrYz.tmpw[]r#=r@Fz = z%s ) r[rE startswithendswithfindrFrtrmrCr!rremoverename) rarwmy_source_handlermy_target_handlercurrent_sectionr4attvalnew_vals r updatezConfigUpdater.updates} $Y 4 4  $Y%7 = = "O) 7 7zz||??3'' >DMM#,>,> >&*1R4jOO-- >$))C..B2F2F#zz#q11HC))++C))++C&>"&+"8"8#uVZ"["[".03WW#=D!'' 6666  # # % % %  # # % % % Ii Ii&() 4 4 4 4 4r N)rnrorprerxrr:r r rrrrysA    2 2 2 5 5 5 5 5r rrc:eZdZd dZdZdZdZdZdZdZ dS) MEBCommandNc"||_||_dSrg)paramsr/)rarr/s r rezMEBCommand.__init__s ,r cdSrgr:rus r read_paramszMEBCommand.read_params r cdSrgr:rus r print_usagezMEBCommand.print_usagerr cv|rtdn|dS)Nz&ERROR: Missing command execution logicr)rprintrrus r executezMEBCommand.executes?       : ; ; ; ;      qr cftrt|jnt|jdz SNr@) is_librarylenrrus r param_countzMEBCommand.param_counts+#-Gs4;3t{3C3Ca3GGr c8|}ts|dz }|j|Sr)rr)rarS real_indexs r get_paramzMEBCommand.get_params%   !OJ{:&&r cf|jr||dzdSt|dS)N )r/r)rarMs r write_outputzMEBCommand.write_outputs:       . . . . . &MMMMMr NN) rnrorprerrrrrrr:r r rrs----      HHH'''r rc2eZdZdfd ZdZdZdZxZS)MEBCommandProcessorNc tt|||d|_i|_t |jd<t |jd<t|jd<t|jd<t|jd<dS)NFBACKUPVERSION GET_PROFILESUPDATE_SCHEDULINGPROPAGATE_DATA) superrre help_needed _commands MEBBackupMEBHelperVersionMEBGetProfilesMEBUpdateSchedulingMEBPropagateSettingsrarr/ __class__s r rezMEBCommandProcessor.__init__sw !4((11&.III #,x $4y!)7~&.A*++?'(((r c,d} tjd|_|jdkrtjd|_d|_n=#t $r0t dtjdtzd}YnwxYw|S)NTrHELPr@z*Error executing helper, use it as follows:z(Unable to execute %s with no parameters.F) sysargvr-upperr IndexErrorrrr$__file__rarNs r rzMEBCommandProcessor.read_paramss 8A;DL|!!##v--"x{ #'     > ? ? ? MDxO P P PGGG  sAA7BBc |d|ddt|jz|d|d|d|dt|jzdS)Nz!mysqlwbmeb z'WHERE : : is one of %s,zF : are the parameters needed for each command.z= You can also use as follows to get each command parameters: zmysqlwbmeb help z(WHERE : : is one of %s )rjoinlistrkeysrus r rzMEBCommandProcessor.print_usages =>>> CchhtTXTbTgTgTiTiOjOjFkFkklll bccc [\\\ 5666 ET^M`M`MbMbHcHccdddddr c~d}d}|ry|j}||jvrW|j|}||j|j}d}|jr|d}n|}|s)| d||S)NFrTrz ERROR Executing mysqlwbmeb ) rr-rrrr/rrrr)ra processedrNr-klassinstances r rzMEBCommandProcessor.executes       1l((**G$.((w/ 5d.ABB #1((***GG&..00G    > ? ? ?      r rrnrorprerrr __classcell__rs@r rrss @ @ @ @ @ @   eeer rc\eZdZd fd ZdZdZdZdZdZdZ d Z d Z d Z d Z xZS)rNctt|||d|_d|_t jd|_t jd|_dS)Nrz%Y-%m-%d_%H-%M-%Sz7\b[1-9]\d\d\d\b-[0-1]\d-[0-3]\d_[0-2]\d-[0-5]\d-[0-5]\dz^mysqlbackup completed OK!) rrrerw time_formatrecompiletime_format_re backup_ok_rers r rezMEBBackup.__init__s^ i''???. j)lmm j)EFFr cV|d|d|d|d|d|d|d|ddS) NzVBACKUP zXWHERE : : is the UUID of the profile to be used for the backup process.zO : indicates if the backup will be compressed. (1 or 0)zP : indicates the backup should be incremental. (1 or 0)zX : indicates the backup will be done to an image file. (1 or 0)zO : indicates the backup should be compressed. (1 or 0)zm : indicates the backup operation to be done, could be backup or backup-and-apply-logzT [file_name] : indicates the target name for the backup file or folder rrus r rzMEBBackup.print_usages rsss tuuu klll lmmm tuuu klll J K K K rsssssr c6gd}||vS)N)1TRUEYES)r)raparam true_params r read_bool_paramzMEBBackup.read_bool_params ))) {{}} **r ctd}|dkr|d|_||d|_||d|_||d|_||d|_|d|_|dkr|d|_ d }|S) NFrrr@T) rrrcrcompress incrementalto_single_filereport_progress bkcommandrwrs r rzMEBBackup.read_paramss      " " $q 1 1D  001B1BCCDM#33DNN14E4EFFD "&"6"6t~~a7H7H"I"ID #'#7#7q8I8I#J#JD !^^A..DN!!A%%!%!2!2Gr ctjt}tj|}tj||j|_t|j}|dddd|_ |dddd|_ |dddd|_ |ddd d |_ |dd d d d k|_ |dd d d|_|ddd d|_|ddd d d k|_|ddd d d k|_|ddd d d k|_|ddd d|_dS)N meb_managerr-Tr mysqlbackup backup_dirincremental_backup_dir using_ttsF0rTruecompress_methodlz4compress_levelrskip_unused_pagesincremental_with_redo_log_onlyuse_encryption_passwordencryption_password)rpathrealpathrdirnamerrcrWrmr-rinc_backup_diruse_ttsrrrrrrr)rathis_file_path backups_homeprofiles r read_profile_datazMEBBackup.read_profile_data(s))(33w~66 GLLt7HIIt011))-D"MM !,,]L$PRSS%00@XZ^`bcc))-eSQQ **=*eUSSW]] &11-ARTY[`aa%00@PRWY\]]!(!3!3MCVX]_d!e!eio!o.5.@.@Pprwy~..DJ/J+'.'9'9-Ibdikp'q'qu{'{$#*#5#5mEZ\ace#f#f   r cd}|jdkry|jrj|jdddkr|xjdz c_|jdd|_|jdd|_n|j}nt |j}|r;tj |j||_|jdz|_dSdS)Nrz.mbi.log) rwrlowerrreplacelog_pathrrrrr)ra target_folders r set_backup_pathszMEBBackup.set_backup_paths?s  >R  " />''))"##.&88NNf,NN#'.""5 $ 6 6vv F F !% %T%566M  5 gll4?MJJDO Of4DMMM 5 5r cd}d|jd|jd|_|jrt |jdddrX|jdkr|xjdz c_nL|xjd |jzz c_|jd kr|xjd |jzz c_n|xjdz c_d }|jrk|}|r=|j r|xjd |zz c_n|xjd|zz c_|j |_ d}n/| dd}n|j r|xjdz c_||xjd|d|j dz c_|jr|xjd|jzz c_|jdkr"d}|jdkrd}|xjd|zz c_|jr|xjdz c_|jr|xjd|jzz c_|xjd|jd|jdz c_|S)NT"z" --defaults-file="r rrz --compressz --compress-method=%srz --compress-level=%sz --backup-dirz= --incremental-with-redo-log-only --incremental-base=dir:"%s"z* --incremental --incremental-base=dir:"%s"z --incremental-backup-dirz>ERROR: Unable to run incremental backup without a base folder.Fz --skip-unused-pages z="z --backup-image=%srzwith-minimum-locking2zwith-full-lockingz --use-tts=%sz --show-progress=stdoutz --encrypt-password=%sz > "z" 2>&1)r-rc command_callrrUrrrget_incremental_base_folderrrrrrrrrwrrrrrr)rarN path_param base_folder tts_values r prepare_commandzMEBBackup.prepare_commandZs;?<<<IZIZIZ[ = 3%dlAr1== 3'500%%6%%%%%)@4CW)WW%%*c11))-CdFY-YY))!!]2!!%    8::<>!!$*j-G"H"HIII      r cFd}td|j}||j|}||krh|j}|}||j|}||kr |}|j}|r3t j|t|j|}|S)Nrz1900-01-01_00-00-00) rrfind_lastest_backuprrrrrr)rar  base_tstamp lastest_full lastest_incs r r z%MEBBackup.get_incremental_base_folders 2D4DEE //MM + % %/K&K2243F TTK[(() "1  a gll;AQS^8_8_`` r cJfdtjD}|d|}|D]f}|j|rJ|tj|rt||j }ng|S)Ncg|]A}tjtj|?|BSr:)rrisdirr)r;namers r z1MEBBackup.find_lastest_backup..s>dddBGMM"',,W[]aJbJb zfWHERE : : Indicates the operation being done with the profile: NEW, UPDATE, DELETE.zV : is the UUID of the profile to be used for the scheduling.z{ [] : indicates the label under which the jobs were scheduled. Applies on UPDATE and DELETE changes.z [] : indicates if the profile was scheduled for full backup. (0 or 1). Applies on UPDATE and DELETE changes.z []: indicates if the profile was scheduled for incremental backup. (0 or 1). Applies on UPDATE and DELETE changes. rrus r rzMEBUpdateScheduling.print_usages `aaa C D D D rsss X Y Y Y a b b b l m m m m mr cd}|dkr|d|_|jdkrd}nd}||kr|d|_d|jz|_|jdkrN|d|_|d|_|d |_d }|S) NFr@rNEWrr%s.cnfrrT)rrchangeuuidrc old_labelold_fb_scheduleold_ib_schedule)rarNrs r rzMEBUpdateScheduling.read_paramss      " "..++DK{e##  !![00 NN1-- $,ty$8!;%''%)^^A%6%6DN+/>>!+<+>!+<+ 'z '; crontab 'z';rm ''z\.cnf\s\d\s1' > ')rrrrr3)rarI cron_filer-s r get_unschedule_commandz*MEBUpdateScheduling.get_unschedule_command1s%(A(AA & emememosoxoxox{D{D{DFOFOFOQZQZQZ[GG !fnememosoxoxox{D{D{DFOFOFOQZQZQZ[Gr c4g}|dtz|d|d|jzd}d}|dkr|jr |jsd}n|dkrd}|||||d|d|jdkr|dkr|d n|d d |S) Nz"%s"rr1rrKrincrzbackup-and-apply-logbackupr)appendrr3rr;r)rarIcmd_data real_compressreal_incrementals r create_backup_command_callz.MEBUpdateScheduling.create_backup_command_call;s))*** !!! 49,---  & } $T^ $ # E ! !"  &&&())) >V # # v(=(= OO2 3 3 3 3 OOH % % %xx!!!r c |j}d}|dkrd}tj||}||}||g}|t|j||j dkrdnt|j ||j dvrdnt|j |d||j dkrdn|j |d|z|d |zd |jz}d |}d |d |d|d|d| }|S)Nz\$BACKUP_NAME.logrPzinc/\$BACKUP_NAME.logr*)rrrrz/BACKUP_NAME=\$(date +\%Y-\%m-\%d_\%H-\%M-\%S); z > \"%s\" 2>&1z'%s/wb_cron_file'rz crontab -l > z; echo "z" >> z ; crontab z; rm ) rrrrrVrrRrrHrDrGrErF) rarIr target_pathr-schedulerM cron_entryschedule_commands r get_schedule_commandz(MEBUpdateScheduling.get_schedule_command_s?) %  1K7<<+6611+>> {+++DK(()))t~44#di..IIIt~@@c$.FYFYZZZt~44$.IIIIGSTTT)H4555($/9 XXh'' T]T]T]_i_i_iktktktvvvBKBKLr ctj}d}|r|jdkr|d}|jdkrt |dr|jn|j}|j|kr d|jznd}|jdks |j|krG| d }tj d |||t|d |j z}|jdks |j|krG| d }tj d |||t|d |j z}|jdkr_|d |d }tj d|jz|t|d |j z}|jdkr_|d |d }tj d|jz|t|d |j z}n||r9|||S)NrDELETErr0r<z, renamed from %sr?rrKz&Unscheduling full backup for profile: FrPz-Unscheduling incremental backup for profile: rz'Scheduling full backup for profile: %s.z.Scheduling incremental backup for profile: %s.)rArBrr2r=hasattrr<r4r5rNrdebugr5rCr6r,rr]r-rrrDrE)rarMrNr-r8messages r rzMEBUpdateScheduling.executesu     ! {h&&!!###G{e##*1$ *D*DX$.BF.TYBYBY->>_b'3..$.E2I2I"99&AAGMMRWRWY`Y`"abbb% GUFL(Q(QQG'3..$.E2I2I"99%@@GMMY^Y^`g`g"hiii% GUFL(Q(QQG#v--&&v...33F;; G$.XYYY!K $M$MM#v--&&u---33E:: NQUQ__```!K $M$MM        9   foo//5577 8 8 8r r) rnrorprerrr=rrNrVr]rrrs@r rrs''''''mmm2YYY, , , ,""""""H   B*******r rc2eZdZdfd ZdZdZdZxZS)rNctt|||d|_d|_t jt}t j ||_ dS)Nr) rrredatafiledatadirrrrrrr)rarr/rrs r rezMEBPropagateSettings.__init__sc "D))226>JJJ  ))(33GOON;;r crd}|dkr|d|_d}|S)NFrrT)rrrers r rz MEBPropagateSettings.read_paramss;      " " NN1--DMGr c|d|d|ddS)NzPROPAGATE_DATA z`WHERE : : is the path to the datadir of the server instance for which the profiles arezZ being loaded. (There could be more than one instance on the same box).rrus r rz MEBPropagateSettings.print_usagesG 4555 |}}} vwwwwwr cd}|r+d}t}tj|j|j}|||j dddd|_ |j tj|jd}ddl }| |D]I}t|}| dddd}||j kr| |Jn|d tj|n||S) Nrrtargetrf*.cnfrFrz4Data propagation file is missing the target datadir.)rrrrrrrrerxrtrmrfglobrWrrrr) rarNupdatersource_config_file search_stringrlfilenamerprofile_datadirs r rzMEBPropagateSettings.executesR      G$ooG!#d.?!O!O     2 3 3 3">44Xy$PTUUDL|' " T-> H H  $ - 8 811H*844G'.&8&8 SXZ\&]&]O&$,66x0001!!"XYYY I( ) ) ) )      r rrrs@r rrsm<<<<<<xxx !!!!!!!r rc8eZdZdfd ZdZdZdZdZxZS)rNcvtt|||d|_d|_dS)Nrr)rrrerf meb_versionrs r rezMEBGetProfiles.__init__s8 nd##,,V^DDD r cd}|dkr6|d|_|d|_d}|S)NFr@rrT)rr meb_commandrfrs r rzMEBGetProfiles.read_paramssO      " "#~~a00D >>!,,DLGr c|d|d|d|dtr|ddSdS)Nz$GET_PROFILES z>WHERE : : is the path to a valid MEB executable.zdWHERE : : is the path to the datadir of the server instance for which the profiles arez^ being loaded. (There could be more than one instance on the same box).zW When executed from python code the WBMEB_BACKUPSHOME environment variable must be set.)rrrus r rzMEBGetProfiles.print_usages @AAA Z[[[ A B B B z{{{  z   x y y y y y z zr c & d}dtjvrtjd}|rW|rBi}tj|d}ddl}||D]}d}t |}|dddd}||jkr|dz}|d d dd} | |j krzi} |dd dd| d <|dd dd| d<|dddd| d<|d ddd| d<tj | d} | j | j z} | j | j z} || | | d<tj| dtjs|dz}|dddd}|dddd}|dddd}|dddd}|dddd}|dddd}d||||||g| d<|dddd}|dddd}|dd dd}|dd!dd}|dd"dd}|dd#dd}d||||||g| d$<t#|dd%dd}|dkrct%|jd&d'drL|d d(dd}|r2d)}t'j|}||}|r|d*z}|dddd}t%|d&d+dr:|d d(dd}|d d,dd}|s|r|d-z}n9|d d.dd}|d d/dd}|s|r|d0z}|| d1<| ||<|r'|t/j|dS|dS)2NrWBMEB_BACKUPSHOMErkrrr-Frrfr8LABELpartialPARTIALrr USING_TTSr BACKUP_DIR AVAILABLErr9full_backups_frequencyfull_backups_month_dayfull_backups_week_daysfull_backups_hourfull_backups_minuter> FSCHEDULEr:inc_backups_frequencyinc_backups_month_dayinc_backups_week_daysinc_backups_hourinc_backups_minute ISCHEDULEr8r includez1^[\dA-Fa-f]{8}-([\dA-Fa-f]{4}-){3}[\dA-Fa-f]{12}$r@r databasesinclude_tablesexclude_tablesrVALID)renvironrrrrlrWrmrvrfstatvfsf_frsizef_blocksf_bfreeget_available_spaceaccessW_OKrIrUrrr rrrr)rar master_datarorlrpprofile_issuesrprofile_commandrqrdfstotalfreer2r(mdwdhmprofile_versionr expressioncompiledr r-rexcludes r rzMEBGetProfiles.executesR "* , ,:&9:L j D,,..j KGLLw??M KKK IIm44X 1X 1!"'x00#*"4"4]IuVX"Y"Y"d&666"b(N#*"4"4]IuVX"Y"Y"dl22D$+$6$6}guVX$Y$YDM&-&8&8 SXZ\&]&]DO(/(:(:=+W\^a(b(bD%)0););Mrs& ########   BBB ####LMMM06.#5#5#5#5#5F#5#5#5L$$$$$$$$N88888*888taaaaa aaaFGGGGG*GGGR88888:888vWWWWWZWWWrz$ zJW%%h//N&(goon&E&EBJ"#(3B3-'HG????G:DZ[[[[##CH--I CHY   !!!!!r