diff --git a/conf/taskotron.yaml.example b/conf/taskotron.yaml.example
--- a/conf/taskotron.yaml.example
+++ b/conf/taskotron.yaml.example
@@ -132,10 +132,11 @@
 ## Url of an image to download and use for disposable client, if force_imageurl was set
 #imageurl: http://download.fedoraproject.org/pub/fedora/linux/releases/23/Cloud/x86_64/Images/Fedora-Cloud-Base-23-20151030.x86_64.qcow2
 
-## Temporary options to define release/flavor/arch for the disposable images discovery
-#disposable_release: 23
-#disposable_flavor: taskotron_cloud
-#disposable_arch: x86_64
+## Default  distro/release/flavor/arch for the disposable images discovery
+#default_disposable_distro: fedora
+#default_disposable_release: 23
+#default_disposable_flavor: taskotron_cloud
+#default_disposable_arch: x86_64
 
 ## Additional repos for minion to install packages from
 #minion_repos:
diff --git a/libtaskotron/config_defaults.py b/libtaskotron/config_defaults.py
--- a/libtaskotron/config_defaults.py
+++ b/libtaskotron/config_defaults.py
@@ -80,9 +80,10 @@
                'releases/23/Cloud/x86_64/Images/Fedora-Cloud-'\
                'Base-23-20151030.x86_64.qcow2'                              #:
     force_imageurl = True                                                   #:
-    disposable_release = '23'                                               #:
-    disposable_flavor = 'taskotron_cloud'                                   #:
-    disposable_arch = 'x86_64'                                              #:
+    default_disposable_distro = 'fedora'                                    #:
+    default_disposable_release = '23'                                       #:
+    default_disposable_flavor = 'taskotron_cloud'                           #:
+    default_disposable_arch = 'x86_64'                                      #:
 
     minion_repos = [
         'https://copr.fedorainfracloud.org/coprs/tflink/taskotron/repo/fedora-23/'
diff --git a/libtaskotron/ext/disposable/vm.py b/libtaskotron/ext/disposable/vm.py
--- a/libtaskotron/ext/disposable/vm.py
+++ b/libtaskotron/ext/disposable/vm.py
@@ -46,8 +46,12 @@
         #: hostname to use for spawned instance - based on username of current user
         self.hostname = 'taskotron-%s' % getpass.getuser()
 
-    def _prepare_image(self):
+    def _prepare_image(self, distro=None, release=None, flavor=None, arch=None):
         '''Use testcloud to prepare an image for local booting
+        :param str distro: Distro to use in image discovery
+        :param str release: Distro's release to use in image discovery
+        :param str flavor: base-image flavor to use in image discovery
+        :param str arch: arch to use in image discovery
         :raises TaskotronImageNotFoundError: when base image of the required type is not found
         :raises TaskotronImageError: for errors in preparing the image with testcloud
         '''
@@ -58,11 +62,19 @@
             if config.get_config().force_imageurl:
                 img_url = config.get_config().imageurl
             else:
-                # FIXME: release/flavor/arch should be provided from formula (?)
+                distro = distro or config.get_config().default_disposable_distro
+                release = release or config.get_config().default_disposable_release
+                flavor = flavor or config.get_config().default_disposable_flavor
+                arch = arch or config.get_config().default_disposable_arch
+
+                log.debug("Looking for image with DISTRO: %s, RELEASE: %s, FLAVOR: %s, ARCH: %s" %
+                          (distro, release, flavor, arch))
+
                 img_url = ImageFinder.get_latest(
-                    release=config.get_config().disposable_release,
-                    flavor=config.get_config().disposable_flavor,
-                    arch=config.get_config().disposable_arch
+                    distro=distro,
+                    release=release,
+                    flavor=flavor,
+                    arch=arch
                     )
         except exc.TaskotronImageNotFoundError, e:
             log.error(e)
@@ -110,14 +122,18 @@
                                                "already defined".format(self.instancename))
         return existing_instance
 
-    def prepare(self):
+    def prepare(self, distro=None, release=None, flavor=None, arch=None):
         '''Prepare a virtual machine for running tasks.
+        :param str distro: Distro to use in image discovery
+        :param str release: Distro's release to use in image discovery
+        :param str flavor: base-image flavor to use in image discovery
+        :param str arch: arch to use in image discovery
 
         :raises TaskotronRemoteError: if there are any errors while preparing
                                       the virtual machine.
        '''
 
-        tc_image = self._prepare_image()
+        tc_image = self._prepare_image(distro, release, flavor, arch)
 
         self._check_existing_instance(should_exist=False)
 
@@ -209,9 +225,10 @@
         return os.listdir(imagesdir)
 
     @classmethod
-    def get_latest(cls, release, flavor, arch='x86_64', imagesdir=None):
+    def get_latest(cls, distro, release, flavor, arch='x86_64', imagesdir=None):
         """Search for the most recent image available on the system.
 
+        :param distro: distro of the image (e.g. ``fedora``)
         :param release: release of the image (e.g. ``23``)
         :param flavor: flavor of the image (e.g. ``minimal``)
         :param imagesdir: absolute path to directory containing the images, path from config is
@@ -225,19 +242,22 @@
         if not imagesdir:
             imagesdir = config.get_config().imagesdir
 
-        latest_metadata = cls.get_latest_metadata(release, flavor, arch, imagesdir)
+        latest_metadata = cls.get_latest_metadata(distro, release, flavor, arch, imagesdir)
 
         if not latest_metadata:
             raise exc.TaskotronImageNotFoundError(
-                'No image for release %s, flavor %s, arch %s in %s' %
-                (release, flavor, arch, imagesdir))
+                'No image for DISTRO: %s, RELEASE: %s, FLAVOR: %s, ARCH: %s in %s' %
+                (distro, release, flavor, arch, imagesdir))
         else:
-            return "file://" + os.path.join(imagesdir, latest_metadata['filename'])
+            url = "file://" + os.path.join(imagesdir, latest_metadata['filename'])
+            log.debug("Found image: %s" % url)
+            return url
 
     @classmethod
-    def get_latest_metadata(cls, release, flavor, arch='x86_64', imagesdir=None):
+    def get_latest_metadata(cls, distro, release, flavor, arch='x86_64', imagesdir=None):
         """Search for the most recent image available on the system.
 
+        :param distro: distro of the image (e.g. ``fedora``)
         :param release: release of the image (e.g. ``23``)
         :param flavor: flavor of the image (e.g. ``minimal``)
         :param imagesdir: absolute path to directory containing the images, path from config is
@@ -248,22 +268,30 @@
         :rtype: dict {'date': str, 'version': str, 'release': str, 'arch': str, 'filename': str}
         """
 
+        if not imagesdir:
+            imagesdir = config.get_config().imagesdir
+
         release = str(release)
-        # The pattern is: YYMMDD_HHMM-fedora-RELEASE-FLAVOR-ARCH.(qcow2|raw|img)
+        # The pattern is: YYMMDD_HHMM-DISTRO-RELEASE-FLAVOR-ARCH.(qcow2|raw|img)
         # For example:    160301_1030-fedora-23-taskotron_cloud-x86_64.img
-        pattern = re.compile(r'^([0-9]{6}_[0-9]{4})-fedora-(.*?)-(.*?)-(.*?)\.(qcow2|raw|img)$')
+        pattern = re.compile(r'^([0-9]{6}_[0-9]{4})-(.*?)-(.*?)-(.*?)-(.*?)\.(qcow2|raw|img)$')
 
         images = []
         for filename in cls.get_all_filenames(imagesdir):
             m = pattern.match(filename)
             if m:
                 images.append({'timestamp': m.group(1),
-                               'release': m.group(2),
-                               'flavor': m.group(3),
-                               'arch': m.group(4),
+                               'distro': m.group(2),
+                               'release': m.group(3),
+                               'flavor': m.group(4),
+                               'arch': m.group(5),
                                'filename': filename})
 
-        filtered = [i for i in images if i['release'] == release and i['flavor'] == flavor and i['arch'] == arch]
+        filtered = [
+            i for i in images if
+            i['distro'] == distro and i['release'] == release and
+            i['flavor'] == flavor and i['arch'] == arch
+            ]
         if not filtered:
             return None
         else:
diff --git a/libtaskotron/minion.py b/libtaskotron/minion.py
--- a/libtaskotron/minion.py
+++ b/libtaskotron/minion.py
@@ -13,6 +13,7 @@
 from libtaskotron import remote_exec
 from libtaskotron import python_utils
 from libtaskotron.logger import log
+from libtaskotron import taskformula
 import libtaskotron.exceptions as exc
 
 try:
@@ -182,8 +183,11 @@
             log.info("Running task on a disposable client using libvirt...")
 
             log.info("Creating VM for task")
+
+            env = taskformula.devise_environment(self.formula, self.arg_data)
+
             task_vm = vm.TestCloudMachine(self.arg_data['uuid'])
-            task_vm.prepare()
+            task_vm.prepare(**env)
             self.machine = task_vm.ipaddr
             self.port = 22
             self.user = task_vm.username
diff --git a/libtaskotron/taskformula.py b/libtaskotron/taskformula.py
--- a/libtaskotron/taskformula.py
+++ b/libtaskotron/taskformula.py
@@ -11,6 +11,7 @@
 
 from libtaskotron import exceptions as exc
 from libtaskotron.logger import log
+from libtaskotron.ext.fedora import rpm_utils
 
 
 def _replace_vars(text, variables):
@@ -107,3 +108,87 @@
             elif isinstance(child_val, collections.Iterable):
                 # traversable further down, mark for visit
                 stack.append(child_val)
+
+
+def devise_environment(formula, arg_data):
+    '''Takes a parsed formula, and returns a required run-environment (i.e.
+    distro, arch, fedora release, and base-image flavor), based on item and type.
+
+    :param dict formula: parsed formula file (or dict with equivalent structure)
+    :param dict arg_data: parsed command-line arguments. item, type and arch
+                          are used in this method
+    :return: dict containing release, flavor, arch. Each either set, or None
+    :raise TaskotronValueError: when environment can't be parsed from the formula
+    '''
+
+    environment = formula.get('environment', {})
+    env = {'distro': None, 'release': None, 'flavor': None, 'arch': None}
+
+    if not isinstance(environment, dict):
+        raise exc.TaskotronValueError(
+            "Environment must be dictionary, not %s" % type(environment))
+
+    env['distro'] = environment.get('distro', None)
+    env['release'] = environment.get('release', None)
+    env['flavor'] = environment.get('flavor', None)
+    env['arch'] = environment.get('arch', None)
+
+    item = arg_data.get('item', None)
+    item_type = arg_data.get('type', None)
+
+    if not env['distro']:
+        if item_type == 'koji_build':
+            # FIXME: find a way to make this not Fedora-specific
+            # For `xchat-2.8.8-21.fc20` disttag is `fc20` for example
+            try:
+                distro = rpm_utils.get_dist_tag(item)[:2]
+                env['distro'] = {'fc': 'fedora'}.get(distro, None)
+            except exc.TaskotronValueError:
+                env['distro'] = None
+
+            if env['distro']:
+                log.debug("Environment/distro inferred from %s:%r to %r" %
+                          (item_type, item, env['distro']))
+            else:
+                log.debug("Environment/distro can not be inferred from %s:%r. "
+                          "Using default." % (item_type, item))
+        else:
+            log.debug("Environment/distro can not be inferred for %r. Using default." %
+                      item_type)
+
+    if not env['release']:
+        if item_type == 'koji_build':
+            # FIXME: find a way to make this not Fedora-specific
+            # Last two characters in rpm's disttag are the Fedora release.
+            # For `xchat-2.8.8-21.fc20` disttag is `fc20` for example
+            try:
+                env['release'] = rpm_utils.get_dist_tag(item)[-2:]
+            except exc.TaskotronValueError:
+                env['release'] = None
+
+            if env['release']:
+                log.debug("Environment/release inferred from %s:%r to %r" %
+                          (item_type, item, env['release']))
+            else:
+                log.debug("Environment/release can not be inferred from %s:%r. "
+                          "Using default." % (item_type, item))
+
+        else:
+            log.debug("Environment/release can not be inferred for %r. Using default." %
+                      item_type)
+
+    if not env['flavor']:
+        log.debug("Environment/flavor not specified. Using default")
+
+    if not env['arch']:
+        arches = [i for i in arg_data.get('arch', []) if i != 'noarch']
+
+        if arches and len(arches) == 1:
+            env['arch'] = arches[0]
+            log.debug("Environment/arch inferred from %r to %r" %
+                      (arg_data.get('arch', []), env['arch']))
+        else:
+            log.warn("Environment/arch can not be inferred from %r. Using default." %
+                     arg_data.get('arch', []))
+
+    return env
diff --git a/testing/test_taskformula.py b/testing/test_taskformula.py
--- a/testing/test_taskformula.py
+++ b/testing/test_taskformula.py
@@ -129,3 +129,52 @@
         with pytest.raises(exc.TaskotronYamlError):
             taskformula._replace_vars('${foo} $', {'foo': 'bar'})
 
+
+class TestDeviseEnvironment(object):
+    def test_raise_invalid_env(self):
+        with pytest.raises(exc.TaskotronValueError):
+            taskformula.devise_environment({'environment': ''}, None)
+
+    def test_empty_env_no_infer_data(self):
+        res = taskformula.devise_environment({}, {})
+        assert res == {'distro': None, 'release': None, 'flavor': None, 'arch': None}
+
+    def test_env_defined_no_infer_needed(self):
+        env = {'distro': 'rhel',
+               'release': 'el7.5',
+               'flavor': 'awesome_albatros',
+               'arch': 'i386'}
+        ret = taskformula.devise_environment({'environment': env}, {})
+        assert ret == env
+
+    def test_infer_from_koji_build(self):
+        arg_data = {"type": "koji_build", "item": "xchat-2.8.8-21.fc20"}
+        ret = taskformula.devise_environment({'environment': {}}, arg_data)
+        assert ret == {'distro': 'fedora', 'release': '20', 'flavor': None, 'arch': None}
+
+    def test_infer_from_koji_build_unknown_distro(self):
+        arg_data = {"type": "koji_build", "item": "xchat-2.8.8-21.XY20"}
+        ret = taskformula.devise_environment({'environment': {}}, arg_data)
+        assert ret == {'distro': None, 'release': None, 'flavor': None, 'arch': None}
+
+    def test_infer_from_arch(self):
+        arg_data = {"arch": []}
+        ret = taskformula.devise_environment({'environment': {}}, arg_data)
+        assert ret == {'distro': None, 'release': None, 'flavor': None, 'arch': None}
+
+        arg_data = {"arch": ['noarch']}
+        ret = taskformula.devise_environment({'environment': {}}, arg_data)
+        assert ret == {'distro': None, 'release': None, 'flavor': None, 'arch': None}
+
+        arg_data = {"arch": ['i386']}
+        ret = taskformula.devise_environment({'environment': {}}, arg_data)
+        assert ret == {'distro': None, 'release': None, 'flavor': None, 'arch': 'i386'}
+
+    def test_infer_from_multiple_arches(self):
+        arg_data = {"arch": ['i386', 'noarch']}
+        ret = taskformula.devise_environment({'environment': {}}, arg_data)
+        assert ret == {'distro': None, 'release': None, 'flavor': None, 'arch': 'i386'}
+
+        arg_data = {"arch": ['i386', 'x86_64']}
+        ret = taskformula.devise_environment({'environment': {}}, arg_data)
+        assert ret == {'distro': None, 'release': None, 'flavor': None, 'arch': None}
diff --git a/testing/test_vm.py b/testing/test_vm.py
--- a/testing/test_vm.py
+++ b/testing/test_vm.py
@@ -175,34 +175,37 @@
                        '151007_0516-fedora-rawhide-minimal-x86_64.qcow2',
                        'windows10.raw',
                        '151008_0315-fedora-23-minimal-i386.qcow2',
-                       '151008_0315-fedora-23-minimal-x86_64.qcow2']
+                       '151008_0315-fedora-23-minimal-x86_64.qcow2',
+                       '151008_0315-ubuntu-fabulous_fanthom-minimal-x86_64.qcow2']
         self.stub_list_images = Dingus()
         monkeypatch.setattr(vm.ImageFinder, 'get_all_filenames', self.stub_list_images)
 
 
     def test_dir_populated(self):
         self.stub_list_images.return_value = self.images
 
-        assert vm.ImageFinder.get_latest_metadata('23', 'minimal', 'i386', '')['filename'] ==\
+        assert vm.ImageFinder.get_latest_metadata('fedora', '23', 'minimal', 'i386', '')['filename'] ==\
             '151008_0315-fedora-23-minimal-i386.qcow2'
-        assert vm.ImageFinder.get_latest_metadata('23', 'minimal', 'x86_64', '')['filename'] ==\
+        assert vm.ImageFinder.get_latest_metadata('fedora', '23', 'minimal', 'x86_64', '')['filename'] ==\
             '151008_0315-fedora-23-minimal-x86_64.qcow2'
+        assert vm.ImageFinder.get_latest_metadata('ubuntu', 'fabulous_fanthom', 'minimal', 'x86_64', '')['filename'] ==\
+            '151008_0315-ubuntu-fabulous_fanthom-minimal-x86_64.qcow2'
 
 
     def test_dir_populated_single(self):
         self.stub_list_images.return_value = self.images
 
-        assert vm.ImageFinder.get_latest_metadata('23', 'cloud', 'x86_64', '')['filename'] ==\
+        assert vm.ImageFinder.get_latest_metadata('fedora', '23', 'cloud', 'x86_64', '')['filename'] ==\
             '151008_0427-fedora-23-cloud-x86_64.qcow2'
-        assert vm.ImageFinder.get_latest_metadata('rawhide', 'minimal', 'x86_64', '')['filename'] ==\
+        assert vm.ImageFinder.get_latest_metadata('fedora', 'rawhide', 'minimal', 'x86_64', '')['filename'] ==\
             '151007_0516-fedora-rawhide-minimal-x86_64.qcow2'
 
     def test_dir_empty(self):
         self.stub_list_images.return_value = []
 
-        assert vm.ImageFinder.get_latest_metadata('23', 'minimal', '') is None
+        assert vm.ImageFinder.get_latest_metadata('fedora', '23', 'minimal', '') is None
 
     def test_no_such_image(self):
         self.stub_list_images.return_value = self.images
 
-        assert vm.ImageFinder.get_latest_metadata('69', 'ultimate', '') is None
+        assert vm.ImageFinder.get_latest_metadata('fedora', '69', 'ultimate', '') is None

