a 'Dg@srdZddlZddlZddlZddlZddlmZddlmZddl m Z e e Z edddZGd d d ZdS) z#A module for common socket helpers.N)suppress) performance)DEFAULT_RUN_DIR)messagecCstjdd}|sdS|ddkr2|dddn|ddkrFtd ttjtjtjB:}t d t || || |d Wdn1s0YdS) z[Send a sd_notify message. :param message: sd-notify message (must be valid ascii) Z NOTIFY_SOCKETNr@/zUnsupported socket typezSending sd_notify(%s)ascii)osenvirongetreplaceOSErrorsocketAF_UNIX SOCK_DGRAM SOCK_CLOEXECLOGinfostrconnectsendallencode)r socket_pathsockr4/usr/lib/python3.9/site-packages/cloudinit/socket.py sd_notifys   rc@s<eZdZdZedddZedddZdd Zd d Zd S) SocketSyncz>sz'SocketSync.__init__..z/shareiT)modeexist_ok/share/z.sockN)stageremotefirst_exceptionsystemd_exit_codeexperienced_any_errorsocketsr makedirsritemsrFileNotFoundErrorremoveZbind)selfr!r#rrrrr__init__-s  (zSocketSync.__init__)r(cCs"||jvrtd|||_|S)aSet the stage before entering context. This enables the context manager to be initialized separately from each stage synchronization. :param stage: the name of a stage to synchronize Example: sync = SocketSync("stage 1", "stage 2"): with sync("stage 1"): pass with sync("stage 2"): pass zInvalid stage name: )r- ValueErrorr()r2r(rrr__call__Ms zSocketSync.__call__cCsttjrtddSd|_td|j d|j |j }t d|j  | d\}|_Wdn1sz0Yd|kr|dddtd t|d n:td |j d t|jkr|dddtd |jtd|j d|S)zWait until a message has been received on this stage's socket. Once the message has been received, enter the context. z:Stdin is a tty, so skipping stage synchronization protocolNrzDSTATUS=Waiting on external services to complete before starting the z stage.zWaiting to start stage sstartzReceived invalid message: []r'z -return.sockz Unexpected path to unix socket: zSTATUS=Running (z stage))r isattysysstdinfilenorrr+rr(r-rZTimedZrecvfromr)__exit__r4rr)r2rchunkrrr __enter__as0 .zSocketSync.__enter__cCsd|j}|rXd|_d|_t|d|j}d}|js@||_t|td||jpft |j|_|j |j}| |j | d|d|jd |dS) z.Notify the socket that this stage is complete.z,Completed socket interaction for boot stage r Tz in zkfatal error, run "systemctl status cloud-init-main.service" and "cloud-init status --long" for more detailszSTATUS=zecho 'z'; exit ;)r(r+r,reprtb_framer*rZfatalrboolr-rr)rrclose)r2exc_typeZexc_valZexc_tbrstatusrrrrr<s*    zSocketSync.__exit__N) __name__ __module__ __qualname____doc__rr3r5r>r<rrrrr *s  'r )rIZloggingr rr9 contextlibrZ cloudinitrZcloudinit.settingsrZ getLoggerrFrrrr rrrrs