2012-05-17 19:08:53 +04:00
/*
* virsh - edit . c : Implementation of generic virsh * - edit intelligence
*
2015-02-19 16:16:39 +03:00
* Copyright ( C ) 2012 , 2015 Red Hat , Inc .
2012-05-17 19:08:53 +04:00
*
2012-07-27 13:39:53 +04:00
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
2012-09-21 02:30:55 +04:00
* License along with this library . If not , see
2012-07-27 13:39:53 +04:00
* < http : //www.gnu.org/licenses/>.
2012-05-17 19:08:53 +04:00
*
* Usage :
* Define macros :
* EDIT_GET_XML - expression which produces a pointer to XML string , e . g :
* # define EDIT_GET_XML virDomainGetXMLDesc ( dom , flags )
*
* EDIT_NOT_CHANGED - this action is taken if the XML wasn ' t changed .
* Note , that you don ' t want to jump to cleanup but edit_cleanup label
* where temporary variables are free ( ) - d and temporary file is deleted :
2016-11-04 17:22:26 +03:00
* # define EDIT_NOT_CHANGED vshPrintExtra ( ctl , _ ( " Domain %s XML not changed " ) , \
* virDomainGetName ( dom ) ) ; \
2012-05-17 19:08:53 +04:00
* ret = true ; goto edit_cleanup ;
* Note that this is a statement .
*
* EDIT_DEFINE - expression which redefines the object . The edited XML from
* user is in ' doc_edited ' variable . Don ' t overwrite the pointer to the
* object , as we may iterate once more over and therefore the pointer
* would be invalid . Hence assign object to a different variable .
* Moreover , this needs to be an expression where :
* - 0 is taken as error ( our virDefine * APIs often return NULL on error )
* - everything else is taken as success
* For example :
* # define EDIT_DEFINE ( dom_edited = virDomainDefineXML ( ctl - > conn , doc_edited ) )
*/
# ifndef EDIT_GET_XML
# error Missing EDIT_GET_XML definition
# endif
# ifndef EDIT_NOT_CHANGED
# error Missing EDIT_NOT_CHANGED definition
# endif
# ifndef EDIT_DEFINE
# error Missing EDIT_DEFINE definition
# endif
do {
char * tmp = NULL ;
char * doc = NULL ;
char * doc_edited = NULL ;
char * doc_reread = NULL ;
2012-06-07 07:13:57 +04:00
const char * msg = NULL ;
2012-09-19 13:31:44 +04:00
bool edit_success = false ;
2015-02-19 16:16:39 +03:00
bool relax_avail = false ;
2012-05-17 19:08:53 +04:00
/* Get the XML configuration of the object. */
doc = ( EDIT_GET_XML ) ;
if ( ! doc )
goto edit_cleanup ;
/* Create and open the temporary file. */
virsh: use common namespacing
Convert the exported items in virsh.h to use a common 'vsh' prefix.
* tools/virsh.h (VIRSH_MAX_XML_FILE): Rename...
(VSH_MAX_XML_FILE): ...and parenthesize.
(DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete.
(vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype.
(editWriteToTempFile, editFile, editReadBackFile, prettyCapacity)
(virshReportError): Rename...
(vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile)
(vshPrettyCapacity, vshReportError): ...into vsh namespace.
(jobWatchTimeoutFunc): Move to virsh-domain.c.
* tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC.
(main): Inline former CTRL_CLOSE_BRACKET.
(vshUsage, vshInit, vshDeinit, vshParseArgv): Make static.
(prettyCapacity, virshReportError, editWriteToTempFile, editFile):
Fix naming, and adjust usage.
(vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust
usage.
* tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare)
(cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice)
(cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount)
(cmdAttachDevice, cmdDomjobinfo): Likewise.
* tools/virsh-edit.c (do): Likewise.
* tools/virsh-interface.c (cmdInterfaceDefine): Likewise.
* tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine):
Likewise.
* tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise.
* tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise.
* tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine)
(cmdPoolDiscoverSources, cmdPoolList): Likewise.
* tools/virsh-secret.c (cmdSecretDefine): Likewise.
* tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate)
(vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent)
(vshGetSnapshotParent): Likewise.
* tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom)
(cmdVolInfo, cmdVolList): Likewise.
2012-08-19 08:10:17 +04:00
tmp = vshEditWriteToTempFile ( ctl , doc ) ;
2012-05-17 19:08:53 +04:00
if ( ! tmp )
goto edit_cleanup ;
2014-03-25 10:53:59 +04:00
reedit :
2015-02-19 16:16:39 +03:00
# ifdef EDIT_RELAX
relax_avail = true ;
# endif
2012-05-17 19:08:53 +04:00
/* Start the editor. */
virsh: use common namespacing
Convert the exported items in virsh.h to use a common 'vsh' prefix.
* tools/virsh.h (VIRSH_MAX_XML_FILE): Rename...
(VSH_MAX_XML_FILE): ...and parenthesize.
(DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete.
(vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype.
(editWriteToTempFile, editFile, editReadBackFile, prettyCapacity)
(virshReportError): Rename...
(vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile)
(vshPrettyCapacity, vshReportError): ...into vsh namespace.
(jobWatchTimeoutFunc): Move to virsh-domain.c.
* tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC.
(main): Inline former CTRL_CLOSE_BRACKET.
(vshUsage, vshInit, vshDeinit, vshParseArgv): Make static.
(prettyCapacity, virshReportError, editWriteToTempFile, editFile):
Fix naming, and adjust usage.
(vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust
usage.
* tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare)
(cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice)
(cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount)
(cmdAttachDevice, cmdDomjobinfo): Likewise.
* tools/virsh-edit.c (do): Likewise.
* tools/virsh-interface.c (cmdInterfaceDefine): Likewise.
* tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine):
Likewise.
* tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise.
* tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise.
* tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine)
(cmdPoolDiscoverSources, cmdPoolList): Likewise.
* tools/virsh-secret.c (cmdSecretDefine): Likewise.
* tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate)
(vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent)
(vshGetSnapshotParent): Likewise.
* tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom)
(cmdVolInfo, cmdVolList): Likewise.
2012-08-19 08:10:17 +04:00
if ( vshEditFile ( ctl , tmp ) = = - 1 )
2012-05-17 19:08:53 +04:00
goto edit_cleanup ;
/* Read back the edited file. */
2013-06-25 17:10:27 +04:00
VIR_FREE ( doc_edited ) ;
virsh: use common namespacing
Convert the exported items in virsh.h to use a common 'vsh' prefix.
* tools/virsh.h (VIRSH_MAX_XML_FILE): Rename...
(VSH_MAX_XML_FILE): ...and parenthesize.
(DIFF_MSEC, CTRL_CLOSE_BRACKET): Delete.
(vshUsage, vshInit, vshDeinit, vshParseArgv): Remove prototype.
(editWriteToTempFile, editFile, editReadBackFile, prettyCapacity)
(virshReportError): Rename...
(vshEditWriteToTempFile, vshEditFile, vshEditReadBackFile)
(vshPrettyCapacity, vshReportError): ...into vsh namespace.
(jobWatchTimeoutFunc): Move to virsh-domain.c.
* tools/virsh.c (vshCommandRun): Inline former DIFF_MSEC.
(main): Inline former CTRL_CLOSE_BRACKET.
(vshUsage, vshInit, vshDeinit, vshParseArgv): Make static.
(prettyCapacity, virshReportError, editWriteToTempFile, editFile):
Fix naming, and adjust usage.
(vshAskReedit, vshCommandRun, vshEventLoop, vshInit): Adjust
usage.
* tools/virsh-domain.c (cmdAttachDevice, cmdCPUCompare)
(cmdCPUBaseline, cmdCreate, cmdDefine, cmdDetachDevice)
(cmdUpdateDevice, cmdDesc, cmdUndefine, cmdStart, cmdVcpucount)
(cmdAttachDevice, cmdDomjobinfo): Likewise.
* tools/virsh-edit.c (do): Likewise.
* tools/virsh-interface.c (cmdInterfaceDefine): Likewise.
* tools/virsh-network.c (cmdNetworkCreate, cmdNetworkDefine):
Likewise.
* tools/virsh-nodedev.c (cmdNodeDeviceCreate): Likewise.
* tools/virsh-nwfilter.c (cmdNWFilterDefine): Likewise.
* tools/virsh-pool.c (cmdPoolCreate, cmdPoolDefine)
(cmdPoolDiscoverSources, cmdPoolList): Likewise.
* tools/virsh-secret.c (cmdSecretDefine): Likewise.
* tools/virsh-snapshot.c (cmdSnapshotCreate, vshSnapshotCreate)
(vshLookupSnapshot, cmdSnapshotEdit, cmdSnapshotCurrent)
(vshGetSnapshotParent): Likewise.
* tools/virsh-volume.c (cmdVolCreate, cmdVolCreateFrom)
(cmdVolInfo, cmdVolList): Likewise.
2012-08-19 08:10:17 +04:00
doc_edited = vshEditReadBackFile ( ctl , tmp ) ;
2012-05-17 19:08:53 +04:00
if ( ! doc_edited )
goto edit_cleanup ;
/* Compare original XML with edited. Has it changed at all? */
2014-11-13 17:20:51 +03:00
if ( STREQ ( doc , doc_edited ) )
2012-05-17 19:08:53 +04:00
EDIT_NOT_CHANGED ;
2014-03-25 10:53:59 +04:00
redefine :
2012-05-18 14:21:06 +04:00
msg = NULL ;
2012-05-17 19:08:53 +04:00
/* Now re-read the object XML. Did someone else change it while
* it was being edited ? This also catches problems such as us
* losing a connection or the object going away .
*/
2013-06-25 17:10:27 +04:00
VIR_FREE ( doc_reread ) ;
2012-05-17 19:08:53 +04:00
doc_reread = ( EDIT_GET_XML ) ;
if ( ! doc_reread )
goto edit_cleanup ;
if ( STRNEQ ( doc , doc_reread ) ) {
2012-05-18 14:21:06 +04:00
msg = _ ( " The XML configuration was changed by another user. " ) ;
VIR_FREE ( doc ) ;
doc = doc_reread ;
doc_reread = NULL ;
2012-05-17 19:08:53 +04:00
}
/* Everything checks out, so redefine the object. */
2014-11-13 17:20:51 +03:00
if ( ! msg & & ! ( EDIT_DEFINE ) )
2012-05-18 14:21:06 +04:00
msg = _ ( " Failed. " ) ;
if ( msg ) {
2015-02-19 16:16:39 +03:00
int c = vshAskReedit ( ctl , msg , relax_avail ) ;
2012-05-18 14:21:06 +04:00
switch ( c ) {
case ' y ' :
goto reedit ;
break ;
case ' f ' :
goto redefine ;
break ;
case ' n ' :
goto edit_cleanup ;
break ;
2015-02-19 16:16:39 +03:00
# ifdef EDIT_RELAX
case ' i ' :
if ( relax_avail ) {
EDIT_RELAX ;
relax_avail = false ;
goto redefine ;
}
2019-10-15 14:38:21 +03:00
G_GNUC_FALLTHROUGH ;
2015-02-19 16:16:39 +03:00
# endif
2012-05-18 14:21:06 +04:00
default :
vshError ( ctl , " %s " , msg ) ;
break ;
}
}
2012-05-17 19:08:53 +04:00
2012-09-19 13:31:44 +04:00
edit_success = true ;
2012-05-17 19:08:53 +04:00
2014-03-25 10:53:59 +04:00
edit_cleanup :
2012-05-17 19:08:53 +04:00
VIR_FREE ( doc ) ;
VIR_FREE ( doc_edited ) ;
VIR_FREE ( doc_reread ) ;
if ( tmp ) {
2012-10-17 13:23:12 +04:00
unlink ( tmp ) ;
2012-05-17 19:08:53 +04:00
VIR_FREE ( tmp ) ;
}
2012-09-19 13:31:44 +04:00
if ( ! edit_success )
goto cleanup ;
2012-05-17 19:08:53 +04:00
} while ( 0 ) ;
# undef EDIT_GET_XML
# undef EDIT_NOT_CHANGED
# undef EDIT_DEFINE