Merge pull request #66 from liaoishere/feat/export-libvirt-error
Add helper function for error detection
This commit is contained in:
		
							
								
								
									
										190
									
								
								const.gen.go
									
									
									
									
									
								
							
							
						
						
									
										190
									
								
								const.gen.go
									
									
									
									
									
								
							| @@ -1963,3 +1963,193 @@ const ( | ||||
| 	StreamEventError    StreamEventType = 4 | ||||
| 	StreamEventHangup   StreamEventType = 8 | ||||
| ) | ||||
|  | ||||
| // errorLevel as declared in libvirt/virterror.h:44 | ||||
| type errorLevel int32 | ||||
|  | ||||
| // errorLevel enumeration from libvirt/virterror.h:44 | ||||
| const ( | ||||
| 	errNone    errorLevel = iota | ||||
| 	errWarning errorLevel = 1 | ||||
| 	errError   errorLevel = 2 | ||||
| ) | ||||
|  | ||||
| // errorDomain as declared in libvirt/virterror.h:139 | ||||
| type errorDomain int32 | ||||
|  | ||||
| // errorDomain enumeration from libvirt/virterror.h:139 | ||||
| const ( | ||||
| 	fromNone           errorDomain = iota | ||||
| 	fromXen            errorDomain = 1 | ||||
| 	fromXend           errorDomain = 2 | ||||
| 	fromXenstore       errorDomain = 3 | ||||
| 	fromSexpr          errorDomain = 4 | ||||
| 	fromXML            errorDomain = 5 | ||||
| 	fromDom            errorDomain = 6 | ||||
| 	fromRPC            errorDomain = 7 | ||||
| 	fromProxy          errorDomain = 8 | ||||
| 	fromConf           errorDomain = 9 | ||||
| 	fromQemu           errorDomain = 10 | ||||
| 	fromNet            errorDomain = 11 | ||||
| 	fromTest           errorDomain = 12 | ||||
| 	fromRemote         errorDomain = 13 | ||||
| 	fromOpenvz         errorDomain = 14 | ||||
| 	fromXenxm          errorDomain = 15 | ||||
| 	fromStatsLinux     errorDomain = 16 | ||||
| 	fromLxc            errorDomain = 17 | ||||
| 	fromStorage        errorDomain = 18 | ||||
| 	fromNetwork        errorDomain = 19 | ||||
| 	fromDomain         errorDomain = 20 | ||||
| 	fromUml            errorDomain = 21 | ||||
| 	fromNodedev        errorDomain = 22 | ||||
| 	fromXenInotify     errorDomain = 23 | ||||
| 	fromSecurity       errorDomain = 24 | ||||
| 	fromVbox           errorDomain = 25 | ||||
| 	fromInterface      errorDomain = 26 | ||||
| 	fromOne            errorDomain = 27 | ||||
| 	fromEsx            errorDomain = 28 | ||||
| 	fromPhyp           errorDomain = 29 | ||||
| 	fromSecret         errorDomain = 30 | ||||
| 	fromCPU            errorDomain = 31 | ||||
| 	fromXenapi         errorDomain = 32 | ||||
| 	fromNwfilter       errorDomain = 33 | ||||
| 	fromHook           errorDomain = 34 | ||||
| 	fromDomainSnapshot errorDomain = 35 | ||||
| 	fromAudit          errorDomain = 36 | ||||
| 	fromSysinfo        errorDomain = 37 | ||||
| 	fromStreams        errorDomain = 38 | ||||
| 	fromVmware         errorDomain = 39 | ||||
| 	fromEvent          errorDomain = 40 | ||||
| 	fromLibxl          errorDomain = 41 | ||||
| 	fromLocking        errorDomain = 42 | ||||
| 	fromHyperv         errorDomain = 43 | ||||
| 	fromCapabilities   errorDomain = 44 | ||||
| 	fromURI            errorDomain = 45 | ||||
| 	fromAuth           errorDomain = 46 | ||||
| 	fromDbus           errorDomain = 47 | ||||
| 	fromParallels      errorDomain = 48 | ||||
| 	fromDevice         errorDomain = 49 | ||||
| 	fromSSH            errorDomain = 50 | ||||
| 	fromLockspace      errorDomain = 51 | ||||
| 	fromInitctl        errorDomain = 52 | ||||
| 	fromIdentity       errorDomain = 53 | ||||
| 	fromCgroup         errorDomain = 54 | ||||
| 	fromAccess         errorDomain = 55 | ||||
| 	fromSystemd        errorDomain = 56 | ||||
| 	fromBhyve          errorDomain = 57 | ||||
| 	fromCrypto         errorDomain = 58 | ||||
| 	fromFirewall       errorDomain = 59 | ||||
| 	fromPolkit         errorDomain = 60 | ||||
| 	fromThread         errorDomain = 61 | ||||
| 	fromAdmin          errorDomain = 62 | ||||
| 	fromLogging        errorDomain = 63 | ||||
| 	fromXenxl          errorDomain = 64 | ||||
| 	fromPerf           errorDomain = 65 | ||||
| 	fromLibssh         errorDomain = 66 | ||||
| ) | ||||
|  | ||||
| // errorNumber as declared in libvirt/virterror.h:322 | ||||
| type errorNumber int32 | ||||
|  | ||||
| // errorNumber enumeration from libvirt/virterror.h:322 | ||||
| const ( | ||||
| 	errOk                    errorNumber = iota | ||||
| 	errInternalError         errorNumber = 1 | ||||
| 	errNoMemory              errorNumber = 2 | ||||
| 	errNoSupport             errorNumber = 3 | ||||
| 	errUnknownHost           errorNumber = 4 | ||||
| 	errNoConnect             errorNumber = 5 | ||||
| 	errInvalidConn           errorNumber = 6 | ||||
| 	errInvalidDomain         errorNumber = 7 | ||||
| 	errInvalidArg            errorNumber = 8 | ||||
| 	errOperationFailed       errorNumber = 9 | ||||
| 	errGetFailed             errorNumber = 10 | ||||
| 	errPostFailed            errorNumber = 11 | ||||
| 	errHTTPError             errorNumber = 12 | ||||
| 	errSexprSerial           errorNumber = 13 | ||||
| 	errNoXen                 errorNumber = 14 | ||||
| 	errXenCall               errorNumber = 15 | ||||
| 	errOsType                errorNumber = 16 | ||||
| 	errNoKernel              errorNumber = 17 | ||||
| 	errNoRoot                errorNumber = 18 | ||||
| 	errNoSource              errorNumber = 19 | ||||
| 	errNoTarget              errorNumber = 20 | ||||
| 	errNoName                errorNumber = 21 | ||||
| 	errNoOs                  errorNumber = 22 | ||||
| 	errNoDevice              errorNumber = 23 | ||||
| 	errNoXenstore            errorNumber = 24 | ||||
| 	errDriverFull            errorNumber = 25 | ||||
| 	errCallFailed            errorNumber = 26 | ||||
| 	errXMLError              errorNumber = 27 | ||||
| 	errDomExist              errorNumber = 28 | ||||
| 	errOperationDenied       errorNumber = 29 | ||||
| 	errOpenFailed            errorNumber = 30 | ||||
| 	errReadFailed            errorNumber = 31 | ||||
| 	errParseFailed           errorNumber = 32 | ||||
| 	errConfSyntax            errorNumber = 33 | ||||
| 	errWriteFailed           errorNumber = 34 | ||||
| 	errXMLDetail             errorNumber = 35 | ||||
| 	errInvalidNetwork        errorNumber = 36 | ||||
| 	errNetworkExist          errorNumber = 37 | ||||
| 	errSystemError           errorNumber = 38 | ||||
| 	errRPC                   errorNumber = 39 | ||||
| 	errGnutlsError           errorNumber = 40 | ||||
| 	warNoNetwork             errorNumber = 41 | ||||
| 	errNoDomain              errorNumber = 42 | ||||
| 	errNoNetwork             errorNumber = 43 | ||||
| 	errInvalidMac            errorNumber = 44 | ||||
| 	errAuthFailed            errorNumber = 45 | ||||
| 	errInvalidStoragePool    errorNumber = 46 | ||||
| 	errInvalidStorageVol     errorNumber = 47 | ||||
| 	warNoStorage             errorNumber = 48 | ||||
| 	errNoStoragePool         errorNumber = 49 | ||||
| 	errNoStorageVol          errorNumber = 50 | ||||
| 	warNoNode                errorNumber = 51 | ||||
| 	errInvalidNodeDevice     errorNumber = 52 | ||||
| 	errNoNodeDevice          errorNumber = 53 | ||||
| 	errNoSecurityModel       errorNumber = 54 | ||||
| 	errOperationInvalid      errorNumber = 55 | ||||
| 	warNoInterface           errorNumber = 56 | ||||
| 	errNoInterface           errorNumber = 57 | ||||
| 	errInvalidInterface      errorNumber = 58 | ||||
| 	errMultipleInterfaces    errorNumber = 59 | ||||
| 	warNoNwfilter            errorNumber = 60 | ||||
| 	errInvalidNwfilter       errorNumber = 61 | ||||
| 	errNoNwfilter            errorNumber = 62 | ||||
| 	errBuildFirewall         errorNumber = 63 | ||||
| 	warNoSecret              errorNumber = 64 | ||||
| 	errInvalidSecret         errorNumber = 65 | ||||
| 	errNoSecret              errorNumber = 66 | ||||
| 	errConfigUnsupported     errorNumber = 67 | ||||
| 	errOperationTimeout      errorNumber = 68 | ||||
| 	errMigratePersistFailed  errorNumber = 69 | ||||
| 	errHookScriptFailed      errorNumber = 70 | ||||
| 	errInvalidDomainSnapshot errorNumber = 71 | ||||
| 	errNoDomainSnapshot      errorNumber = 72 | ||||
| 	errInvalidStream         errorNumber = 73 | ||||
| 	errArgumentUnsupported   errorNumber = 74 | ||||
| 	errStorageProbeFailed    errorNumber = 75 | ||||
| 	errStoragePoolBuilt      errorNumber = 76 | ||||
| 	errSnapshotRevertRisky   errorNumber = 77 | ||||
| 	errOperationAborted      errorNumber = 78 | ||||
| 	errAuthCancelled         errorNumber = 79 | ||||
| 	errNoDomainMetadata      errorNumber = 80 | ||||
| 	errMigrateUnsafe         errorNumber = 81 | ||||
| 	errOverflow              errorNumber = 82 | ||||
| 	errBlockCopyActive       errorNumber = 83 | ||||
| 	errOperationUnsupported  errorNumber = 84 | ||||
| 	errSSH                   errorNumber = 85 | ||||
| 	errAgentUnresponsive     errorNumber = 86 | ||||
| 	errResourceBusy          errorNumber = 87 | ||||
| 	errAccessDenied          errorNumber = 88 | ||||
| 	errDbusService           errorNumber = 89 | ||||
| 	errStorageVolExist       errorNumber = 90 | ||||
| 	errCPUIncompatible       errorNumber = 91 | ||||
| 	errXMLInvalidSchema      errorNumber = 92 | ||||
| 	errMigrateFinishOk       errorNumber = 93 | ||||
| 	errAuthUnavailable       errorNumber = 94 | ||||
| 	errNoServer              errorNumber = 95 | ||||
| 	errNoClient              errorNumber = 96 | ||||
| 	errAgentUnsynced         errorNumber = 97 | ||||
| 	errLibssh                errorNumber = 98 | ||||
| ) | ||||
|   | ||||
| @@ -30,6 +30,7 @@ PARSER: | ||||
|     IncludePaths: [./lv_source/include] | ||||
|     SourcesPaths: | ||||
|         - libvirt/libvirt.h | ||||
|         - libvirt/virterror.h | ||||
|  | ||||
| TRANSLATOR: | ||||
|     ConstRules: | ||||
| @@ -52,6 +53,10 @@ TRANSLATOR: | ||||
|             - {action: replace, from: "Uri([A-Z]|$)", to: "URI$1"} | ||||
|             - {action: replace, from: "Vcpu([A-Z]|$)", to: "VCPU$1"} | ||||
|             - {action: replace, from: "Xml([A-Z]|$)", to: "XML$1"} | ||||
|             - {action: replace, from: "Rpc([A-Z]|$)", to: "RPC$1"} | ||||
|             - {action: replace, from: "Ssh([A-Z]|$)", to: "SSH$1"} | ||||
|             - {action: replace, from: "Http([A-Z]|$)", to: "HTTP$1"} | ||||
|             - {transform: unexport, from: "^(Err|From|War)"} | ||||
|         const: | ||||
|             - {action: accept, from: "^VIR_"} | ||||
|             # Special case to prevent a collision with a type: | ||||
|   | ||||
							
								
								
									
										23
									
								
								rpc.go
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								rpc.go
									
									
									
									
									
								
							| @@ -113,6 +113,23 @@ type libvirtError struct { | ||||
| 	Level    uint32 | ||||
| } | ||||
|  | ||||
| func (e libvirtError) Error() string { | ||||
| 	return e.Message | ||||
| } | ||||
|  | ||||
| func checkError(err error, expectedError errorNumber) bool { | ||||
| 	e, ok := err.(libvirtError) | ||||
| 	if ok { | ||||
| 		return e.Code == uint32(expectedError) | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // IsNotFound detects libvirt's ERR_NO_DOMAIN. | ||||
| func IsNotFound(err error) bool { | ||||
| 	return checkError(err, errNoDomain) | ||||
| } | ||||
|  | ||||
| // listen processes incoming data and routes | ||||
| // responses to their respective callback handler. | ||||
| func (l *Libvirt) listen() { | ||||
| @@ -328,8 +345,12 @@ func decodeError(buf []byte) error { | ||||
| 	if strings.Contains(e.Message, "unknown procedure") { | ||||
| 		return ErrUnsupported | ||||
| 	} | ||||
| 	// if libvirt returns ERR_OK, ignore the error | ||||
| 	if checkError(e, errOk) { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	return errors.New(e.Message) | ||||
| 	return e | ||||
| } | ||||
|  | ||||
| // decodeEvent extracts an event from the given byte slice. | ||||
|   | ||||
							
								
								
									
										40
									
								
								rpc_test.go
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								rpc_test.go
									
									
									
									
									
								
							| @@ -89,7 +89,7 @@ var ( | ||||
| 	} | ||||
|  | ||||
| 	testErrorMessage = []byte{ | ||||
| 		0x00, 0x00, 0x00, 0x37, // code | ||||
| 		0x00, 0x00, 0x00, 0x37, // code (55, errOperationInvalid) | ||||
| 		0x00, 0x00, 0x00, 0x0a, // domain id | ||||
|  | ||||
| 		// message ("Requested operation is not valid: domain is not running") | ||||
| @@ -106,6 +106,25 @@ var ( | ||||
| 		0x00, 0x00, 0x00, 0x02, | ||||
| 	} | ||||
|  | ||||
| 	testErrorNotFoundMessage = []byte{ | ||||
| 		0x00, 0x00, 0x00, 0x2a, // code (42 errDoDmain) | ||||
| 		0x00, 0x00, 0x00, 0x0a, // domain id | ||||
|  | ||||
| 		// message | ||||
| 		0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, | ||||
| 		0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x6e, | ||||
| 		0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, | ||||
| 		0x3a, 0x20, 0x6e, 0x6f, 0x20, 0x64, 0x6f, 0x6d, | ||||
| 		0x61, 0x69, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, | ||||
| 		0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, | ||||
| 		0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x27, | ||||
| 		0x74, 0x65, 0x73, 0x74, 0x2d, 0x2d, 0x2d, 0x27, | ||||
| 		0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, | ||||
|  | ||||
| 		// error level | ||||
| 		0x00, 0x00, 0x00, 0x01, | ||||
| 	} | ||||
|  | ||||
| 	testDomain = &Domain{ | ||||
| 		Name: "test-domain", | ||||
| 		UUID: testUUID, | ||||
| @@ -204,11 +223,24 @@ func TestDecodeEvent(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestDecodeError(t *testing.T) { | ||||
| 	expected := "Requested operation is not valid: domain is not running" | ||||
| 	expectedMsg := "Requested operation is not valid: domain is not running" | ||||
| 	expectedCode := errOperationInvalid | ||||
|  | ||||
| 	err := decodeError(testErrorMessage) | ||||
| 	if err.Error() != expected { | ||||
| 		t.Errorf("expected error %s, got %s", expected, err.Error()) | ||||
| 	e := err.(libvirtError) | ||||
| 	if e.Message != expectedMsg { | ||||
| 		t.Errorf("expected error message %s, got %s", expectedMsg, err.Error()) | ||||
| 	} | ||||
| 	if e.Code != uint32(expectedCode) { | ||||
| 		t.Errorf("expected code %d, got %d", expectedCode, e.Code) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestErrNotFound(t *testing.T) { | ||||
| 	err := decodeError(testErrorNotFoundMessage) | ||||
| 	ok := IsNotFound(err) | ||||
| 	if !ok { | ||||
| 		t.Errorf("expected true, got %t", ok) | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user