- 积分
- 16843
在线时间 小时
最后登录1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?开始注册
x
解决办法(不太严谨)
3 H2 i6 E$ @8 n% o2 [, c根据日志提示' [5 g3 E% N& P
+ |$ f w w( b$ f! ?
2025-01-27 20:08:29.656 59902 ERROR cinder.volume.api [req-e5dea5da-9565-4e0e-b05b-9dbc58f7deef req-87c34a80-75b3-4bdd-87bf-1136cbb88b96 950f09833b4e4dffaf4acf3ac9f1d4bd 840a040edf78409f92d7c7a128652718 - - default default] Detected user call to delete in-use attachment. Call must come from the nova service and nova must be configured to send the service token. Bug #2004555" J+ ?! H9 D* C, ?+ h+ D+ _. x# Q
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault [req-e5dea5da-9565-4e0e-b05b-9dbc58f7deef req-87c34a80-75b3-4bdd-87bf-1136cbb88b96 950f09833b4e4dffaf4acf3ac9f1d4bd 840a040edf78409f92d7c7a128652718 - - default default] Caught error: <class 'cinder.exception.ConflictNovaUsingAttachment'> Detach volume from instance 4164eba5-b07e-4546-8d41-c4cdc030c396 using the Compute API: cinder.exception.ConflictNovaUsingAttachment: Detach volume from instance 4164eba5-b07e-4546-8d41-c4cdc030c396 using the Compute API9 f7 J$ Z* S. N: T3 R3 b
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault Traceback (most recent call last):, Z0 Q1 w( a( j* x# Z* O1 O
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/cinder/api/middleware/fault.py", line 84, in __call__' a& z. L) X0 V' R2 k$ g
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return req.get_response(self.application)# l7 ~+ F' @$ K# s
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/webob/request.py", line 1313, in send/ I' q% P1 R3 F9 z, Q3 w! O7 y W7 v
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault status, headers, app_iter = self.call_application(, T" o' j) Q: y/ H0 ]. O' C. ]; p2 x1 V
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/webob/request.py", line 1278, in call_application6 N3 c9 }. R7 z6 J9 |5 [
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault app_iter = application(self.environ, start_response); T/ b5 G: t9 l* o7 m- s5 k) R
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/webob/dec.py", line 143, in __call__; a; `( w+ {* i/ a4 q' n
! X) D4 l" g8 U3 r9 W' O2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return resp(environ, start_response) o8 Q W% O! _9 N; m7 k
2 D6 T' h3 Z( D O& ?3 Z2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/webob/dec.py", line 129, in __call__. ^4 q, L3 G8 ^2 U1 ~ s; W
! B/ h- H$ k$ h% q- [* ]1 F
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault resp = self.call_func(req, *args, **kw)
7 O" b1 u# u: i! n7 t1 @0 O0 p: p! r. B8 u: E. c1 b- n, e
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/webob/dec.py", line 193, in call_func b6 ` Q8 ?( l' e
+ J( R \% y( {' K$ H3 r$ O7 j
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return self.func(req, *args, **kwargs)
2 S- Y+ _) ?* V" b, h! d% ]9 }6 t4 H( V( d$ P
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/osprofiler/web.py", line 111, in __call__2 W u! G S# E* |( Z! S) @
& t( }' }/ t" k; ~5 F1 `2 A
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return request.get_response(self.application)
" P. V6 p9 U% p. \# L+ L' |0 T6 s+ a7 Y8 E$ \( N$ Q
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/webob/request.py", line 1313, in send
& b' y5 T5 N$ Z+ U' a/ L9 ?1 t z& @6 P B3 p+ x/ @ q) @
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault status, headers, app_iter = self.call_application(
" R" H$ R2 {- o2 b! n( e
( n+ O& r3 Z5 c1 |2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/webob/request.py", line 1278, in call_application
* V: g5 P5 r3 ]- X9 [# \8 c) K$ I
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault app_iter = application(self.environ, start_response)
5 a( P9 U1 E: w' A+ }/ g+ Q. {7 |1 J z0 S* [7 F; u+ I8 u& e
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/webob/dec.py", line 129, in __call__& U" m) Y7 z! A7 ?- e. i
0 s+ d' I* l, |, ?2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault resp = self.call_func(req, *args, **kw)/ F1 k; N$ S: Q: V7 T4 B: n3 v
4 a* z3 J7 M3 _: @$ J2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/webob/dec.py", line 193, in call_func$ T. l; ?* o4 }# ~
; S. L: s6 Q. k/ Q2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return self.func(req, *args, **kwargs)
" B! ]% \! I8 y% i& x
- T- y0 K/ l5 r8 T2 q2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/keystonemiddleware/auth_token/__init__.py", line 340, in __call__# k0 i0 d( \6 j
- n3 l; N7 x! S2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault response = req.get_response(self._app): _: V1 x# b% e7 D3 m, c/ N% w- r
" ]% g7 I- i4 ]! N/ u2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/webob/request.py", line 1313, in send
- @0 J& ?7 e0 M& \5 h, @' s5 _# Q. y) @5 @/ K4 c" O
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault status, headers, app_iter = self.call_application(! G1 i1 G9 m9 p5 V- E
+ W9 ?$ l, ^. M( l7 t
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/webob/request.py", line 1278, in call_application2 o8 Q" u; l3 z6 Z4 B* E7 E
( r+ O% l" r* Y8 d8 Y1 y- ?- H
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault app_iter = application(self.environ, start_response)1 Q2 r; l) O% u$ U, H9 k
, }) }- t5 v n i0 a
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/webob/dec.py", line 143, in __call__
+ e! w, [# C, W- G+ ^
, x; p/ ^5 \$ k2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return resp(environ, start_response)
8 z2 ?+ C1 q8 e) L3 y; I3 H5 `( [+ B M# q5 B8 m
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/webob/dec.py", line 143, in __call__8 Y% c: y- L- e n, J' p; U; s
' L0 H! l+ u) @5 L& P2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return resp(environ, start_response)
) q" F1 y: {1 T7 P; M
( Q; q% y7 I, l: v2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/routes/middleware.py", line 153, in __call__0 a( a+ H7 i& N
- L! t, U( m( |# _3 g7 Q8 ?( U, B2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault response = self.app(environ, start_response)' }; M! [3 ~5 y# ~8 K+ z
+ O5 J4 g; ]$ E$ j1 ^' P4 R5 D2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/webob/dec.py", line 143, in __call__
/ u7 r# V" x% t' g4 S) a7 r+ k; A
; |; L7 Z. O( A5 x1 N! F2 P/ L8 `1 Q2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return resp(environ, start_response)( O* A, Z" q+ T$ F' z" `) o
: Q7 C* I. \0 l7 g4 P- w- H
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/webob/dec.py", line 129, in __call__# N% Y; J* Z. y2 @. N1 @
9 P1 P. a) M* L# b8 y% G
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault resp = self.call_func(req, *args, **kw); w- B3 m: K+ ?2 h
& }9 {5 R6 W# [/ R# P2 a% i
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/webob/dec.py", line 193, in call_func$ T) r/ F. }- M5 E1 w* k
6 r3 n# J i0 [/ ~
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return self.func(req, *args, **kwargs)
/ `! d! Q' B6 r1 p7 m) K* q7 a/ s: d e$ e
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/cinder/api/openstack/wsgi.py", line 839, in __call__
' ?7 i9 {, U; i0 ]9 l# q" Z, \- M. K
4 N1 D8 ?' |9 |! @3 o2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return self._process_stack(request, action, action_args,
2 m; M8 Q7 r- T/ j. J8 e& ] Z |: n6 j% T) N
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/cinder/api/openstack/wsgi.py", line 900, in _process_stack
# u: S2 X; |7 p$ d; L6 u, A) T1 a
3 J) t( J- o2 G% `9 B4 j+ O9 n2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault action_result = self.dispatch(meth, request, action_args)$ n: \2 E1 n" W8 {+ `+ g) ~7 }
. U9 t8 [4 ^0 z3 \( U3 A( D
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/cinder/api/openstack/wsgi.py", line 995, in dispatch; o5 j {- t, v
( m# Q- i4 v, w \6 l8 T2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return method(req=request, **action_args)& U5 @4 Z3 z5 s$ W7 z1 J
* r G" x4 H, ~
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/cinder/api/openstack/wsgi.py", line 1160, in version_select
8 H4 m: \( k4 N8 p! C1 w1 r! k
: {1 L& s4 w& u; ]6 W5 x) Q8 D2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return func.func(self, *args, **kwargs)5 i6 o/ C8 Q7 B5 u' n
! f8 b1 q6 f& ^& W6 B6 N
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/cinder/api/v3/attachments.py", line 282, in delete; |+ W* |, z# t& y5 o
7 K& g% ~8 H3 b+ o2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault attachments = self.volume_api.attachment_delete(context, attachment)
$ v. X2 u/ A! d8 Z/ g; \
, P. t6 p {; Y. o2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/cinder/volume/api.py", line 2668, in attachment_delete
6 R& t3 A- m1 L3 o, G+ `; Y5 }, x9 M& ?! y) G5 h
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault self.attachment_deletion_allowed(ctxt, attachment)8 y+ ~- N+ z6 X( ~2 y+ Z9 B
# Z$ P/ H" D' b
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault File "/usr/local/lib/python3.9/site-packages/cinder/volume/api.py", line 2659, in attachment_deletion_allowed
% |9 k6 r- i) ^8 L) {, r
; ^! _. E- p& L2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault raise exception.ConflictNovaUsingAttachment(instance_id=server_id)
5 N' `0 t1 l" U, z5 T+ [" C+ f9 e0 q! F4 M; B) B0 ^: C
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault cinder.exception.ConflictNovaUsingAttachment: Detach volume from instance 4164eba5-b07e-4546-8d41-c4cdc030c396 using the Compute API' H% Z8 B4 X6 m7 y0 J
$ N p9 c+ U, z6 R2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault& z r d6 g( I* _
* W. i* _/ S& |/ u) _1 z9 g
: K% C' c& i8 u5 p& M& G
- r9 e; z; k/ j% Z& |6 U+ Z
提示我using the Compute API6 B6 d- o- U4 E% ]' v4 ~
于是我去设置如下的内容& S' k, @+ J; a8 D& p
controller节点" d R, ^6 j& D5 q' ]
9 M/ o, }; O/ X; H1 Q* X7 L! ]& j
vim /etc/nova/nova.conf8 S2 D; D! |4 ~
5 V* {& A, q/ R[cinder]; d( q, L" Y9 }6 c, e- h ]# Q+ q
send_service_user_token = True #添加7 \$ L* E0 b$ q, k
( d9 i6 |4 ` I C; _% I% m
. s. K7 X5 P' w% U
compute节点
; ?( E/ ?) p5 ~; e6 b& a0 E2 } z b! r' u0 P
vim /etc/nova/nova.conf ^" e/ z/ z/ Z
- m1 c; V: r- @$ |6 C# V
[cinder]
, Q S9 m( a! ?" w/ I+ W1 zsend_service_user_token = True #添加
1 V- e" {( A- B3 \) j6 m- c& j' S3 M/ x/ k$ S% o
2 v* E: Q# Y4 d* D9 F但是没有解决,还是提示同样的问题8 R7 |5 N% {" o( G5 T5 `
于是去查看源代码
' Z. K; A1 _ p' y
, Y+ X2 W2 P) F, ?. N1 @在/usr/local/lib/python3.9/site-packages/cinder/volume/api.py
5 j: i# N% V- u, V9 ?8 u
1 L( {' k+ N9 r8 `( |源代码如下
# r& i, X( m& T4 i. P3 Q: F- H4 h( g6 u/ o+ `+ w
def attachment_deletion_allowed(self, _5 B9 `5 L: h0 R, W& {: E) \
ctxt: context.RequestContext,6 R# v! L! J; n* b) @; {
attachment_or_attachment_id,
0 I1 R0 A& K9 [ volume=None):: O/ p- Y, S2 V5 y6 j' N( L/ f! \. H
"""Check if deleting an attachment is allowed (Bug #2004555)
; I6 E: D5 A: U- ^/ W
; D+ c0 { S& ~$ Z% r$ \$ n/ { Allowed is based on the REST API policy, the status of the attachment,
& ~" F1 j, p7 _$ Q where it is used, and who is making the request.+ h8 i" c( t0 Z/ U6 o! A
4 u3 c* c1 L- G9 h
Deleting an attachment on the Cinder side while leaving the volume
# }% t4 i0 f3 O7 X connected to the nova host results in leftover devices that can lead to
% Z% {( a6 k) P0 L0 j5 i data leaks/corruption.7 n! G1 u- m o, Q; C! v
: F4 v' B# C; N; e* U/ w; J OS-Brick may have code to detect it, but in some cases it is detected
9 G/ |$ d2 O( l! j2 w6 Z after it has already been exposed, so it's better to prevent users from$ [" O n8 ~/ P- E
being able to intentionally triggering the issue.
5 C7 @4 z! x4 q& o8 d5 `! ? """
( V& B2 p, p7 |% M; S" p/ v+ q # It's ok to delete an attachment if the request comes from a service6 L) Z7 B# P# ^, v
if self.is_service_request(ctxt):
1 q7 K7 y) V0 _+ M+ A+ K return& Z9 M0 ^/ n% G! f
; Y' u" D+ S; ^: P6 C* E" ^ ?/ D6 s
if not attachment_or_attachment_id and volume:
3 K/ j# _2 [: C+ }( \; s' M: \3 ~ if not volume.volume_attachment:
3 @; @$ r w r3 f5 \ return3 u3 Q1 a' G5 z }+ v6 k
if len(volume.volume_attachment) == 1:/ }) K% a2 G% j9 p s9 Q, I' t
attachment_or_attachment_id = volume.volume_attachment[0] O* m& T6 i5 h; U
3 h3 x- y9 d0 f8 }& F/ p9 i
if isinstance(attachment_or_attachment_id, str):7 W }1 i1 p. Y' B
try:
+ I& h& D) c3 Y. M attachment = objects.VolumeAttachment.get_by_id(1 s- `# Q1 j# `- Y/ X
ctxt, attachment_or_attachment_id)5 s8 a9 S+ k8 p0 J' T' |2 q1 u
except exception.VolumeAttachmentNotFound:$ ]2 U& D5 q* ^5 e' o6 i. q8 _
attachment = None
: {, k! ?$ S, K* f: ?) K else:$ U% t5 A A% U
attachment = attachment_or_attachment_id3 z9 ]* w. W' o7 o0 p% U0 q
+ B. W. [- C! S( v+ s; o' X if attachment:
+ _% ]9 Z+ Y! K3 n9 J, i* b8 | if volume:# E1 J) r ]& I, z7 W7 ~
if volume.id != attachment.volume_id:+ M+ |8 E" s4 _1 o: n& g+ d3 U) M
raise exception.InvalidInput(
5 a U4 q. c) ^1 ]3 V reason='Mismatched volume and attachment')
3 X, A J2 t, v5 S+ M/ X$ x
/ u) _9 h i3 I4 a: j9 I server_id = attachment.instance_uuid0 h8 S0 q0 U c( n
# It's ok to delete if it's not connected to a vm.
( C. l+ ^; I4 i6 X/ J5 P if not server_id or not attachment.connection_info:- ~+ W7 _6 Z* h: v
return
+ l' s. U! i- G
0 {! ~) @$ n8 Z% l" i# l/ R9 p) i volume = volume or attachment.volume
7 c, c& `; Y; X' z5 R nova = compute.API()
( g4 U6 y6 b( F+ O! y y2 `- F LOG.info('Attachment connected to vm %s, checking data on nova',1 |! D a3 W. \; k* Z3 f
server_id)! i, w* j$ O' @. L$ j' J
# If nova is down the client raises 503 and we report that
, a7 D4 F( p$ |- N% n2 ?/ ? try:8 y- C0 {! ~+ Q. p" p# o2 ~
nova_volume = nova.get_server_volume(ctxt, server_id,
: ?3 _& f; [; n1 M volume.id)2 v3 r& E W* G3 O" B
except nova.NotFound:, n7 Q+ f2 p. O! |5 f
LOG.warning('Instance or volume not found on Nova, deleting '
6 T) U& |! `0 q" a 'attachment locally, which may leave leftover '1 L& v/ L! {, b/ n
'devices on Nova compute')/ E; r1 i/ [5 U/ y4 _* T
return
/ A p$ i; a7 E4 M+ t" H) K5 K' \9 A& G/ Q. {
if nova_volume.attachment_id != attachment.id:
: f' _$ M6 s1 c; f; ~5 N' R. j% J LOG.warning('Mismatch! Nova has different attachment id (%s) '5 p+ i1 `( {9 }! m, v
'for the volume, deleting attachment locally. '* P' R- J- }( K9 G/ E5 v. \$ S
'May leave leftover devices in a compute node',3 S( y2 ~$ w8 I- F- ^% n
nova_volume.attachment_id)
6 m7 w2 g0 a- E0 A s return
: D# ?- N! Y% q0 Z5 I else:' }# i3 K; u+ X/ `& V0 B$ w2 Z
server_id = ''% y) u7 h- y9 V, n: @* S$ Q
7 |4 r" V, c" w) ]4 |& F2 F- W
LOG.error('Detected user call to delete in-use attachment. Call must ' Z' Z$ z1 r) Z5 ?9 r0 g
'come from the nova service and nova must be configured to '
) H0 D' }- b5 J( D 'send the service token. Bug #2004555')0 z0 e' H' J2 B3 P. s5 y3 \
raise exception.ConflictNovaUsingAttachment(instance_id=server_id)
; |6 A' @, P9 r" G6 p( Q- [4 p4 F5 [6 J- c
修改后的完整的代码如下. k# I- p# M1 q6 _) A; R. T
0 O$ V1 u: Z+ gdef attachment_deletion_allowed(self,
) Q6 P% j) u! o7 i4 p" U$ t5 P7 J ctxt: context.RequestContext,0 p: ^& R6 B* ~% g# x$ _7 p
attachment_or_attachment_id,) ]. m, s, q4 V
volume=None):9 B3 d9 ]% W3 j# i+ i4 G* o) o
# 服务请求直接允许删除" W* }4 H2 M( G% {5 a: g; y3 R
if self.is_service_request(ctxt):
; t2 N- k" f. W# Z) p return True
; p G" o0 z- V: k9 E& }9 `% t) r/ a
# 参数验证* Y$ _1 G3 T% c! K- L" U
if not attachment_or_attachment_id and not volume:
& a& ?, l4 ]- C7 K& q% @7 i# q' k raise exception.InvalidInput(reason='Either attachment or volume must be provided')
# f$ u6 G1 o8 l% F, W' H0 C1 Z: ?9 d+ G8 D- Z$ h5 d! ^
# 获取 attachment
& {) Q7 a3 L& @4 I$ a) I if not attachment_or_attachment_id and volume:4 n q- W+ |1 y. {
if not volume.volume_attachment:) K- p3 M8 w3 o2 F# |7 o
return True3 w7 m) ^: ^2 p' J+ z9 F. F
if len(volume.volume_attachment) == 1:" G( P* s/ N3 {+ m8 w9 Q) E
attachment_or_attachment_id = volume.volume_attachment[0]: E6 C1 x' S: G+ _; ~8 H
" L/ i) \7 x) M) C8 u
# 获取 attachment 对象7 h% b" t6 k7 B) T. z- r$ w% O
attachment = None
% q" s6 m4 b5 s* @ ` if isinstance(attachment_or_attachment_id, str):) Q( e" e* [1 ]: Q: K
try:0 X% h, J/ K% L/ K5 g3 s. L: N
attachment = objects.VolumeAttachment.get_by_id(
6 ]) Y4 P( Y O; o) T& N ctxt, attachment_or_attachment_id)
- `, P j H1 i; j except exception.VolumeAttachmentNotFound:+ Q" Y" V* a3 A# F9 A2 |
return True # 如果找不到 attachment,允许删除. m4 @4 n6 n4 w# b* Z
8 r# t* r7 N% Q$ o else:
) U) h3 K0 c s8 `( \ attachment = attachment_or_attachment_id
- ~8 a3 j2 A! d1 t; g! c
& i! i* V5 Y' _, b1 W1 W* {6 E* L if not attachment:
2 m/ Y: F J9 x7 |. f return True. g& ^' n% }8 x/ h2 A
: T8 N7 ^) V, L9 I. }! i
# 验证 volume 和 attachment 的关系
) K# S# |* ]4 Y) `( p2 q5 A# u8 Q if volume and volume.id != attachment.volume_id:
; J% L, R0 f Y# G raise exception.InvalidInput(! Z8 I; {& J& Z( S! s' H6 _
reason='Mismatched volume and attachment')
. N2 z. e$ [$ V. C* b; q4 }) ^0 y* h% A
# 检查是否连接到 VM# s' g6 q* m: f2 U+ `8 w
server_id = attachment.instance_uuid: ]6 I5 S! u; n3 L: ]2 j. S
if not server_id or not attachment.connection_info:; o4 `1 [3 Y$ _ j
return True
: A% g! `( l% v2 Q* |2 _( n
?2 C6 ]" f2 }' W # 检查 Nova 端的状态
; \/ M) n. K b9 k9 B& `, j volume = volume or attachment.volume
0 u- m/ E' q2 `0 C& M& \ nova = compute.API()
1 ?4 ^# E0 X1 b# x" C% b- I try:% J" f$ T5 _6 V9 j1 e3 `- ~
nova_volume = nova.get_server_volume(ctxt, server_id, volume.id), d5 ~6 z; ~3 i: I# V& ]
except nova.NotFound:+ v( l6 X1 i$ p
LOG.warning('Instance or volume not found on Nova, deleting '
8 Y% ?# m4 ?; y7 o$ Z 'attachment locally, which may leave leftover ') m$ x& f( z+ I$ o6 O
'devices on Nova compute')
" G: Q7 J& \( D4 b, S& a return True
: C/ s0 `$ z* E2 s0 B
5 c0 K, h9 a& Q8 P& y if nova_volume.attachment_id != attachment.id:
$ b* W# K) e3 e1 ~" U LOG.warning('Mismatch! Nova has different attachment id (%s) '
5 W9 D: m T& K9 Q 'for the volume, deleting attachment locally. '8 i! d! i9 d7 K
'May leave leftover devices in a compute node',
: C% _ h- k9 Q1 ^! J6 h* L nova_volume.attachment_id)
1 c/ Z4 v2 f5 F1 ~/ B: N/ h# g, M return True4 {: Q2 g6 |9 w
9 q0 M6 w" a& U: m( G
# 检查实例的其他附件
+ u% D1 V9 l, J3 S! p try:
1 `1 ~3 A3 W* O. ~: W E attachments = objects.VolumeAttachmentList.get_all_by_instance_uuid(
& q7 }; T* y4 ` ctxt, attachment.instance_uuid)! ~& S ?3 l% z J! \1 z
if attachments:
; F2 j5 J+ E) `& K1 J5 x LOG.info("Instance %s has other attachments: %s",
; H1 ]* a3 H% k/ \& P% d& c0 }7 K attachment.instance_uuid,+ `0 F6 q s# E7 E9 H' |1 _
[att.id for att in attachments])2 U& Y. B h. Y( Q8 P8 ]2 ]7 B
return False
* R) K4 ~# U( h. o- @ else:. B' [2 s) c5 i/ y9 ?! R
LOG.info("No other attachments found for instance %s",
# F3 b' M# Q5 Z$ p attachment.instance_uuid)
$ V* d0 t# F. M; J0 Z3 A return True
- d9 K# C1 e4 V$ j1 L. P# L2 V except Exception as e:: d6 O0 \3 M" a: V( p1 l0 @
LOG.error("Failed to retrieve attachments for instance %s: %s",
( c+ y. C4 F3 U& t B+ E attachment.instance_uuid, str(e))
/ e' H" h* |5 S4 K4 s# X raise exception.VolumeBackendAPIException(reason=str(e)): ^8 Z, a' w8 q* I% P
' a: p7 U; j! o' R Y% s
) c4 e5 r2 s0 \% j1 u- M最终成功解决,但是这个方法不是很严谨5 d3 n+ P1 T: b+ X
$ v1 g1 m5 y' f6 ^. X( ^3 N9 k
2 {6 V0 l9 B- ?, m/ J
|
|