lxd/db/containers.go
func (c *ClusterTx) ContainersListByNodeAddress(project string) (map[string][]string, error) {
	offlineThreshold, err := c.NodeOfflineThreshold()
	if err != nil {
		return nil, err
	}

	stmt := `
SELECT containers.name, nodes.id, nodes.address, nodes.heartbeat
  FROM containers
  JOIN nodes ON nodes.id = containers.node_id
  JOIN projects ON projects.id = containers.project_id
  WHERE containers.type=?
    AND projects.name = ?
  ORDER BY containers.id
`
	rows, err := c.tx.Query(stmt, CTypeRegular, project)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	result := map[string][]string{}

	for i := 0; rows.Next(); i++ {
		var name string
		var nodeAddress string
		var nodeID int64
		var nodeHeartbeat time.Time
		err := rows.Scan(&name, &nodeID, &nodeAddress, &nodeHeartbeat)
		if err != nil {
			return nil, err
		}
		if nodeID == c.nodeID {
			nodeAddress = ""
		} else if nodeIsOffline(offlineThreshold, nodeHeartbeat) {
			nodeAddress = "0.0.0.0"
		}
		result[nodeAddress] = append(result[nodeAddress], name)
	}

	err = rows.Err()
	if err != nil {
		return nil, err
	}
	return result, nil
}
func (c *ClusterTx) ContainersListByNodeAddress(project string) (map[string][]string, error) {
	offlineThreshold, err := c.NodeOfflineThreshold()
	if err != nil {
		return nil, err
	}

	stmt := `
SELECT containers.name, nodes.id, nodes.address, nodes.heartbeat
  FROM containers
  JOIN nodes ON nodes.id = containers.node_id
  JOIN projects ON projects.id = containers.project_id
  WHERE containers.type=?
    AND projects.name = ?
  ORDER BY containers.id
`
	rows, err := c.tx.Query(stmt, CTypeRegular, project)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	result := map[string][]string{}

	for i := 0; rows.Next(); i++ {
		var name string
		var nodeAddress string
		var nodeID int64
		var nodeHeartbeat time.Time
		err := rows.Scan(&name, &nodeID, &nodeAddress, &nodeHeartbeat)
		if err != nil {
			return nil, err
		}
		if nodeID == c.nodeID {
			nodeAddress = ""
		} else if nodeIsOffline(offlineThreshold, nodeHeartbeat) {
			nodeAddress = "0.0.0.0"
		}
		result[nodeAddress] = append(result[nodeAddress], name)
	}

	err = rows.Err()
	if err != nil {
		return nil, err
	}
	return result, nil
}
// ContainersListByNodeAddress returns the names of all containers grouped by
// cluster node address.
//
// The node address of containers running on the local node is set to the empty
// string, to distinguish it from remote nodes.
//
// Containers whose node is down are addeded to the special address "0.0.0.0".