- 积分
- 16843
在线时间 小时
最后登录1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?开始注册
x
解决办法(不太严谨)- c" [0 j5 K& U1 _4 o1 M1 V
根据日志提示( P p' w9 V' X% n, h
" \8 M7 }- ^* v2025-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
( N. W3 a3 z' ^& X% P) S2025-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 API5 [+ D1 K' u9 l* \
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault Traceback (most recent call last):
1 m# `0 v+ M e8 N2025-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__
# K: G8 p# j8 j6 l, J' C2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return req.get_response(self.application)
# c8 O) R* E/ G/ i2 {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
0 w# m2 I0 @# i# M/ l5 _) G2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault status, headers, app_iter = self.call_application(" U) Y: u! P7 V9 U2 S6 e+ e: z
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 l- n& Z) i/ k5 T2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault app_iter = application(self.environ, start_response)
5 k! M8 t6 ~9 D! S' 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__% k' v8 ~2 R) T7 n" Q- w
. l7 U J& M0 h( c
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return resp(environ, start_response)% `" }- c, f2 s0 U! ?
8 B; }* P0 U. z! A6 k2025-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 o. n) b; T* r7 G. M1 t' y8 x, j8 G% p0 O9 T& }
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault resp = self.call_func(req, *args, **kw)8 e. G2 j; s( L+ U4 ]2 {
+ f6 o% V8 ]; m* A 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: l h2 @! `4 }0 ~; _5 s
& Z( K9 X8 u4 J0 |) Q1 D' d8 ~3 x
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return self.func(req, *args, **kwargs)) X5 A- u& A: j9 ?! w. ^
2 Y" V3 q0 {+ @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__" S: B+ f2 g1 o7 \! S' }+ l: x* o8 q
8 c% c% h, Q5 j. `8 E/ q
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return request.get_response(self.application)! X4 D+ q3 x Q: E
2 x1 i& @- v- X* o2025-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
' N' o3 | r* c' p$ }# ^' v* I7 c! x7 b! k' F
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault status, headers, app_iter = self.call_application(
' V! }, U, R4 g. \- ^
" h7 T: a9 f) K2025-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
! x7 X1 ~% i* H7 F- a0 P; ?& z* L$ i J& m9 {" t, {3 h4 H
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault app_iter = application(self.environ, start_response)
' m$ P5 P+ k$ B. D
/ P6 f- k S. O: y% w* U: C: w2025-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__
; A2 M; \% L0 B, u1 a0 G: B9 f4 D
* F0 {: w5 L( Y3 u: g. D2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault resp = self.call_func(req, *args, **kw)
. o1 }( x2 ]' Y1 z- u4 } U M( a4 r9 Q) }" d/ y+ @2 T/ T w
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. {, {; v& f% f' k
9 t% j) C( f, t" a' {2 {& E; e+ f2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return self.func(req, *args, **kwargs)
2 j4 p; ~7 c4 s" a7 p
8 l2 W8 F( P# A4 ~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__% B1 u% t5 u8 |' ?- m. }
8 o# ~' e' j8 W" ?/ u; |2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault response = req.get_response(self._app), J L" ]1 k' m
9 \: b# z9 y& c) Z2025-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
% e" p% o3 t5 `! a3 @( L0 c, S8 g: M; ]: d2 l' g& q" w7 E
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault status, headers, app_iter = self.call_application(
- H- G7 N' m# r# O9 G: M' I2 x
' N0 l' h" i; ~ t" K2025-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
1 b3 l0 B- q/ C, {
$ A2 `. c9 ?: A# P1 [$ W# ]2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault app_iter = application(self.environ, start_response)3 l3 w! N. i; F% e/ C* G8 T" e
2 D: o' ~6 T+ t4 d4 ^3 O2 e5 S
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__0 W, d0 [+ ?0 x0 y6 j
0 a1 k; v: U8 A T, U" E2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return resp(environ, start_response)7 d; _( E$ J$ P9 ]
( V0 }- e0 P4 w: I5 A9 W
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__
- S8 b; N% W1 P0 h8 G8 ^: R1 I. A* q! {) [# d- g
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return resp(environ, start_response)
- W" a& ~$ ?; p( ?+ F+ v, }5 r N5 Q: V
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__
! x1 I7 C% p# W. B( g# B
: y$ M* B8 Z6 x2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault response = self.app(environ, start_response)8 I5 X4 i1 {2 ?" e4 L7 I0 u: g
/ h' t2 z. t4 N: G' [# N2025-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__
3 {% } |, o6 l& V
$ f3 S e1 G( c4 F: T# u0 A2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return resp(environ, start_response)% ]- y( X$ a+ u: R2 }" Z3 c/ o: F) q
, W- Y! D) @& U6 e0 w5 c) K
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__' ^- P6 _6 ]8 G) l& O
- L, \, x. M: e1 C2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault resp = self.call_func(req, *args, **kw)" m7 ?: k$ {) [
& i9 R3 F/ Z7 Z. @3 ~' T1 [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
0 e6 b" l1 r l# N. c# {+ Y6 X' Z: U9 r8 x O) z
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return self.func(req, *args, **kwargs)3 T4 n7 K5 q5 a. U+ d
8 w" e7 t# T- ~/ a. N9 f
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__* u5 {# v8 t" g, x+ z
. ` x. g7 V3 d- h& x
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return self._process_stack(request, action, action_args,
0 K' k+ T3 h$ c7 W* T3 W4 L0 b2 h4 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 900, in _process_stack
' c ?2 G( B( C. [
) ?" h. w7 j% k5 Y( ?2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault action_result = self.dispatch(meth, request, action_args)
$ i$ H$ W9 Q+ l5 {: h: j% ]& [* l* K$ 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 995, in dispatch
+ q2 n! a+ y; E% U( |2 M6 Y' W5 c: D( P, p9 K5 E/ n
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return method(req=request, **action_args)
. U4 X' h; w+ Q2 f W
2 D' P& J2 z- n/ E2025-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 M8 S" i- [/ j8 F( ~
$ Y9 w% b; n5 H) X2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault return func.func(self, *args, **kwargs)
. U* P. w$ T# Y3 J: s+ K# O, R3 I4 {1 a- ]0 u
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 o$ M5 P( g) c
- j$ l; l5 M' Q: ^! a- F2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault attachments = self.volume_api.attachment_delete(context, attachment)
* o( b' d; Q3 _$ J, g, p+ o- h M
1 |9 t7 ?+ N; W$ x$ f: I2025-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
$ O; f- L! |5 r% ?: p2 V6 M) W- j1 a# s# C! s( x
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault self.attachment_deletion_allowed(ctxt, attachment)8 s+ x, t9 j* |* _
% ?0 r7 t6 ~8 @. s8 \) l. _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_allowed5 Z, ?, w6 k/ b" {! [9 v
# L9 t! J# v4 d L( T2 v
2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault raise exception.ConflictNovaUsingAttachment(instance_id=server_id)
. }1 f0 {7 d4 r6 j6 q' T+ y3 q! I( i; }$ Y5 r' ^ O# K! k
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: r. f4 X7 G, h% ^
$ v5 C5 L3 W- [# s3 w: \5 F2025-01-27 20:08:29.656 59902 ERROR cinder.api.middleware.fault, Q( c" Q+ q' b- T
0 H* f) x8 K# C
/ |( C5 T% r1 y
" N: C+ T. W, G提示我using the Compute API
% P. d; s8 s0 N" |于是我去设置如下的内容
' x: b9 d0 V# v( qcontroller节点6 e, j$ N# H" {, L. r8 t3 ?) l
7 a3 X5 i0 @6 G c5 y
vim /etc/nova/nova.conf
/ {! I+ r- k2 h4 [7 ~( g4 l- X/ k9 Q- |- ]% z
[cinder]. I. V1 k+ o1 q: @* J
send_service_user_token = True #添加
/ K1 @# Z- C" O% d) K
$ e/ b6 K4 l0 q4 E
3 A$ [* t' O: |4 b% E* B8 p( Xcompute节点. ]' x+ G S8 N4 u, F* a+ h) ~
( r) R; K. |& @- [vim /etc/nova/nova.conf; n. N" [8 W: F& q0 R4 g: H
+ |: o; L H* b' w
[cinder]; S/ h4 b) q' I& U' H& h7 ?- ^0 U
send_service_user_token = True #添加( ^- @3 l% ^" _8 L
# \) n; G) Z4 g1 x
* y, M. Y* }7 S但是没有解决,还是提示同样的问题
& U# ]9 s' @- K8 Z4 T7 D于是去查看源代码
7 _5 H; i' V! O3 z7 P. {5 p- S6 v/ U
在/usr/local/lib/python3.9/site-packages/cinder/volume/api.py
) Q4 v7 v1 ?0 `: ~1 R5 k% `% S' |! z9 E, [8 t3 Q0 Q
源代码如下
9 _1 t/ `3 ]! A$ c, L) Y2 t V) O% m
def attachment_deletion_allowed(self,
5 I1 d( L" `5 B; x1 g$ c ctxt: context.RequestContext,8 J- ^& f/ }5 L& R2 M. K& O) X
attachment_or_attachment_id,: o; m. t" p f8 V
volume=None):) O1 G3 T# T# p
"""Check if deleting an attachment is allowed (Bug #2004555)
g% e$ m/ w- F* ?4 ]" F1 X" L/ h& } N1 ?' {# A- I
Allowed is based on the REST API policy, the status of the attachment,% o, e9 r ]1 A7 K
where it is used, and who is making the request.( e3 L& D' a- I9 Z( K; I
9 ]1 m5 p9 {4 g, d
Deleting an attachment on the Cinder side while leaving the volume C9 i( o, v R
connected to the nova host results in leftover devices that can lead to
3 w! u! c K& p- M- _/ g data leaks/corruption.- x. j: h+ b& r& B1 Z) a
* n1 l" N' T- B! u OS-Brick may have code to detect it, but in some cases it is detected; C9 _7 l9 x. d3 A) A/ n% v
after it has already been exposed, so it's better to prevent users from/ x/ f0 t0 c0 L. V
being able to intentionally triggering the issue.
$ I0 A9 b# }& _' O7 } """! J3 H: v3 K9 t: i! ]0 q5 V' h
# It's ok to delete an attachment if the request comes from a service9 B: C2 `: S R3 r+ E
if self.is_service_request(ctxt):
/ {4 k& Q+ P8 _9 i return
# d) t3 X, K2 c3 o& E6 w; C1 E
+ Y. w8 p% X9 h" B$ { if not attachment_or_attachment_id and volume:
6 o! c0 I H- _- X if not volume.volume_attachment:( L, ?1 A8 c, X0 U
return
$ x) s+ b8 `- A( z8 ^* _. z. g if len(volume.volume_attachment) == 1:
) q. i; L# I/ E. X8 {. ~ attachment_or_attachment_id = volume.volume_attachment[0]! E3 v: }# ~% ?
8 O- Y' [7 w" m; l; q B0 u if isinstance(attachment_or_attachment_id, str):
$ e* o+ f" @ A/ [+ Z try:
o; h( {* ?' e& F# Q' K attachment = objects.VolumeAttachment.get_by_id(
, I: g: B- h) K$ P) K3 A: c ctxt, attachment_or_attachment_id)8 D* L, x3 _2 b+ d( f* B0 V7 ^$ \
except exception.VolumeAttachmentNotFound:
2 T) o/ P1 N3 a! F7 h z7 g, U attachment = None! r2 V2 @) o' s z; C9 ?
else:5 u9 ?9 ^% u% V: {
attachment = attachment_or_attachment_id; m7 W. t7 Q7 r; S2 F+ w
2 J0 A1 D2 u9 A8 R7 I if attachment:
% ^. P: `0 t- t3 O if volume:
' b+ k$ L; |0 h1 O: I% w% |9 J5 G if volume.id != attachment.volume_id:
! X) J5 \0 g5 g* K1 l0 I raise exception.InvalidInput(' [- o; O+ Y" @5 u
reason='Mismatched volume and attachment')& D J; r! F: F) Z
- m& ]! V' l( Z/ S
server_id = attachment.instance_uuid
: t- q, F F3 \5 Y # It's ok to delete if it's not connected to a vm.$ e3 U- R& I ^
if not server_id or not attachment.connection_info:4 U9 H% W' m4 [* @6 Q5 q
return6 v+ }( q* j2 [. b2 T
& E/ Q' e9 x$ \, p
volume = volume or attachment.volume; w$ V( V- k9 W1 n: W! ~ w2 Q
nova = compute.API()
7 g- W' S# \9 ~7 M" |! i LOG.info('Attachment connected to vm %s, checking data on nova',
/ C" C' w7 j2 l4 o server_id) z: \- i3 P! a. S
# If nova is down the client raises 503 and we report that J4 H, ^$ v5 X0 N* `, u0 ~. S
try:
0 O+ R2 W. @% L1 y nova_volume = nova.get_server_volume(ctxt, server_id,
$ k7 [. f5 ~+ Q volume.id)" b) [4 ^% X- P+ C& c9 ?% B/ k6 \
except nova.NotFound:" Q; Y0 C* P0 N. o+ Z! ^
LOG.warning('Instance or volume not found on Nova, deleting '9 R2 J9 l3 p. Y0 v- J" i. U: H3 C8 z
'attachment locally, which may leave leftover '1 V" m' K; u7 @6 B
'devices on Nova compute')" n6 e6 C9 W4 E/ `
return
* `" K6 m- \$ u+ v0 L" u0 m1 K" N% h5 M
if nova_volume.attachment_id != attachment.id:
; E& o* @7 C: k+ O- x LOG.warning('Mismatch! Nova has different attachment id (%s) '
( I, W9 A2 y8 j' r2 q T, {7 Q 'for the volume, deleting attachment locally. '
& a9 U# I8 o# Z9 O 'May leave leftover devices in a compute node',+ V) S5 {! O. I: I
nova_volume.attachment_id)
; c# K+ g- ?1 G" ? return# f* M; ]4 R5 o5 E( L* w& @
else: f8 B4 P% e" I, ~7 X/ h8 h- S
server_id = ''2 X* [, j# u$ z c& i: ~4 |
$ O) l( u7 r2 g* I; P! F# p
LOG.error('Detected user call to delete in-use attachment. Call must '7 L: a: K- e. S$ J: k! M; W8 l* B$ y
'come from the nova service and nova must be configured to '
; y* k8 N* `: u: F; J2 r 'send the service token. Bug #2004555')( M& s4 r2 A9 }: ~* m, r
raise exception.ConflictNovaUsingAttachment(instance_id=server_id), J: o2 l- h" Y; E
- n/ h1 O% x! U3 f/ q
修改后的完整的代码如下1 R- a7 E" m6 Z% }7 J. f
! C, @- E* v G6 ] C
def attachment_deletion_allowed(self,3 y2 _- x ?( y5 E7 t( y: J
ctxt: context.RequestContext,
8 ^) B+ V) J+ p. q- [" c attachment_or_attachment_id,' m& Y( z6 A z- G- ^
volume=None):' @6 f4 S9 R8 Q( o' m; S
# 服务请求直接允许删除7 X! U$ D* F8 q) X$ L
if self.is_service_request(ctxt):
; w1 S9 C3 k6 }( f2 n return True% t. ^2 U$ _: T( k
. o8 ~& |9 P, O
# 参数验证7 x& s" y8 `6 Q# q3 A
if not attachment_or_attachment_id and not volume:
& x4 T$ Y0 r( a raise exception.InvalidInput(reason='Either attachment or volume must be provided')
+ K8 n( b% b7 ^" A6 c* }
9 `$ W/ F; ^! ^5 e2 O4 T# _ # 获取 attachment5 V4 e' b0 J' ]/ L2 r! ^! N
if not attachment_or_attachment_id and volume:
6 e% n; F O5 ~3 a) y if not volume.volume_attachment:
/ c- z" {3 x/ C8 Q- P! r) i return True
. J5 b* q$ D9 d) [' v2 y* }; d' ` if len(volume.volume_attachment) == 1:
6 S( r, _) c6 j$ c' ^7 o+ `2 V attachment_or_attachment_id = volume.volume_attachment[0], L" K! @; [9 @; F- s2 ?
9 O' o4 e, s, f$ {5 `- }5 j
# 获取 attachment 对象
/ G( p# _, Y3 ]5 A attachment = None. j& k2 `! G# z; k0 q7 q
if isinstance(attachment_or_attachment_id, str):
9 M; `( \: ~5 J8 f2 S try:* c( w2 w4 Q$ Q2 G2 G
attachment = objects.VolumeAttachment.get_by_id(
# E/ l% t+ B# v5 T- E7 G5 q ctxt, attachment_or_attachment_id)
$ } ~$ S$ S0 k: S3 r: f- J' p0 W except exception.VolumeAttachmentNotFound:+ N4 g2 K! L1 H0 D; g
return True # 如果找不到 attachment,允许删除
t( G+ C: ~; k- X# G$ j2 K' k, c2 H0 S ]
else:5 v$ H0 I2 s* j$ W/ K/ E
attachment = attachment_or_attachment_id7 h- e% r5 O8 {- ?2 ]
% Y( A0 r& Q: o" k' x if not attachment:
* ^% h, H( x6 y- m1 y+ o return True6 f1 n+ q. U# d- ]$ ]: S$ k
# y9 P# P7 |8 y7 }- R. D # 验证 volume 和 attachment 的关系
& R. O4 r5 o3 s) ] if volume and volume.id != attachment.volume_id:8 v% O) l7 T4 R$ o
raise exception.InvalidInput(
j+ x/ E" u2 x* D reason='Mismatched volume and attachment')# y( A1 x; w; e; d6 }
3 l) v: W B. G/ D. N # 检查是否连接到 VM
% a \ n8 @- o' P3 g9 e server_id = attachment.instance_uuid
3 k0 Q# F5 a! G6 Z) H if not server_id or not attachment.connection_info:
; e( R+ L. W' l( V' k, }8 y return True2 T$ ~7 |- a7 A% S
# ]& f4 j" b2 u% z # 检查 Nova 端的状态
" R5 v( ?: y- ^ volume = volume or attachment.volume
A; K9 B& Y) C7 r- b nova = compute.API()# f4 D" O( z- O) f- J
try:
! p" F& F$ m$ e K" q8 B" ~ nova_volume = nova.get_server_volume(ctxt, server_id, volume.id)
! h% D0 x) L0 L4 S3 z except nova.NotFound:
5 V, t- f8 s. b0 {! l8 H( K LOG.warning('Instance or volume not found on Nova, deleting '
4 L, L @7 N% h. T 'attachment locally, which may leave leftover '. L8 R) I& S2 i3 {
'devices on Nova compute')
6 a5 {' g: v+ M9 T return True
( {+ K1 n( P5 z
9 T' A$ U' A* ] if nova_volume.attachment_id != attachment.id:# n @# l& _- P& x7 w
LOG.warning('Mismatch! Nova has different attachment id (%s) '1 X. X0 r" }1 X3 [" c
'for the volume, deleting attachment locally. '8 N, B2 _) _7 D: z% R- r
'May leave leftover devices in a compute node',
4 `& g! M/ ]- U9 m. j0 R nova_volume.attachment_id)) }' m+ ~4 j& N3 p
return True
* ~& B# f9 k: v$ w" T6 L# U8 K$ I$ t( O& N2 J
# 检查实例的其他附件. j5 S% g! P- F! _; e
try:0 ]" `4 L$ @ z1 a* E* C
attachments = objects.VolumeAttachmentList.get_all_by_instance_uuid(
7 G( W9 a' ~0 K' [! D0 I' {" q* Q, m ctxt, attachment.instance_uuid)- j; k3 V* h; w3 Z3 c( o8 F
if attachments:
0 o9 G3 H3 K5 r) _ LOG.info("Instance %s has other attachments: %s",6 C8 G* b0 G" O0 `# b; T
attachment.instance_uuid,
+ N( z& \, y {) ]. ]; { [att.id for att in attachments])
+ ]3 O/ g+ p0 `; `' S a* l return False
; n' C6 `/ d) X2 H- }3 D else:
/ S8 L2 ?' C2 J LOG.info("No other attachments found for instance %s",' l8 s) W3 a6 L& W7 d/ G
attachment.instance_uuid)
a3 s9 @: }+ A# W$ a: d% e( ] return True7 E1 ~& X# o7 a8 ~/ k% h( z
except Exception as e:1 O& X* ]3 y* k; w9 s
LOG.error("Failed to retrieve attachments for instance %s: %s",
; J) f, u; ^$ N& H- D7 Y4 | attachment.instance_uuid, str(e))( w; S1 r/ s. f
raise exception.VolumeBackendAPIException(reason=str(e))
T: c3 X2 M$ d$ L( r ^" S; H3 f: P {, C$ }8 }9 n
$ \+ G8 X5 b2 d9 N0 d* k. D最终成功解决,但是这个方法不是很严谨
0 i9 v. Y) k. H0 U" { m! ^" ^3 u/ c/ w6 T! f% U& j) g! W6 i
! A* @ U" ]( i2 ? |
|