o x[h@srdZddlZddlZddlZddlZddlmZddlmZddl m Z e e Z defddZGd d d ZdS) z#A module for common socket helpers.N)suppress) performance)DEFAULT_RUN_DIRmessagecCstjdd}|s dS|ddkr|dddn |ddkr#td ttjtjtjB}t d t || || |d WddS1sOwYdS) z[Send a sd_notify message. :param message: sd-notify message (must be valid ascii) NOTIFY_SOCKETNr@/zUnsupported socket typezSending sd_notify(%s)ascii)osenvirongetreplaceOSErrorsocketAF_UNIX SOCK_DGRAM SOCK_CLOEXECLOGinfostrconnectsendallencode)r socket_pathsockr2/usr/lib/python3/dist-packages/cloudinit/socket.py sd_notifys   "r c@s<eZdZdZdefddZdefddZdd Zd d Zd S) SocketSyncz>s z'SocketSync.__init__..z/shareiT)modeexist_ok/share/z.sockN)stageremotefirst_exceptionsystemd_exit_codeexperienced_any_errorsocketsr makedirsritemsrFileNotFoundErrorremovebind)selfr"r$rrrrr__init__-s     zSocketSync.__init__r)cCs"||jvr td|||_|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))r4r)rrr__call__Ms zSocketSync.__call__cCsttjrtddSd|_td|j d|j |j }t d|j | d\}|_Wdn1s=wYd|krW|dddtd t|d td |j d t|jkrt|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,r r)r.rTimedrecvfromr*__exit__r6rr)r4rchunkrrr __enter__as2 zSocketSync.__enter__cCsd|j}|r,d|_d|_t|d|j}d}|js ||_t|td||jp3t |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+rfatalr boolr.rr*rrclose)r4exc_typeexc_valexc_tbrstatusrrrrr@s*    zSocketSync.__exit__N) __name__ __module__ __qualname____doc__rr5r7rBr@rrrrr!*s   'r!)rPloggingr rr; contextlibr cloudinitrcloudinit.settingsr getLoggerrMrrr r!rrrrs