|
|
解决办法(不太严谨)
% o Y, L& @ g0 ~. g根据日志提示
" K1 I' Y3 Y6 W$ _% `' D4 E; D4 @0 \( i! w1 Q
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
8 ]. p0 {- P! e& C2025-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 API
- H7 U2 H# ^- V. c. u/ G4 t2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault Traceback (most recent call last):
- R$ E Y- Z/ d' J7 Y2025-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__
, }: K1 W$ f8 S4 F' o1 L0 D4 c- |2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return req.get_response(self.application)
: }. G) [2 d3 p2025-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$ G: b9 w& E* O! ?' [0 i1 g
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault status, headers, app_iter = self.call_application() \; {# v% j- ^" g9 h! \3 _' G
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_application1 G: ~0 V+ Z% h* y' D
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault app_iter = application(self.environ, start_response)
. W- B6 z+ u6 a c. }4 M2025-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__
$ W' _' k8 W |! ]: c: k3 o# o5 o1 ?" _4 q8 n$ A4 M5 ^
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return resp(environ, start_response)
! d0 U$ ~* G& \$ O. {1 P/ B7 R, {' D4 m- U- }: t1 _/ i7 v
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__
8 I& g* Z t2 ?7 [2 l: ~! _% ~' T2 V
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault resp = self.call_func(req, *args, **kw). ^( S" {7 e. A3 K* x; j0 \
U( }6 H: y5 w7 a( F2025-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
0 j* |! u% L% ^* t- V' \6 O
8 o& X2 s! T3 I9 P6 g7 C. |7 C2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return self.func(req, *args, **kwargs)" @5 o9 U7 b6 s3 W
& f: z- l$ b- o q
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 @. Q& h- q3 C/ ]
" h2 x2 W# H4 f8 Q* Q2 h3 ]
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return request.get_response(self.application)1 s0 v( \; x x
) S8 `. Q# z# X4 s2025-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
6 ]% U" n& \0 N% {6 }2 `. M
# c" |( Q- n% U6 i9 K7 p2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault status, headers, app_iter = self.call_application(- z# x3 n4 l( n
) K% W( Y6 J1 ?3 U3 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 1278, in call_application
9 O. F B8 o" B7 L5 z; Z# z# d. {' c7 b! ] `0 i
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault app_iter = application(self.environ, start_response)6 }( M' t/ O3 q- O/ n
2 X5 G: V- Z) t4 m' B* n
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__
2 Q' N3 f/ n6 \) N- I1 T0 J
3 j' F- s) |/ E! x! g+ C$ E' k2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault resp = self.call_func(req, *args, **kw)
. C( q0 G# c% Z0 U$ C5 R/ B3 u' i' `0 j/ k* p9 i& r5 x. { X
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" H' k8 t& K6 E
$ s6 r8 ?& q; J: { a- |# O9 q& x2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return self.func(req, *args, **kwargs)( t& T. h* @+ q: m
) a4 n/ w' D# ]! J$ D
2025-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__
# H$ V+ e7 c) V7 m: t( [
( K! B+ r$ r- K. L3 |) ^7 U2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault response = req.get_response(self._app)
6 b- Q) C% K2 O% r" p5 g4 U* Y9 \! 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" B3 k4 m) {" w o: S
1 k% p" C" U6 |/ V8 `* q: @
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault status, headers, app_iter = self.call_application(
; a ?8 C1 ?6 n: B X* ^
; H/ `6 R5 E/ N( c J, r2025-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
9 f5 [* L8 h1 j- \7 e& P0 u0 M C- b& `) `0 J
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault app_iter = application(self.environ, start_response)
* F" k2 D& k, F% T7 K3 k" Y0 a# {8 N! 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__6 z2 I8 @; w- \9 _/ k+ n5 X
% o9 z3 y0 w7 X9 o: r2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return resp(environ, start_response)1 c/ z1 b( s6 f% Y' {
. e0 t2 \" l! b+ {: k0 N
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__
: \& ]' h( l* {% ~* F$ I% C# U% h) u( a& c2 g
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return resp(environ, start_response)7 u- x% ]6 r' \! E+ ?$ M, q
% b+ Q$ v: v' }0 p
2025-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__
# K. j! i+ V# u) I5 M" U7 \6 y- \" P) V* m- A0 ^* a. l2 S/ N
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault response = self.app(environ, start_response)
6 R. P" J8 D2 p, g I% F
/ A- L0 |! L' U1 L2 E/ |1 q- C+ v2025-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__ G8 R; \( h( P) F: k( Y4 u* b
3 Q% W8 c) T' U7 v& A; d# s2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return resp(environ, start_response)
( r, X3 Z3 F) l. a; |
/ r6 G. K& r0 Q" W) j: i2025-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__0 f% R' z0 G; c. J3 y; `7 c
2 Z& }7 W) n! P( \; T7 O6 y" d
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault resp = self.call_func(req, *args, **kw)
. b8 X3 F; ~5 p. o# d6 b
2 u/ b. @$ E+ y2 m# ?8 t/ p2025-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: z! y3 @. \' e2 a6 y3 G
6 s# [" S7 @1 S# M! u2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return self.func(req, *args, **kwargs)
& _5 f) Y" s n8 `. ~ Q4 m
" g' K5 \# n" t8 Q1 h2025-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__
: U; P7 t3 O' L2 s4 t- }
$ x: D3 j5 m8 l- r. u3 o* l3 o7 |2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return self._process_stack(request, action, action_args,
) j% @6 G. c( @9 J! J4 Z
& L9 }% F' i1 @9 g& k# Y; _. c2025-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_stack4 X& {1 A+ t7 C
1 v% J H0 N, e5 r2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault action_result = self.dispatch(meth, request, action_args)
* c- r/ P0 W4 c) L/ O+ y! |. h4 H( [6 Y# S- n8 q1 i3 M
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
, Q( g0 Z5 }. `6 L2 ^% x- G, |/ C$ t/ D ]2 i# U/ z. l% U
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return method(req=request, **action_args)) v1 B( W; D( ?) U( C1 K- P; E1 W
1 `6 |* l7 g# W6 w* j' }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/ ]1 g. x4 N9 {/ I' U$ @1 W# f
/ S2 t/ A1 k+ X9 i+ k) Z
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return func.func(self, *args, **kwargs)
/ u+ N: @2 R4 c! \) g7 A; _, E( u' y/ i$ ^; 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
2 b' m' W0 D3 ]+ c8 X
9 `1 v3 W/ j4 X9 m2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault attachments = self.volume_api.attachment_delete(context, attachment)
7 w9 g9 o2 D3 j& i' s6 N, j4 M2 X# [* L9 j* n& T; U5 I
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 2668, in attachment_delete7 Q1 C+ L: S: B7 k5 o! {/ a
! u6 Y) u" j+ Y( ?
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault self.attachment_deletion_allowed(ctxt, attachment)
1 L) S2 \, ~, B$ _* B; v6 R' Y
, V5 I$ r( {. m f" H0 D8 m+ N2025-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
- B) D K: C- [
) ^2 s3 x- k8 |: x, ~, l2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault raise exception.ConflictNovaUsingAttachment(instance_id=server_id)
8 t5 e( g: P* }' M3 v
# _* f1 H' p% r2025-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
( t6 ~/ t A! [$ I& ?: R p3 u) X" Z. b8 r' H; u# \
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault
8 b: q3 {5 W! U: r( P6 d; y
( }% _' ?( D/ F1 c4 R
9 M0 A1 I, s: C
' i; P% o3 ~4 J' [0 k提示我using the Compute API
) N5 p' c0 C1 Y8 M1 U. a$ F2 N z于是我去设置如下的内容% M/ c0 _; l& D. `4 B8 `" ?7 ]( t, F
controller节点# v# l0 l: J; u# n: N
0 p" z/ Q& |0 V ?" hvim /etc/nova/nova.conf
& @% ?- N( O/ ^" e; a1 V2 D2 w: c F$ Y* v8 p! P
[cinder]
* e- i9 H" [3 l% v! Zsend_service_user_token = True #添加
4 V, \1 `* I7 N; E3 ^9 H( p* x$ W7 @/ I
( i" |; A* H# O) v* b8 w! u8 \) `6 Y
compute节点
, X: \0 A. q, Z3 H2 a
2 m: g; C$ T' m& Q0 Cvim /etc/nova/nova.conf+ x8 j+ { U; l: R
' W/ o5 d, N. @3 t
[cinder] |1 x' b0 Z+ ^
send_service_user_token = True #添加' F* t) [8 X4 G1 n: u0 {
# S6 ]; T3 Q% ^3 ~- T/ y+ u* D( }* W* b }+ G
但是没有解决,还是提示同样的问题, G) f# @# n. {9 F: C2 E% o$ Q2 B
于是去查看源代码
/ ?3 G2 K: Y2 E' S: q( s4 f
+ ^5 x, k. i2 V$ O% O6 T在/usr/local/lib/python3.9/site-packages/cinder/volume/api.py
7 y9 L9 f$ m0 E( ?( I1 _5 z
9 W' A3 m, M9 K3 g9 w! `源代码如下) w8 Z" R. q9 ]
7 g) u. j/ L# Y( W, Rdef attachment_deletion_allowed(self,: }6 G/ V1 W$ }3 f
ctxt: context.RequestContext,1 E/ e* m& }3 A% x. p/ Z: i% Z
attachment_or_attachment_id,2 r: @6 ]9 _" b
volume=None):
7 e# |$ E- {: I9 u4 K6 z """Check if deleting an attachment is allowed (Bug #2004555). _! W# e# X" G3 B4 V
! V! H3 J/ {( @& x
Allowed is based on the REST API policy, the status of the attachment,
, P3 P! V$ A n. D where it is used, and who is making the request.$ V- a9 I4 N* h) y5 p, B+ t! d
1 o" B( T7 L; ?9 X- `% F# ^ Deleting an attachment on the Cinder side while leaving the volume! F Y. F/ n a' X7 G
connected to the nova host results in leftover devices that can lead to, J+ e+ Z" b" _: P! T. c: u, N3 J# p
data leaks/corruption.: _/ B j/ v& \/ ]
i8 l" a& f$ J6 \( ]8 v* y OS-Brick may have code to detect it, but in some cases it is detected& F( Z4 w* v3 e" m# D, x
after it has already been exposed, so it's better to prevent users from
- ~! v; W, L0 j( x0 @) X! ~ G- N4 W being able to intentionally triggering the issue.
; M4 A& V5 N) u$ B """
( Y! p0 `' w+ y4 w0 K) G% i # It's ok to delete an attachment if the request comes from a service
* j, e; [0 k! t if self.is_service_request(ctxt):; }1 ?5 w; h! J0 P3 j/ r: P
return3 m0 Q2 U% w$ Z, u9 I1 a
3 S* [# @& d) w& r+ ~! ?) e) I if not attachment_or_attachment_id and volume:; S; {% {$ s3 u8 X6 f2 ~' v0 R
if not volume.volume_attachment:: q' P# ]& \' N! x
return/ y3 p: z! E8 W0 `8 _4 u) q+ F! s
if len(volume.volume_attachment) == 1:3 J* n* U3 Z7 A- _! O4 `5 U7 i
attachment_or_attachment_id = volume.volume_attachment[0]! y; u* F9 [" B; [* s% j
5 _( r b+ f N2 p+ f0 Y) m
if isinstance(attachment_or_attachment_id, str):- S- N! G v# I% ~: a
try:1 C0 ]0 l2 L$ U: O( T) t' z' W) J
attachment = objects.VolumeAttachment.get_by_id(
8 ?" `: g* _; d& E/ D' r- A7 r! W ctxt, attachment_or_attachment_id)
. t$ M0 F' G5 L2 R( U$ K except exception.VolumeAttachmentNotFound:
Y! A0 R; c1 {0 k attachment = None
. W$ c$ F% ] Z8 ]0 o( N6 l7 _, B else:! W6 {4 _$ T; _3 k
attachment = attachment_or_attachment_id
, S3 @2 x% p$ J' K9 K
/ g: V$ e0 r0 O" L7 L6 H' F if attachment:) w/ x8 B) l( c: R8 B
if volume:
& A' M1 i& h6 J; U7 s+ X( E8 e if volume.id != attachment.volume_id:4 m: f! D9 d4 c9 y
raise exception.InvalidInput(( d, _; U( X [( z/ V0 }
reason='Mismatched volume and attachment')
+ l" r. k# A$ k# S0 b. O0 w
% J& ~1 h) A! s1 E3 A server_id = attachment.instance_uuid
+ i: h3 ~/ ^+ g1 c" K' K # It's ok to delete if it's not connected to a vm.. U2 G0 v5 Z% B& R0 O
if not server_id or not attachment.connection_info:+ F) N& u/ K' j( H% i+ _- ?
return
6 l8 e l7 c0 g/ ?4 ?: F4 d* ^
) h f. i* [8 r5 A volume = volume or attachment.volume
% F) ]7 C9 A1 X* h& l" ]; w- r( Q/ @ nova = compute.API()
0 T7 e2 k' d E4 R LOG.info('Attachment connected to vm %s, checking data on nova',
3 S% [6 j" m( M8 o* M# c$ p server_id)6 P( _0 x2 N4 f7 E
# If nova is down the client raises 503 and we report that
( f7 b2 h9 o. S, ` try:: v0 Z! U6 W% ?7 u
nova_volume = nova.get_server_volume(ctxt, server_id,( `$ J7 |& ^+ k1 {
volume.id)
& u0 {+ P. K6 ^# K( Z except nova.NotFound:
+ \6 m! M$ M7 O. ~8 [; B5 c$ R8 { LOG.warning('Instance or volume not found on Nova, deleting '/ @0 ?" `0 [# |
'attachment locally, which may leave leftover '6 [* b4 }4 G _3 c \
'devices on Nova compute')6 p Q$ G1 m+ `* y7 v8 h6 A
return
! ], R6 u) l8 F. M4 a+ t; L9 S; h8 `& v" g: d
if nova_volume.attachment_id != attachment.id:- f2 k8 _2 M7 D- C( W2 ?; e
LOG.warning('Mismatch! Nova has different attachment id (%s) '
- e% Z* `8 R/ d/ k* [) @$ H1 k 'for the volume, deleting attachment locally. '
5 _! @& H* S7 o B 'May leave leftover devices in a compute node',
. F/ \* ]% b2 f% h% r8 b3 ?1 @ nova_volume.attachment_id)/ w/ |$ p4 c5 E
return
5 L# ~ v5 A3 H3 S; t else:
+ W+ A. U C* p7 S2 g# a server_id = ''$ y6 l t' e: i- N. `
9 N1 g3 m' r$ O# M
LOG.error('Detected user call to delete in-use attachment. Call must '9 x7 I, G9 }% v& q ~
'come from the nova service and nova must be configured to '. k" u* \& ^# A& X! N! p3 ~
'send the service token. Bug #2004555')4 h6 k' ~( j8 h% o Z, \% N
raise exception.ConflictNovaUsingAttachment(instance_id=server_id). }7 B0 n( r8 p7 G9 f6 Y5 p! X7 N
1 i; }6 E. P' |. ^& v( E# x* i
修改后的完整的代码如下2 u. ^$ I) a D, k
. M8 Y' t* x+ L
def attachment_deletion_allowed(self,
/ G4 |: L% ]! T+ X2 O) E ctxt: context.RequestContext,
2 X# f3 u( {" a+ f- _ attachment_or_attachment_id,
, r5 @; X" P6 j* r4 a3 ~+ [ volume=None):8 _& Q6 @ R1 w% j. y8 F
# 服务请求直接允许删除
& e, v, j% q; N- C if self.is_service_request(ctxt):) `* ?: w1 c( o; g% \) f
return True
, B# g9 [0 W8 d3 A% s
% V) I( l7 a6 F& @8 w # 参数验证9 A4 x# V, W& a
if not attachment_or_attachment_id and not volume:' l% @/ h1 e, K
raise exception.InvalidInput(reason='Either attachment or volume must be provided')# Y; S! h% G2 n0 V8 s( l
* G! Z+ Q- P0 ~0 S) K # 获取 attachment7 S0 u. L9 e9 ~
if not attachment_or_attachment_id and volume:
- u$ b1 R Z. E0 z: A Y* P if not volume.volume_attachment: P1 I I. G5 Y: U& k' x/ C- u
return True: m5 q+ C# w2 H9 N$ [
if len(volume.volume_attachment) == 1:' c3 H/ P5 R7 w# u! @ O/ Y$ x
attachment_or_attachment_id = volume.volume_attachment[0]
: I: m" i5 y% n8 {" M: x4 q( E! k# V
: c) C) F0 @9 x # 获取 attachment 对象
, O h) C9 t7 {7 b6 s5 ?0 w. ^ attachment = None
5 W8 F- ]$ U# O if isinstance(attachment_or_attachment_id, str):6 I: D# g! c. r. [! u0 r
try:
% J [! E6 c6 h! ]" \4 Q attachment = objects.VolumeAttachment.get_by_id(
) |4 k* i0 o) m3 t2 E. K3 K ctxt, attachment_or_attachment_id)
; W* @/ z9 u1 Z3 D6 O [8 ? except exception.VolumeAttachmentNotFound:' [2 q7 U, ?/ b
return True # 如果找不到 attachment,允许删除
5 w2 I8 H4 F2 @8 F: p, i% [% f$ Y" H/ K; A+ V( Q, r) R( j
else:4 L( X6 _2 m- O# F
attachment = attachment_or_attachment_id9 Q- X7 Q0 y; A" n( f. k. h1 q3 E
7 W9 C, F4 e4 Q: A2 t( x, A, U
if not attachment:; f7 r3 V2 }' T, T! E( H" b
return True' H r, l1 ^1 D) F( ?- f* c! G
9 E6 ^8 r2 G0 a e& G
# 验证 volume 和 attachment 的关系
" y4 k, D! M! R" S/ } if volume and volume.id != attachment.volume_id:
3 \5 p2 v: o9 w raise exception.InvalidInput(
5 Y/ x, d+ ^7 O4 G1 }" g5 j reason='Mismatched volume and attachment')
3 G5 B1 m; y$ G
! Q6 S! g0 R ^' n# T) I9 N # 检查是否连接到 VM5 ?" A: n V; ^- d5 F2 u
server_id = attachment.instance_uuid8 S; F! R/ L" b
if not server_id or not attachment.connection_info:
2 j4 t. f0 u! D% z return True
0 e$ W7 t0 ?; A) ^, ^& E/ J+ _' K3 x* Z
# 检查 Nova 端的状态, L3 i; B1 y& T) @3 |
volume = volume or attachment.volume
( O" @* u4 `1 F" k nova = compute.API()5 B" m* W. Q: M
try:
: p' u: [; e. U nova_volume = nova.get_server_volume(ctxt, server_id, volume.id)
1 [+ x m9 F2 t9 s5 C, _0 c except nova.NotFound:
. H" |# h0 P. A* r LOG.warning('Instance or volume not found on Nova, deleting '8 e! s* K3 s+ W$ u4 k9 }2 ?2 l% ^; k
'attachment locally, which may leave leftover '
6 {8 ?( r; H8 K 'devices on Nova compute')5 S$ `; d1 _* _
return True
3 i T2 T" C1 r/ u: J8 b" S
7 l1 F3 x( |1 b3 m8 n( V0 _$ z. ^+ y if nova_volume.attachment_id != attachment.id:2 |! e7 H1 }) [7 e
LOG.warning('Mismatch! Nova has different attachment id (%s) '
0 `) a1 |( h6 M, t: Y* t: ^ 'for the volume, deleting attachment locally. '
; u8 ^5 V+ M2 o6 D! a5 g" I- J0 G 'May leave leftover devices in a compute node',6 D; [# o* a6 Z- c0 [% y
nova_volume.attachment_id)6 Q$ l. p, Y. c' _' O) p# v$ s6 m
return True
- Z" U" I' q2 Q3 h O8 \) q, Z. @& z8 M
# 检查实例的其他附件3 E x' g4 m+ @- s4 c( c
try:
. s& `8 D, G7 R+ _ attachments = objects.VolumeAttachmentList.get_all_by_instance_uuid(, @( ~3 J# \6 o( V
ctxt, attachment.instance_uuid)- @/ w* v& M r: w0 [# H
if attachments:
- @( o( M. c0 s" e# S, a LOG.info("Instance %s has other attachments: %s",4 K7 @1 Q/ C; M9 c8 \! j
attachment.instance_uuid,
: a$ p/ w, v' T* c( z [att.id for att in attachments])
% G0 A1 m- F" ~& c5 N8 _$ t% g1 D return False
# Y2 P7 n) I- ], u else:% N0 K0 q9 V( C
LOG.info("No other attachments found for instance %s",3 }- F# T, R/ R* g- e8 A
attachment.instance_uuid)( w" V* G, `8 ~8 ^1 {8 b% P
return True
/ G4 {8 ^; s( f& }9 F a( S8 r except Exception as e:+ K# Q& y% r/ v. N k; B* D1 X
LOG.error("Failed to retrieve attachments for instance %s: %s",$ Q( w0 y& b* x+ f+ ^
attachment.instance_uuid, str(e))
' F! C; p7 d c" J raise exception.VolumeBackendAPIException(reason=str(e))
; [8 |9 D2 U" s9 I- P
/ a+ u- G4 o8 x7 D: t3 E6 P. r8 d( n W5 |: C
最终成功解决,但是这个方法不是很严谨
" s* _7 h, J! C* e2 _; D+ U3 |& }" W4 ~" o- ]* j- O( ]! W |
3 p" R4 r( h( N2 O& U. q- A |
|