func()

in cmd/ntpcheck/checker/chrony.go [82:157]


func (n *ChronyCheck) Run() (*NTPCheckResult, error) {
	var packet chrony.ResponsePacket
	var err error
	result := NewNTPCheckResult()
	// tracking data
	trackReq := chrony.NewTrackingPacket()
	packet, err = n.Client.Communicate(trackReq)
	if err != nil {
		return nil, errors.Wrap(err, "failed to get 'tracking' response")
	}
	log.Debugf("Got 'tracking' response:")
	log.Debugf("Status: %v", packet.GetStatus())
	tracking, ok := packet.(*chrony.ReplyTracking)
	if !ok {
		return nil, errors.Errorf("Got wrong 'tracking' response %+v", packet)
	}
	result.Correction = tracking.CurrentCorrection
	result.LIDesc = control.LeapDesc[uint8(tracking.LeapStatus)]
	result.LI = uint8(tracking.LeapStatus)
	result.Event = "clock_sync" // no real events for chrony
	result.SysVars = NewSystemVariablesFromChrony(tracking)

	// sources list
	sourcesReq := chrony.NewSourcesPacket()
	packet, err = n.Client.Communicate(sourcesReq)
	if err != nil {
		return nil, errors.Wrap(err, "failed to get 'sources' response")
	}
	sources, ok := packet.(*chrony.ReplySources)
	if !ok {
		return nil, errors.Errorf("Got wrong 'sources' response %+v", packet)
	}
	log.Debugf("Got %d sources", sources.NSources)

	// per-source data
	for i := 0; i < int(sources.NSources); i++ {
		log.Debugf("Fetching source #%d info", i)
		sourceDataReq := chrony.NewSourceDataPacket(int32(i))
		packet, err = n.Client.Communicate(sourceDataReq)
		if err != nil {
			return nil, errors.Wrapf(err, "failed to get 'sourcedata' response for source #%d", i)
		}
		sourceData, ok := packet.(*chrony.ReplySourceData)
		if !ok {
			return nil, errors.Errorf("Got wrong 'sourcedata' response %+v", packet)
		}
		// get ntpdata when using a unix socket
		var ntpData *chrony.ReplyNTPData
		if sourceData.Mode != chrony.SourceModeRef && n.Unix() {
			ntpDataReq := chrony.NewNTPDataPacket(sourceData.IPAddr)
			packet, err = n.Client.Communicate(ntpDataReq)
			if err != nil {
				return nil, errors.Wrapf(err, "failed to get 'ntpdata' response for source #%d", i)
			}
			ntpData, ok = packet.(*chrony.ReplyNTPData)
			if !ok {
				return nil, errors.Errorf("Got wrong 'ntpdata' response %+v", packet)
			}
		}
		peer, err := NewPeerFromChrony(sourceData, ntpData)
		if err != nil {
			return nil, errors.Wrapf(err, "failed to create Peer structure from response packet for peer=%s", sourceData.IPAddr)
		}
		result.Peers[uint16(i)] = peer
		// if main sync source, update ClockSource info
		if sourceData.State == chrony.SourceStateSync {
			if sourceData.Mode == chrony.SourceModeRef {
				result.ClockSource = "local"
			} else {
				result.ClockSource = "ntp"
			}
		}
	}

	return result, nil
}