|
|
解决办法(不太严谨)8 i& _2 v; b' _( v3 n
根据日志提示" E, \, h3 k' w8 Y$ O$ B2 g
9 M8 q# h" E8 i7 W0 Q0 D
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, q6 v' U# [) r3 `& L
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 API2 @5 z* X0 b9 B2 z' k8 m
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault Traceback (most recent call last):" o4 |' ?5 ^. v- |! j1 T( s. e% e) J
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__, @# D: y" ^2 @+ t, T2 Z
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return req.get_response(self.application)- A7 Y5 Y. S3 \8 l4 Q" Y$ c8 o
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- @: S9 W3 @. G
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault status, headers, app_iter = self.call_application( |8 C% P4 Z5 U$ V1 Y! I# U
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 X, L" y( K' C7 p5 C
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault app_iter = application(self.environ, start_response)3 l9 w" ?* X- N8 v$ ]3 Y0 O
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__9 c& v% T) J5 e& Q* i0 I
8 u' P3 B5 n- r# y
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return resp(environ, start_response) A# s- t# l, Y/ A0 z. c
* A0 E7 ]/ c! P% 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 129, in __call__7 n' J' H+ l" \$ F7 i0 j0 t
4 y: y6 Z0 Y4 [9 X9 }. y% o2 K$ L2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault resp = self.call_func(req, *args, **kw)- ?4 |, ~0 B S" J2 @
7 i9 ]; c7 ]* T" W$ h- g
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
# p' i9 q6 x* K2 \3 P9 X9 ?- a" G' M! Y& O1 g+ f9 p* S
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return self.func(req, *args, **kwargs)
- Y) ?6 k" z1 F9 }& H7 A; Y+ A b; E' M3 T, }& @
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__
& U0 ^7 T: T& C) ^+ k9 C a5 J+ b, D, x3 z3 Y1 k" _
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return request.get_response(self.application)
A1 X: A8 ^7 I5 q& \. s$ s7 \
( H# T# i- A+ F! J3 f4 C. B, J/ c2025-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
5 ?3 j/ r6 W2 V, x1 J9 V6 n# W# V- }* B$ O" v
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault status, headers, app_iter = self.call_application(# I6 L/ ?+ C% P% ?
' h3 }) }+ t: ^; {( l2025-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_application3 r) d0 V$ o- E
1 E6 l; ^) S& c% I* ~- Q
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault app_iter = application(self.environ, start_response)
b0 j4 M. T' v8 s( ]) j9 G/ {7 d* I) O/ O: w! U
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__* m- L6 W% g5 W" {* R5 g3 o
+ `! L; m% W3 V# [/ t2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault resp = self.call_func(req, *args, **kw)
( L2 q* E+ W% K) a0 _: ^$ ?3 ~
8 _" @# G; q* m" q3 J; s: 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 193, in call_func& ^2 o4 Q3 y; B, L- u
" h+ z6 {7 W; q0 |2 n, W6 z6 ?2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return self.func(req, *args, **kwargs)
1 I8 O( T: n8 T# b5 i; j, a+ w8 i' L6 k& C9 V5 C2 _
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__
R! w9 @( W: w V k+ {0 H5 t
6 ]4 b7 Y! I+ [0 M7 O8 M8 d: b. A2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault response = req.get_response(self._app)3 |0 `' ~+ d$ T$ L) T. L. g
$ V( @5 ~& y: J$ x2025-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$ v, u! `; n# {- l: i- q, e2 i+ c
p7 l. O) c) q1 ?( h0 b' h
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault status, headers, app_iter = self.call_application(% G# V1 I; q; T- w/ W1 x' A
7 O: c5 J0 D! `+ K$ }' W2025-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_application8 W& |, n; L! }1 a2 W$ ~
- ?0 X2 p# o! C9 M7 i$ p& ^) H6 G' a
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault app_iter = application(self.environ, start_response)
. U% H0 s- Q3 J4 R0 P6 o5 x( o" E
3 g- M/ L! u% E& k) F$ q2025-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__, F, F6 p/ H: k! i$ n
% s; j# ]* P4 t$ H6 }4 Y7 T7 Q2 U
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return resp(environ, start_response)
- ^% I1 b/ H6 q7 F( ?- q" D! O$ v2 ~8 @2 z" c1 w c8 _: O
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__& k2 d) o% ~) ]# L3 F# @: K( ^- s3 x
$ Y" f( `/ Q! R& t$ R$ ]
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return resp(environ, start_response)
# I/ B" K _: ?; v
) b/ j: V% L' J# s7 w1 v6 ^8 X2025-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__- Y' b$ Z4 W! ^
+ x5 }; g' b4 V/ Q4 i
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault response = self.app(environ, start_response)8 s; w7 l; G! z7 R
, g* ~+ y! y1 m( 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 143, in __call__
1 N& Q8 \( m& M5 n
0 p4 U7 J: |! ]6 T2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return resp(environ, start_response)
( ? j3 T) s$ E3 E1 L; T' H; S& m1 d$ `7 Y; 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__. ~5 j1 X m4 w' R! X. `
9 T1 }/ o. x. w7 i. m: J
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault resp = self.call_func(req, *args, **kw)
8 y4 }, a4 r, G' _
/ j: R' Q- z1 r* | l F/ 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 193, in call_func& D1 C! N1 X) P& ]3 V7 U: K
8 [& A4 r1 ~ A5 U9 f6 B8 R' ?2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return self.func(req, *args, **kwargs)+ Z; E. q2 x* G0 d9 \
2 r8 k3 ^& V3 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 839, in __call__- e. h1 }& b1 {
- N$ ^" u. P @+ F
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return self._process_stack(request, action, action_args,2 O8 t- f3 O' y% r2 W8 W% W
+ h" ~9 J0 _- ^: d i
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
- [. T4 y& n8 W7 J5 o0 u0 B D( E( q4 G8 K, k
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault action_result = self.dispatch(meth, request, action_args)5 q" V4 W$ t* u. C( a% a2 g
& a+ ]( u' d7 A7 ^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/ i* s0 W$ k9 A" `
1 T( q/ }" D, _3 K0 }! s2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return method(req=request, **action_args)
2 q# _9 j3 [; M$ @# M1 l% I3 [+ d9 v4 p* g' R
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; m/ h5 k; W$ j) f5 ?$ H0 [6 L+ W
0 I/ L% Y. f9 [/ K# a9 K
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return func.func(self, *args, **kwargs), [" v, x6 O8 C7 k, K4 |3 l" ?
/ F4 q" x) Z6 }* h$ i' s2025-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
% x8 K" j5 k7 q& c+ ~: F! v4 d0 d, x0 z
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault attachments = self.volume_api.attachment_delete(context, attachment)
3 ^/ y' s/ @& ]2 R% j
N& {7 y- B' t: O k$ a2025-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
' c ]7 ~1 `) B5 J- A+ i
8 v+ F) a0 K/ b' M) u2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault self.attachment_deletion_allowed(ctxt, attachment)
5 o$ ], d( x( _0 l& l1 D8 A) A5 {
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 G; V6 k! Z- G1 P+ Q5 v; e/ m; W
5 `+ W# L& r1 k2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault raise exception.ConflictNovaUsingAttachment(instance_id=server_id)) l6 b6 x" a# I# Q1 j8 S
3 Z+ @! e! Y7 `6 w2025-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
% [# ]) @" J/ F
% o$ I- u7 G: N1 p$ R) g2 D. j2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault/ H0 v$ e. \2 L4 J' S( R
, a$ X! M& w% }: @, N( i; I
& ]/ R) b; |' t! N5 ? f/ _( O, O5 b% f0 Z$ x2 T& y' P& F
提示我using the Compute API
) H t" e0 p* q( P- X; f7 y于是我去设置如下的内容) d& Z* }$ e) R+ B, ~0 }- B
controller节点
8 c' g2 _) O0 F' b, t0 [5 N# {9 o; c' ]
vim /etc/nova/nova.conf, U5 P3 Y% ^4 V" Y1 {8 p7 `7 |
& q/ _- `8 M6 }- r# J0 ~0 j[cinder]
f" C0 G. [/ {7 n0 E/ Bsend_service_user_token = True #添加
8 O( P1 f% I0 B( E) B0 W& W
0 H, B- \! H. h
9 \( A+ u; j* Q1 K0 q2 ccompute节点6 y x8 N- h/ [
5 u+ L6 E6 X, B/ ?1 E0 o& z& X) qvim /etc/nova/nova.conf
' A9 O% v6 t( k5 |, M
& { Z+ S% }9 R( `. a) G% P[cinder]
; q6 S: I& y, Z- g) c Z/ Lsend_service_user_token = True #添加( v# n/ S- a7 w9 M# R( V0 H+ l
; x2 |; v2 ?4 y/ B
. }9 I* v3 I: p0 _& p; T. f但是没有解决,还是提示同样的问题6 s2 z2 y1 ]1 J2 [0 j
于是去查看源代码4 P5 f* |. J. z2 ]9 M( N
, Y2 z2 }8 ^+ i' k' S) C
在/usr/local/lib/python3.9/site-packages/cinder/volume/api.py
0 K6 W6 K8 c# L* x9 k: l5 A1 e, T0 z" V9 {, K
源代码如下
& c: A; G6 K' C; c0 F! G# a
) ^6 \0 q3 s: y- t8 ~def attachment_deletion_allowed(self,1 J% ^ w) k, f
ctxt: context.RequestContext,3 G U& `# X3 f+ _+ D* p. L& Q
attachment_or_attachment_id,
# _. _, M$ f" ]# Z. Z! q, b volume=None):8 ^3 b6 S, _: F* @& m, W( `, X
"""Check if deleting an attachment is allowed (Bug #2004555)- [* l( e, [8 N Q
4 @* C+ l! ?3 } Allowed is based on the REST API policy, the status of the attachment," h3 g& g3 _$ ?7 P
where it is used, and who is making the request.( n0 H" s& ^* T, Q$ N j
5 o; N: `% Q1 i: @( s Deleting an attachment on the Cinder side while leaving the volume: }! V9 k& O9 i8 F
connected to the nova host results in leftover devices that can lead to
0 B9 Q, E6 i& K! E% P3 b+ u. o data leaks/corruption.) L' s& t5 h8 T/ ` a c9 ]
4 `9 e A0 N) G. l* Q OS-Brick may have code to detect it, but in some cases it is detected
6 i Q o% p0 ]6 V6 L9 h: h after it has already been exposed, so it's better to prevent users from3 `- R& e( q% B X/ ]4 r/ K- {
being able to intentionally triggering the issue.
. ~& F: j- o/ I$ {, g" l( r, H """
, F/ k+ p {+ W5 q2 n- `/ g # It's ok to delete an attachment if the request comes from a service! M* o- ~( \) A1 G" i2 L6 ?) Y- M
if self.is_service_request(ctxt):
9 M( [8 |. @1 g/ r! u3 O return; J: a' j: ?* S- F9 ]( L4 X- \
! x* M* c$ B4 ~( p6 O if not attachment_or_attachment_id and volume:
8 X/ W4 u/ A9 y5 C4 q) X! x* Q if not volume.volume_attachment:
+ |9 [3 X8 N0 C1 b4 Y return
# M( w$ h5 Q$ J; [. l1 ]" ]6 j if len(volume.volume_attachment) == 1:$ Z! A2 c+ Y4 M
attachment_or_attachment_id = volume.volume_attachment[0]
& M0 L" ], \, O3 e) @+ J; i; R. w4 J, M0 L* J
if isinstance(attachment_or_attachment_id, str):
# S7 C, g+ H) R1 `5 q try:. C6 X/ ?( ]" V9 b: _$ b5 V
attachment = objects.VolumeAttachment.get_by_id(/ |5 b9 p0 C7 Q1 c1 \( b. o
ctxt, attachment_or_attachment_id)" P3 g e8 T3 ^
except exception.VolumeAttachmentNotFound:: g( O9 N n- a" P
attachment = None
- `2 W" r0 l3 f% u- G4 Q0 b else:* v$ b" @; O' ]2 m0 P$ R, p9 x
attachment = attachment_or_attachment_id
$ G. |5 V+ s) H0 M1 ]
3 x$ |; k* K4 o, s3 B I9 \8 \ if attachment:
# }! _; u2 W" n# | if volume:
7 h( j9 ?* a5 {) \ if volume.id != attachment.volume_id:
/ ^+ U( }7 y1 g3 a) |7 k1 j raise exception.InvalidInput(
# ]+ ~% c$ R" T2 ]1 J: s reason='Mismatched volume and attachment')
+ ^# V3 e% P' ?( U* W+ M9 G* c9 K4 m6 D9 J3 ^) p" N
server_id = attachment.instance_uuid
5 a8 [; J, d( P5 N: e # It's ok to delete if it's not connected to a vm.
' H, |6 F1 |/ j if not server_id or not attachment.connection_info:
# `/ \. H m7 u* J6 ~) ^: N2 D return6 V& ^0 X3 i+ ]- |0 J4 U1 V
. K' P* z, Y6 g/ _, I) Q volume = volume or attachment.volume& L2 [5 R" F' p- x0 }) m
nova = compute.API()
4 \4 k0 H2 n/ ?/ k LOG.info('Attachment connected to vm %s, checking data on nova',
5 W& q& r' ~/ n* |4 U/ p server_id)7 X* e; P$ g I6 a: i( n; ?
# If nova is down the client raises 503 and we report that
$ l: T, f i9 F& \8 H5 L& L try:) L( Q! A( C! s! ~2 H% i
nova_volume = nova.get_server_volume(ctxt, server_id,
, S( w2 ]7 L% a: t2 l/ G0 `% C0 C2 }! m volume.id)5 o, d* `! }. X6 \4 p3 p9 C3 ]/ M4 R" o
except nova.NotFound:
' e, G' ?* E! P5 B* m7 v- A LOG.warning('Instance or volume not found on Nova, deleting '+ n6 w; @* o2 M/ r" M, O& u
'attachment locally, which may leave leftover '
( [4 C, G. N6 O( V8 M 'devices on Nova compute')
+ k# @/ o3 N/ ^' t- A- w ~ return% e6 e+ P) A+ U Y- H
1 M0 R, d5 \# G4 F
if nova_volume.attachment_id != attachment.id:, S% |3 e4 q$ i/ V) {' | b p
LOG.warning('Mismatch! Nova has different attachment id (%s) '/ l8 o1 A; t7 e; F; G' T' [/ U. L
'for the volume, deleting attachment locally. '9 |* b) o$ E0 y! w0 J
'May leave leftover devices in a compute node',
- e+ W' l, v+ I. y8 ^, O. Z nova_volume.attachment_id)
8 _+ b. |1 J0 B( u9 Z$ P# r return2 v0 R& X5 m; T6 _0 M V' I
else:- ^ p- R8 c5 R) ]" |$ E' X8 U0 r
server_id = ''# k+ c1 a. g5 }
- N# i1 G: G# x) C. a
LOG.error('Detected user call to delete in-use attachment. Call must '
+ e: M( v& y8 g 'come from the nova service and nova must be configured to '
0 A1 s2 d' L3 A; Q7 B v, G- z3 _ 'send the service token. Bug #2004555')7 {, U* c" I* M0 C- U/ J
raise exception.ConflictNovaUsingAttachment(instance_id=server_id)
9 y& v0 I ]# |7 Q: C- \4 [8 D% d' U8 B& i7 Z* f5 a3 v
修改后的完整的代码如下- x. P9 V2 ]# s, N- U' E
% [7 C: K" C9 H2 x* J/ H8 m( vdef attachment_deletion_allowed(self,
4 i; R) w: ?) e- I: D ctxt: context.RequestContext,
* [- o J0 {* d attachment_or_attachment_id,# l) {1 ]+ O* t4 Z1 u/ w7 _; ^' c" f
volume=None):% ]0 [8 s# X' h9 u. Z
# 服务请求直接允许删除( f! O3 ^, T6 b3 U" E2 F8 Z- s
if self.is_service_request(ctxt):
7 q" s' c+ h/ d/ s return True
M; f2 s8 x! R0 J- Z2 L: m1 O! ^
# 参数验证- c* p8 W& y h
if not attachment_or_attachment_id and not volume:
7 p% i3 l3 b2 ]9 i raise exception.InvalidInput(reason='Either attachment or volume must be provided')6 I3 R3 v- z* m4 q P
8 e; \' s% b; h8 C5 b0 U0 s
# 获取 attachment
0 }1 F) s6 i+ @ if not attachment_or_attachment_id and volume:
% N) C+ I% J# d4 a if not volume.volume_attachment:9 e6 A8 |9 s# R6 I
return True
( j& _, S; N9 l if len(volume.volume_attachment) == 1:
4 K$ B9 @5 n. \# V+ ?% C w attachment_or_attachment_id = volume.volume_attachment[0]' s/ x$ P n: I
- z& o) Z- F! b/ x # 获取 attachment 对象 N# M' U8 o& \9 q
attachment = None
' c0 M! Y+ F6 a2 O1 ^4 t if isinstance(attachment_or_attachment_id, str):/ a8 D2 f% d3 Q ]* z3 e
try:
0 v, F, v" @6 ] attachment = objects.VolumeAttachment.get_by_id(! y" L7 m1 X% Q8 f
ctxt, attachment_or_attachment_id)% h! P1 p! S$ O7 _. U: n" f
except exception.VolumeAttachmentNotFound:
/ p- Z& X' t' `/ O t/ ]6 v return True # 如果找不到 attachment,允许删除
7 b3 z' L6 M6 m7 D$ V/ W% {, V" h$ e. o' r' ?
else:( l) `5 s% o/ B% c! e, c. M2 H
attachment = attachment_or_attachment_id. V5 Q) U" y; U9 m/ A; f
0 h2 B! v* P0 ~
if not attachment:4 p7 e( Y/ S3 X$ j1 x
return True
4 g/ O7 T- ]# M* S
2 ?# m2 n |: e5 |- b% d # 验证 volume 和 attachment 的关系. R$ d) A9 e+ d/ u1 b& C/ \
if volume and volume.id != attachment.volume_id:* X! ?# m/ u4 h8 y6 i5 J2 _% }: H
raise exception.InvalidInput() z& ]1 F' q k' U8 i/ N
reason='Mismatched volume and attachment')( W& n" G+ f" }4 Z
# n) F/ n9 d0 J, D& L& I# I7 n # 检查是否连接到 VM
2 ] z( V9 y$ h& A' ] server_id = attachment.instance_uuid8 s/ c9 ]4 x! v" M
if not server_id or not attachment.connection_info:
5 |/ |( {9 J- M( ? return True( D2 _$ z* _4 P2 Q2 T4 {% F
1 _: \6 D7 p- c$ e # 检查 Nova 端的状态
) |# A6 X8 M& ~$ v [ volume = volume or attachment.volume9 J! z( z* p/ Z! q: g! m |
nova = compute.API()( [# N+ R- v% z4 f: {9 t% K" p
try:+ c) \# s; y$ J7 h
nova_volume = nova.get_server_volume(ctxt, server_id, volume.id)$ ~6 @! d8 \2 } ?
except nova.NotFound:7 |, b. c3 z f
LOG.warning('Instance or volume not found on Nova, deleting '
; B1 t! n& G o! ~2 o5 `; W 'attachment locally, which may leave leftover '/ S, Z+ p6 |& Y, s3 |* ~ H0 [
'devices on Nova compute')
) z8 P0 a; x' l( E) v; X return True
8 q& n. G. ~: ?: {; P6 `
$ g! }+ {" Q' e: W- j8 ^ if nova_volume.attachment_id != attachment.id:8 X2 V7 T1 ~% w p* {7 }# z
LOG.warning('Mismatch! Nova has different attachment id (%s) '( F* P# R2 z" I" \: T, r
'for the volume, deleting attachment locally. '
1 l1 d0 @9 _7 j$ @# l. E# C4 n 'May leave leftover devices in a compute node',0 z, }" E% t6 a/ b3 B+ o
nova_volume.attachment_id)
$ n0 f, P- @$ \4 g9 w6 N return True+ [6 A4 y' y( t! [) g9 R q
1 D, z/ L! {! B8 d: A: ?
# 检查实例的其他附件
A( ?; X4 y$ n* e! l" C try:7 j8 l) F. s; W. O/ n
attachments = objects.VolumeAttachmentList.get_all_by_instance_uuid(
7 E( T2 {3 M; k/ L5 W: V J6 i6 j1 B ctxt, attachment.instance_uuid)9 Q, u3 u+ g, V$ J- I
if attachments:
+ r" H" U' p' o2 T' x4 Y LOG.info("Instance %s has other attachments: %s",* Y& f* X! J' j" b7 T5 l
attachment.instance_uuid,; j/ v: s' y9 p4 F7 s8 [6 h9 T
[att.id for att in attachments])
( M3 i' [! w ?$ O return False
! J# h: o6 Q5 Z/ _' a! X else:8 T' V2 f9 p' U5 S- ?3 y% C9 s' |
LOG.info("No other attachments found for instance %s",
( |. m* X! W' Y( i+ V9 `' Q attachment.instance_uuid)
' y& U8 F7 `8 t7 Q/ x7 L) ] return True! ? }& c: i# O! N1 ^4 D& H( ~( k5 q
except Exception as e:
! `5 H# d4 M# F; q$ n LOG.error("Failed to retrieve attachments for instance %s: %s",1 q% t" P4 `% a9 \# _
attachment.instance_uuid, str(e))
4 ~0 K# w& s h% {" m/ `! ~ raise exception.VolumeBackendAPIException(reason=str(e))/ p$ p( x# y' H. j
3 s! P3 P# E7 W# F! L" q. @
6 K& c2 O3 D: a8 O最终成功解决,但是这个方法不是很严谨. ?% _, l) F: f! x0 S4 x
' U' \4 {. u3 I" G$ x
/ M3 T) m; e9 B& ?% I# }% G
|
|