nodes: 0, module; 1, function_definition; 2, function_name:subvolume_list; 3, parameters; 4, block; 5, identifier:path; 6, default_parameter; 7, default_parameter; 8, default_parameter; 9, default_parameter; 10, default_parameter; 11, default_parameter; 12, default_parameter; 13, default_parameter; 14, default_parameter; 15, default_parameter; 16, default_parameter; 17, default_parameter; 18, default_parameter; 19, default_parameter; 20, expression_statement; 21, if_statement; 22, expression_statement; 23, if_statement; 24, expression_statement; 25, expression_statement; 26, expression_statement; 27, if_statement; 28, if_statement; 29, comment:# We already validated the content of the list; 30, if_statement; 31, expression_statement; 32, expression_statement; 33, expression_statement; 34, comment:# Parse the output. ID and gen are always at the begining, and; 35, comment:# path is always at the end. There is only one column that; 36, comment:# contains space (top level), and the path value can also have; 37, comment:# spaces. The issue is that we do not know how many spaces do we; 38, comment:# have in the path name, so any classic solution based on split; 39, comment:# will fail.; 40, comment:#; 41, comment:# This list is in order.; 42, expression_statement; 43, expression_statement; 44, for_statement; 45, return_statement; 46, identifier:parent_id; 47, False; 48, identifier:absolute; 49, False; 50, identifier:ogeneration; 51, False; 52, identifier:generation; 53, False; 54, identifier:subvolumes; 55, False; 56, identifier:uuid; 57, False; 58, identifier:parent_uuid; 59, False; 60, identifier:sent_subvolume_uuid; 61, False; 62, identifier:snapshots; 63, False; 64, identifier:readonly; 65, False; 66, identifier:deleted; 67, False; 68, identifier:generation_cmp; 69, None; 70, identifier:ogeneration_cmp; 71, None; 72, identifier:sort; 73, None; 74, string; 75, boolean_operator; 76, block; 77, assignment; 78, boolean_operator; 79, block; 80, assignment; 81, assignment; 82, call; 83, identifier:generation_cmp; 84, block; 85, identifier:ogeneration_cmp; 86, block; 87, identifier:sort; 88, block; 89, call; 90, assignment; 91, call; 92, assignment; 93, assignment; 94, identifier:line; 95, call; 96, block; 97, identifier:result; 98, string_content:List the subvolumes present in the filesystem.
  
      path
          Mount point for the subvolume
  
      parent_id
          Print parent ID
  
      absolute
          Print all the subvolumes in the filesystem and distinguish
          between absolute and relative path with respect to the given
          <path>
  
      ogeneration
          Print the ogeneration of the subvolume
  
      generation
          Print the generation of the subvolume
  
      subvolumes
          Print only subvolumes below specified <path>
  
      uuid
          Print the UUID of the subvolume
  
      parent_uuid
          Print the parent uuid of subvolumes (and snapshots)
  
      sent_subvolume_uuid
          Print the UUID of the sent subvolume, where the subvolume is
          the result of a receive operation
  
      snapshots
          Only snapshot subvolumes in the filesystem will be listed
  
      readonly
          Only readonly subvolumes in the filesystem will be listed
  
      deleted
          Only deleted subvolumens that are ye not cleaned
  
      generation_cmp
          List subvolumes in the filesystem that its generation is >=,
          <= or = value. '+' means >= value, '-' means <= value, If
          there is neither '+' nor '-', it means = value
  
      ogeneration_cmp
          List subvolumes in the filesystem that its ogeneration is >=,
          <= or = value
  
      sort
          List subvolumes in order by specified items. Possible values:
          * rootid
          * gen
          * ogen
          * path
          You can add '+' or '-' in front of each items, '+' means
          ascending, '-' means descending. The default is ascending. You
          can combite it in a list.
  
      CLI Example:
  
      .. code-block:: bash
  
          salt '*' btrfs.subvolume_list /var/volumes/tmp
          salt '*' btrfs.subvolume_list /var/volumes/tmp path=True
          salt '*' btrfs.subvolume_list /var/volumes/tmp sort='[-rootid]'; 99, identifier:sort; 100, comparison_operator:type(sort) is not list; 101, raise_statement; 102, identifier:valid_sorts; 103, list_comprehension; 104, identifier:sort; 105, not_operator; 106, raise_statement; 107, identifier:cmd; 108, list; 109, identifier:params; 110, tuple; 111, attribute; 112, generator_expression; 113, expression_statement; 114, expression_statement; 115, expression_statement; 116, attribute; 117, argument_list; 118, identifier:res; 119, call; 120, attribute; 121, argument_list; 122, identifier:columns; 123, tuple; 124, identifier:result; 125, list; 126, attribute; 127, argument_list; 128, expression_statement; 129, for_statement; 130, comment:# If line is not empty here, we are not able to parse it; 131, if_statement; 132, call; 133, identifier:list; 134, call; 135, call; 136, for_in_clause; 137, call; 138, call; 139, string; 140, string; 141, string; 142, tuple; 143, tuple; 144, tuple; 145, tuple; 146, tuple; 147, tuple; 148, tuple; 149, tuple; 150, tuple; 151, tuple; 152, tuple; 153, identifier:cmd; 154, identifier:extend; 155, subscript; 156, for_in_clause; 157, if_clause; 158, call; 159, call; 160, call; 161, identifier:cmd; 162, identifier:append; 163, identifier:path; 164, subscript; 165, argument_list; 166, attribute; 167, identifier:_verify_run; 168, identifier:res; 169, string; 170, string; 171, string; 172, string; 173, string; 174, string; 175, string; 176, string; 177, string; 178, string; 179, subscript; 180, identifier:splitlines; 181, assignment; 182, identifier:key; 183, identifier:columns; 184, block; 185, not_operator; 186, block; 187, identifier:type; 188, argument_list; 189, identifier:CommandExecutionError; 190, argument_list; 191, attribute; 192, argument_list; 193, pattern_list; 194, call; 195, identifier:all; 196, generator_expression; 197, identifier:CommandExecutionError; 198, argument_list; 199, string_content:btrfs; 200, string_content:subvolume; 201, string_content:list; 202, identifier:parent_id; 203, string; 204, identifier:absolute; 205, string; 206, identifier:ogeneration; 207, string; 208, identifier:generation; 209, string; 210, identifier:subvolumes; 211, string; 212, identifier:uuid; 213, string; 214, identifier:parent_uuid; 215, string; 216, identifier:sent_subvolume_uuid; 217, string; 218, identifier:snapshots; 219, string; 220, identifier:readonly; 221, string; 222, identifier:deleted; 223, string; 224, identifier:p; 225, integer:1; 226, identifier:p; 227, identifier:params; 228, subscript; 229, attribute; 230, argument_list; 231, attribute; 232, argument_list; 233, attribute; 234, argument_list; 235, identifier:__salt__; 236, string; 237, identifier:cmd; 238, attribute; 239, identifier:fsutils; 240, string_content:ID; 241, string_content:gen; 242, string_content:cgen; 243, string_content:parent; 244, string_content:top level; 245, string_content:otime; 246, string_content:parent_uuid; 247, string_content:received_uuid; 248, string_content:uuid; 249, string_content:path; 250, identifier:res; 251, string; 252, identifier:table; 253, dictionary; 254, expression_statement; 255, if_statement; 256, identifier:line; 257, expression_statement; 258, identifier:sort; 259, string; 260, string; 261, identifier:join; 262, tuple; 263, identifier:order; 264, identifier:attrib; 265, attribute; 266, argument_list; 267, comparison_operator:s in valid_sorts; 268, for_in_clause; 269, string; 270, string_content:-p; 271, string_content:-a; 272, string_content:-c; 273, string_content:-g; 274, string_content:-o; 275, string_content:-u; 276, string_content:-q; 277, string_content:-R; 278, string_content:-s; 279, string_content:-r; 280, string_content:-d; 281, identifier:p; 282, integer:0; 283, identifier:cmd; 284, identifier:extend; 285, list; 286, identifier:cmd; 287, identifier:extend; 288, list; 289, identifier:cmd; 290, identifier:append; 291, call; 292, string_content:cmd.run_all; 293, identifier:salt; 294, identifier:utils; 295, string_content:stdout; 296, assignment; 297, identifier:value; 298, block; 299, call; 300, string_content:Sort parameter must be a list; 301, identifier:order; 302, identifier:attrib; 303, identifier:itertools; 304, identifier:product; 305, tuple; 306, tuple; 307, identifier:s; 308, identifier:valid_sorts; 309, identifier:s; 310, identifier:sort; 311, string_content:Value for sort not recognized; 312, string; 313, identifier:generation_cmp; 314, string; 315, identifier:ogeneration_cmp; 316, attribute; 317, argument_list; 318, pattern_list; 319, call; 320, expression_statement; 321, attribute; 322, argument_list; 323, string; 324, string; 325, string; 326, string; 327, string; 328, string; 329, string; 330, string_content:-G; 331, string_content:-C; 332, string; 333, identifier:format; 334, call; 335, identifier:value; 336, identifier:line; 337, identifier:_pop; 338, argument_list; 339, assignment; 340, identifier:result; 341, identifier:append; 342, identifier:table; 343, string_content:-; 344, string_content:+; 345, string_content:rootid; 346, string_content:gen; 347, string_content:ogen; 348, string_content:path; 349, string_content:--sort={}; 350, attribute; 351, argument_list; 352, identifier:line; 353, identifier:key; 354, comparison_operator:key == 'path'; 355, subscript; 356, identifier:value; 357, string; 358, identifier:join; 359, identifier:sort; 360, identifier:key; 361, string; 362, identifier:table; 363, call; 364, string_content:,; 365, string_content:path; 366, attribute; 367, argument_list; 368, identifier:key; 369, identifier:lower
code: def subvolume_list(path, parent_id=False, absolute=False,
                     ogeneration=False, generation=False,
                     subvolumes=False, uuid=False, parent_uuid=False,
                     sent_subvolume_uuid=False, snapshots=False,
                     readonly=False, deleted=False, generation_cmp=None,
                     ogeneration_cmp=None, sort=None):
      '''
      List the subvolumes present in the filesystem.
  
      path
          Mount point for the subvolume
  
      parent_id
          Print parent ID
  
      absolute
          Print all the subvolumes in the filesystem and distinguish
          between absolute and relative path with respect to the given
          <path>
  
      ogeneration
          Print the ogeneration of the subvolume
  
      generation
          Print the generation of the subvolume
  
      subvolumes
          Print only subvolumes below specified <path>
  
      uuid
          Print the UUID of the subvolume
  
      parent_uuid
          Print the parent uuid of subvolumes (and snapshots)
  
      sent_subvolume_uuid
          Print the UUID of the sent subvolume, where the subvolume is
          the result of a receive operation
  
      snapshots
          Only snapshot subvolumes in the filesystem will be listed
  
      readonly
          Only readonly subvolumes in the filesystem will be listed
  
      deleted
          Only deleted subvolumens that are ye not cleaned
  
      generation_cmp
          List subvolumes in the filesystem that its generation is >=,
          <= or = value. '+' means >= value, '-' means <= value, If
          there is neither '+' nor '-', it means = value
  
      ogeneration_cmp
          List subvolumes in the filesystem that its ogeneration is >=,
          <= or = value
  
      sort
          List subvolumes in order by specified items. Possible values:
          * rootid
          * gen
          * ogen
          * path
          You can add '+' or '-' in front of each items, '+' means
          ascending, '-' means descending. The default is ascending. You
          can combite it in a list.
  
      CLI Example:
  
      .. code-block:: bash
  
          salt '*' btrfs.subvolume_list /var/volumes/tmp
          salt '*' btrfs.subvolume_list /var/volumes/tmp path=True
          salt '*' btrfs.subvolume_list /var/volumes/tmp sort='[-rootid]'
  
      '''
      if sort and type(sort) is not list:
          raise CommandExecutionError('Sort parameter must be a list')
  
      valid_sorts = [
          ''.join((order, attrib)) for order, attrib in itertools.product(
              ('-', '', '+'), ('rootid', 'gen', 'ogen', 'path'))
      ]
      if sort and not all(s in valid_sorts for s in sort):
          raise CommandExecutionError('Value for sort not recognized')
  
      cmd = ['btrfs', 'subvolume', 'list']
  
      params = ((parent_id, '-p'),
                (absolute, '-a'),
                (ogeneration, '-c'),
                (generation, '-g'),
                (subvolumes, '-o'),
                (uuid, '-u'),
                (parent_uuid, '-q'),
                (sent_subvolume_uuid, '-R'),
                (snapshots, '-s'),
                (readonly, '-r'),
                (deleted, '-d'))
      cmd.extend(p[1] for p in params if p[0])
  
      if generation_cmp:
          cmd.extend(['-G', generation_cmp])
  
      if ogeneration_cmp:
          cmd.extend(['-C', ogeneration_cmp])
  
      # We already validated the content of the list
      if sort:
          cmd.append('--sort={}'.format(','.join(sort)))
  
      cmd.append(path)
  
      res = __salt__['cmd.run_all'](cmd)
      salt.utils.fsutils._verify_run(res)
  
      # Parse the output. ID and gen are always at the begining, and
      # path is always at the end. There is only one column that
      # contains space (top level), and the path value can also have
      # spaces. The issue is that we do not know how many spaces do we
      # have in the path name, so any classic solution based on split
      # will fail.
      #
      # This list is in order.
      columns = ('ID', 'gen', 'cgen', 'parent', 'top level', 'otime',
                 'parent_uuid', 'received_uuid', 'uuid', 'path')
      result = []
      for line in res['stdout'].splitlines():
          table = {}
          for key in columns:
              value, line = _pop(line, key, key == 'path')
              if value:
                  table[key.lower()] = value
          # If line is not empty here, we are not able to parse it
          if not line:
              result.append(table)
  
      return result